Merge "Add windowIsFloating to window blur documentation" into sc-dev
diff --git a/apex/appsearch/framework/api/current.txt b/apex/appsearch/framework/api/current.txt
index 5a2f702..30fb4c6 100644
--- a/apex/appsearch/framework/api/current.txt
+++ b/apex/appsearch/framework/api/current.txt
@@ -98,13 +98,13 @@
method @NonNull public android.app.appsearch.AppSearchSchema.DoublePropertyConfig.Builder setCardinality(int);
}
- public static final class AppSearchSchema.Int64PropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
+ public static final class AppSearchSchema.LongPropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
}
- public static final class AppSearchSchema.Int64PropertyConfig.Builder {
- ctor public AppSearchSchema.Int64PropertyConfig.Builder(@NonNull String);
- method @NonNull public android.app.appsearch.AppSearchSchema.Int64PropertyConfig build();
- method @NonNull public android.app.appsearch.AppSearchSchema.Int64PropertyConfig.Builder setCardinality(int);
+ public static final class AppSearchSchema.LongPropertyConfig.Builder {
+ ctor public AppSearchSchema.LongPropertyConfig.Builder(@NonNull String);
+ method @NonNull public android.app.appsearch.AppSearchSchema.LongPropertyConfig build();
+ method @NonNull public android.app.appsearch.AppSearchSchema.LongPropertyConfig.Builder setCardinality(int);
}
public abstract static class AppSearchSchema.PropertyConfig {
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 c1fcd6c..3619a56 100644
--- a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java
@@ -182,7 +182,7 @@
@IntDef(
value = {
DATA_TYPE_STRING,
- DATA_TYPE_INT64,
+ DATA_TYPE_LONG,
DATA_TYPE_DOUBLE,
DATA_TYPE_BOOLEAN,
DATA_TYPE_BYTES,
@@ -195,7 +195,7 @@
public static final int DATA_TYPE_STRING = 1;
/** @hide */
- public static final int DATA_TYPE_INT64 = 2;
+ public static final int DATA_TYPE_LONG = 2;
/** @hide */
public static final int DATA_TYPE_DOUBLE = 3;
@@ -315,8 +315,8 @@
switch (propertyBundle.getInt(PropertyConfig.DATA_TYPE_FIELD)) {
case PropertyConfig.DATA_TYPE_STRING:
return new StringPropertyConfig(propertyBundle);
- case PropertyConfig.DATA_TYPE_INT64:
- return new Int64PropertyConfig(propertyBundle);
+ case PropertyConfig.DATA_TYPE_LONG:
+ return new LongPropertyConfig(propertyBundle);
case PropertyConfig.DATA_TYPE_DOUBLE:
return new DoublePropertyConfig(propertyBundle);
case PropertyConfig.DATA_TYPE_BOOLEAN:
@@ -485,8 +485,13 @@
}
}
- /** Configuration for a property containing a 64-bit integer. */
- public static final class Int64PropertyConfig extends PropertyConfig {
+ /**
+ * @deprecated TODO(b/181887768): Exists for dogfood transition; must be removed.
+ * @hide
+ */
+ @Deprecated
+ @UnsupportedAppUsage(implicitMember = "")
+ public static class Int64PropertyConfig extends PropertyConfig {
Int64PropertyConfig(@NonNull Bundle bundle) {
super(bundle);
}
@@ -497,6 +502,7 @@
private @Cardinality int mCardinality = CARDINALITY_OPTIONAL;
/** Creates a new {@link Int64PropertyConfig.Builder}. */
+ @UnsupportedAppUsage
public Builder(@NonNull String propertyName) {
mPropertyName = Objects.requireNonNull(propertyName);
}
@@ -509,6 +515,7 @@
*/
@SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
@NonNull
+ @UnsupportedAppUsage
public Int64PropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
Preconditions.checkArgumentInRange(
cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
@@ -518,16 +525,61 @@
/** Constructs a new {@link Int64PropertyConfig} from the contents of this builder. */
@NonNull
+ @UnsupportedAppUsage
public Int64PropertyConfig build() {
Bundle bundle = new Bundle();
bundle.putString(NAME_FIELD, mPropertyName);
- bundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_INT64);
+ bundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_LONG);
bundle.putInt(CARDINALITY_FIELD, mCardinality);
return new Int64PropertyConfig(bundle);
}
}
}
+ /** Configuration for a property containing a 64-bit integer. */
+ // TODO(b/181887768): This should extend directly from PropertyConfig
+ public static final class LongPropertyConfig extends Int64PropertyConfig {
+ LongPropertyConfig(@NonNull Bundle bundle) {
+ super(bundle);
+ }
+
+ /** Builder for {@link LongPropertyConfig}. */
+ public static final class Builder {
+ private final String mPropertyName;
+ private @Cardinality int mCardinality = CARDINALITY_OPTIONAL;
+
+ /** Creates a new {@link LongPropertyConfig.Builder}. */
+ public Builder(@NonNull String propertyName) {
+ mPropertyName = Objects.requireNonNull(propertyName);
+ }
+
+ /**
+ * The cardinality of the property (whether it is optional, required or repeated).
+ *
+ * <p>If this method is not called, the default cardinality is {@link
+ * PropertyConfig#CARDINALITY_OPTIONAL}.
+ */
+ @SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
+ @NonNull
+ public LongPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
+ Preconditions.checkArgumentInRange(
+ cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
+ mCardinality = cardinality;
+ return this;
+ }
+
+ /** Constructs a new {@link LongPropertyConfig} from the contents of this builder. */
+ @NonNull
+ public LongPropertyConfig build() {
+ Bundle bundle = new Bundle();
+ bundle.putString(NAME_FIELD, mPropertyName);
+ bundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_LONG);
+ bundle.putInt(CARDINALITY_FIELD, mCardinality);
+ return new LongPropertyConfig(bundle);
+ }
+ }
+ }
+
/** Configuration for a property containing a double-precision decimal number. */
public static final class DoublePropertyConfig extends PropertyConfig {
DoublePropertyConfig(@NonNull Bundle bundle) {
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchLoggerHelper.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchLoggerHelper.java
index 4a5ecf1..4b92ce6 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchLoggerHelper.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchLoggerHelper.java
@@ -103,8 +103,7 @@
toStatsBuilder
.setNativeLatencyMillis(fromNativeStats.getLatencyMs())
.setTermCount(fromNativeStats.getNumTerms())
- // TODO(b/173532925) query length missing in native
- // .setNativeQueryLength(0)
+ .setQueryLength(fromNativeStats.getQueryLength())
.setFilteredNamespaceCount(fromNativeStats.getNumNamespacesFiltered())
.setFilteredSchemaTypeCount(fromNativeStats.getNumSchemaTypesFiltered())
.setRequestedPageSize(fromNativeStats.getRequestedPageSize())
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java
index 0cdad37..9ce916f 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java
@@ -199,7 +199,7 @@
case AppSearchSchema.PropertyConfig.DATA_TYPE_STRING:
documentBuilder.setPropertyString(propertyName, EMPTY_STRING_ARRAY);
break;
- case AppSearchSchema.PropertyConfig.DATA_TYPE_INT64:
+ case AppSearchSchema.PropertyConfig.DATA_TYPE_LONG:
documentBuilder.setPropertyLong(propertyName, EMPTY_LONG_ARRAY);
break;
case AppSearchSchema.PropertyConfig.DATA_TYPE_DOUBLE:
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
index 80f7007..3e4e7d2 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
@@ -133,7 +133,7 @@
case STRING:
return toStringPropertyConfig(proto);
case INT64:
- return new AppSearchSchema.Int64PropertyConfig.Builder(proto.getPropertyName())
+ return new AppSearchSchema.LongPropertyConfig.Builder(proto.getPropertyName())
.setCardinality(proto.getCardinality().getNumber())
.build();
case DOUBLE:
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/RemoveStats.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/RemoveStats.java
new file mode 100644
index 0000000..b900c49
--- /dev/null
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/RemoveStats.java
@@ -0,0 +1,181 @@
+/*
+ * 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.stats;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.app.appsearch.AppSearchResult;
+import android.app.appsearch.RemoveByDocumentIdRequest;
+import android.app.appsearch.SearchSpec;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Class holds detailed stats for {@link
+ * android.app.appsearch.AppSearchSession#remove(RemoveByDocumentIdRequest)} and {@link
+ * android.app.appsearch.AppSearchSession#remove(String, SearchSpec)}
+ *
+ * @hide
+ */
+public final class RemoveStats {
+ @IntDef(
+ value = {
+ // It needs to be sync with DeleteType.Code in
+ // external/icing/proto/icing/proto/logging.proto#DeleteStatsProto
+ UNKNOWN,
+ SINGLE,
+ QUERY,
+ NAMESPACE,
+ SCHEMA_TYPE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DeleteType {}
+
+ /** Default. Should never be used. */
+ public static final int UNKNOWN = 0;
+ /** Delete by namespace + id. */
+ public static final int SINGLE = 1;
+ /** Delete by query. */
+ public static final int QUERY = 2;
+ /** Delete by namespace. */
+ public static final int NAMESPACE = 3;
+ /** Delete by schema type. */
+ public static final int SCHEMA_TYPE = 4;
+
+ @NonNull private final String mPackageName;
+ @NonNull private final String mDatabase;
+ /**
+ * The status code returned by {@link AppSearchResult#getResultCode()} for the call or internal
+ * state.
+ */
+ @AppSearchResult.ResultCode private final int mStatusCode;
+
+ private final int mTotalLatencyMillis;
+ private final int mNativeLatencyMillis;
+ @DeleteType private final int mNativeDeleteType;
+ private final int mNativeNumDocumentsDeleted;
+
+ RemoveStats(@NonNull Builder builder) {
+ Objects.requireNonNull(builder);
+ mPackageName = builder.mPackageName;
+ mDatabase = builder.mDatabase;
+ mStatusCode = builder.mStatusCode;
+ mTotalLatencyMillis = builder.mTotalLatencyMillis;
+ mNativeLatencyMillis = builder.mNativeLatencyMillis;
+ mNativeDeleteType = builder.mNativeDeleteType;
+ mNativeNumDocumentsDeleted = builder.mNativeNumDocumentsDeleted;
+ }
+
+ /** Returns calling package name. */
+ @NonNull
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ /** Returns calling database name. */
+ @NonNull
+ public String getDatabase() {
+ return mDatabase;
+ }
+
+ /** Returns status code for this remove. */
+ @AppSearchResult.ResultCode
+ public int getStatusCode() {
+ return mStatusCode;
+ }
+
+ /** Returns total latency of this remove in millis. */
+ public int getTotalLatencyMillis() {
+ return mTotalLatencyMillis;
+ }
+
+ /** Returns how much time in millis spent in the native code. */
+ public int getNativeLatencyMillis() {
+ return mNativeLatencyMillis;
+ }
+
+ /** Returns what type of delete for this remove call. */
+ @DeleteType
+ public int getDeleteType() {
+ return mNativeDeleteType;
+ }
+
+ /** Returns how many documents get deleted in this call. */
+ public int getDeletedDocumentCount() {
+ return mNativeNumDocumentsDeleted;
+ }
+
+ /** Builder for {@link RemoveStats}. */
+ public static class Builder {
+ @NonNull final String mPackageName;
+ @NonNull final String mDatabase;
+ @AppSearchResult.ResultCode int mStatusCode;
+ int mTotalLatencyMillis;
+ int mNativeLatencyMillis;
+ @DeleteType int mNativeDeleteType;
+ int mNativeNumDocumentsDeleted;
+
+ /** Constructor for the {@link Builder}. */
+ public Builder(@NonNull String packageName, @NonNull String database) {
+ mPackageName = Objects.requireNonNull(packageName);
+ mDatabase = Objects.requireNonNull(database);
+ }
+
+ /** Sets the status code. */
+ @NonNull
+ public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
+ mStatusCode = statusCode;
+ return this;
+ }
+
+ /** Sets total latency in millis. */
+ @NonNull
+ public Builder setTotalLatencyMillis(int totalLatencyMillis) {
+ mTotalLatencyMillis = totalLatencyMillis;
+ return this;
+ }
+
+ /** Sets native latency in millis. */
+ @NonNull
+ public Builder setNativeLatencyMillis(int nativeLatencyMillis) {
+ mNativeLatencyMillis = nativeLatencyMillis;
+ return this;
+ }
+
+ /** Sets delete type for this call. */
+ @NonNull
+ public Builder setDeleteType(@DeleteType int nativeDeleteType) {
+ mNativeDeleteType = nativeDeleteType;
+ return this;
+ }
+
+ /** Sets how many documents get deleted for this call. */
+ @NonNull
+ public Builder setDeletedDocumentCount(int nativeNumDocumentsDeleted) {
+ mNativeNumDocumentsDeleted = nativeNumDocumentsDeleted;
+ return this;
+ }
+
+ /** Creates a {@link RemoveStats}. */
+ @NonNull
+ public RemoveStats build() {
+ return new RemoveStats(/* builder= */ this);
+ }
+ }
+}
diff --git a/apex/appsearch/synced_jetpack_changeid.txt b/apex/appsearch/synced_jetpack_changeid.txt
index 9723de6..9bfe071 100644
--- a/apex/appsearch/synced_jetpack_changeid.txt
+++ b/apex/appsearch/synced_jetpack_changeid.txt
@@ -1 +1 @@
-a83c33a5a394141fea1d065ce0fab513a62d4bcf
+c6630eba424d98dd54ece674e769d9b0b883e410
diff --git a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
index 22ee501..38500af 100644
--- a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
+++ b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
@@ -258,8 +258,7 @@
public @NonNull ParcelFileDescriptor openBlob(@NonNull BlobHandle blobHandle)
throws IOException {
try {
- return mService.openBlob(blobHandle, mContext.getOpPackageName(),
- mContext.getAttributionTag());
+ return mService.openBlob(blobHandle, mContext.getOpPackageName());
} catch (ParcelableException e) {
e.maybeRethrow(IOException.class);
throw new RuntimeException(e);
@@ -316,7 +315,7 @@
@CurrentTimeMillisLong long leaseExpiryTimeMillis) throws IOException {
try {
mService.acquireLease(blobHandle, descriptionResId, null, leaseExpiryTimeMillis,
- mContext.getOpPackageName(), mContext.getAttributionTag());
+ mContext.getOpPackageName());
} catch (ParcelableException e) {
e.maybeRethrow(IOException.class);
e.maybeRethrow(LimitExceededException.class);
@@ -379,7 +378,7 @@
@CurrentTimeMillisLong long leaseExpiryTimeMillis) throws IOException {
try {
mService.acquireLease(blobHandle, INVALID_RES_ID, description, leaseExpiryTimeMillis,
- mContext.getOpPackageName(), mContext.getAttributionTag());
+ mContext.getOpPackageName());
} catch (ParcelableException e) {
e.maybeRethrow(IOException.class);
e.maybeRethrow(LimitExceededException.class);
@@ -498,8 +497,7 @@
*/
public void releaseLease(@NonNull BlobHandle blobHandle) throws IOException {
try {
- mService.releaseLease(blobHandle, mContext.getOpPackageName(),
- mContext.getAttributionTag());
+ mService.releaseLease(blobHandle, mContext.getOpPackageName());
} catch (ParcelableException e) {
e.maybeRethrow(IOException.class);
throw new RuntimeException(e);
@@ -604,8 +602,7 @@
@Nullable
public LeaseInfo getLeaseInfo(@NonNull BlobHandle blobHandle) throws IOException {
try {
- return mService.getLeaseInfo(blobHandle, mContext.getOpPackageName(),
- mContext.getAttributionTag());
+ return mService.getLeaseInfo(blobHandle, mContext.getOpPackageName());
} catch (ParcelableException e) {
e.maybeRethrow(IOException.class);
throw new RuntimeException(e);
@@ -900,64 +897,6 @@
}
/**
- * Allow apps with location permission to access this blob data once it is committed using
- * a {@link BlobHandle} representing the blob.
- *
- * <p> This needs to be called before committing the blob using
- * {@link #commit(Executor, Consumer)}.
- *
- * Note that if a caller allows access to the blob using this API in addition to other APIs
- * like {@link #allowPackageAccess(String, byte[])}, then apps satisfying any one of these
- * access conditions will be allowed to access the blob.
- *
- * @param permissionName the name of the location permission that needs to be granted
- * for the app. This can be either one of
- * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
- * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
- *
- * @throws IOException when there is an I/O error while changing the access.
- * @throws SecurityException when the caller is not the owner of the session.
- * @throws IllegalStateException when the caller tries to change access for a blob which is
- * already committed.
- */
- public void allowPackagesWithLocationPermission(@NonNull String permissionName)
- throws IOException {
- try {
- mSession.allowPackagesWithLocationPermission(permissionName);
- } catch (ParcelableException e) {
- e.maybeRethrow(IOException.class);
- throw new RuntimeException(e);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Returns {@code true} if access has been allowed for apps with location permission by
- * using {@link #allowPackagesWithLocationPermission(String)}.
- *
- * @param permissionName the name of the location permission that needs to be granted
- * for the app. This can be either one of
- * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
- * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
- *
- * @throws IOException when there is an I/O error while getting the access type.
- * @throws IllegalStateException when the caller tries to get access type from a session
- * which is closed or abandoned.
- */
- public boolean arePackagesWithLocationPermissionAllowed(@NonNull String permissionName)
- throws IOException {
- try {
- return mSession.arePackagesWithLocationPermissionAllowed(permissionName);
- } catch (ParcelableException e) {
- e.maybeRethrow(IOException.class);
- throw new RuntimeException(e);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
* Commit the file that was written so far to this session to the blob store maintained by
* the system.
*
diff --git a/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl b/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
index db6cb5c9..39a9fb4 100644
--- a/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
+++ b/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
@@ -25,13 +25,12 @@
interface IBlobStoreManager {
long createSession(in BlobHandle handle, in String packageName);
IBlobStoreSession openSession(long sessionId, in String packageName);
- ParcelFileDescriptor openBlob(in BlobHandle handle, in String packageName,
- in String attributionTag);
+ ParcelFileDescriptor openBlob(in BlobHandle handle, in String packageName);
void abandonSession(long sessionId, in String packageName);
void acquireLease(in BlobHandle handle, int descriptionResId, in CharSequence description,
- long leaseTimeoutMillis, in String packageName, in String attributionTag);
- void releaseLease(in BlobHandle handle, in String packageName, in String attributionTag);
+ long leaseTimeoutMillis, in String packageName);
+ void releaseLease(in BlobHandle handle, in String packageName);
long getRemainingLeaseQuotaBytes(String packageName);
void waitForIdle(in RemoteCallback callback);
@@ -40,6 +39,5 @@
void deleteBlob(long blobId);
List<BlobHandle> getLeasedBlobs(in String packageName);
- LeaseInfo getLeaseInfo(in BlobHandle blobHandle, in String packageName,
- in String attributionTag);
+ LeaseInfo getLeaseInfo(in BlobHandle blobHandle, in String packageName);
}
\ No newline at end of file
diff --git a/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl b/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl
index e3ccfb8..4035b96 100644
--- a/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl
+++ b/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl
@@ -26,12 +26,10 @@
void allowPackageAccess(in String packageName, in byte[] certificate);
void allowSameSignatureAccess();
void allowPublicAccess();
- void allowPackagesWithLocationPermission(in String permissionName);
boolean isPackageAccessAllowed(in String packageName, in byte[] certificate);
boolean isSameSignatureAccessAllowed();
boolean isPublicAccessAllowed();
- boolean arePackagesWithLocationPermissionAllowed(in String permissionName);
long getSize();
void close();
diff --git a/apex/blobstore/framework/java/android/app/blob/XmlTags.java b/apex/blobstore/framework/java/android/app/blob/XmlTags.java
index 6e4b2f7..bfc5826 100644
--- a/apex/blobstore/framework/java/android/app/blob/XmlTags.java
+++ b/apex/blobstore/framework/java/android/app/blob/XmlTags.java
@@ -38,7 +38,6 @@
public static final String ATTR_TYPE = "t";
public static final String TAG_ALLOWED_PACKAGE = "wl";
public static final String ATTR_CERTIFICATE = "ct";
- public static final String TAG_ALLOWED_PERMISSION = "ap";
// For BlobHandle
public static final String TAG_BLOB_HANDLE = "bh";
@@ -56,7 +55,4 @@
public static final String TAG_LEASEE = "l";
public static final String ATTR_DESCRIPTION_RES_NAME = "rn";
public static final String ATTR_DESCRIPTION = "d";
-
- // Generic
- public static final String ATTR_VALUE = "val";
}
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java b/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java
index 09260b7..0d17bbc 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java
@@ -15,30 +15,19 @@
*/
package com.android.server.blob;
-import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
-import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static android.app.blob.XmlTags.ATTR_CERTIFICATE;
import static android.app.blob.XmlTags.ATTR_PACKAGE;
import static android.app.blob.XmlTags.ATTR_TYPE;
-import static android.app.blob.XmlTags.ATTR_VALUE;
import static android.app.blob.XmlTags.TAG_ALLOWED_PACKAGE;
-import static android.app.blob.XmlTags.TAG_ALLOWED_PERMISSION;
-
-import static com.android.server.blob.BlobStoreConfig.TAG;
import android.annotation.IntDef;
import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
-import android.os.UserHandle;
-import android.permission.PermissionManager;
import android.util.ArraySet;
import android.util.Base64;
import android.util.DebugUtils;
import android.util.IndentingPrintWriter;
-import android.util.Slog;
import com.android.internal.util.XmlUtils;
@@ -64,27 +53,21 @@
ACCESS_TYPE_PUBLIC,
ACCESS_TYPE_SAME_SIGNATURE,
ACCESS_TYPE_ALLOWLIST,
- ACCESS_TYPE_LOCATION_PERMISSION,
})
@interface AccessType {}
public static final int ACCESS_TYPE_PRIVATE = 1 << 0;
public static final int ACCESS_TYPE_PUBLIC = 1 << 1;
public static final int ACCESS_TYPE_SAME_SIGNATURE = 1 << 2;
public static final int ACCESS_TYPE_ALLOWLIST = 1 << 3;
- public static final int ACCESS_TYPE_LOCATION_PERMISSION = 1 << 4;
private int mAccessType = ACCESS_TYPE_PRIVATE;
private final ArraySet<PackageIdentifier> mAllowedPackages = new ArraySet<>();
- private final ArraySet<String> mAllowedPermissions = new ArraySet<>();
void allow(BlobAccessMode other) {
if ((other.mAccessType & ACCESS_TYPE_ALLOWLIST) != 0) {
mAllowedPackages.addAll(other.mAllowedPackages);
}
- if ((other.mAccessType & ACCESS_TYPE_LOCATION_PERMISSION) != 0) {
- mAllowedPermissions.addAll(other.mAllowedPermissions);
- }
mAccessType |= other.mAccessType;
}
@@ -101,11 +84,6 @@
mAllowedPackages.add(PackageIdentifier.create(packageName, certificate));
}
- void allowPackagesWithLocationPermission(@NonNull String permissionName) {
- mAccessType |= ACCESS_TYPE_LOCATION_PERMISSION;
- mAllowedPermissions.add(permissionName);
- }
-
boolean isPublicAccessAllowed() {
return (mAccessType & ACCESS_TYPE_PUBLIC) != 0;
}
@@ -121,15 +99,8 @@
return mAllowedPackages.contains(PackageIdentifier.create(packageName, certificate));
}
- boolean arePackagesWithLocationPermissionAllowed(@NonNull String permissionName) {
- if ((mAccessType & ACCESS_TYPE_LOCATION_PERMISSION) == 0) {
- return false;
- }
- return mAllowedPermissions.contains(permissionName);
- }
-
- boolean isAccessAllowedForCaller(Context context, @NonNull String callingPackage,
- @NonNull String committerPackage, int callingUid, @Nullable String attributionTag) {
+ boolean isAccessAllowedForCaller(Context context,
+ @NonNull String callingPackage, @NonNull String committerPackage) {
if ((mAccessType & ACCESS_TYPE_PUBLIC) != 0) {
return true;
}
@@ -153,37 +124,9 @@
}
}
- if ((mAccessType & ACCESS_TYPE_LOCATION_PERMISSION) != 0) {
- final AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
- for (int i = 0; i < mAllowedPermissions.size(); ++i) {
- final String permission = mAllowedPermissions.valueAt(i);
- if (PermissionManager.checkPackageNamePermission(permission, callingPackage,
- UserHandle.getUserId(callingUid)) != PackageManager.PERMISSION_GRANTED) {
- continue;
- }
- // TODO: Add appropriate message
- if (appOpsManager.noteOpNoThrow(getAppOp(permission), callingUid, callingPackage,
- attributionTag, null /* message */) == AppOpsManager.MODE_ALLOWED) {
- return true;
- }
- }
- }
-
return false;
}
- private static String getAppOp(String permission) {
- switch (permission) {
- case ACCESS_FINE_LOCATION:
- return AppOpsManager.OPSTR_FINE_LOCATION;
- case ACCESS_COARSE_LOCATION:
- return AppOpsManager.OPSTR_COARSE_LOCATION;
- default:
- Slog.w(TAG, "Unknown permission found: " + permission);
- return null;
- }
- }
-
int getAccessType() {
return mAccessType;
}
@@ -205,16 +148,6 @@
}
fout.decreaseIndent();
}
- fout.print("Allowed permissions:");
- if (mAllowedPermissions.isEmpty()) {
- fout.println(" (Empty)");
- } else {
- fout.increaseIndent();
- for (int i = 0, count = mAllowedPermissions.size(); i < count; ++i) {
- fout.println(mAllowedPermissions.valueAt(i).toString());
- }
- fout.decreaseIndent();
- }
}
void writeToXml(@NonNull XmlSerializer out) throws IOException {
@@ -226,12 +159,6 @@
XmlUtils.writeByteArrayAttribute(out, ATTR_CERTIFICATE, packageIdentifier.certificate);
out.endTag(null, TAG_ALLOWED_PACKAGE);
}
- for (int i = 0, count = mAllowedPermissions.size(); i < count; ++i) {
- out.startTag(null, TAG_ALLOWED_PERMISSION);
- final String permission = mAllowedPermissions.valueAt(i);
- XmlUtils.writeStringAttribute(out, ATTR_VALUE, permission);
- out.endTag(null, TAG_ALLOWED_PERMISSION);
- }
}
@NonNull
@@ -249,10 +176,6 @@
final byte[] certificate = XmlUtils.readByteArrayAttribute(in, ATTR_CERTIFICATE);
blobAccessMode.allowPackageAccess(packageName, certificate);
}
- if (TAG_ALLOWED_PERMISSION.equals(in.getName())) {
- final String permission = XmlUtils.readStringAttribute(in, ATTR_VALUE);
- blobAccessMode.allowPackagesWithLocationPermission(permission);
- }
}
return blobAccessMode;
}
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java b/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java
index e477156..e116c81 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java
@@ -263,8 +263,7 @@
return getBlobFile().length();
}
- boolean isAccessAllowedForCaller(@NonNull String callingPackage, int callingUid,
- @Nullable String attributionTag) {
+ boolean isAccessAllowedForCaller(@NonNull String callingPackage, int callingUid) {
// Don't allow the blob to be accessed after it's expiry time has passed.
if (getBlobHandle().isExpired()) {
return false;
@@ -293,7 +292,7 @@
// Check if the caller is allowed access as per the access mode specified
// by the committer.
if (committer.blobAccessMode.isAccessAllowedForCaller(mContext,
- callingPackage, committer.packageName, callingUid, attributionTag)) {
+ callingPackage, committer.packageName)) {
return true;
}
}
@@ -316,7 +315,7 @@
// Check if the caller is allowed access as per the access mode specified
// by the committer.
if (committer.blobAccessMode.isAccessAllowedForCaller(mContext,
- callingPackage, committer.packageName, callingUid, attributionTag)) {
+ callingPackage, committer.packageName)) {
return true;
}
}
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
index 731ba92..beeffd6 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
@@ -397,11 +397,11 @@
}
private ParcelFileDescriptor openBlobInternal(BlobHandle blobHandle, int callingUid,
- String callingPackage, String attributionTag) throws IOException {
+ String callingPackage) throws IOException {
synchronized (mBlobsLock) {
final BlobMetadata blobMetadata = mBlobsMap.get(blobHandle);
if (blobMetadata == null || !blobMetadata.isAccessAllowedForCaller(
- callingPackage, callingUid, attributionTag)) {
+ callingPackage, callingUid)) {
if (blobMetadata == null) {
FrameworkStatsLog.write(FrameworkStatsLog.BLOB_OPENED, callingUid,
INVALID_BLOB_ID, INVALID_BLOB_SIZE,
@@ -449,7 +449,7 @@
private void acquireLeaseInternal(BlobHandle blobHandle, int descriptionResId,
CharSequence description, long leaseExpiryTimeMillis,
- int callingUid, String callingPackage, String attributionTag) {
+ int callingUid, String callingPackage) {
synchronized (mBlobsLock) {
final int leasesCount = getLeasedBlobsCountLocked(callingUid, callingPackage);
if (leasesCount >= getMaxLeasedBlobs()) {
@@ -470,7 +470,7 @@
final BlobMetadata blobMetadata = mBlobsMap.get(blobHandle);
if (blobMetadata == null || !blobMetadata.isAccessAllowedForCaller(
- callingPackage, callingUid, attributionTag)) {
+ callingPackage, callingUid)) {
if (blobMetadata == null) {
FrameworkStatsLog.write(FrameworkStatsLog.BLOB_LEASED, callingUid,
INVALID_BLOB_ID, INVALID_BLOB_SIZE,
@@ -521,11 +521,11 @@
}
private void releaseLeaseInternal(BlobHandle blobHandle, int callingUid,
- String callingPackage, String attributionTag) {
+ String callingPackage) {
synchronized (mBlobsLock) {
final BlobMetadata blobMetadata = mBlobsMap.get(blobHandle);
if (blobMetadata == null || !blobMetadata.isAccessAllowedForCaller(
- callingPackage, callingUid, attributionTag)) {
+ callingPackage, callingUid)) {
throw new SecurityException("Caller not allowed to access " + blobHandle
+ "; callingUid=" + callingUid + ", callingPackage=" + callingPackage);
}
@@ -632,11 +632,11 @@
}
private LeaseInfo getLeaseInfoInternal(BlobHandle blobHandle,
- int callingUid, @NonNull String callingPackage, String attributionTag) {
+ int callingUid, @NonNull String callingPackage) {
synchronized (mBlobsLock) {
final BlobMetadata blobMetadata = mBlobsMap.get(blobHandle);
if (blobMetadata == null || !blobMetadata.isAccessAllowedForCaller(
- callingPackage, callingUid, attributionTag)) {
+ callingPackage, callingUid)) {
throw new SecurityException("Caller not allowed to access " + blobHandle
+ "; callingUid=" + callingUid + ", callingPackage=" + callingPackage);
}
@@ -1478,7 +1478,7 @@
@Override
public ParcelFileDescriptor openBlob(@NonNull BlobHandle blobHandle,
- @NonNull String packageName, @Nullable String attributionTag) {
+ @NonNull String packageName) {
Objects.requireNonNull(blobHandle, "blobHandle must not be null");
blobHandle.assertIsValid();
Objects.requireNonNull(packageName, "packageName must not be null");
@@ -1493,7 +1493,7 @@
}
try {
- return openBlobInternal(blobHandle, callingUid, packageName, attributionTag);
+ return openBlobInternal(blobHandle, callingUid, packageName);
} catch (IOException e) {
throw ExceptionUtils.wrap(e);
}
@@ -1502,8 +1502,7 @@
@Override
public void acquireLease(@NonNull BlobHandle blobHandle, @IdRes int descriptionResId,
@Nullable CharSequence description,
- @CurrentTimeSecondsLong long leaseExpiryTimeMillis, @NonNull String packageName,
- @Nullable String attributionTag) {
+ @CurrentTimeSecondsLong long leaseExpiryTimeMillis, @NonNull String packageName) {
Objects.requireNonNull(blobHandle, "blobHandle must not be null");
blobHandle.assertIsValid();
Preconditions.checkArgument(
@@ -1527,7 +1526,7 @@
try {
acquireLeaseInternal(blobHandle, descriptionResId, description,
- leaseExpiryTimeMillis, callingUid, packageName, attributionTag);
+ leaseExpiryTimeMillis, callingUid, packageName);
} catch (Resources.NotFoundException e) {
throw new IllegalArgumentException(e);
} catch (LimitExceededException e) {
@@ -1536,8 +1535,7 @@
}
@Override
- public void releaseLease(@NonNull BlobHandle blobHandle, @NonNull String packageName,
- @Nullable String attributionTag) {
+ public void releaseLease(@NonNull BlobHandle blobHandle, @NonNull String packageName) {
Objects.requireNonNull(blobHandle, "blobHandle must not be null");
blobHandle.assertIsValid();
Objects.requireNonNull(packageName, "packageName must not be null");
@@ -1551,7 +1549,7 @@
+ "callingUid=" + callingUid + ", callingPackage=" + packageName);
}
- releaseLeaseInternal(blobHandle, callingUid, packageName, attributionTag);
+ releaseLeaseInternal(blobHandle, callingUid, packageName);
}
@Override
@@ -1621,8 +1619,7 @@
@Override
@Nullable
- public LeaseInfo getLeaseInfo(@NonNull BlobHandle blobHandle, @NonNull String packageName,
- @Nullable String attributionTag) {
+ public LeaseInfo getLeaseInfo(@NonNull BlobHandle blobHandle, @NonNull String packageName) {
Objects.requireNonNull(blobHandle, "blobHandle must not be null");
blobHandle.assertIsValid();
Objects.requireNonNull(packageName, "packageName must not be null");
@@ -1636,7 +1633,7 @@
+ "callingUid=" + callingUid + ", callingPackage=" + packageName);
}
- return getLeaseInfoInternal(blobHandle, callingUid, packageName, attributionTag);
+ return getLeaseInfoInternal(blobHandle, callingUid, packageName);
}
@Override
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
index 3f0032f..8eef8ce 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
@@ -15,8 +15,6 @@
*/
package com.android.server.blob;
-import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
-import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static android.app.blob.BlobStoreManager.COMMIT_RESULT_ERROR;
import static android.app.blob.XmlTags.ATTR_CREATION_TIME_MS;
import static android.app.blob.XmlTags.ATTR_ID;
@@ -368,21 +366,6 @@
}
@Override
- public void allowPackagesWithLocationPermission(@NonNull String permissionName) {
- assertCallerIsOwner();
- Preconditions.checkArgument(ACCESS_FINE_LOCATION.equals(permissionName)
- || ACCESS_COARSE_LOCATION.equals(permissionName),
- "permissionName is unknown: " + permissionName);
- synchronized (mSessionLock) {
- if (mState != STATE_OPENED) {
- throw new IllegalStateException("Not allowed to change access type in state: "
- + stateToString(mState));
- }
- mBlobAccessMode.allowPackagesWithLocationPermission(permissionName);
- }
- }
-
- @Override
public boolean isPackageAccessAllowed(@NonNull String packageName,
@NonNull byte[] certificate) {
assertCallerIsOwner();
@@ -423,21 +406,6 @@
}
@Override
- public boolean arePackagesWithLocationPermissionAllowed(@NonNull String permissionName) {
- assertCallerIsOwner();
- Preconditions.checkArgument(ACCESS_FINE_LOCATION.equals(permissionName)
- || ACCESS_COARSE_LOCATION.equals(permissionName),
- "permissionName is unknown: " + permissionName);
- synchronized (mSessionLock) {
- if (mState != STATE_OPENED) {
- throw new IllegalStateException("Not allowed to change access type in state: "
- + stateToString(mState));
- }
- return mBlobAccessMode.arePackagesWithLocationPermissionAllowed(permissionName);
- }
- }
-
- @Override
public void close() {
closeSession(STATE_CLOSED, false /* sendCallback */);
}
diff --git a/core/api/current.txt b/core/api/current.txt
index a9df1a4..37dd6b8 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -7905,10 +7905,8 @@
public static class BlobStoreManager.Session implements java.io.Closeable {
method public void abandon() throws java.io.IOException;
method public void allowPackageAccess(@NonNull String, @NonNull byte[]) throws java.io.IOException;
- method public void allowPackagesWithLocationPermission(@NonNull String) throws java.io.IOException;
method public void allowPublicAccess() throws java.io.IOException;
method public void allowSameSignatureAccess() throws java.io.IOException;
- method public boolean arePackagesWithLocationPermissionAllowed(@NonNull String) throws java.io.IOException;
method public void close() throws java.io.IOException;
method public void commit(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>) throws java.io.IOException;
method public long getSize() throws java.io.IOException;
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 415dfda..8e13c33 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -4997,11 +4997,15 @@
public final class SatellitePvt implements android.os.Parcelable {
method public int describeContents();
- method @NonNull public android.location.SatellitePvt.ClockInfo getClockInfo();
+ method @Nullable public android.location.SatellitePvt.ClockInfo getClockInfo();
+ method public int getFlags();
method @FloatRange public double getIonoDelayMeters();
- method @NonNull public android.location.SatellitePvt.PositionEcef getPositionEcef();
+ method @Nullable public android.location.SatellitePvt.PositionEcef getPositionEcef();
method @FloatRange public double getTropoDelayMeters();
- method @NonNull public android.location.SatellitePvt.VelocityEcef getVelocityEcef();
+ method @Nullable public android.location.SatellitePvt.VelocityEcef getVelocityEcef();
+ method public boolean hasIono();
+ method public boolean hasPositionVelocityClockInfo();
+ method public boolean hasTropo();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.location.SatellitePvt> CREATOR;
}
@@ -5010,6 +5014,7 @@
ctor public SatellitePvt.Builder();
method @NonNull public android.location.SatellitePvt build();
method @NonNull public android.location.SatellitePvt.Builder setClockInfo(@NonNull android.location.SatellitePvt.ClockInfo);
+ method @NonNull public android.location.SatellitePvt.Builder setFlags(int);
method @NonNull public android.location.SatellitePvt.Builder setIonoDelayMeters(@FloatRange double);
method @NonNull public android.location.SatellitePvt.Builder setPositionEcef(@NonNull android.location.SatellitePvt.PositionEcef);
method @NonNull public android.location.SatellitePvt.Builder setTropoDelayMeters(@FloatRange double);
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index c8e365e..12d9bee 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -2103,6 +2103,7 @@
public final class DeviceConfig {
field public static final String NAMESPACE_ALARM_MANAGER = "alarm_manager";
field public static final String NAMESPACE_ANDROID = "android";
+ field public static final String NAMESPACE_CONSTRAIN_DISPLAY_APIS = "constrain_display_apis";
field public static final String NAMESPACE_DEVICE_IDLE = "device_idle";
field public static final String NAMESPACE_JOB_SCHEDULER = "jobscheduler";
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 295943d..854c9f2 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -970,8 +970,7 @@
private UiTranslationController mUiTranslationController;
private SplashScreen mSplashScreen;
- /** @hide */
- SplashScreenView mSplashScreenView;
+ private SplashScreenView mSplashScreenView;
private final WindowControllerCallback mWindowControllerCallback =
new WindowControllerCallback() {
@@ -1631,16 +1630,14 @@
}
}
- /**
- * Clear the splash screen view if exist.
- * @hide
- */
- public void detachSplashScreenView() {
- synchronized (this) {
- if (mSplashScreenView != null) {
- mSplashScreenView = null;
- }
- }
+ /** @hide */
+ public void setSplashScreenView(SplashScreenView v) {
+ mSplashScreenView = v;
+ }
+
+ /** @hide */
+ SplashScreenView getSplashScreenView() {
+ return mSplashScreenView;
}
/**
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b1438ea..f626d4b 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4051,10 +4051,7 @@
final SplashScreenView.Builder builder = new SplashScreenView.Builder(r.activity);
final SplashScreenView view = builder.createFromParcel(parcelable).build();
decorView.addView(view);
- view.cacheRootWindow(r.window);
- view.makeSystemUIColorsTransparent();
- r.activity.mSplashScreenView = view;
- view.attachHostActivity(r.activity);
+ view.attachHostActivityAndSetSystemUIColors(r.activity, r.window);
view.requestLayout();
// Ensure splash screen view is shown before remove the splash screen window.
final ViewRootImpl impl = decorView.getViewRootImpl();
@@ -4096,12 +4093,13 @@
@Override
public void handOverSplashScreenView(@NonNull ActivityClientRecord r) {
- if (r.activity.mSplashScreenView != null) {
- synchronized (this) {
- if (mSplashScreenGlobal != null) {
- mSplashScreenGlobal.dispatchOnExitAnimation(r.token,
- r.activity.mSplashScreenView);
- }
+ final SplashScreenView v = r.activity.getSplashScreenView();
+ if (v == null) {
+ return;
+ }
+ synchronized (this) {
+ if (mSplashScreenGlobal != null) {
+ mSplashScreenGlobal.dispatchOnExitAnimation(r.token, v);
}
}
}
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 010f4e4..ed00436 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -7394,20 +7394,27 @@
/** @hide */
public void setUserRestriction(int code, boolean restricted, IBinder token) {
- setUserRestriction(code, restricted, token, /*exceptionPackages*/null);
+ setUserRestriction(code, restricted, token, (Map<String, String[]>) null);
}
- /** @hide */
+ /**
+ * An empty array of attribution tags means exclude all tags under that package.
+ * @hide
+ */
public void setUserRestriction(int code, boolean restricted, IBinder token,
- String[] exceptionPackages) {
- setUserRestrictionForUser(code, restricted, token, exceptionPackages, mContext.getUserId());
+ @Nullable Map<String, String[]> excludedPackageTags) {
+ setUserRestrictionForUser(code, restricted, token, excludedPackageTags,
+ mContext.getUserId());
}
- /** @hide */
+ /**
+ * An empty array of attribution tags means exclude all tags under that package.
+ * @hide
+ */
public void setUserRestrictionForUser(int code, boolean restricted, IBinder token,
- String[] exceptionPackages, int userId) {
+ @Nullable Map<String, String[]> excludedPackageTags, int userId) {
try {
- mService.setUserRestriction(code, restricted, token, userId, exceptionPackages);
+ mService.setUserRestriction(code, restricted, token, userId, excludedPackageTags);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -7949,7 +7956,7 @@
*/
public int unsafeCheckOpRawNoThrow(int op, int uid, @NonNull String packageName) {
try {
- return mService.checkOperationRaw(op, uid, packageName);
+ return mService.checkOperationRaw(op, uid, packageName, null);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/app/AppOpsManagerInternal.java b/core/java/android/app/AppOpsManagerInternal.java
index 341b9c5..2de0ddb 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.NonaFunction;
import com.android.internal.util.function.OctFunction;
import com.android.internal.util.function.QuadFunction;
+import com.android.internal.util.function.QuintFunction;
import com.android.internal.util.function.TriFunction;
/**
@@ -45,12 +46,14 @@
* @param code The op code to check.
* @param uid The UID for which to check.
* @param packageName The package for which to check.
- * @param superImpl The super implementation.
+ * @param attributionTag The attribution tag for which to check.
* @param raw Whether to check the raw op i.e. not interpret the mode based on UID state.
+ * @param superImpl The super implementation.
* @return The app op check result.
*/
- int checkOperation(int code, int uid, String packageName, boolean raw,
- QuadFunction<Integer, Integer, String, Boolean, Integer> superImpl);
+ int checkOperation(int code, int uid, String packageName, @Nullable String attributionTag,
+ boolean raw,
+ QuintFunction<Integer, Integer, String, String, Boolean, Integer> superImpl);
/**
* Allows overriding check audio operation behavior.
diff --git a/core/java/android/app/timezonedetector/TimeZoneDetector.java b/core/java/android/app/timezonedetector/TimeZoneDetector.java
index b216e91..a71cffe 100644
--- a/core/java/android/app/timezonedetector/TimeZoneDetector.java
+++ b/core/java/android/app/timezonedetector/TimeZoneDetector.java
@@ -48,6 +48,13 @@
String SHELL_COMMAND_SET_AUTO_DETECTION_ENABLED = "set_auto_detection_enabled";
/**
+ * A shell command that prints whether the telephony-based time zone detection feature is
+ * supported on the device.
+ * @hide
+ */
+ String SHELL_COMMAND_IS_TELEPHONY_DETECTION_SUPPORTED = "is_telephony_detection_supported";
+
+ /**
* A shell command that prints whether the geolocation-based time zone detection feature is
* supported on the device.
* @hide
diff --git a/core/java/android/content/pm/AppSearchShortcutInfo.java b/core/java/android/content/pm/AppSearchShortcutInfo.java
index afaecec..63f93bf 100644
--- a/core/java/android/content/pm/AppSearchShortcutInfo.java
+++ b/core/java/android/content/pm/AppSearchShortcutInfo.java
@@ -92,7 +92,7 @@
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.build()
- ).addProperty(new AppSearchSchema.Int64PropertyConfig.Builder(KEY_SHORT_LABEL_RES_ID)
+ ).addProperty(new AppSearchSchema.LongPropertyConfig.Builder(KEY_SHORT_LABEL_RES_ID)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.build()
@@ -108,7 +108,7 @@
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.build()
- ).addProperty(new AppSearchSchema.Int64PropertyConfig.Builder(KEY_LONG_LABEL_RES_ID)
+ ).addProperty(new AppSearchSchema.LongPropertyConfig.Builder(KEY_LONG_LABEL_RES_ID)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.build()
@@ -124,7 +124,7 @@
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
.build()
- ).addProperty(new AppSearchSchema.Int64PropertyConfig.Builder(
+ ).addProperty(new AppSearchSchema.LongPropertyConfig.Builder(
KEY_DISABLED_MESSAGE_RES_ID)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.build()
@@ -170,7 +170,7 @@
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
.build()
- ).addProperty(new AppSearchSchema.Int64PropertyConfig.Builder(KEY_IMPLICIT_RANK)
+ ).addProperty(new AppSearchSchema.LongPropertyConfig.Builder(KEY_IMPLICIT_RANK)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.build()
@@ -184,7 +184,7 @@
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
.build()
- ).addProperty(new AppSearchSchema.Int64PropertyConfig.Builder(KEY_ICON_RES_ID)
+ ).addProperty(new AppSearchSchema.LongPropertyConfig.Builder(KEY_ICON_RES_ID)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.build()
diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
index 5d74e74..022ba16 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
@@ -2816,15 +2816,7 @@
}
}
- @SuppressWarnings("AndroidFrameworkCompatChange")
private void convertSplitPermissions(ParsingPackage pkg) {
- // STOPSHIP(b/183905675): REMOVE THIS TERRIBLE, HORRIBLE, NO GOOD, VERY BAD HACK
- if ("com.android.chrome".equals(pkg.getPackageName())
- && pkg.getVersionCode() <= 445500399
- && pkg.getTargetSdkVersion() > Build.VERSION_CODES.R) {
- pkg.setTargetSdkVersion(Build.VERSION_CODES.R);
- }
-
final int listSize = mSplitPermissionInfos.size();
for (int is = 0; is < listSize; is++) {
final PermissionManager.SplitPermissionInfo spi = mSplitPermissionInfos.get(is);
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 1092adf..3daa3a5 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -31,6 +31,7 @@
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.net.Uri;
+import android.provider.Settings.Config.SyncDisabledMode;
import android.provider.Settings.ResetMode;
import android.util.ArrayMap;
import android.util.Log;
@@ -585,8 +586,16 @@
*
* @hide
*/
+ @TestApi
public static final String NAMESPACE_CONSTRAIN_DISPLAY_APIS = "constrain_display_apis";
+ /**
+ * Trace error logger properties definitions.
+ *
+ * @hide
+ */
+ public static final String NAMESPACE_TRACE_ERROR_LOGGER = "trace_error_logger";
+
private static final Object sLock = new Object();
@GuardedBy("sLock")
private static ArrayMap<OnPropertiesChangedListener, Pair<String, Executor>> sListeners =
@@ -839,6 +848,37 @@
}
/**
+ * Disables or re-enables bulk modifications ({@link #setProperties(Properties)}) to device
+ * config values. This is intended for use during tests to prevent a sync operation clearing
+ * config values, which could influence the outcome of the tests, i.e. by changing behavior.
+ *
+ * @param syncDisabledMode the mode to use, see {@link Settings.Config#SYNC_DISABLED_MODE_NONE},
+ * {@link Settings.Config#SYNC_DISABLED_MODE_PERSISTENT} and {@link
+ * Settings.Config#SYNC_DISABLED_MODE_UNTIL_REBOOT}
+ *
+ * @see #isSyncDisabled()
+ * @hide
+ */
+ @RequiresPermission(WRITE_DEVICE_CONFIG)
+ public static void setSyncDisabled(@SyncDisabledMode int syncDisabledMode) {
+ ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver();
+ Settings.Config.setSyncDisabled(contentResolver, syncDisabledMode);
+ }
+
+ /**
+ * Returns the current state of sync disabling, {@code true} when disabled, {@code false}
+ * otherwise.
+ *
+ * @see #setSyncDisabled(int)
+ * @hide
+ */
+ @RequiresPermission(WRITE_DEVICE_CONFIG)
+ public static boolean isSyncDisabled() {
+ ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver();
+ return Settings.Config.isSyncDisabled(contentResolver);
+ }
+
+ /**
* Add a listener for property changes.
* <p>
* This listener will be called whenever properties in the specified namespace change. Callbacks
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index e410e50..b948ce2 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -267,8 +267,40 @@
/** @hide */
public static final String EXTRA_NETWORK_TEMPLATE = "network_template";
+ /**
+ * The return values for {@link Settings.Config#set}
+ * @hide
+ */
+ @IntDef(prefix = "SET_ALL_RESULT_",
+ value = { SET_ALL_RESULT_FAILURE, SET_ALL_RESULT_SUCCESS, SET_ALL_RESULT_DISABLED })
+ @Retention(RetentionPolicy.SOURCE)
+ @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
+ public @interface SetAllResult {}
+
+ /**
+ * A return value for {@link #KEY_CONFIG_SET_ALL_RETURN}, indicates failure.
+ * @hide
+ */
+ public static final int SET_ALL_RESULT_FAILURE = 0;
+
+ /**
+ * A return value for {@link #KEY_CONFIG_SET_ALL_RETURN}, indicates success.
+ * @hide
+ */
+ public static final int SET_ALL_RESULT_SUCCESS = 1;
+
+ /**
+ * A return value for {@link #KEY_CONFIG_SET_ALL_RETURN}, indicates a set all is disabled.
+ * @hide
+ */
+ public static final int SET_ALL_RESULT_DISABLED = 2;
+
/** @hide */
- public static final String KEY_CONFIG_SET_RETURN = "config_set_return";
+ public static final String KEY_CONFIG_SET_ALL_RETURN = "config_set_all_return";
+
+ /** @hide */
+ public static final String KEY_CONFIG_IS_SYNC_DISABLED_RETURN =
+ "config_is_sync_disabled_return";
/**
* An int extra specifying a subscription ID.
@@ -890,6 +922,21 @@
"android.settings.LOCALE_SETTINGS";
/**
+ * Activity Action: Show settings to allow configuration of lockscreen.
+ * <p>
+ * In some cases, a matching Activity may not exist, so ensure you
+ * safeguard against this.
+ * <p>
+ * Input: Nothing.
+ * <p>
+ * Output: Nothing.
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_LOCKSCREEN_SETTINGS = "android.settings.LOCK_SCREEN_SETTINGS";
+
+ /**
* Activity Action: Show settings to configure input methods, in particular
* allowing the user to enable input methods.
* <p>
@@ -2324,6 +2371,11 @@
public static final String CALL_METHOD_PREFIX_KEY = "_prefix";
/**
+ * @hide - String argument extra to the fast-path call()-based requests
+ */
+ public static final String CALL_METHOD_SYNC_DISABLED_MODE_KEY = "_disabled_mode";
+
+ /**
* @hide - RemoteCallback monitor callback argument extra to the fast-path call()-based requests
*/
public static final String CALL_METHOD_MONITOR_CALLBACK_KEY = "_monitor_callback_key";
@@ -2386,6 +2438,15 @@
/** @hide - Private call() method to reset to defaults the 'configuration' table */
public static final String CALL_METHOD_LIST_CONFIG = "LIST_config";
+ /** @hide - Private call() method to disable / re-enable syncs to the 'configuration' table */
+ public static final String CALL_METHOD_SET_SYNC_DISABLED_CONFIG = "SET_SYNC_DISABLED_config";
+
+ /**
+ * @hide - Private call() method to return whether syncs are disabled for the 'configuration'
+ * table
+ */
+ public static final String CALL_METHOD_IS_SYNC_DISABLED_CONFIG = "IS_SYNC_DISABLED_config";
+
/** @hide - Private call() method to register monitor callback for 'configuration' table */
public static final String CALL_METHOD_REGISTER_MONITOR_CALLBACK_CONFIG =
"REGISTER_MONITOR_CALLBACK_config";
@@ -2762,11 +2823,11 @@
return true;
}
- public boolean setStringsForPrefix(ContentResolver cr, String prefix,
+ public @SetAllResult int setStringsForPrefix(ContentResolver cr, String prefix,
HashMap<String, String> keyValues) {
if (mCallSetAllCommand == null) {
// This NameValueCache does not support atomically setting multiple flags
- return false;
+ return SET_ALL_RESULT_FAILURE;
}
try {
Bundle args = new Bundle();
@@ -2776,10 +2837,10 @@
Bundle bundle = cp.call(cr.getAttributionSource(),
mProviderHolder.mUri.getAuthority(),
mCallSetAllCommand, null, args);
- return bundle.getBoolean(KEY_CONFIG_SET_RETURN);
+ return bundle.getInt(KEY_CONFIG_SET_ALL_RETURN);
} catch (RemoteException e) {
// Not supported by the remote side
- return false;
+ return SET_ALL_RESULT_FAILURE;
}
}
@@ -9985,6 +10046,12 @@
@Readable
public static final String NAS_SETTINGS_UPDATED = "nas_settings_updated";
+ /**
+ * Control whether Game Dashboard shortcut is always on for all games.
+ * @hide
+ */
+ @Readable
+ public static final String GAME_DASHBOARD_ALWAYS_ON = "game_dashboard_always_on";
/**
* These entries are considered common between the personal and the managed profile,
@@ -14199,6 +14266,15 @@
public static final String ARE_USER_DISABLED_HDR_FORMATS_ALLOWED =
"are_user_disabled_hdr_formats_allowed";
+ /**
+ * Whether or not syncs (bulk set operations) for {@link DeviceConfig} are disabled
+ * currently. The value is boolean (1 or 0). The value '1' means that {@link
+ * DeviceConfig#setProperties(DeviceConfig.Properties)} will return {@code false}.
+ *
+ * @hide
+ */
+ public static final String DEVICE_CONFIG_SYNC_DISABLED = "device_config_sync_disabled";
+
/** @hide */ public static String zenModeToString(int mode) {
if (mode == ZEN_MODE_IMPORTANT_INTERRUPTIONS) return "ZEN_MODE_IMPORTANT_INTERRUPTIONS";
if (mode == ZEN_MODE_ALARMS) return "ZEN_MODE_ALARMS";
@@ -16033,6 +16109,39 @@
* @hide
*/
public static final class Config extends NameValueTable {
+
+ /**
+ * The modes that can be used when disabling syncs to the 'config' settings.
+ * @hide
+ */
+ @IntDef(prefix = "DISABLE_SYNC_MODE_",
+ value = { SYNC_DISABLED_MODE_NONE, SYNC_DISABLED_MODE_PERSISTENT,
+ SYNC_DISABLED_MODE_UNTIL_REBOOT })
+ @Retention(RetentionPolicy.SOURCE)
+ @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
+ public @interface SyncDisabledMode {}
+
+ /**
+ * Sync is not not disabled.
+ *
+ * @hide
+ */
+ public static final int SYNC_DISABLED_MODE_NONE = 0;
+
+ /**
+ * Disabling of Config bulk update / syncing is persistent, i.e. it survives a device
+ * reboot.
+ * @hide
+ */
+ public static final int SYNC_DISABLED_MODE_PERSISTENT = 1;
+
+ /**
+ * Disabling of Config bulk update / syncing is not persistent, i.e. it will not survive a
+ * device reboot.
+ * @hide
+ */
+ public static final int SYNC_DISABLED_MODE_UNTIL_REBOOT = 2;
+
private static final ContentProviderHolder sProviderHolder =
new ContentProviderHolder(DeviceConfig.CONTENT_URI);
@@ -16125,7 +16234,7 @@
* @param resolver to access the database with.
* @param namespace to which the names should be set.
* @param keyValues map of key names (without the prefix) to values.
- * @return
+ * @return true if the name/value pairs were set, false if setting was blocked
*
* @hide
*/
@@ -16138,12 +16247,15 @@
compositeKeyValueMap.put(
createCompositeName(namespace, entry.getKey()), entry.getValue());
}
- // If can't set given configuration that means it's bad
- if (!sNameValueCache.setStringsForPrefix(resolver, createPrefix(namespace),
- compositeKeyValueMap)) {
- throw new DeviceConfig.BadConfigException();
+ int result = sNameValueCache.setStringsForPrefix(
+ resolver, createPrefix(namespace), compositeKeyValueMap);
+ if (result == SET_ALL_RESULT_SUCCESS) {
+ return true;
+ } else if (result == SET_ALL_RESULT_DISABLED) {
+ return false;
}
- return true;
+ // If can't set given configuration that means it's bad
+ throw new DeviceConfig.BadConfigException();
}
/**
@@ -16179,6 +16291,50 @@
}
/**
+ * Bridge method between {@link DeviceConfig#setSyncDisabled(int)} and the
+ * {@link com.android.providers.settings.SettingsProvider} implementation.
+ *
+ * @hide
+ */
+ @SuppressLint("AndroidFrameworkRequiresPermission")
+ @RequiresPermission(Manifest.permission.WRITE_DEVICE_CONFIG)
+ static void setSyncDisabled(
+ @NonNull ContentResolver resolver, @SyncDisabledMode int disableSyncMode) {
+ try {
+ Bundle args = new Bundle();
+ args.putInt(CALL_METHOD_SYNC_DISABLED_MODE_KEY, disableSyncMode);
+ IContentProvider cp = sProviderHolder.getProvider(resolver);
+ cp.call(resolver.getAttributionSource(),
+ sProviderHolder.mUri.getAuthority(), CALL_METHOD_SET_SYNC_DISABLED_CONFIG,
+ null, args);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Can't set sync disabled " + DeviceConfig.CONTENT_URI, e);
+ }
+ }
+
+ /**
+ * Bridge method between {@link DeviceConfig#isSyncDisabled()} and the
+ * {@link com.android.providers.settings.SettingsProvider} implementation.
+ *
+ * @hide
+ */
+ @SuppressLint("AndroidFrameworkRequiresPermission")
+ @RequiresPermission(Manifest.permission.WRITE_DEVICE_CONFIG)
+ static boolean isSyncDisabled(@NonNull ContentResolver resolver) {
+ try {
+ Bundle args = Bundle.EMPTY;
+ IContentProvider cp = sProviderHolder.getProvider(resolver);
+ Bundle bundle = cp.call(resolver.getAttributionSource(),
+ sProviderHolder.mUri.getAuthority(), CALL_METHOD_IS_SYNC_DISABLED_CONFIG,
+ null, args);
+ return bundle.getBoolean(KEY_CONFIG_IS_SYNC_DISABLED_RETURN);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Can't query sync disabled " + DeviceConfig.CONTENT_URI, e);
+ }
+ return false;
+ }
+
+ /**
* Register callback for monitoring Config table.
*
* @param resolver Handle to the content resolver.
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 572e50a..c9a7949 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -72,7 +72,7 @@
DEFAULT_FLAGS.put("settings_contextual_home", "false");
DEFAULT_FLAGS.put(SETTINGS_PROVIDER_MODEL, "true");
DEFAULT_FLAGS.put(SETTINGS_USE_NEW_BACKUP_ELIGIBILITY_RULES, "true");
- DEFAULT_FLAGS.put(SETTINGS_ENABLE_SECURITY_HUB, "false");
+ DEFAULT_FLAGS.put(SETTINGS_ENABLE_SECURITY_HUB, "true");
}
private static final Set<String> PERSISTENT_FLAGS;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 89562dc..9bbd5dd 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1201,8 +1201,7 @@
Looper.myLooper());
if (mAttachInfo.mThreadedRenderer != null) {
- InputMetricsListener listener =
- new InputMetricsListener(mInputEventReceiver);
+ InputMetricsListener listener = new InputMetricsListener();
mHardwareRendererObserver = new HardwareRendererObserver(
listener, listener.data, mHandler, true /*waitForPresentTime*/);
mAttachInfo.mThreadedRenderer.addObserver(mHardwareRendererObserver);
@@ -1414,6 +1413,9 @@
if (mAttachInfo.mThreadedRenderer != null) {
mAttachInfo.mHardwareAccelerated =
mAttachInfo.mHardwareAccelerationRequested = true;
+ if (mHardwareRendererObserver != null) {
+ mAttachInfo.mThreadedRenderer.addObserver(mHardwareRendererObserver);
+ }
}
}
}
@@ -8118,6 +8120,9 @@
ThreadedRenderer hardwareRenderer = mAttachInfo.mThreadedRenderer;
if (hardwareRenderer != null) {
+ if (mHardwareRendererObserver != null) {
+ hardwareRenderer.removeObserver(mHardwareRendererObserver);
+ }
if (mView != null) {
hardwareRenderer.destroyHardwareResources(mView);
}
@@ -8619,18 +8624,12 @@
super.dispose();
}
}
- WindowInputEventReceiver mInputEventReceiver;
+ private WindowInputEventReceiver mInputEventReceiver;
final class InputMetricsListener
implements HardwareRendererObserver.OnFrameMetricsAvailableListener {
public long[] data = new long[FrameMetrics.Index.FRAME_STATS_COUNT];
- private InputEventReceiver mReceiver;
-
- InputMetricsListener(InputEventReceiver receiver) {
- mReceiver = receiver;
- }
-
@Override
public void onFrameMetricsAvailable(int dropCountSinceLastInvocation) {
final int inputEventId = (int) data[FrameMetrics.Index.INPUT_EVENT_ID];
@@ -8643,6 +8642,20 @@
// available, we cannot compute end-to-end input latency metrics.
return;
}
+ final long gpuCompletedTime = data[FrameMetrics.Index.GPU_COMPLETED];
+ if (mInputEventReceiver == null) {
+ return;
+ }
+ if (gpuCompletedTime >= presentTime) {
+ final double discrepancyMs = (gpuCompletedTime - presentTime) * 1E-6;
+ final long vsyncId = data[FrameMetrics.Index.FRAME_TIMELINE_VSYNC_ID];
+ Log.w(TAG, "Not reporting timeline because gpuCompletedTime is " + discrepancyMs
+ + "ms ahead of presentTime. FRAME_TIMELINE_VSYNC_ID=" + vsyncId
+ + ", INPUT_EVENT_ID=" + inputEventId);
+ // TODO(b/186664409): figure out why this sometimes happens
+ return;
+ }
+ mInputEventReceiver.reportTimeline(inputEventId, gpuCompletedTime, presentTime);
}
}
HardwareRendererObserver mHardwareRendererObserver;
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 23a4359..aa9ea19 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -1354,6 +1354,11 @@
public void setDecorFitsSystemWindows(boolean decorFitsSystemWindows) {
}
+ /** @hide */
+ public boolean decorFitsSystemWindows() {
+ return false;
+ }
+
/**
* Specify custom window attributes. <strong>PLEASE NOTE:</strong> the
* layout params you give here should generally be from values previously
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index 53e145e..ec07209 100755
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -259,6 +259,11 @@
}
mCurrentDate.set(Calendar.YEAR, year);
+ if (mCurrentDate.compareTo(mMinDate) < 0) {
+ mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
+ } else if (mCurrentDate.compareTo(mMaxDate) > 0) {
+ mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
+ }
onDateChanged(true, true);
// Automatically switch to day picker.
diff --git a/core/java/android/window/SplashScreenView.java b/core/java/android/window/SplashScreenView.java
index 8debe5d..d67fb32 100644
--- a/core/java/android/window/SplashScreenView.java
+++ b/core/java/android/window/SplashScreenView.java
@@ -17,6 +17,8 @@
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
+import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
import android.annotation.ColorInt;
import android.annotation.NonNull;
@@ -40,11 +42,13 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
+import android.view.WindowInsetsController;
import android.view.WindowManager;
import android.widget.FrameLayout;
import com.android.internal.R;
import com.android.internal.policy.DecorView;
+import com.android.internal.util.ContrastColorUtil;
import java.time.Duration;
import java.time.Instant;
@@ -69,6 +73,12 @@
private static final String TAG = SplashScreenView.class.getSimpleName();
private static final boolean DEBUG = false;
+ private static final int LIGHT_BARS_MASK =
+ WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
+ | WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
+ private static final int WINDOW_FLAG_MASK = FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
+ | FLAG_TRANSLUCENT_NAVIGATION | FLAG_TRANSLUCENT_STATUS;
+
private boolean mNotCopyable;
private boolean mRevealAnimationSupported = true;
private int mInitBackgroundColor;
@@ -84,10 +94,14 @@
private Activity mHostActivity;
// cache original window and status
private Window mWindow;
- private boolean mDrawBarBackground;
+ private int mAppWindowFlags;
private int mStatusBarColor;
private int mNavigationBarColor;
+ private int mSystemBarsAppearance;
private boolean mHasRemoved;
+ private boolean mNavigationContrastEnforced;
+ private boolean mStatusContrastEnforced;
+ private boolean mDecorFitsSystemWindows;
/**
* Internal builder to create a SplashScreenView object.
@@ -347,54 +361,63 @@
mWindow = null;
}
if (mHostActivity != null) {
- mHostActivity.detachSplashScreenView();
+ mHostActivity.setSplashScreenView(null);
+ mHostActivity = null;
}
mHasRemoved = true;
}
/**
- * Called when this view is attached to an activity.
+ * Called when this view is attached to an activity. This also makes SystemUI colors
+ * transparent so the content of splash screen view can draw fully.
* @hide
*/
- public void attachHostActivity(Activity activity) {
+ public void attachHostActivityAndSetSystemUIColors(Activity activity, Window window) {
+ activity.setSplashScreenView(this);
mHostActivity = activity;
- }
-
- /**
- * Cache the root window.
- * @hide
- */
- public void cacheRootWindow(Window window) {
mWindow = window;
+ final WindowManager.LayoutParams attr = window.getAttributes();
+ mAppWindowFlags = attr.flags;
+ mStatusBarColor = window.getStatusBarColor();
+ mNavigationBarColor = window.getNavigationBarColor();
+ mSystemBarsAppearance = window.getInsetsController().getSystemBarsAppearance();
+ mNavigationContrastEnforced = window.isNavigationBarContrastEnforced();
+ mStatusContrastEnforced = window.isStatusBarContrastEnforced();
+ mDecorFitsSystemWindows = window.decorFitsSystemWindows();
+
+ applySystemBarsContrastColor(window.getInsetsController(), mInitBackgroundColor);
+ // Let app draw the background of bars.
+ window.addFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
+ // Use specified bar colors instead of window background.
+ window.clearFlags(FLAG_TRANSLUCENT_STATUS | FLAG_TRANSLUCENT_NAVIGATION);
+ window.setStatusBarColor(Color.TRANSPARENT);
+ window.setNavigationBarColor(Color.TRANSPARENT);
+ window.setDecorFitsSystemWindows(false);
+ window.setStatusBarContrastEnforced(false);
+ window.setNavigationBarContrastEnforced(false);
+ }
+
+ /** Called when this view is removed from the host activity. */
+ private void restoreSystemUIColors() {
+ mWindow.setFlags(mAppWindowFlags, WINDOW_FLAG_MASK);
+ mWindow.setStatusBarColor(mStatusBarColor);
+ mWindow.setNavigationBarColor(mNavigationBarColor);
+ mWindow.getInsetsController().setSystemBarsAppearance(mSystemBarsAppearance,
+ LIGHT_BARS_MASK);
+ mWindow.setDecorFitsSystemWindows(mDecorFitsSystemWindows);
+ mWindow.setStatusBarContrastEnforced(mStatusContrastEnforced);
+ mWindow.setNavigationBarContrastEnforced(mNavigationContrastEnforced);
}
/**
- * Called after SplashScreenView has added on the root window.
+ * Makes the icon color of system bars contrast.
* @hide
*/
- public void makeSystemUIColorsTransparent() {
- if (mWindow != null) {
- final WindowManager.LayoutParams attr = mWindow.getAttributes();
- mDrawBarBackground = (attr.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
- mWindow.addFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
- mStatusBarColor = mWindow.getStatusBarColor();
- mNavigationBarColor = mWindow.getNavigationBarDividerColor();
- mWindow.setStatusBarColor(Color.TRANSPARENT);
- mWindow.setNavigationBarColor(Color.TRANSPARENT);
- }
- setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
- }
-
- private void restoreSystemUIColors() {
- if (mWindow != null) {
- if (!mDrawBarBackground) {
- mWindow.clearFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
- }
- mWindow.setStatusBarColor(mStatusBarColor);
- mWindow.setNavigationBarColor(mNavigationBarColor);
- }
+ public static void applySystemBarsContrastColor(WindowInsetsController windowInsetsController,
+ int backgroundColor) {
+ final int lightBarAppearance = ContrastColorUtil.isColorLight(backgroundColor)
+ ? LIGHT_BARS_MASK : 0;
+ windowInsetsController.setSystemBarsAppearance(lightBarAppearance, LIGHT_BARS_MASK);
}
/**
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index 281702e..3cf4621 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -92,7 +92,7 @@
void setAudioRestriction(int code, int usage, int uid, int mode, in String[] exceptionPackages);
void setUserRestrictions(in Bundle restrictions, IBinder token, int userHandle);
- void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle, in String[] exceptionPackages);
+ void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle, in Map<String, String[]> excludedPackageTags);
void removeUser(int userHandle);
void startWatchingActive(in int[] ops, IAppOpsActiveCallback callback);
@@ -113,7 +113,7 @@
void stopWatchingAsyncNoted(String packageName, IAppOpsAsyncNotedCallback callback);
List<AsyncNotedAppOp> extractAsyncOps(String packageName);
- int checkOperationRaw(int code, int uid, String packageName);
+ int checkOperationRaw(int code, int uid, String packageName, @nullable String attributionTag);
void reloadNonHistoricalState();
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 0ea299d..1a23cc1 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -3931,6 +3931,11 @@
applyDecorFitsSystemWindows();
}
+ @Override
+ public boolean decorFitsSystemWindows() {
+ return mDecorFitsSystemWindows;
+ }
+
private void applyDecorFitsSystemWindows() {
ViewRootImpl impl = getViewRootImplOrNull();
if (impl != null) {
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
index 44597cc..a699f91 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -241,13 +241,13 @@
}
// Some other error. Give up
- ALOGW("Failed to send outbound event on channel '%s'. status=%d",
- getInputChannelName().c_str(), status);
+ ALOGW("Failed to send outbound event on channel '%s'. status=%s(%d)",
+ getInputChannelName().c_str(), statusToString(status).c_str(), status);
if (status != DEAD_OBJECT) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
std::string message =
- android::base::StringPrintf("Failed to send outbound event. status=%d",
- status);
+ android::base::StringPrintf("Failed to send outbound event. status=%s(%d)",
+ statusToString(status).c_str(), status);
jniThrowRuntimeException(env, message.c_str());
mMessageQueue->raiseAndClearException(env, "finishInputEvent");
}
@@ -319,8 +319,8 @@
status_t status = mInputConsumer.consume(&mInputEventFactory,
consumeBatches, frameTime, &seq, &inputEvent);
if (status != OK && status != WOULD_BLOCK) {
- ALOGE("channel '%s' ~ Failed to consume input event. status=%d",
- getInputChannelName().c_str(), status);
+ ALOGE("channel '%s' ~ Failed to consume input event. status=%s(%d)",
+ getInputChannelName().c_str(), statusToString(status).c_str(), status);
return status;
}
@@ -502,9 +502,9 @@
receiverWeak, inputChannel, messageQueue);
status_t status = receiver->initialize();
if (status) {
- std::string message =
- android::base::StringPrintf("Failed to initialize input event receiver. status=%d",
- status);
+ std::string message = android::base::
+ StringPrintf("Failed to initialize input event receiver. status=%s(%d)",
+ statusToString(status).c_str(), status);
jniThrowRuntimeException(env, message.c_str());
return 0;
}
@@ -531,7 +531,7 @@
if (status != DEAD_OBJECT) {
std::string message =
android::base::StringPrintf("Failed to finish input event. status=%s(%d)",
- strerror(-status), status);
+ statusToString(status).c_str(), status);
jniThrowRuntimeException(env, message.c_str());
}
}
@@ -564,8 +564,8 @@
&consumedBatch);
if (status && status != DEAD_OBJECT && !env->ExceptionCheck()) {
std::string message =
- android::base::StringPrintf("Failed to consume batched input event. status=%d",
- status);
+ android::base::StringPrintf("Failed to consume batched input event. status=%s(%d)",
+ statusToString(status).c_str(), status);
jniThrowRuntimeException(env, message.c_str());
return JNI_FALSE;
}
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index b157146..fa1e9d4 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -221,6 +221,9 @@
optional string name = 2 [ (.android.privacy).dest = DEST_EXPLICIT ];
repeated DisplayAreaChildProto children = 3 [deprecated=true];
optional bool is_task_display_area = 4;
+ optional bool is_root_display_area = 5;
+ optional int32 feature_id = 6;
+ optional bool is_organized = 7;
}
/* represents a generic child of a DisplayArea */
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 3edc17b..eca623a 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3936,6 +3936,9 @@
<!-- Handle volume keys directly in Window Manager without passing them to the foreground app -->
<bool name="config_handleVolumeKeysInWindowManager">false</bool>
+ <!-- Rely or not on hardcoded aliased streams table within AudioService -->
+ <bool name="config_handleVolumeAliasesUsingVolumeGroups">false</bool>
+
<!-- Volume level of in-call notification tone playback [0..1] -->
<item name="config_inCallNotificationVolume" format="float" type="dimen">.10</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ce558fb..f2328567 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3632,6 +3632,7 @@
<java-symbol type="array" name="config_allowedSecureInstantAppSettings" />
<java-symbol type="bool" name="config_handleVolumeKeysInWindowManager" />
+ <java-symbol type="bool" name="config_handleVolumeAliasesUsingVolumeGroups" />
<java-symbol type="dimen" name="config_inCallNotificationVolume" />
<java-symbol type="string" name="config_inCallNotificationSound" />
<java-symbol type="integer" name="config_autoGroupAtCount" />
diff --git a/core/tests/coretests/src/android/provider/DeviceConfigTest.java b/core/tests/coretests/src/android/provider/DeviceConfigTest.java
index 61f58b0..fd39cde 100644
--- a/core/tests/coretests/src/android/provider/DeviceConfigTest.java
+++ b/core/tests/coretests/src/android/provider/DeviceConfigTest.java
@@ -762,6 +762,62 @@
// }
// }
+ @Test
+ public void syncDisabling() throws Exception {
+ Properties properties1 = new Properties.Builder(NAMESPACE)
+ .setString(KEY, VALUE)
+ .build();
+ Properties properties2 = new Properties.Builder(NAMESPACE)
+ .setString(KEY, VALUE2)
+ .build();
+
+ try {
+ // Ensure the device starts in a known state.
+ DeviceConfig.setSyncDisabled(Settings.Config.SYNC_DISABLED_MODE_NONE);
+
+ // Assert starting state.
+ assertThat(DeviceConfig.isSyncDisabled()).isFalse();
+ assertThat(DeviceConfig.setProperties(properties1)).isTrue();
+ assertThat(DeviceConfig.getProperties(NAMESPACE, KEY).getString(KEY, DEFAULT_VALUE))
+ .isEqualTo(VALUE);
+
+ // Test disabled (persistent). Persistence is not actually tested, that would require
+ // a host test.
+ DeviceConfig.setSyncDisabled(Settings.Config.SYNC_DISABLED_MODE_PERSISTENT);
+ assertThat(DeviceConfig.isSyncDisabled()).isTrue();
+ assertThat(DeviceConfig.setProperties(properties2)).isFalse();
+ assertThat(DeviceConfig.getProperties(NAMESPACE, KEY).getString(KEY, DEFAULT_VALUE))
+ .isEqualTo(VALUE);
+
+ // Return to not disabled.
+ DeviceConfig.setSyncDisabled(Settings.Config.SYNC_DISABLED_MODE_NONE);
+ assertThat(DeviceConfig.isSyncDisabled()).isFalse();
+ assertThat(DeviceConfig.setProperties(properties2)).isTrue();
+ assertThat(DeviceConfig.getProperties(NAMESPACE, KEY).getString(KEY, DEFAULT_VALUE))
+ .isEqualTo(VALUE2);
+
+ // Test disabled (persistent). Absence of persistence is not actually tested, that would
+ // require a host test.
+ DeviceConfig.setSyncDisabled(Settings.Config.SYNC_DISABLED_MODE_UNTIL_REBOOT);
+ assertThat(DeviceConfig.isSyncDisabled()).isTrue();
+ assertThat(DeviceConfig.setProperties(properties1)).isFalse();
+ assertThat(DeviceConfig.getProperties(NAMESPACE, KEY).getString(KEY, DEFAULT_VALUE))
+ .isEqualTo(VALUE2);
+
+ // Return to not disabled.
+ DeviceConfig.setSyncDisabled(Settings.Config.SYNC_DISABLED_MODE_NONE);
+ assertThat(DeviceConfig.isSyncDisabled()).isFalse();
+ assertThat(DeviceConfig.setProperties(properties1)).isTrue();
+ assertThat(DeviceConfig.getProperties(NAMESPACE, KEY).getString(KEY, DEFAULT_VALUE))
+ .isEqualTo(VALUE);
+ } finally {
+ // Try to return to the default sync disabled state in case of failure.
+ DeviceConfig.setSyncDisabled(Settings.Config.SYNC_DISABLED_MODE_NONE);
+
+ // NAMESPACE will be cleared by cleanUp()
+ }
+ }
+
private static boolean deleteViaContentProvider(String namespace, String key) {
ContentResolver resolver = InstrumentationRegistry.getContext().getContentResolver();
String compositeName = namespace + "/" + key;
diff --git a/core/tests/coretests/src/android/provider/NameValueCacheTest.java b/core/tests/coretests/src/android/provider/NameValueCacheTest.java
index 97e66c4..ee0b127 100644
--- a/core/tests/coretests/src/android/provider/NameValueCacheTest.java
+++ b/core/tests/coretests/src/android/provider/NameValueCacheTest.java
@@ -96,7 +96,8 @@
mCacheGenerationStore.set(0, ++mCurrentGeneration);
Bundle result = new Bundle();
- result.putBoolean(Settings.KEY_CONFIG_SET_RETURN, true);
+ result.putInt(Settings.KEY_CONFIG_SET_ALL_RETURN,
+ Settings.SET_ALL_RESULT_SUCCESS);
return result;
});
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index 85b60f8..be1e2b2 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -127,6 +127,20 @@
}
prebuilt_etc {
+ name: "privapp_whitelist_com.android.networkstack",
+ sub_dir: "permissions",
+ src: "com.android.networkstack.xml",
+ filename_from_src: true,
+}
+
+prebuilt_etc {
+ name: "privapp_whitelist_com.android.networkstack.tethering",
+ sub_dir: "permissions",
+ src: "com.android.networkstack.tethering.xml",
+ filename_from_src: true,
+}
+
+prebuilt_etc {
name: "privapp_whitelist_com.android.provision",
system_ext_specific: true,
sub_dir: "permissions",
diff --git a/data/etc/com.android.networkstack.tethering.xml b/data/etc/com.android.networkstack.tethering.xml
new file mode 100644
index 0000000..f26a961
--- /dev/null
+++ b/data/etc/com.android.networkstack.tethering.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
+-->
+
+<permissions>
+ <privapp-permissions package="com.android.networkstack.tethering">
+ <permission name="android.permission.BLUETOOTH_PRIVILEGED" />
+ <permission name="android.permission.MANAGE_USB"/>
+ <permission name="android.permission.MODIFY_PHONE_STATE"/>
+ <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/>
+ <permission name="android.permission.TETHER_PRIVILEGED"/>
+ <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
+ <permission name="android.permission.UPDATE_DEVICE_STATS"/>
+ </privapp-permissions>
+</permissions>
diff --git a/data/etc/com.android.networkstack.xml b/data/etc/com.android.networkstack.xml
new file mode 100644
index 0000000..06fec1c
--- /dev/null
+++ b/data/etc/com.android.networkstack.xml
@@ -0,0 +1,38 @@
+<?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
+-->
+
+<permissions>
+ <privapp-permissions package="com.android.networkstack">
+ <permission name="android.permission.ACCESS_NETWORK_CONDITIONS"/>
+ <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
+ <permission name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"/>
+ <permission name="android.permission.CONTROL_VPN"/>
+ <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+ <permission name="android.permission.LOCAL_MAC_ADDRESS"/>
+ <permission name="android.permission.MANAGE_SUBSCRIPTION_PLANS"/>
+ <permission name="android.permission.MANAGE_USB"/>
+ <permission name="android.permission.NETWORK_BYPASS_PRIVATE_DNS"/>
+ <permission name="android.permission.PACKET_KEEPALIVE_OFFLOAD"/>
+ <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/>
+ <permission name="android.permission.READ_PRECISE_PHONE_STATE"/>
+ <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
+ <permission name="android.permission.READ_WIFI_CREDENTIAL"/>
+ <permission name="android.permission.RECEIVE_DATA_ACTIVITY_CHANGE"/>
+ <permission name="android.permission.TETHER_PRIVILEGED"/>
+ <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+ </privapp-permissions>
+</permissions>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 545a564..194c4a2 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -271,36 +271,6 @@
<permission name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
</privapp-permissions>
- <privapp-permissions package="com.android.networkstack">
- <permission name="android.permission.ACCESS_NETWORK_CONDITIONS"/>
- <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
- <permission name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"/>
- <permission name="android.permission.CONTROL_VPN"/>
- <permission name="android.permission.INTERACT_ACROSS_USERS"/>
- <permission name="android.permission.LOCAL_MAC_ADDRESS"/>
- <permission name="android.permission.MANAGE_SUBSCRIPTION_PLANS"/>
- <permission name="android.permission.MANAGE_USB"/>
- <permission name="android.permission.NETWORK_BYPASS_PRIVATE_DNS"/>
- <permission name="android.permission.PACKET_KEEPALIVE_OFFLOAD"/>
- <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/>
- <permission name="android.permission.READ_PRECISE_PHONE_STATE"/>
- <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
- <permission name="android.permission.READ_WIFI_CREDENTIAL"/>
- <permission name="android.permission.RECEIVE_DATA_ACTIVITY_CHANGE"/>
- <permission name="android.permission.TETHER_PRIVILEGED"/>
- <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
- </privapp-permissions>
-
- <privapp-permissions package="com.android.networkstack.tethering">
- <permission name="android.permission.BLUETOOTH_PRIVILEGED" />
- <permission name="android.permission.MANAGE_USB"/>
- <permission name="android.permission.MODIFY_PHONE_STATE"/>
- <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/>
- <permission name="android.permission.TETHER_PRIVILEGED"/>
- <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
- <permission name="android.permission.UPDATE_DEVICE_STATS"/>
- </privapp-permissions>
-
<privapp-permissions package="com.android.server.telecom">
<permission name="android.permission.BIND_CONNECTION_SERVICE"/>
<permission name="android.permission.BIND_INCALL_SERVICE"/>
diff --git a/graphics/java/android/graphics/drawable/RippleShader.java b/graphics/java/android/graphics/drawable/RippleShader.java
index 6c0981a..e5651e0 100644
--- a/graphics/java/android/graphics/drawable/RippleShader.java
+++ b/graphics/java/android/graphics/drawable/RippleShader.java
@@ -50,15 +50,17 @@
+ "}"
+ "const float PI = 3.1415926535897932384626;\n"
+ "\n"
+ + "float threshold(float v, float l, float h) {\n"
+ + " return step(l, v) * (1.0 - step(h, v));\n"
+ + "}\n"
+ "float sparkles(vec2 uv, float t) {\n"
+ " float n = triangleNoise(uv);\n"
+ " float s = 0.0;\n"
+ " for (float i = 0; i < 4; i += 1) {\n"
- + " float l = i * 0.01;\n"
- + " float h = l + 0.2;\n"
- + " float o = smoothstep(n - l, h, n);\n"
- + " o *= abs(sin(PI * o * (t + 0.55 * i)));\n"
- + " s += o;\n"
+ + " float l = i * 0.1;\n"
+ + " float h = l + 0.025;\n"
+ + " float o = sin(PI * (t + 0.35 * i));\n"
+ + " s += threshold(n + o, l, h);\n"
+ " }\n"
+ " return saturate(s) * in_sparkleColor.a;\n"
+ "}\n"
@@ -125,9 +127,6 @@
private static final double PI_ROTATE_RIGHT = Math.PI * 0.0078125;
private static final double PI_ROTATE_LEFT = Math.PI * -0.0078125;
- private float mNoisePhase;
- private float mProgress;
-
RippleShader() {
super(SHADER, false);
}
@@ -143,15 +142,6 @@
setUniform("in_maxRadius", radius);
}
- /**
- * Continuous offset used as noise phase.
- */
- public void setNoisePhase(float phase) {
- mNoisePhase = phase;
- setUniform("in_noisePhase", phase);
- updateTurbulence();
- }
-
public void setOrigin(float x, float y) {
setUniform("in_origin", new float[] {x, y});
}
@@ -161,18 +151,20 @@
}
public void setProgress(float progress) {
- mProgress = progress;
setUniform("in_progress", progress);
- updateTurbulence();
}
- private void updateTurbulence() {
- final float turbulencePhase = (float) ((mProgress + mNoisePhase * 0.333f) * 5f * Math.PI);
- setUniform("in_turbulencePhase", turbulencePhase);
+ /**
+ * Continuous offset used as noise phase.
+ */
+ public void setNoisePhase(float phase) {
+ setUniform("in_noisePhase", phase * 0.001f);
//
// Keep in sync with: frameworks/base/libs/hwui/pipeline/skia/AnimatedDrawables.h
//
+ final float turbulencePhase = phase;
+ setUniform("in_turbulencePhase", turbulencePhase);
final float scale = 1.5f;
setUniform("in_tCircle1", new float[]{
(float) (scale * 0.5 + (turbulencePhase * 0.01 * Math.cos(scale * 0.55))),
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java
index d451f4a..0b941b5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java
@@ -16,14 +16,14 @@
package com.android.wm.shell;
-import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_POSITION_BOTTOM_OR_RIGHT;
+import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import com.android.wm.shell.apppairs.AppPairsController;
import com.android.wm.shell.common.ShellExecutor;
-import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutoutController;
import com.android.wm.shell.legacysplitscreen.LegacySplitScreenController;
import com.android.wm.shell.onehanded.OneHandedController;
+import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.splitscreen.SplitScreenController;
import java.io.PrintWriter;
@@ -145,7 +145,7 @@
}
final int taskId = new Integer(args[2]);
final int sideStagePosition = args.length > 3
- ? new Integer(args[3]) : STAGE_POSITION_BOTTOM_OR_RIGHT;
+ ? new Integer(args[3]) : SPLIT_POSITION_BOTTOM_OR_RIGHT;
mSplitScreenOptional.ifPresent(split -> split.moveToSideStage(taskId, sideStagePosition));
return true;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
index dc61345..e6d088e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
@@ -20,11 +20,15 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_BOTTOM_OR_RIGHT;
+import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_TOP_OR_LEFT;
+import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_UNDEFINED;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG;
import android.app.ActivityManager;
import android.graphics.Rect;
import android.view.SurfaceControl;
+import android.view.SurfaceSession;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
@@ -35,6 +39,7 @@
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.SurfaceUtils;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.split.SplitLayout;
@@ -45,7 +50,7 @@
* {@link #mTaskInfo1} and {@link #mTaskInfo2} in the pair.
* Also includes all UI for managing the pair like the divider.
*/
-class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.LayoutChangeListener {
+class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.SplitLayoutHandler {
private static final String TAG = AppPair.class.getSimpleName();
private ActivityManager.RunningTaskInfo mRootTaskInfo;
@@ -54,6 +59,9 @@
private SurfaceControl mTaskLeash1;
private ActivityManager.RunningTaskInfo mTaskInfo2;
private SurfaceControl mTaskLeash2;
+ private SurfaceControl mDimLayer1;
+ private SurfaceControl mDimLayer2;
+ private final SurfaceSession mSurfaceSession = new SurfaceSession();
private final AppPairsController mController;
private final SyncTransactionQueue mSyncQueue;
@@ -101,7 +109,8 @@
mSplitLayout = new SplitLayout(TAG + "SplitDivider",
mDisplayController.getDisplayContext(mRootTaskInfo.displayId),
mRootTaskInfo.configuration, this /* layoutChangeListener */,
- b -> b.setParent(mRootTaskLeash), mDisplayImeController);
+ b -> b.setParent(mRootTaskLeash), mDisplayImeController,
+ mController.getTaskOrganizer());
final WindowContainerToken token1 = task1.token;
final WindowContainerToken token2 = task2.token;
@@ -153,9 +162,13 @@
} else if (taskInfo.taskId == getTaskId1()) {
mTaskInfo1 = taskInfo;
mTaskLeash1 = leash;
+ mSyncQueue.runInSync(t -> mDimLayer1 =
+ SurfaceUtils.makeDimLayer(t, mTaskLeash1, "Dim layer", mSurfaceSession));
} else if (taskInfo.taskId == getTaskId2()) {
mTaskInfo2 = taskInfo;
mTaskLeash2 = leash;
+ mSyncQueue.runInSync(t -> mDimLayer2 =
+ SurfaceUtils.makeDimLayer(t, mTaskLeash2, "Dim layer", mSurfaceSession));
} else {
throw new IllegalStateException("Unknown task=" + taskInfo.taskId);
}
@@ -213,12 +226,31 @@
}
@Override
+ public int getSplitItemPosition(WindowContainerToken token) {
+ if (token == null) {
+ return SPLIT_POSITION_UNDEFINED;
+ }
+
+ if (token.equals(mTaskInfo1.getToken())) {
+ return SPLIT_POSITION_TOP_OR_LEFT;
+ } else if (token.equals(mTaskInfo2.getToken())) {
+ return SPLIT_POSITION_BOTTOM_OR_RIGHT;
+ }
+
+ return SPLIT_POSITION_UNDEFINED;
+ }
+
+ @Override
public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
if (taskInfo.taskId == getRootTaskId()) {
// We don't want to release this object back to the pool since the root task went away.
mController.unpair(mRootTaskInfo.taskId, false /* releaseToPool */);
- } else if (taskInfo.taskId == getTaskId1() || taskInfo.taskId == getTaskId2()) {
+ } else if (taskInfo.taskId == getTaskId1()) {
mController.unpair(mRootTaskInfo.taskId);
+ mSyncQueue.runInSync(t -> t.remove(mDimLayer1));
+ } else if (taskInfo.taskId == getTaskId2()) {
+ mController.unpair(mRootTaskInfo.taskId);
+ mSyncQueue.runInSync(t -> t.remove(mDimLayer2));
}
}
@@ -264,40 +296,16 @@
@Override
public void onBoundsChanging(SplitLayout layout) {
- final SurfaceControl dividerLeash = mSplitLayout.getDividerLeash();
- if (dividerLeash == null) return;
- final Rect dividerBounds = layout.getDividerBounds();
- final Rect bounds1 = layout.getBounds1();
- final Rect bounds2 = layout.getBounds2();
- mSyncQueue.runInSync(t -> t
- .setPosition(dividerLeash, dividerBounds.left, dividerBounds.top)
- .setPosition(mTaskLeash1, bounds1.left, bounds1.top)
- .setPosition(mTaskLeash2, bounds2.left, bounds2.top)
- // Sets crop to prevent visible region of tasks overlap with each other when
- // re-positioning surfaces while resizing.
- .setWindowCrop(mTaskLeash1, bounds1.width(), bounds1.height())
- .setWindowCrop(mTaskLeash2, bounds2.width(), bounds2.height()));
+ mSyncQueue.runInSync(t ->
+ layout.applySurfaceChanges(t, mTaskLeash1, mTaskLeash2, mDimLayer1, mDimLayer2));
}
@Override
public void onBoundsChanged(SplitLayout layout) {
- final SurfaceControl dividerLeash = mSplitLayout.getDividerLeash();
- if (dividerLeash == null) return;
- final Rect dividerBounds = layout.getDividerBounds();
- final Rect bounds1 = layout.getBounds1();
- final Rect bounds2 = layout.getBounds2();
final WindowContainerTransaction wct = new WindowContainerTransaction();
- wct.setBounds(mTaskInfo1.token, bounds1)
- .setBounds(mTaskInfo2.token, bounds2);
- mController.getTaskOrganizer().applyTransaction(wct);
- mSyncQueue.runInSync(t -> t
- // Resets layer of divider bar to make sure it is always on top.
- .setLayer(dividerLeash, Integer.MAX_VALUE)
- .setPosition(dividerLeash, dividerBounds.left, dividerBounds.top)
- .setPosition(mTaskLeash1, bounds1.left, bounds1.top)
- .setPosition(mTaskLeash2, bounds2.left, bounds2.top)
- // Resets crop to apply new surface bounds directly.
- .setWindowCrop(mTaskLeash1, null)
- .setWindowCrop(mTaskLeash2, null));
+ layout.applyTaskChanges(wct, mTaskInfo1, mTaskInfo2);
+ mSyncQueue.queue(wct);
+ mSyncQueue.runInSync(t ->
+ layout.applySurfaceChanges(t, mTaskLeash1, mTaskLeash2, mDimLayer1, mDimLayer2));
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SurfaceUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SurfaceUtils.java
new file mode 100644
index 0000000..55c5125
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SurfaceUtils.java
@@ -0,0 +1,38 @@
+/*
+ * 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.wm.shell.common;
+
+import android.view.SurfaceControl;
+import android.view.SurfaceSession;
+
+/**
+ * Helpers for handling surface.
+ */
+public class SurfaceUtils {
+ /** Creates a dim layer above indicated host surface. */
+ public static SurfaceControl makeDimLayer(SurfaceControl.Transaction t, SurfaceControl host,
+ String name, SurfaceSession surfaceSession) {
+ SurfaceControl dimLayer = new SurfaceControl.Builder(surfaceSession)
+ .setParent(host)
+ .setColorLayer()
+ .setName(name)
+ .setCallsite("SurfaceUtils.makeDimLayer")
+ .build();
+ t.setLayer(dimLayer, Integer.MAX_VALUE).setColor(dimLayer, new float[]{0f, 0f, 0f});
+ return dimLayer;
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
index 442e7a4..a920f9c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
@@ -36,13 +36,11 @@
import com.android.internal.policy.DividerSnapAlgorithm;
import com.android.wm.shell.R;
import com.android.wm.shell.animation.Interpolators;
-import com.android.wm.shell.common.DisplayImeController;
/**
* Divider for multi window splits.
*/
-public class DividerView extends FrameLayout implements View.OnTouchListener,
- DisplayImeController.ImePositionProcessor {
+public class DividerView extends FrameLayout implements View.OnTouchListener {
public static final long TOUCH_ANIMATION_DURATION = 150;
public static final long TOUCH_RELEASE_ANIMATION_DURATION = 200;
@@ -99,12 +97,6 @@
}
@Override
- public void onImeVisibilityChanged(int displayId, boolean isShowing) {
- if (displayId != getDisplay().getDisplayId()) return;
- setInteractive(!isShowing);
- }
-
- @Override
public boolean onTouch(View v, MotionEvent event) {
if (mSplitLayout == null || !mInteractive) {
return false;
@@ -217,7 +209,7 @@
mViewHost.relayout(lp);
}
- private void setInteractive(boolean interactive) {
+ void setInteractive(boolean interactive) {
if (interactive == mInteractive) return;
mInteractive = interactive;
releaseTouching();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index d318a5a..e42f511 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -25,16 +25,22 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
+import android.annotation.IntDef;
+import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.Rect;
import android.view.SurfaceControl;
import android.view.WindowInsets;
import android.view.WindowManager;
+import android.window.WindowContainerToken;
+import android.window.WindowContainerTransaction;
import androidx.annotation.Nullable;
import com.android.internal.policy.DividerSnapAlgorithm;
+import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.common.DisplayImeController;
@@ -42,7 +48,32 @@
* Records and handles layout of splits. Helps to calculate proper bounds when configuration or
* divide position changes.
*/
-public class SplitLayout {
+public final class SplitLayout {
+ /**
+ * Split position isn't specified normally meaning to use what ever it is currently set to.
+ */
+ public static final int SPLIT_POSITION_UNDEFINED = -1;
+
+ /**
+ * Specifies that a split is positioned at the top half of the screen if
+ * in portrait mode or at the left half of the screen if in landscape mode.
+ */
+ public static final int SPLIT_POSITION_TOP_OR_LEFT = 0;
+
+ /**
+ * Specifies that a split is positioned at the bottom half of the screen if
+ * in portrait mode or at the right half of the screen if in landscape mode.
+ */
+ public static final int SPLIT_POSITION_BOTTOM_OR_RIGHT = 1;
+
+ @IntDef(prefix = {"SPLIT_POSITION_"}, value = {
+ SPLIT_POSITION_UNDEFINED,
+ SPLIT_POSITION_TOP_OR_LEFT,
+ SPLIT_POSITION_BOTTOM_OR_RIGHT
+ })
+ public @interface SplitPosition {
+ }
+
private final int mDividerWindowWidth;
private final int mDividerInsets;
private final int mDividerSize;
@@ -51,8 +82,11 @@
private final Rect mDividerBounds = new Rect();
private final Rect mBounds1 = new Rect();
private final Rect mBounds2 = new Rect();
- private final LayoutChangeListener mLayoutChangeListener;
+ private final SplitLayoutHandler mSplitLayoutHandler;
private final SplitWindowManager mSplitWindowManager;
+ private final DisplayImeController mDisplayImeController;
+ private final ImePositionProcessor mImePositionProcessor;
+ private final ShellTaskOrganizer mTaskOrganizer;
private Context mContext;
private DividerSnapAlgorithm mDividerSnapAlgorithm;
@@ -60,18 +94,21 @@
private boolean mInitialized = false;
public SplitLayout(String windowName, Context context, Configuration configuration,
- LayoutChangeListener layoutChangeListener,
+ SplitLayoutHandler splitLayoutHandler,
SplitWindowManager.ParentContainerCallbacks parentContainerCallbacks,
- DisplayImeController displayImeController) {
+ DisplayImeController displayImeController, ShellTaskOrganizer taskOrganizer) {
mContext = context.createConfigurationContext(configuration);
- mLayoutChangeListener = layoutChangeListener;
+ mSplitLayoutHandler = splitLayoutHandler;
+ mDisplayImeController = displayImeController;
mSplitWindowManager = new SplitWindowManager(
- windowName, mContext, configuration, parentContainerCallbacks,
- displayImeController);
+ windowName, mContext, configuration, parentContainerCallbacks);
+ mTaskOrganizer = taskOrganizer;
+ mImePositionProcessor = new ImePositionProcessor(mContext.getDisplayId());
- mDividerWindowWidth = context.getResources().getDimensionPixelSize(
+ final Resources resources = context.getResources();
+ mDividerWindowWidth = resources.getDimensionPixelSize(
com.android.internal.R.dimen.docked_stack_divider_thickness);
- mDividerInsets = context.getResources().getDimensionPixelSize(
+ mDividerInsets = resources.getDimensionPixelSize(
com.android.internal.R.dimen.docked_stack_divider_insets);
mDividerSize = mDividerWindowWidth - mDividerInsets * 2;
@@ -82,17 +119,17 @@
/** Gets bounds of the primary split. */
public Rect getBounds1() {
- return mBounds1;
+ return new Rect(mBounds1);
}
/** Gets bounds of the secondary split. */
public Rect getBounds2() {
- return mBounds2;
+ return new Rect(mBounds2);
}
/** Gets bounds of divider window. */
public Rect getDividerBounds() {
- return mDividerBounds;
+ return new Rect(mDividerBounds);
}
/** Returns leash of the current divider bar. */
@@ -153,6 +190,7 @@
if (mInitialized) return;
mInitialized = true;
mSplitWindowManager.init(this);
+ mDisplayImeController.addPositionProcessor(mImePositionProcessor);
}
/** Releases the surface holding the current {@link DividerView}. */
@@ -160,6 +198,8 @@
if (!mInitialized) return;
mInitialized = false;
mSplitWindowManager.release();
+ mDisplayImeController.removePositionProcessor(mImePositionProcessor);
+ mImePositionProcessor.reset();
}
/**
@@ -168,14 +208,14 @@
*/
void updateDivideBounds(int position) {
updateBounds(position);
- mLayoutChangeListener.onBoundsChanging(this);
mSplitWindowManager.setResizingSplits(true);
+ mSplitLayoutHandler.onBoundsChanging(this);
}
void setDividePosition(int position) {
mDividePosition = position;
updateBounds(mDividePosition);
- mLayoutChangeListener.onBoundsChanged(this);
+ mSplitLayoutHandler.onBoundsChanged(this);
mSplitWindowManager.setResizingSplits(false);
}
@@ -192,11 +232,11 @@
public void snapToTarget(int currentPosition, DividerSnapAlgorithm.SnapTarget snapTarget) {
switch (snapTarget.flag) {
case FLAG_DISMISS_START:
- mLayoutChangeListener.onSnappedToDismiss(false /* bottomOrRight */);
+ mSplitLayoutHandler.onSnappedToDismiss(false /* bottomOrRight */);
mSplitWindowManager.setResizingSplits(false);
break;
case FLAG_DISMISS_END:
- mLayoutChangeListener.onSnappedToDismiss(true /* bottomOrRight */);
+ mSplitLayoutHandler.onSnappedToDismiss(true /* bottomOrRight */);
mSplitWindowManager.setResizingSplits(false);
break;
default:
@@ -206,7 +246,7 @@
}
void onDoubleTappedDivider() {
- mLayoutChangeListener.onDoubleTappedDivider();
+ mSplitLayoutHandler.onDoubleTappedDivider();
}
/**
@@ -265,8 +305,38 @@
return bounds.width() > bounds.height();
}
- /** Listens layout change event. */
- public interface LayoutChangeListener {
+ /** Apply recorded surface layout to the {@link SurfaceControl.Transaction}. */
+ public void applySurfaceChanges(SurfaceControl.Transaction t, SurfaceControl leash1,
+ SurfaceControl leash2, SurfaceControl dimLayer1, SurfaceControl dimLayer2) {
+ final Rect dividerBounds = mImePositionProcessor.adjustForIme(mDividerBounds);
+ final Rect bounds1 = mImePositionProcessor.adjustForIme(mBounds1);
+ final Rect bounds2 = mImePositionProcessor.adjustForIme(mBounds2);
+ final SurfaceControl dividerLeash = getDividerLeash();
+ if (dividerLeash != null) {
+ t.setPosition(dividerLeash, dividerBounds.left, dividerBounds.top)
+ // Resets layer of divider bar to make sure it is always on top.
+ .setLayer(dividerLeash, Integer.MAX_VALUE);
+ }
+
+ t.setPosition(leash1, bounds1.left, bounds1.top)
+ .setWindowCrop(leash1, bounds1.width(), bounds1.height());
+
+ t.setPosition(leash2, bounds2.left, bounds2.top)
+ .setWindowCrop(leash2, bounds2.width(), bounds2.height());
+
+ mImePositionProcessor.applySurfaceDimValues(t, dimLayer1, dimLayer2);
+ }
+
+ /** Apply recorded task layout to the {@link WindowContainerTransaction}. */
+ public void applyTaskChanges(WindowContainerTransaction wct,
+ ActivityManager.RunningTaskInfo task1, ActivityManager.RunningTaskInfo task2) {
+ wct.setBounds(task1.token, mImePositionProcessor.adjustForIme(mBounds1))
+ .setBounds(task2.token, mImePositionProcessor.adjustForIme(mBounds2));
+ }
+
+ /** Handles layout change event. */
+ public interface SplitLayoutHandler {
+
/** Calls when dismissing split. */
void onSnappedToDismiss(boolean snappedToEnd);
@@ -279,5 +349,133 @@
/** Calls when user double tapped on the divider bar. */
default void onDoubleTappedDivider() {
}
+
+ /** Returns split position of the token. */
+ @SplitPosition
+ int getSplitItemPosition(WindowContainerToken token);
+ }
+
+ /** Records IME top offset changes and updates SplitLayout correspondingly. */
+ private class ImePositionProcessor implements DisplayImeController.ImePositionProcessor {
+ /**
+ * Maximum size of an adjusted split bounds relative to original stack bounds. Used to
+ * restrict IME adjustment so that a min portion of top split remains visible.
+ */
+ private static final float ADJUSTED_SPLIT_FRACTION_MAX = 0.7f;
+ private static final float ADJUSTED_NONFOCUS_DIM = 0.3f;
+
+ private final int mDisplayId;
+
+ private int mYOffsetForIme;
+ private float mDimValue1;
+ private float mDimValue2;
+
+ private int mStartImeTop;
+ private int mEndImeTop;
+
+ private int mTargetYOffset;
+ private int mLastYOffset;
+ private float mTargetDim1;
+ private float mTargetDim2;
+ private float mLastDim1;
+ private float mLastDim2;
+
+ private ImePositionProcessor(int displayId) {
+ mDisplayId = displayId;
+ }
+
+ @Override
+ public int onImeStartPositioning(int displayId, int hiddenTop, int shownTop,
+ boolean showing, boolean isFloating, SurfaceControl.Transaction t) {
+ if (displayId != mDisplayId) return 0;
+ final int imeTargetPosition = getImeTargetPosition();
+ if (!mInitialized || imeTargetPosition == SPLIT_POSITION_UNDEFINED) return 0;
+ mStartImeTop = showing ? hiddenTop : shownTop;
+ mEndImeTop = showing ? shownTop : hiddenTop;
+
+ // Update target dim values
+ mLastDim1 = mDimValue1;
+ mTargetDim1 = imeTargetPosition == SPLIT_POSITION_BOTTOM_OR_RIGHT && showing
+ ? ADJUSTED_NONFOCUS_DIM : 0.0f;
+ mLastDim2 = mDimValue2;
+ mTargetDim2 = imeTargetPosition == SPLIT_POSITION_TOP_OR_LEFT && showing
+ ? ADJUSTED_NONFOCUS_DIM : 0.0f;
+
+ // Calculate target bounds offset for IME
+ mLastYOffset = mYOffsetForIme;
+ final boolean needOffset = imeTargetPosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
+ && !isFloating && !isLandscape(mRootBounds) && showing;
+ mTargetYOffset = needOffset ? getTargetYOffset() : 0;
+
+ // Make {@link DividerView} non-interactive while IME showing in split mode. Listen to
+ // ImePositionProcessor#onImeVisibilityChanged directly in DividerView is not enough
+ // because DividerView won't receive onImeVisibilityChanged callback after it being
+ // re-inflated.
+ mSplitWindowManager.setInteractive(
+ !showing || imeTargetPosition == SPLIT_POSITION_UNDEFINED);
+
+ return 0;
+ }
+
+ @Override
+ public void onImePositionChanged(int displayId, int imeTop, SurfaceControl.Transaction t) {
+ if (displayId != mDisplayId) return;
+ onProgress(getProgress(imeTop));
+ mSplitLayoutHandler.onBoundsChanging(SplitLayout.this);
+ }
+
+ @Override
+ public void onImeEndPositioning(int displayId, boolean cancel,
+ SurfaceControl.Transaction t) {
+ if (displayId != mDisplayId || cancel) return;
+ onProgress(1.0f);
+ mSplitLayoutHandler.onBoundsChanging(SplitLayout.this);
+ }
+
+ private int getTargetYOffset() {
+ final int desireOffset = Math.abs(mEndImeTop - mStartImeTop);
+ // Make sure to keep at least 30% visible for the top split.
+ final int maxOffset = (int) (mBounds1.height() * ADJUSTED_SPLIT_FRACTION_MAX);
+ return -Math.min(desireOffset, maxOffset);
+ }
+
+ @SplitPosition
+ private int getImeTargetPosition() {
+ final WindowContainerToken token = mTaskOrganizer.getImeTarget(mDisplayId);
+ return mSplitLayoutHandler.getSplitItemPosition(token);
+ }
+
+ private float getProgress(int currImeTop) {
+ return ((float) currImeTop - mStartImeTop) / (mEndImeTop - mStartImeTop);
+ }
+
+ private void onProgress(float progress) {
+ mDimValue1 = getProgressValue(mLastDim1, mTargetDim1, progress);
+ mDimValue2 = getProgressValue(mLastDim2, mTargetDim2, progress);
+ mYOffsetForIme =
+ (int) getProgressValue((float) mLastYOffset, (float) mTargetYOffset, progress);
+ }
+
+ private float getProgressValue(float start, float end, float progress) {
+ return start + (end - start) * progress;
+ }
+
+ private void reset() {
+ mYOffsetForIme = 0;
+ mDimValue1 = mDimValue2 = 0.0f;
+ }
+
+ /* Adjust bounds with IME offset. */
+ private Rect adjustForIme(Rect bounds) {
+ final Rect temp = new Rect(bounds);
+ if (mYOffsetForIme != 0) temp.offset(0, mYOffsetForIme);
+ return temp;
+ }
+
+ private void applySurfaceDimValues(SurfaceControl.Transaction t, SurfaceControl dimLayer1,
+ SurfaceControl dimLayer2) {
+ t.setAlpha(dimLayer1, mDimValue1).setVisibility(dimLayer1, mDimValue1 > 0.001f);
+ t.setAlpha(dimLayer2, mDimValue2).setVisibility(dimLayer2, mDimValue2 > 0.001f);
+ }
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
index f6efb01..0cea0ef 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
@@ -46,7 +46,6 @@
import androidx.annotation.Nullable;
import com.android.wm.shell.R;
-import com.android.wm.shell.common.DisplayImeController;
/**
* Holds view hierarchy of a root surface and helps to inflate {@link DividerView} for a split.
@@ -55,7 +54,6 @@
private static final String TAG = SplitWindowManager.class.getSimpleName();
private final String mWindowName;
- private final DisplayImeController mDisplayImeController;
private final ParentContainerCallbacks mParentContainerCallbacks;
private Context mContext;
private SurfaceControlViewHost mViewHost;
@@ -68,13 +66,11 @@
}
public SplitWindowManager(String windowName, Context context, Configuration config,
- ParentContainerCallbacks parentContainerCallbacks,
- DisplayImeController displayImeController) {
+ ParentContainerCallbacks parentContainerCallbacks) {
super(config, null /* rootSurface */, null /* hostInputToken */);
mContext = context.createConfigurationContext(config);
mParentContainerCallbacks = parentContainerCallbacks;
mWindowName = windowName;
- mDisplayImeController = displayImeController;
}
@Override
@@ -128,7 +124,6 @@
lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY;
mViewHost.setView(mDividerView, lp);
mDividerView.setup(splitLayout, mViewHost);
- mDisplayImeController.addPositionProcessor(mDividerView);
}
/**
@@ -137,7 +132,6 @@
*/
void release() {
if (mDividerView != null) {
- mDisplayImeController.removePositionProcessor(mDividerView);
mDividerView = null;
}
@@ -152,6 +146,11 @@
}
}
+ void setInteractive(boolean interactive) {
+ if (mDividerView == null) return;
+ mDividerView.setInteractive(interactive);
+ }
+
void setResizingSplits(boolean resizing) {
if (resizing == mResizingSplits) return;
try {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
index 9a09ca4..9bcc3ac 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
@@ -29,14 +29,14 @@
import static android.content.Intent.EXTRA_TASK_ID;
import static android.content.Intent.EXTRA_USER;
+import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_BOTTOM_OR_RIGHT;
+import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_TOP_OR_LEFT;
+import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_UNDEFINED;
import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_FULLSCREEN;
import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_BOTTOM;
import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_LEFT;
import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_RIGHT;
import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_TOP;
-import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_POSITION_BOTTOM_OR_RIGHT;
-import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_POSITION_TOP_OR_LEFT;
-import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_POSITION_UNDEFINED;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
@@ -64,7 +64,7 @@
import androidx.annotation.VisibleForTesting;
import com.android.wm.shell.common.DisplayLayout;
-import com.android.wm.shell.splitscreen.SplitScreen.StagePosition;
+import com.android.wm.shell.common.split.SplitLayout.SplitPosition;
import com.android.wm.shell.splitscreen.SplitScreen.StageType;
import com.android.wm.shell.splitscreen.SplitScreenController;
@@ -203,10 +203,10 @@
final boolean leftOrTop = target.type == TYPE_SPLIT_TOP || target.type == TYPE_SPLIT_LEFT;
@StageType int stage = STAGE_TYPE_UNDEFINED;
- @StagePosition int position = STAGE_POSITION_UNDEFINED;
+ @SplitPosition int position = SPLIT_POSITION_UNDEFINED;
if (target.type != TYPE_FULLSCREEN && mSplitScreen != null) {
// Update launch options for the split side we are targeting.
- position = leftOrTop ? STAGE_POSITION_TOP_OR_LEFT : STAGE_POSITION_BOTTOM_OR_RIGHT;
+ position = leftOrTop ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT;
if (!inSplitScreen) {
// Launch in the side stage if we are not in split-screen already.
stage = STAGE_TYPE_SIDE;
@@ -219,7 +219,7 @@
}
private void startClipDescription(ClipDescription description, Intent intent,
- @StageType int stage, @StagePosition int position) {
+ @StageType int stage, @SplitPosition int position) {
final boolean isTask = description.hasMimeType(MIMETYPE_APPLICATION_TASK);
final boolean isShortcut = description.hasMimeType(MIMETYPE_APPLICATION_SHORTCUT);
final Bundle opts = intent.hasExtra(EXTRA_ACTIVITY_OPTIONS)
@@ -291,12 +291,12 @@
* Interface for actually committing the task launches.
*/
public interface Starter {
- void startTask(int taskId, @StageType int stage, @StagePosition int position,
+ void startTask(int taskId, @StageType int stage, @SplitPosition int position,
@Nullable Bundle options);
void startShortcut(String packageName, String shortcutId, @StageType int stage,
- @StagePosition int position, @Nullable Bundle options, UserHandle user);
+ @SplitPosition int position, @Nullable Bundle options, UserHandle user);
void startIntent(PendingIntent intent, Intent fillInIntent,
- @StageType int stage, @StagePosition int position,
+ @StageType int stage, @SplitPosition int position,
@Nullable Bundle options);
void enterSplitScreen(int taskId, boolean leftOrTop);
void exitSplitScreen();
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 60f7ee2..0f16c8a 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
@@ -685,9 +685,9 @@
mTmpRect.set(mHandle.getLeft(), mHandle.getTop(), mHandle.getRight(), mHandle.getBottom());
if (isHorizontalDivision()) {
- mTmpRect.offsetTo(0, mDividerPositionY);
+ mTmpRect.offsetTo(mHandle.getLeft(), mDividerPositionY);
} else {
- mTmpRect.offsetTo(mDividerPositionX, 0);
+ mTmpRect.offsetTo(mDividerPositionX, mHandle.getTop());
}
mWindowManagerProxy.setTouchRegion(mTmpRect);
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 9eacaec..ee2202a 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
@@ -577,7 +577,7 @@
mSplits.getSplitTransitions().dismissSplit(
mSplits, mSplitLayout, !toPrimaryTask, snapped);
} else {
- mWindowManagerProxy.applyDismissSplit(mSplits, mSplitLayout, !toPrimaryTask);
+ mWindowManagerProxy.applyDismissSplit(mSplits, mSplitLayout, !toPrimaryTask);
onDismissSplit();
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java
index 13596ea..86bf3ff 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java
@@ -38,6 +38,7 @@
import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.SurfaceUtils;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.transition.Transitions;
@@ -70,9 +71,9 @@
private final LegacySplitScreenTransitions mSplitTransitions;
LegacySplitScreenTaskListener(LegacySplitScreenController splitScreenController,
- ShellTaskOrganizer shellTaskOrganizer,
- Transitions transitions,
- SyncTransactionQueue syncQueue) {
+ ShellTaskOrganizer shellTaskOrganizer,
+ Transitions transitions,
+ SyncTransactionQueue syncQueue) {
mSplitScreenController = splitScreenController;
mTaskOrganizer = shellTaskOrganizer;
mSplitTransitions = new LegacySplitScreenTransitions(splitScreenController.mTransactionPool,
@@ -146,21 +147,11 @@
ProtoLog.v(WM_SHELL_TASK_ORG, "%s onTaskAppeared Supported", TAG);
// Initialize dim surfaces:
- mPrimaryDim = new SurfaceControl.Builder(mSurfaceSession)
- .setParent(mPrimarySurface).setColorLayer()
- .setName("Primary Divider Dim")
- .setCallsite("SplitScreenTaskOrganizer.onTaskAppeared")
- .build();
- mSecondaryDim = new SurfaceControl.Builder(mSurfaceSession)
- .setParent(mSecondarySurface).setColorLayer()
- .setName("Secondary Divider Dim")
- .setCallsite("SplitScreenTaskOrganizer.onTaskAppeared")
- .build();
SurfaceControl.Transaction t = getTransaction();
- t.setLayer(mPrimaryDim, Integer.MAX_VALUE);
- t.setColor(mPrimaryDim, new float[]{0f, 0f, 0f});
- t.setLayer(mSecondaryDim, Integer.MAX_VALUE);
- t.setColor(mSecondaryDim, new float[]{0f, 0f, 0f});
+ mPrimaryDim = SurfaceUtils.makeDimLayer(
+ t, mPrimarySurface, "Primary Divider Dim", mSurfaceSession);
+ mSecondaryDim = SurfaceUtils.makeDimLayer(
+ t, mSecondarySurface, "Secondary Divider Dim", mSurfaceSession);
t.apply();
releaseTransaction(t);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java
index 7e5fd92..1ae2636 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java
@@ -19,6 +19,7 @@
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
+import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Rect;
import android.view.SurfaceControl;
@@ -203,8 +204,10 @@
}
OneHandedTransitionAnimator addOneHandedAnimationCallback(
- OneHandedAnimationCallback callback) {
- mOneHandedAnimationCallbacks.add(callback);
+ @Nullable OneHandedAnimationCallback callback) {
+ if (callback != null) {
+ mOneHandedAnimationCallbacks.add(callback);
+ }
return this;
}
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 e506542..49266ce 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
@@ -217,7 +217,7 @@
OneHandedTimeoutHandler timeoutHandler = new OneHandedTimeoutHandler(mainExecutor);
OneHandedState transitionState = new OneHandedState();
OneHandedTutorialHandler tutorialHandler = new OneHandedTutorialHandler(context,
- displayLayout, windowManager, mainExecutor);
+ displayLayout, windowManager, settingsUtil, mainExecutor);
OneHandedAnimationController animationController =
new OneHandedAnimationController(context);
OneHandedTouchHandler touchHandler = new OneHandedTouchHandler(timeoutHandler,
@@ -299,6 +299,8 @@
mAccessibilityManager = AccessibilityManager.getInstance(context);
mAccessibilityManager.addAccessibilityStateChangeListener(
mAccessibilityStateChangeListener);
+
+ mState.addSListeners(mTutorialHandler);
}
public OneHanded asOneHanded() {
@@ -627,13 +629,13 @@
}
private void onConfigChanged(Configuration newConfig) {
- if (mTutorialHandler != null) {
- if (!mIsOneHandedEnabled
- || newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
- return;
- }
- mTutorialHandler.onConfigurationChanged(newConfig);
+ if (mTutorialHandler == null) {
+ return;
}
+ if (!mIsOneHandedEnabled || newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ return;
+ }
+ mTutorialHandler.onConfigurationChanged();
}
private void onUserSwitch(int newUserId) {
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 bb68224..90fc823 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
@@ -29,7 +29,7 @@
import java.lang.annotation.RetentionPolicy;
/**
- * APIs for querying or updating one handed settings .
+ * APIs for querying or updating one handed settings.
*/
public final class OneHandedSettingsUtil {
private static final String TAG = "OneHandedSettingsUtil";
@@ -62,7 +62,7 @@
public static final int ONE_HANDED_TIMEOUT_LONG_IN_SECONDS = 12;
/**
- * Register one handed preference settings observer
+ * Registers one handed preference settings observer
*
* @param key Setting key to monitor in observer
* @param resolver ContentResolver of context
@@ -82,7 +82,7 @@
}
/**
- * Unregister one handed preference settings observer
+ * Unregisters one handed preference settings observer.
*
* @param resolver ContentResolver of context
* @param observer preference key change observer
@@ -95,7 +95,7 @@
}
/**
- * Query one handed enable or disable flag from Settings provider.
+ * Queries one handed enable or disable flag from Settings provider.
*
* @return enable or disable one handed mode flag.
*/
@@ -105,7 +105,7 @@
}
/**
- * Query taps app to exit config from Settings provider.
+ * Queries taps app to exit config from Settings provider.
*
* @return enable or disable taps app exit.
*/
@@ -115,7 +115,7 @@
}
/**
- * Query timeout value from Settings provider. Default is
+ * Queries timeout value from Settings provider. Default is.
* {@link OneHandedSettingsUtil#ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS}
*
* @return timeout value in seconds.
@@ -135,10 +135,31 @@
Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, 0, userId) == 1;
}
+
/**
- * Sets one handed activated or not to notify state for shortcut
+ * Queries tutorial shown counts from Settings provider. Default is 0.
*
- * @return activated or not
+ * @return counts tutorial shown counts.
+ */
+ public int getTutorialShownCounts(ContentResolver resolver, int userId) {
+ return Settings.Secure.getIntForUser(resolver,
+ Settings.Secure.ONE_HANDED_TUTORIAL_SHOW_COUNT, 0, userId);
+ }
+
+ /**
+ * Sets tutorial shown counts.
+ *
+ * @return true if the value was set, false on database errors.
+ */
+ public boolean setTutorialShownCounts(ContentResolver resolver, int shownCounts, int userId) {
+ return Settings.Secure.putIntForUser(resolver,
+ Settings.Secure.ONE_HANDED_TUTORIAL_SHOW_COUNT, shownCounts, userId);
+ }
+
+ /**
+ * Sets one handed activated or not to notify state for shortcut.
+ *
+ * @return true if one handed mode is activated.
*/
public boolean getOneHandedModeActivated(ContentResolver resolver, int userId) {
return Settings.Secure.getIntForUser(resolver,
@@ -146,9 +167,9 @@
}
/**
- * Sets one handed activated or not to notify state for shortcut
+ * Sets one handed activated or not to notify state for shortcut.
*
- * @return activated or not
+ * @return true if the value was set, false on database errors.
*/
public boolean setOneHandedModeActivated(ContentResolver resolver, int state, int userId) {
return Settings.Secure.putIntForUser(resolver,
@@ -167,6 +188,8 @@
pw.println(getSettingsTapsAppToExit(resolver, userId));
pw.print(innerPrefix + "shortcutActivated=");
pw.println(getOneHandedModeActivated(resolver, userId));
+ pw.print(innerPrefix + "tutorialShownCounts=");
+ pw.println(getTutorialShownCounts(resolver, userId));
}
public OneHandedSettingsUtil() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedState.java
index facc4bd..47bb99d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedState.java
@@ -21,6 +21,8 @@
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
/**
Represents current OHM state by following steps, a generic CUJ is
@@ -28,13 +30,13 @@
*/
public class OneHandedState {
/** DEFAULT STATE after OHM feature initialized. */
- public static final int STATE_NONE = 0x00000000;
+ public static final int STATE_NONE = 0;
/** The state flag set when user trigger OHM. */
- public static final int STATE_ENTERING = 0x00000001;
+ public static final int STATE_ENTERING = 1;
/** The state flag set when transitioning */
- public static final int STATE_ACTIVE = 0x00000002;
+ public static final int STATE_ACTIVE = 2;
/** The state flag set when user stop OHM feature. */
- public static final int STATE_EXITING = 0x00000004;
+ public static final int STATE_EXITING = 3;
@IntDef(prefix = { "STATE_" }, value = {
STATE_NONE,
@@ -54,9 +56,18 @@
private static final String TAG = OneHandedState.class.getSimpleName();
+ private List<OnStateChangedListener> mStateChangeListeners = new ArrayList<>();
+
+ /**
+ * Adds listener to be called back when one handed state changed.
+ * @param listener the listener to be called back
+ */
+ public void addSListeners(OnStateChangedListener listener) {
+ mStateChangeListeners.add(listener);
+ }
+
/**
* Gets current transition state of One handed mode.
- *
* @return The bitwise flags representing current states.
*/
public @State int getState() {
@@ -85,6 +96,9 @@
*/
public void setState(@State int newState) {
sCurrentState = newState;
+ if (!mStateChangeListeners.isEmpty()) {
+ mStateChangeListeners.forEach((listener) -> listener.onStateChanged(newState));
+ }
}
/** Dumps internal state. */
@@ -93,4 +107,14 @@
pw.println(TAG);
pw.println(innerPrefix + "sCurrentState=" + sCurrentState);
}
+
+ /**
+ * Gets notified when one handed state changed
+ *
+ * @see OneHandedState
+ */
+ public interface OnStateChangedListener {
+ /** Called when one handed state changed */
+ default void onStateChanged(@State int newState) {}
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java
index e8cee8a..6cee404 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java
@@ -16,13 +16,19 @@
package com.android.wm.shell.onehanded;
+import static android.os.UserHandle.myUserId;
+
+import static com.android.wm.shell.onehanded.OneHandedState.STATE_ACTIVE;
+import static com.android.wm.shell.onehanded.OneHandedState.STATE_ENTERING;
+import static com.android.wm.shell.onehanded.OneHandedState.STATE_EXITING;
+import static com.android.wm.shell.onehanded.OneHandedState.STATE_NONE;
+
+import android.annotation.Nullable;
import android.content.ContentResolver;
import android.content.Context;
-import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.SystemProperties;
-import android.provider.Settings;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
@@ -32,6 +38,7 @@
import androidx.annotation.NonNull;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.wm.shell.R;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.ShellExecutor;
@@ -39,42 +46,33 @@
import java.io.PrintWriter;
/**
- * Manages the user tutorial handling for One Handed operations, including animations synchronized
- * with one-handed translation.
- * Refer {@link OneHandedGestureHandler} and {@link OneHandedTouchHandler} to see start and stop
- * one handed gesture
+ * Handles tutorial visibility and synchronized transition for One Handed operations,
+ * TargetViewContainer only be created and attach to window when
+ * shown counts < {@link MAX_TUTORIAL_SHOW_COUNT}, and detach TargetViewContainer from window
+ * after exiting one handed mode.
*/
-public class OneHandedTutorialHandler implements OneHandedTransitionCallback {
+public class OneHandedTutorialHandler implements OneHandedTransitionCallback,
+ OneHandedState.OnStateChangedListener {
private static final String TAG = "OneHandedTutorialHandler";
private static final String ONE_HANDED_MODE_OFFSET_PERCENTAGE =
"persist.debug.one_handed_offset_percentage";
private static final int MAX_TUTORIAL_SHOW_COUNT = 2;
- private final WindowManager mWindowManager;
- private final String mPackageName;
+
private final float mTutorialHeightRatio;
+ private final WindowManager mWindowManager;
+ private final OneHandedSettingsUtil mSettingsUtil;
+ private final ShellExecutor mShellExecutor;
+
+ private boolean mCanShow;
+ private @OneHandedState.State int mCurrentState;
+ private int mShownCounts;
+ private int mTutorialAreaHeight;
private Context mContext;
- private Rect mDisplayBounds;
- private View mTutorialView;
private ContentResolver mContentResolver;
- private boolean mCanShowTutorial;
- private boolean mIsOneHandedMode;
-
- private enum ONE_HANDED_TRIGGER_STATE {
- UNSET, ENTERING, EXITING
- }
- /**
- * Current One-Handed trigger state.
- * Note: This is a dynamic state, whenever last state has been confirmed
- * (i.e. onStartFinished() or onStopFinished()), the state should be set "UNSET" at final.
- */
- private ONE_HANDED_TRIGGER_STATE mTriggerState = ONE_HANDED_TRIGGER_STATE.UNSET;
-
- /**
- * Container of the tutorial panel showing at outside region when one handed starting
- */
- private ViewGroup mTargetViewContainer;
- private int mTutorialAreaHeight;
+ private Rect mDisplayBounds;
+ private @Nullable View mTutorialView;
+ private @Nullable ViewGroup mTargetViewContainer;
private final OneHandedAnimationCallback mAnimationCallback = new OneHandedAnimationCallback() {
@Override
@@ -82,63 +80,51 @@
if (!canShowTutorial()) {
return;
}
- mTargetViewContainer.setVisibility(View.VISIBLE);
mTargetViewContainer.setTransitionGroup(true);
mTargetViewContainer.setTranslationY(yPos - mTargetViewContainer.getHeight());
}
-
- @Override
- public void onOneHandedAnimationStart(
- OneHandedAnimationController.OneHandedTransitionAnimator animator) {
- final float startValue = (float) animator.getStartValue();
- if (mTriggerState == ONE_HANDED_TRIGGER_STATE.UNSET) {
- mTriggerState = (startValue == 0f)
- ? ONE_HANDED_TRIGGER_STATE.ENTERING : ONE_HANDED_TRIGGER_STATE.EXITING;
- if (mCanShowTutorial && mTriggerState == ONE_HANDED_TRIGGER_STATE.ENTERING) {
- attachTurtorialTarget();
- }
- }
- }
};
public OneHandedTutorialHandler(Context context, DisplayLayout displayLayout,
- WindowManager windowManager, ShellExecutor mainExecutor) {
+ WindowManager windowManager, OneHandedSettingsUtil settingsUtil,
+ ShellExecutor mainExecutor) {
mContext = context;
- mWindowManager = windowManager;
- mPackageName = context.getPackageName();
mContentResolver = context.getContentResolver();
+ mWindowManager = windowManager;
+ mSettingsUtil = settingsUtil;
+ mShellExecutor = mainExecutor;
final float offsetPercentageConfig = context.getResources().getFraction(
R.fraction.config_one_handed_offset, 1, 1);
final int sysPropPercentageConfig = SystemProperties.getInt(
ONE_HANDED_MODE_OFFSET_PERCENTAGE, Math.round(offsetPercentageConfig * 100.0f));
mTutorialHeightRatio = sysPropPercentageConfig / 100.0f;
- onDisplayChanged(displayLayout);
- mCanShowTutorial = (Settings.Secure.getInt(mContentResolver,
- Settings.Secure.ONE_HANDED_TUTORIAL_SHOW_COUNT, 0) >= MAX_TUTORIAL_SHOW_COUNT)
- ? false : true;
- mIsOneHandedMode = false;
-
- mainExecutor.execute(() -> {
- recreateTutorialView(mContext);
- });
+ mShownCounts = mSettingsUtil.getTutorialShownCounts(mContentResolver, myUserId());
}
@Override
- public void onStartFinished(Rect bounds) {
- updateFinished(View.VISIBLE, 0f);
- updateTutorialCount();
- mTriggerState = ONE_HANDED_TRIGGER_STATE.UNSET;
- }
-
- @Override
- public void onStopFinished(Rect bounds) {
- updateFinished(View.INVISIBLE, -mTargetViewContainer.getHeight());
- removeTutorialFromWindowManager();
- mTriggerState = ONE_HANDED_TRIGGER_STATE.UNSET;
+ public void onStateChanged(int newState) {
+ mCurrentState = newState;
+ if (!canShowTutorial()) {
+ return;
+ }
+ switch (newState) {
+ case STATE_ENTERING:
+ createViewAndAttachToWindow(mContext);
+ break;
+ case STATE_ACTIVE:
+ case STATE_EXITING:
+ // no - op
+ break;
+ case STATE_NONE:
+ removeTutorialFromWindowManager(true /* increment */);
+ break;
+ default:
+ break;
+ }
}
/**
- * Called when onDisplayAdded() or onDisplayRemoved() callback
+ * Called when onDisplayAdded() or onDisplayRemoved() callback.
* @param displayLayout The latest {@link DisplayLayout} representing current displayId
*/
public void onDisplayChanged(DisplayLayout displayLayout) {
@@ -151,38 +137,32 @@
mTutorialAreaHeight = Math.round(mDisplayBounds.height() * mTutorialHeightRatio);
}
- private void recreateTutorialView(Context context) {
- mTutorialView = LayoutInflater.from(context).inflate(R.layout.one_handed_tutorial,
- null);
- mTargetViewContainer = new FrameLayout(context);
- mTargetViewContainer.setClipChildren(false);
- mTargetViewContainer.addView(mTutorialView);
- mTargetViewContainer.setVisibility(mIsOneHandedMode ? View.VISIBLE : View.GONE);
- }
-
- private void updateFinished(int visible, float finalPosition) {
+ @VisibleForTesting
+ void createViewAndAttachToWindow(Context context) {
if (!canShowTutorial()) {
return;
}
- mIsOneHandedMode = (finalPosition == 0f) ? true : false;
- mTargetViewContainer.setVisibility(visible);
- mTargetViewContainer.setTranslationY(finalPosition);
+ mTutorialView = LayoutInflater.from(context).inflate(R.layout.one_handed_tutorial, null);
+ mTargetViewContainer = new FrameLayout(context);
+ mTargetViewContainer.setClipChildren(false);
+ mTargetViewContainer.addView(mTutorialView);
+
+ attachTargetToWindow();
}
- private void updateTutorialCount() {
- int showCount = Settings.Secure.getInt(mContentResolver,
- Settings.Secure.ONE_HANDED_TUTORIAL_SHOW_COUNT, 0);
- showCount = Math.min(MAX_TUTORIAL_SHOW_COUNT, showCount + 1);
- mCanShowTutorial = showCount < MAX_TUTORIAL_SHOW_COUNT;
- Settings.Secure.putInt(mContentResolver,
- Settings.Secure.ONE_HANDED_TUTORIAL_SHOW_COUNT, showCount);
+ @VisibleForTesting
+ boolean setTutorialShownCountIncrement() {
+ if (!canShowTutorial()) {
+ return false;
+ }
+ mShownCounts += 1;
+ return mSettingsUtil.setTutorialShownCounts(mContentResolver, mShownCounts, myUserId());
}
/**
- * Adds the tutorial target view to the WindowManager and update its layout, so it's ready
- * to be animated in.
+ * Adds the tutorial target view to the WindowManager and update its layout.
*/
- private void attachTurtorialTarget() {
+ private void attachTargetToWindow() {
if (!mTargetViewContainer.isAttachedToWindow()) {
try {
mWindowManager.addView(mTargetViewContainer, getTutorialTargetLayoutParams());
@@ -195,14 +175,18 @@
}
}
- private void removeTutorialFromWindowManager() {
- if (mTargetViewContainer.isAttachedToWindow()) {
+ @VisibleForTesting
+ void removeTutorialFromWindowManager(boolean increment) {
+ if (mTargetViewContainer != null && mTargetViewContainer.isAttachedToWindow()) {
mWindowManager.removeViewImmediate(mTargetViewContainer);
+ if (increment) {
+ setTutorialShownCountIncrement();
+ }
}
}
- OneHandedAnimationCallback getAnimationCallback() {
- return mAnimationCallback;
+ @Nullable OneHandedAnimationCallback getAnimationCallback() {
+ return canShowTutorial() ? mAnimationCallback : null /* Disabled */;
}
/**
@@ -222,38 +206,36 @@
return lp;
}
- void dump(@NonNull PrintWriter pw) {
- final String innerPrefix = " ";
- pw.println(TAG);
- pw.print(innerPrefix + "mTriggerState=");
- pw.println(mTriggerState);
- pw.print(innerPrefix + "mDisplayBounds=");
- pw.println(mDisplayBounds);
- pw.print(innerPrefix + "mTutorialAreaHeight=");
- pw.println(mTutorialAreaHeight);
- }
-
- private boolean canShowTutorial() {
- if (!mCanShowTutorial) {
- // Since canSHowTutorial() will be called in onAnimationUpdate() and we still need to
- // hide Tutorial text in the period of continuously onAnimationUpdate() API call,
- // so we have to hide mTargetViewContainer here.
- mTargetViewContainer.setVisibility(View.GONE);
- return false;
- }
- return true;
+ @VisibleForTesting
+ boolean canShowTutorial() {
+ return mCanShow = mShownCounts < MAX_TUTORIAL_SHOW_COUNT;
}
/**
* onConfigurationChanged events for updating tutorial text.
- * @param newConfig
*/
- public void onConfigurationChanged(Configuration newConfig) {
- if (!mCanShowTutorial) {
+ public void onConfigurationChanged() {
+ if (!canShowTutorial()) {
return;
}
- removeTutorialFromWindowManager();
- recreateTutorialView(mContext.createConfigurationContext(newConfig));
- attachTurtorialTarget();
+ removeTutorialFromWindowManager(false /* increment */);
+ if (mCurrentState == STATE_ENTERING || mCurrentState == STATE_ACTIVE) {
+ createViewAndAttachToWindow(mContext);
+ }
+ }
+
+ void dump(@NonNull PrintWriter pw) {
+ final String innerPrefix = " ";
+ pw.println(TAG);
+ pw.print(innerPrefix + "mCanShow=");
+ pw.println(mCanShow);
+ pw.print(innerPrefix + "mCurrentState=");
+ pw.println(mCurrentState);
+ pw.print(innerPrefix + "mDisplayBounds=");
+ pw.println(mDisplayBounds);
+ pw.print(innerPrefix + "mShownCounts=");
+ pw.println(mShownCounts);
+ pw.print(innerPrefix + "mTutorialAreaHeight=");
+ pw.println(mTutorialAreaHeight);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipPinchResizingAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipPinchResizingAlgorithm.java
index f8125fd..23153be72 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipPinchResizingAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipPinchResizingAlgorithm.java
@@ -27,6 +27,7 @@
private static final int PINCH_RESIZE_MAX_ANGLE_ROTATION = 45;
private static final float OVERROTATE_DAMP_FACTOR = 0.4f;
private static final float ANGLE_THRESHOLD = 5f;
+ private static final float OVERRESIZE_DAMP_FACTOR = 0.25f;
private final PointF mTmpDownVector = new PointF();
private final PointF mTmpLastVector = new PointF();
@@ -46,7 +47,10 @@
lastSecondPoint.y - lastPoint.y);
float minScale = getMinScale(initialBounds, minSize);
float maxScale = getMaxScale(initialBounds, maxSize);
- float scale = Math.max(minScale, Math.min(maxScale, dist / downDist));
+ float overStretchMin = minScale - dist / downDist > 0 ? minScale - dist / downDist : 0;
+ float overStretchMax = dist / downDist - maxScale > 0 ? dist / downDist - maxScale : 0;
+ float scale = Math.max(minScale - overStretchMin * OVERRESIZE_DAMP_FACTOR,
+ Math.min(maxScale + overStretchMax * OVERRESIZE_DAMP_FACTOR, dist / downDist));
// Scale the bounds by the change in distance between the points
resizeBoundsOut.set(initialBounds);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
index 0878f54..f9a196d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
@@ -383,14 +383,17 @@
return;
}
+ final Rect pipBounds = mPipBoundsState.getBounds();
if (action == MotionEvent.ACTION_POINTER_DOWN) {
- if (mFirstIndex == -1 && mSecondIndex == -1) {
+ if (mFirstIndex == -1 && mSecondIndex == -1
+ && pipBounds.contains((int) ev.getRawX(0), (int) ev.getRawY(0))
+ && pipBounds.contains((int) ev.getRawX(1), (int) ev.getRawY(1))) {
mAllowGesture = true;
mFirstIndex = 0;
mSecondIndex = 1;
mDownPoint.set(ev.getRawX(mFirstIndex), ev.getRawY(mFirstIndex));
mDownSecondPoint.set(ev.getRawX(mSecondIndex), ev.getRawY(mSecondIndex));
- mDownBounds.set(mPipBoundsState.getBounds());
+ mDownBounds.set(pipBounds);
mLastPoint.set(mDownPoint);
mLastSecondPoint.set(mLastSecondPoint);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
index 8f9dcef..f2e250a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
@@ -472,17 +472,20 @@
float aspectRatio) {
final int shorterLength = Math.min(mPipBoundsState.getDisplayBounds().width(),
mPipBoundsState.getDisplayBounds().height());
- final int totalPadding = insetBounds.left * 2;
+ final int totalHorizontalPadding = insetBounds.left
+ + (mPipBoundsState.getDisplayBounds().width() - insetBounds.right);
+ final int totalVerticalPadding = insetBounds.top
+ + (mPipBoundsState.getDisplayBounds().height() - insetBounds.bottom);
final int minWidth, minHeight, maxWidth, maxHeight;
if (aspectRatio > 1f) {
minWidth = (int) Math.min(normalBounds.width(), shorterLength * MINIMUM_SIZE_PERCENT);
minHeight = (int) (minWidth / aspectRatio);
- maxWidth = (int) Math.max(normalBounds.width(), shorterLength - totalPadding);
+ maxWidth = (int) Math.max(normalBounds.width(), shorterLength - totalHorizontalPadding);
maxHeight = (int) (maxWidth / aspectRatio);
} else {
minHeight = (int) Math.min(normalBounds.height(), shorterLength * MINIMUM_SIZE_PERCENT);
minWidth = (int) (minHeight * aspectRatio);
- maxHeight = (int) Math.max(normalBounds.height(), shorterLength - totalPadding);
+ maxHeight = (int) Math.max(normalBounds.height(), shorterLength - totalVerticalPadding);
maxWidth = (int) (maxHeight * aspectRatio);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
index 66a4a60..d0998eb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
@@ -19,6 +19,7 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import android.graphics.Rect;
+import android.view.SurfaceSession;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
@@ -36,8 +37,9 @@
private boolean mIsActive = false;
MainStage(ShellTaskOrganizer taskOrganizer, int displayId,
- StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue) {
- super(taskOrganizer, displayId, callbacks, syncQueue);
+ StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue,
+ SurfaceSession surfaceSession) {
+ super(taskOrganizer, displayId, callbacks, syncQueue, surfaceSession);
}
boolean isActive() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
index 01a81d2..82f95a4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
@@ -18,6 +18,7 @@
import android.app.ActivityManager;
import android.graphics.Rect;
+import android.view.SurfaceSession;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
@@ -33,8 +34,9 @@
private static final String TAG = SideStage.class.getSimpleName();
SideStage(ShellTaskOrganizer taskOrganizer, int displayId,
- StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue) {
- super(taskOrganizer, displayId, callbacks, syncQueue);
+ StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue,
+ SurfaceSession surfaceSession) {
+ super(taskOrganizer, displayId, callbacks, syncQueue, surfaceSession);
}
void addTask(ActivityManager.RunningTaskInfo task, Rect rootBounds,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
index d4506fd..002bfb6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import com.android.wm.shell.common.annotations.ExternalThread;
+import com.android.wm.shell.common.split.SplitLayout.SplitPosition;
/**
* Interface to engage split-screen feature.
@@ -27,29 +28,6 @@
@ExternalThread
public interface SplitScreen {
/**
- * Stage position isn't specified normally meaning to use what ever it is currently set to.
- */
- int STAGE_POSITION_UNDEFINED = -1;
- /**
- * Specifies that a stage is positioned at the top half of the screen if
- * in portrait mode or at the left half of the screen if in landscape mode.
- */
- int STAGE_POSITION_TOP_OR_LEFT = 0;
-
- /**
- * Specifies that a stage is positioned at the bottom half of the screen if
- * in portrait mode or at the right half of the screen if in landscape mode.
- */
- int STAGE_POSITION_BOTTOM_OR_RIGHT = 1;
-
- @IntDef(prefix = { "STAGE_POSITION_" }, value = {
- STAGE_POSITION_UNDEFINED,
- STAGE_POSITION_TOP_OR_LEFT,
- STAGE_POSITION_BOTTOM_OR_RIGHT
- })
- @interface StagePosition {}
-
- /**
* Stage type isn't specified normally meaning to use what ever the default is.
* E.g. exit split-screen and launch the app in fullscreen.
*/
@@ -75,7 +53,7 @@
/** Callback interface for listening to changes in a split-screen stage. */
interface SplitScreenListener {
- void onStagePositionChanged(@StageType int stage, @StagePosition int position);
+ void onStagePositionChanged(@StageType int stage, @SplitPosition int position);
void onTaskStageChanged(int taskId, @StageType int stage, boolean visible);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index 5aa59f2..9a457b5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -19,9 +19,9 @@
import static android.view.Display.DEFAULT_DISPLAY;
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
-import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_POSITION_BOTTOM_OR_RIGHT;
-import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_POSITION_TOP_OR_LEFT;
-import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_POSITION_UNDEFINED;
+import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_BOTTOM_OR_RIGHT;
+import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_TOP_OR_LEFT;
+import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_UNDEFINED;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_MAIN;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
@@ -53,6 +53,7 @@
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.TransactionPool;
import com.android.wm.shell.common.annotations.ExternalThread;
+import com.android.wm.shell.common.split.SplitLayout.SplitPosition;
import com.android.wm.shell.draganddrop.DragAndDropPolicy;
import com.android.wm.shell.splitscreen.ISplitScreenListener;
import com.android.wm.shell.transition.Transitions;
@@ -122,7 +123,7 @@
return mStageCoordinator.isSplitScreenVisible();
}
- public boolean moveToSideStage(int taskId, @SplitScreen.StagePosition int sideStagePosition) {
+ public boolean moveToSideStage(int taskId, @SplitPosition int sideStagePosition) {
final ActivityManager.RunningTaskInfo task = mTaskOrganizer.getRunningTaskInfo(taskId);
if (task == null) {
throw new IllegalArgumentException("Unknown taskId" + taskId);
@@ -131,7 +132,7 @@
}
public boolean moveToSideStage(ActivityManager.RunningTaskInfo task,
- @SplitScreen.StagePosition int sideStagePosition) {
+ @SplitPosition int sideStagePosition) {
return mStageCoordinator.moveToSideStage(task, sideStagePosition);
}
@@ -139,7 +140,7 @@
return mStageCoordinator.removeFromSideStage(taskId);
}
- public void setSideStagePosition(@SplitScreen.StagePosition int sideStagePosition) {
+ public void setSideStagePosition(@SplitPosition int sideStagePosition) {
mStageCoordinator.setSideStagePosition(sideStagePosition);
}
@@ -149,7 +150,7 @@
public void enterSplitScreen(int taskId, boolean leftOrTop) {
moveToSideStage(taskId,
- leftOrTop ? STAGE_POSITION_TOP_OR_LEFT : STAGE_POSITION_BOTTOM_OR_RIGHT);
+ leftOrTop ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT);
}
public void exitSplitScreen() {
@@ -173,7 +174,7 @@
}
public void startTask(int taskId, @SplitScreen.StageType int stage,
- @SplitScreen.StagePosition int position, @Nullable Bundle options) {
+ @SplitPosition int position, @Nullable Bundle options) {
options = resolveStartStage(stage, position, options);
try {
@@ -184,7 +185,7 @@
}
public void startShortcut(String packageName, String shortcutId,
- @SplitScreen.StageType int stage, @SplitScreen.StagePosition int position,
+ @SplitScreen.StageType int stage, @SplitPosition int position,
@Nullable Bundle options, UserHandle user) {
options = resolveStartStage(stage, position, options);
@@ -199,7 +200,7 @@
}
public void startIntent(PendingIntent intent, Intent fillInIntent,
- @SplitScreen.StageType int stage, @SplitScreen.StagePosition int position,
+ @SplitScreen.StageType int stage, @SplitPosition int position,
@Nullable Bundle options) {
options = resolveStartStage(stage, position, options);
@@ -211,11 +212,11 @@
}
private Bundle resolveStartStage(@SplitScreen.StageType int stage,
- @SplitScreen.StagePosition int position, @Nullable Bundle options) {
+ @SplitPosition int position, @Nullable Bundle options) {
switch (stage) {
case STAGE_TYPE_UNDEFINED: {
// Use the stage of the specified position is valid.
- if (position != STAGE_POSITION_UNDEFINED) {
+ if (position != SPLIT_POSITION_UNDEFINED) {
if (position == mStageCoordinator.getSideStagePosition()) {
options = resolveStartStage(STAGE_TYPE_SIDE, position, options);
} else {
@@ -228,7 +229,7 @@
break;
}
case STAGE_TYPE_SIDE: {
- if (position != STAGE_POSITION_UNDEFINED) {
+ if (position != SPLIT_POSITION_UNDEFINED) {
mStageCoordinator.setSideStagePosition(position);
} else {
position = mStageCoordinator.getSideStagePosition();
@@ -240,10 +241,10 @@
break;
}
case STAGE_TYPE_MAIN: {
- if (position != STAGE_POSITION_UNDEFINED) {
+ if (position != SPLIT_POSITION_UNDEFINED) {
// Set the side stage opposite of what we want to the main stage.
- final int sideStagePosition = position == STAGE_POSITION_TOP_OR_LEFT
- ? STAGE_POSITION_BOTTOM_OR_RIGHT : STAGE_POSITION_TOP_OR_LEFT;
+ final int sideStagePosition = position == SPLIT_POSITION_TOP_OR_LEFT
+ ? SPLIT_POSITION_BOTTOM_OR_RIGHT : SPLIT_POSITION_TOP_OR_LEFT;
mStageCoordinator.setSideStagePosition(sideStagePosition);
} else {
position = mStageCoordinator.getMainStagePosition();
@@ -418,7 +419,7 @@
@Override
public void startTasks(int mainTaskId, @Nullable Bundle mainOptions,
int sideTaskId, @Nullable Bundle sideOptions,
- @SplitScreen.StagePosition int sidePosition,
+ @SplitPosition int sidePosition,
@Nullable IRemoteTransition remoteTransition) {
executeRemoteCallWithTaskPermission(mController, "startTasks",
(controller) -> controller.mStageCoordinator.startTasks(mainTaskId, mainOptions,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index eb60dc2..0264c5a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -25,8 +25,9 @@
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.WindowManager.transitTypeToString;
-import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_POSITION_BOTTOM_OR_RIGHT;
-import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_POSITION_TOP_OR_LEFT;
+import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_BOTTOM_OR_RIGHT;
+import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_TOP_OR_LEFT;
+import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_UNDEFINED;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_MAIN;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
@@ -47,14 +48,15 @@
import android.os.IBinder;
import android.util.Log;
import android.view.SurfaceControl;
+import android.view.SurfaceSession;
import android.view.WindowManager;
import android.window.DisplayAreaInfo;
import android.window.IRemoteTransition;
import android.window.TransitionInfo;
import android.window.TransitionRequestInfo;
+import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
-
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
@@ -64,6 +66,7 @@
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.TransactionPool;
import com.android.wm.shell.common.split.SplitLayout;
+import com.android.wm.shell.common.split.SplitLayout.SplitPosition;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.transition.Transitions;
@@ -84,19 +87,22 @@
* This rules are mostly implemented in {@link #onStageVisibilityChanged(StageListenerImpl)} and
* {@link #onStageHasChildrenChanged(StageListenerImpl).}
*/
-class StageCoordinator implements SplitLayout.LayoutChangeListener,
- RootTaskDisplayAreaOrganizer.RootTaskDisplayAreaListener, Transitions.TransitionHandler {
+class StageCoordinator implements SplitLayout.SplitLayoutHandler,
+ RootTaskDisplayAreaOrganizer.RootTaskDisplayAreaListener, Transitions.TransitionHandler {
private static final String TAG = StageCoordinator.class.getSimpleName();
/** internal value for mDismissTop that represents no dismiss */
private static final int NO_DISMISS = -2;
+ private final SurfaceSession mSurfaceSession = new SurfaceSession();
+
private final MainStage mMainStage;
private final StageListenerImpl mMainStageListener = new StageListenerImpl();
private final SideStage mSideStage;
private final StageListenerImpl mSideStageListener = new StageListenerImpl();
- private @SplitScreen.StagePosition int mSideStagePosition = STAGE_POSITION_BOTTOM_OR_RIGHT;
+ @SplitPosition
+ private int mSideStagePosition = SPLIT_POSITION_BOTTOM_OR_RIGHT;
private final int mDisplayId;
private SplitLayout mSplitLayout;
@@ -115,8 +121,8 @@
/** Whether the device is supporting legacy split or not. */
private boolean mUseLegacySplit;
-
@SplitScreen.StageType int mDismissTop = NO_DISMISS;
+
private final Runnable mOnTransitionAnimationComplete = () -> {
// If still playing, let it finish.
if (!isSplitScreenVisible()) {
@@ -137,8 +143,18 @@
mSyncQueue = syncQueue;
mRootTDAOrganizer = rootTDAOrganizer;
mTaskOrganizer = taskOrganizer;
- mMainStage = new MainStage(mTaskOrganizer, mDisplayId, mMainStageListener, mSyncQueue);
- mSideStage = new SideStage(mTaskOrganizer, mDisplayId, mSideStageListener, mSyncQueue);
+ mMainStage = new MainStage(
+ mTaskOrganizer,
+ mDisplayId,
+ mMainStageListener,
+ mSyncQueue,
+ mSurfaceSession);
+ mSideStage = new SideStage(
+ mTaskOrganizer,
+ mDisplayId,
+ mSideStageListener,
+ mSyncQueue,
+ mSurfaceSession);
mDisplayImeController = displayImeController;
mRootTDAOrganizer.registerListener(displayId, this);
mSplitTransitions = new SplitScreenTransitions(transactionPool, transitions,
@@ -176,7 +192,7 @@
}
boolean moveToSideStage(ActivityManager.RunningTaskInfo task,
- @SplitScreen.StagePosition int sideStagePosition) {
+ @SplitPosition int sideStagePosition) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
setSideStagePosition(sideStagePosition);
mMainStage.activate(getMainStageBounds(), wct);
@@ -201,7 +217,7 @@
/** Starts 2 tasks in one transition. */
void startTasks(int mainTaskId, @Nullable Bundle mainOptions, int sideTaskId,
- @Nullable Bundle sideOptions, @SplitScreen.StagePosition int sidePosition,
+ @Nullable Bundle sideOptions, @SplitPosition int sidePosition,
@Nullable IRemoteTransition remoteTransition) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
mainOptions = mainOptions != null ? mainOptions : new Bundle();
@@ -225,20 +241,22 @@
TRANSIT_SPLIT_SCREEN_PAIR_OPEN, wct, remoteTransition, this);
}
- @SplitScreen.StagePosition int getSideStagePosition() {
+ @SplitLayout.SplitPosition
+ int getSideStagePosition() {
return mSideStagePosition;
}
- @SplitScreen.StagePosition int getMainStagePosition() {
- return mSideStagePosition == STAGE_POSITION_TOP_OR_LEFT
- ? STAGE_POSITION_BOTTOM_OR_RIGHT : STAGE_POSITION_TOP_OR_LEFT;
+ @SplitLayout.SplitPosition
+ int getMainStagePosition() {
+ return mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT
+ ? SPLIT_POSITION_BOTTOM_OR_RIGHT : SPLIT_POSITION_TOP_OR_LEFT;
}
- void setSideStagePosition(@SplitScreen.StagePosition int sideStagePosition) {
+ void setSideStagePosition(@SplitPosition int sideStagePosition) {
setSideStagePosition(sideStagePosition, true /* updateVisibility */);
}
- private void setSideStagePosition(@SplitScreen.StagePosition int sideStagePosition,
+ private void setSideStagePosition(@SplitPosition int sideStagePosition,
boolean updateVisibility) {
if (mSideStagePosition == sideStagePosition) return;
mSideStagePosition = sideStagePosition;
@@ -289,7 +307,7 @@
opts.putParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN, stage.mRootTaskInfo.token);
}
- void updateActivityOptions(Bundle opts, @SplitScreen.StagePosition int position) {
+ void updateActivityOptions(Bundle opts, @SplitPosition int position) {
addActivityOptions(opts, position == mSideStagePosition ? mSideStage : mMainStage);
if (!mMainStage.isActive()) {
@@ -487,8 +505,8 @@
@Override
public void onSnappedToDismiss(boolean bottomOrRight) {
final boolean mainStageToTop =
- bottomOrRight ? mSideStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT
- : mSideStagePosition == STAGE_POSITION_TOP_OR_LEFT;
+ bottomOrRight ? mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
+ : mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT;
if (ENABLE_SHELL_TRANSITIONS) {
onSnappedToDismissTransition(mainStageToTop);
return;
@@ -497,55 +515,49 @@
}
@Override
- public void onBoundsChanging(SplitLayout layout) {
- final SurfaceControl dividerLeash = mSplitLayout.getDividerLeash();
- if (dividerLeash == null) return;
- final Rect mainStageBounds = getMainStageBounds();
- final Rect sideStageBounds = getSideStageBounds();
-
- mSyncQueue.runInSync(t -> t
- .setPosition(dividerLeash,
- mSplitLayout.getDividerBounds().left, mSplitLayout.getDividerBounds().top)
- .setPosition(mMainStage.mRootLeash, mainStageBounds.left, mainStageBounds.top)
- .setPosition(mSideStage.mRootLeash, sideStageBounds.left, sideStageBounds.top)
- // Sets crop to prevent visible region of tasks overlap with each other when
- // re-positioning surfaces while resizing.
- .setWindowCrop(mMainStage.mRootLeash,
- mainStageBounds.width(), mainStageBounds.height())
- .setWindowCrop(mSideStage.mRootLeash,
- sideStageBounds.width(), sideStageBounds.height()));
-
+ public void onDoubleTappedDivider() {
+ setSideStagePosition(mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT
+ ? SPLIT_POSITION_BOTTOM_OR_RIGHT : SPLIT_POSITION_TOP_OR_LEFT);
}
@Override
- public void onDoubleTappedDivider() {
- setSideStagePosition(mSideStagePosition == STAGE_POSITION_TOP_OR_LEFT
- ? STAGE_POSITION_BOTTOM_OR_RIGHT : STAGE_POSITION_TOP_OR_LEFT);
+ public void onBoundsChanging(SplitLayout layout) {
+ final StageTaskListener topLeftStage =
+ mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage;
+ final StageTaskListener bottomRightStage =
+ mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage;
+
+ mSyncQueue.runInSync(t -> layout.applySurfaceChanges(t, topLeftStage.mRootLeash,
+ bottomRightStage.mRootLeash, topLeftStage.mDimLayer, bottomRightStage.mDimLayer));
}
@Override
public void onBoundsChanged(SplitLayout layout) {
- final SurfaceControl dividerLeash = mSplitLayout.getDividerLeash();
- if (dividerLeash == null) return;
- final Rect mainStageBounds = getMainStageBounds();
- final Rect sideStageBounds = getSideStageBounds();
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- mMainStage.setBounds(mainStageBounds, wct);
- mSideStage.setBounds(sideStageBounds, wct);
- mTaskOrganizer.applyTransaction(wct);
+ final StageTaskListener topLeftStage =
+ mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage;
+ final StageTaskListener bottomRightStage =
+ mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage;
- mSyncQueue.runInSync(t -> t
- // Resets layer of divider bar to make sure it is always on top.
- .setLayer(dividerLeash, Integer.MAX_VALUE)
- .setPosition(dividerLeash,
- mSplitLayout.getDividerBounds().left, mSplitLayout.getDividerBounds().top)
- .setPosition(mMainStage.mRootLeash,
- mainStageBounds.left, mainStageBounds.top)
- .setPosition(mSideStage.mRootLeash,
- sideStageBounds.left, sideStageBounds.top)
- // Resets crop to apply new surface bounds directly.
- .setWindowCrop(mMainStage.mRootLeash, null)
- .setWindowCrop(mSideStage.mRootLeash, null));
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ layout.applyTaskChanges(wct, topLeftStage.mRootTaskInfo, bottomRightStage.mRootTaskInfo);
+ mSyncQueue.queue(wct);
+ mSyncQueue.runInSync(t -> layout.applySurfaceChanges(t, topLeftStage.mRootLeash,
+ bottomRightStage.mRootLeash, topLeftStage.mDimLayer, bottomRightStage.mDimLayer));
+ }
+
+ @Override
+ public int getSplitItemPosition(WindowContainerToken token) {
+ if (token == null) {
+ return SPLIT_POSITION_UNDEFINED;
+ }
+
+ if (token.equals(mMainStage.mRootTaskInfo.getToken())) {
+ return getMainStagePosition();
+ } else if (token.equals(mSideStage.mRootTaskInfo.getToken())) {
+ return getSideStagePosition();
+ }
+
+ return SPLIT_POSITION_UNDEFINED;
}
@Override
@@ -555,7 +567,7 @@
mSplitLayout = new SplitLayout(TAG + "SplitDivider", mContext,
mDisplayAreaInfo.configuration, this,
b -> mRootTDAOrganizer.attachToDisplayArea(mDisplayId, b),
- mDisplayImeController);
+ mDisplayImeController, mTaskOrganizer);
}
}
@@ -574,12 +586,12 @@
}
private Rect getSideStageBounds() {
- return mSideStagePosition == STAGE_POSITION_TOP_OR_LEFT
+ return mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT
? mSplitLayout.getBounds1() : mSplitLayout.getBounds2();
}
private Rect getMainStageBounds() {
- return mSideStagePosition == STAGE_POSITION_TOP_OR_LEFT
+ return mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT
? mSplitLayout.getBounds2() : mSplitLayout.getBounds1();
}
@@ -742,7 +754,7 @@
// Update local states (before animating).
setDividerVisibility(true);
- setSideStagePosition(STAGE_POSITION_BOTTOM_OR_RIGHT, false /* updateVisibility */);
+ setSideStagePosition(SPLIT_POSITION_BOTTOM_OR_RIGHT, false /* updateVisibility */);
setSplitsVisible(true);
addDividerBarToTransition(info, t, true /* show */);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index 147a9df7..0fd8eca62 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -29,11 +29,13 @@
import android.graphics.Rect;
import android.util.SparseArray;
import android.view.SurfaceControl;
+import android.view.SurfaceSession;
import android.window.WindowContainerTransaction;
import androidx.annotation.NonNull;
import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.SurfaceUtils;
import com.android.wm.shell.common.SyncTransactionQueue;
import java.io.PrintWriter;
@@ -44,6 +46,7 @@
* They only serve to hold a collection of tasks and provide APIs like
* {@link #setBounds(Rect, WindowContainerTransaction)} for the centralized {@link StageCoordinator}
* to perform operations in-sync with other containers.
+ *
* @see StageCoordinator
*/
class StageTaskListener implements ShellTaskOrganizer.TaskListener {
@@ -58,23 +61,31 @@
/** Callback interface for listening to changes in a split-screen stage. */
public interface StageListenerCallbacks {
void onRootTaskAppeared();
+
void onStatusChanged(boolean visible, boolean hasChildren);
+
void onChildTaskStatusChanged(int taskId, boolean present, boolean visible);
+
void onRootTaskVanished();
void onNoLongerSupportMultiWindow();
}
+
private final StageListenerCallbacks mCallbacks;
private final SyncTransactionQueue mSyncQueue;
+ private final SurfaceSession mSurfaceSession;
protected ActivityManager.RunningTaskInfo mRootTaskInfo;
protected SurfaceControl mRootLeash;
+ protected SurfaceControl mDimLayer;
protected SparseArray<ActivityManager.RunningTaskInfo> mChildrenTaskInfo = new SparseArray<>();
private final SparseArray<SurfaceControl> mChildrenLeashes = new SparseArray<>();
StageTaskListener(ShellTaskOrganizer taskOrganizer, int displayId,
- StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue) {
+ StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue,
+ SurfaceSession surfaceSession) {
mCallbacks = callbacks;
mSyncQueue = syncQueue;
+ mSurfaceSession = surfaceSession;
taskOrganizer.createRootTask(displayId, WINDOWING_MODE_MULTI_WINDOW, this);
}
@@ -94,6 +105,8 @@
mRootTaskInfo = taskInfo;
mCallbacks.onRootTaskAppeared();
sendStatusChanged();
+ mSyncQueue.runInSync(t -> mDimLayer =
+ SurfaceUtils.makeDimLayer(t, mRootLeash, "Dim layer", mSurfaceSession));
} else if (taskInfo.parentTaskId == mRootTaskInfo.taskId) {
final int taskId = taskInfo.taskId;
mChildrenLeashes.put(taskId, leash);
@@ -146,6 +159,7 @@
final int taskId = taskInfo.taskId;
if (mRootTaskInfo.taskId == taskId) {
mCallbacks.onRootTaskVanished();
+ mSyncQueue.runInSync(t -> t.remove(mDimLayer));
mRootTaskInfo = null;
} else if (mChildrenTaskInfo.contains(taskId)) {
mChildrenTaskInfo.remove(taskId);
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 81e87f1..a646231 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
@@ -39,6 +39,7 @@
import android.os.Trace;
import android.util.Slog;
import android.view.SurfaceControl;
+import android.view.View;
import android.window.SplashScreenView;
import com.android.internal.R;
@@ -398,7 +399,17 @@
splashScreenView.setNotCopyable();
splashScreenView.setRevealAnimationSupported(false);
}
- splashScreenView.makeSystemUIColorsTransparent();
+ splashScreenView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ SplashScreenView.applySystemBarsContrastColor(v.getWindowInsetsController(),
+ splashScreenView.getInitBackgroundColor());
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ }
+ });
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
return splashScreenView;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index 26e8753..187e104 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
@@ -25,12 +25,10 @@
import android.app.ActivityTaskManager;
import android.content.Context;
import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
-import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.os.IBinder;
@@ -43,13 +41,13 @@
import android.view.SurfaceControl;
import android.view.View;
import android.view.WindowManager;
+import android.widget.FrameLayout;
import android.window.SplashScreenView;
import android.window.SplashScreenView.SplashScreenViewParcelable;
import android.window.StartingWindowInfo;
import android.window.TaskSnapshot;
import com.android.internal.R;
-import com.android.internal.policy.PhoneWindow;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.TransactionPool;
@@ -152,14 +150,6 @@
return;
}
- CharSequence nonLocalizedLabel = activityInfo.nonLocalizedLabel;
- int labelRes = activityInfo.labelRes;
- if (activityInfo.nonLocalizedLabel == null && activityInfo.labelRes == 0) {
- ApplicationInfo app = activityInfo.applicationInfo;
- nonLocalizedLabel = app.nonLocalizedLabel;
- labelRes = app.labelRes;
- }
-
final int taskId = taskInfo.taskId;
Context context = mContext;
// replace with the default theme if the application didn't set
@@ -169,8 +159,7 @@
: com.android.internal.R.style.Theme_DeviceDefault_DayNight;
if (DEBUG_SPLASH_SCREEN) {
Slog.d(TAG, "addSplashScreen " + activityInfo.packageName
- + ": nonLocalizedLabel=" + nonLocalizedLabel + " theme="
- + Integer.toHexString(theme) + " task= " + taskInfo.taskId);
+ + " theme=" + Integer.toHexString(theme) + " task= " + taskInfo.taskId);
}
// Obtain proper context to launch on the right display.
@@ -180,7 +169,7 @@
return;
}
context = displayContext;
- if (theme != context.getThemeResId() || labelRes != 0) {
+ if (theme != context.getThemeResId()) {
try {
context = context.createPackageContextAsUser(activityInfo.packageName,
CONTEXT_RESTRICTED, UserHandle.of(taskInfo.userId));
@@ -222,23 +211,22 @@
typedArray.recycle();
}
- final PhoneWindow win = new PhoneWindow(context);
- win.setIsStartingWindow(true);
-
- final Resources res = context.getResources();
- final CharSequence label = res.getText(labelRes, null);
- // Only change the accessibility title if the label is localized
- if (label != null) {
- win.setTitle(label, true);
- } else {
- win.setTitle(nonLocalizedLabel, false);
- }
-
- int windowFlags = WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+ final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
+ WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
+ params.setFitInsetsSides(0);
+ params.setFitInsetsTypes(0);
+ int windowFlags = WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
+ | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
+ | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+ | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
final TypedArray a = context.obtainStyledAttributes(R.styleable.Window);
if (a.getBoolean(R.styleable.Window_windowShowWallpaper, false)) {
windowFlags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
}
+ params.layoutInDisplayCutoutMode = a.getInt(
+ R.styleable.Window_windowLayoutInDisplayCutoutMode,
+ params.layoutInDisplayCutoutMode);
+ params.windowAnimations = a.getResourceId(R.styleable.Window_windowAnimationStyle, 0);
a.recycle();
// Assumes it's safe to show starting windows of launched apps while
@@ -256,28 +244,15 @@
windowFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
- win.setFlags(windowFlags, windowFlags);
-
- final int iconRes = activityInfo.getIconResource();
- final int logoRes = activityInfo.getLogoResource();
- win.setDefaultIcon(iconRes);
- win.setDefaultLogo(logoRes);
-
- final WindowManager.LayoutParams params = win.getAttributes();
- params.type = WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
- params.width = WindowManager.LayoutParams.MATCH_PARENT;
- params.height = WindowManager.LayoutParams.MATCH_PARENT;
+ params.flags = windowFlags;
params.token = appToken;
params.packageName = activityInfo.packageName;
- params.windowAnimations = win.getWindowStyle().getResourceId(
- com.android.internal.R.styleable.Window_windowAnimationStyle, 0);
params.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
// Setting as trusted overlay to let touches pass through. This is safe because this
// window is controlled by the system.
params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
- params.format = PixelFormat.RGBA_8888;
- if (!res.getCompatibilityInfo().supportsScreen()) {
+ if (!context.getResources().getCompatibilityInfo().supportsScreen()) {
params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
}
@@ -297,6 +272,7 @@
// Record whether create splash screen view success, notify to current thread after
// create splash screen view finished.
final SplashScreenViewSupplier viewSupplier = new SplashScreenViewSupplier();
+ final FrameLayout rootLayout = new FrameLayout(context);
final Runnable setViewSynchronized = () -> {
// waiting for setContentView before relayoutWindow
SplashScreenView contentView = viewSupplier.get();
@@ -306,8 +282,7 @@
// if view == null then creation of content view was failed.
if (contentView != null) {
try {
- win.setContentView(contentView);
- contentView.cacheRootWindow(win);
+ rootLayout.addView(contentView);
} catch (RuntimeException e) {
Slog.w(TAG, "failed set content view to starting window "
+ "at taskId: " + taskId, e);
@@ -321,9 +296,8 @@
viewSupplier::setView);
try {
- final View view = win.getDecorView();
final WindowManager wm = context.getSystemService(WindowManager.class);
- postAddWindow(taskId, appToken, view, wm, params);
+ postAddWindow(taskId, appToken, rootLayout, wm, params);
// We use the splash screen worker thread to create SplashScreenView while adding the
// window, as otherwise Choreographer#doFrame might be delayed on this thread.
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
index 7b0e6b9..952dc31 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
@@ -35,6 +35,7 @@
import androidx.test.filters.SmallTest;
import com.android.internal.policy.DividerSnapAlgorithm;
+import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.common.DisplayImeController;
@@ -48,9 +49,10 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
public class SplitLayoutTests extends ShellTestCase {
- @Mock SplitLayout.LayoutChangeListener mLayoutChangeListener;
+ @Mock SplitLayout.SplitLayoutHandler mSplitLayoutHandler;
@Mock SurfaceControl mRootLeash;
@Mock DisplayImeController mDisplayImeController;
+ @Mock ShellTaskOrganizer mTaskOrganizer;
private SplitLayout mSplitLayout;
@Before
@@ -60,9 +62,10 @@
"TestSplitLayout",
mContext,
getConfiguration(false),
- mLayoutChangeListener,
+ mSplitLayoutHandler,
b -> b.setParent(mRootLeash),
- mDisplayImeController);
+ mDisplayImeController,
+ mTaskOrganizer);
}
@Test
@@ -76,19 +79,19 @@
@Test
public void testUpdateDivideBounds() {
mSplitLayout.updateDivideBounds(anyInt());
- verify(mLayoutChangeListener).onBoundsChanging(any(SplitLayout.class));
+ verify(mSplitLayoutHandler).onBoundsChanging(any(SplitLayout.class));
}
@Test
public void testSetDividePosition() {
mSplitLayout.setDividePosition(anyInt());
- verify(mLayoutChangeListener).onBoundsChanged(any(SplitLayout.class));
+ verify(mSplitLayoutHandler).onBoundsChanged(any(SplitLayout.class));
}
@Test
public void testOnDoubleTappedDivider() {
mSplitLayout.onDoubleTappedDivider();
- verify(mLayoutChangeListener).onDoubleTappedDivider();
+ verify(mSplitLayoutHandler).onDoubleTappedDivider();
}
@Test
@@ -98,11 +101,11 @@
DividerSnapAlgorithm.SnapTarget snapTarget = getSnapTarget(0 /* position */,
DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_START);
mSplitLayout.snapToTarget(0 /* currentPosition */, snapTarget);
- verify(mLayoutChangeListener).onSnappedToDismiss(eq(false));
+ verify(mSplitLayoutHandler).onSnappedToDismiss(eq(false));
snapTarget = getSnapTarget(0 /* position */,
DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_END);
mSplitLayout.snapToTarget(0 /* currentPosition */, snapTarget);
- verify(mLayoutChangeListener).onSnappedToDismiss(eq(true));
+ verify(mSplitLayoutHandler).onSnappedToDismiss(eq(true));
}
private static Configuration getConfiguration(boolean isLandscape) {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitWindowManagerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitWindowManagerTests.java
index 86d0d82..698315a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitWindowManagerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitWindowManagerTests.java
@@ -29,7 +29,6 @@
import androidx.test.filters.SmallTest;
import com.android.wm.shell.ShellTestCase;
-import com.android.wm.shell.common.DisplayImeController;
import org.junit.Before;
import org.junit.Test;
@@ -43,7 +42,6 @@
public class SplitWindowManagerTests extends ShellTestCase {
@Mock SurfaceControl mSurfaceControl;
@Mock SplitLayout mSplitLayout;
- @Mock DisplayImeController mDisplayImeController;
private SplitWindowManager mSplitWindowManager;
@Before
@@ -52,7 +50,7 @@
final Configuration configuration = new Configuration();
configuration.setToDefaults();
mSplitWindowManager = new SplitWindowManager("TestSplitDivider", mContext, configuration,
- b -> b.setParent(mSurfaceControl), mDisplayImeController);
+ b -> b.setParent(mSurfaceControl));
when(mSplitLayout.getDividerBounds()).thenReturn(
new Rect(0, 0, configuration.windowConfiguration.getBounds().width(),
configuration.windowConfiguration.getBounds().height()));
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
index 2f2bbba..ba73d55 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
@@ -24,13 +24,13 @@
import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK;
+import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_BOTTOM_OR_RIGHT;
+import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_UNDEFINED;
import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_FULLSCREEN;
import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_BOTTOM;
import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_LEFT;
import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_RIGHT;
import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_TOP;
-import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_POSITION_BOTTOM_OR_RIGHT;
-import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_POSITION_UNDEFINED;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
@@ -206,7 +206,7 @@
mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData);
verify(mSplitScreenStarter).startIntent(any(), any(),
- eq(STAGE_TYPE_UNDEFINED), eq(STAGE_POSITION_UNDEFINED), any());
+ eq(STAGE_TYPE_UNDEFINED), eq(SPLIT_POSITION_UNDEFINED), any());
}
@Test
@@ -218,12 +218,12 @@
mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData);
verify(mSplitScreenStarter).startIntent(any(), any(),
- eq(STAGE_TYPE_UNDEFINED), eq(STAGE_POSITION_UNDEFINED), any());
+ eq(STAGE_TYPE_UNDEFINED), eq(SPLIT_POSITION_UNDEFINED), any());
reset(mSplitScreenStarter);
mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_RIGHT), mActivityClipData);
verify(mSplitScreenStarter).startIntent(any(), any(),
- eq(STAGE_TYPE_SIDE), eq(STAGE_POSITION_BOTTOM_OR_RIGHT), any());
+ eq(STAGE_TYPE_SIDE), eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), any());
}
@Test
@@ -235,12 +235,12 @@
mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData);
verify(mSplitScreenStarter).startIntent(any(), any(),
- eq(STAGE_TYPE_UNDEFINED), eq(STAGE_POSITION_UNDEFINED), any());
+ eq(STAGE_TYPE_UNDEFINED), eq(SPLIT_POSITION_UNDEFINED), any());
reset(mSplitScreenStarter);
mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_BOTTOM), mActivityClipData);
verify(mSplitScreenStarter).startIntent(any(), any(),
- eq(STAGE_TYPE_SIDE), eq(STAGE_POSITION_BOTTOM_OR_RIGHT), any());
+ eq(STAGE_TYPE_SIDE), eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), any());
}
@Test
@@ -252,7 +252,7 @@
mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData);
verify(mSplitScreenStarter).startIntent(any(), any(),
- eq(STAGE_TYPE_UNDEFINED), eq(STAGE_POSITION_UNDEFINED), any());
+ eq(STAGE_TYPE_UNDEFINED), eq(SPLIT_POSITION_UNDEFINED), any());
}
@Test
@@ -264,7 +264,7 @@
mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData);
verify(mSplitScreenStarter).startIntent(any(), any(),
- eq(STAGE_TYPE_UNDEFINED), eq(STAGE_POSITION_UNDEFINED), any());
+ eq(STAGE_TYPE_UNDEFINED), eq(SPLIT_POSITION_UNDEFINED), any());
}
@Test
@@ -277,13 +277,13 @@
mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData);
verify(mSplitScreenStarter).startIntent(any(), any(),
- eq(STAGE_TYPE_UNDEFINED), eq(STAGE_POSITION_UNDEFINED), any());
+ eq(STAGE_TYPE_UNDEFINED), eq(SPLIT_POSITION_UNDEFINED), any());
reset(mSplitScreenStarter);
// TODO(b/169894807): Just verify starting for the non-docked task until we have app pairs
mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_RIGHT), mActivityClipData);
verify(mSplitScreenStarter).startIntent(any(), any(),
- eq(STAGE_TYPE_SIDE), eq(STAGE_POSITION_BOTTOM_OR_RIGHT), any());
+ eq(STAGE_TYPE_SIDE), eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), any());
}
@Test
@@ -296,13 +296,13 @@
mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData);
verify(mSplitScreenStarter).startIntent(any(), any(),
- eq(STAGE_TYPE_UNDEFINED), eq(STAGE_POSITION_UNDEFINED), any());
+ eq(STAGE_TYPE_UNDEFINED), eq(SPLIT_POSITION_UNDEFINED), any());
reset(mSplitScreenStarter);
// TODO(b/169894807): Just verify starting for the non-docked task until we have app pairs
mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_BOTTOM), mActivityClipData);
verify(mSplitScreenStarter).startIntent(any(), any(),
- eq(STAGE_TYPE_SIDE), eq(STAGE_POSITION_BOTTOM_OR_RIGHT), any());
+ eq(STAGE_TYPE_SIDE), eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), any());
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java
index 25d90b3..1852279 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
@@ -398,4 +398,14 @@
verify(mSpiedOneHandedController, never()).startOneHanded();
verify(mSpiedOneHandedController, never()).stopOneHanded();
}
+
+ @Test
+ public void testControllerInit_tutorialAddStateChangeListener() {
+ when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(true);
+ when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE);
+ when(mSpiedTransitionState.isTransitioning()).thenReturn(false);
+ when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(false);
+
+ verify(mSpiedTransitionState).addSListeners(mMockTutorialHandler);
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java
index 5f2bfad..1bc2a08 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java
@@ -16,19 +16,26 @@
package com.android.wm.shell.onehanded;
+import static com.android.wm.shell.onehanded.OneHandedState.STATE_ENTERING;
+import static com.android.wm.shell.onehanded.OneHandedState.STATE_NONE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.content.om.IOverlayManager;
-import android.os.Handler;
import android.testing.AndroidTestingRunner;
-import android.util.ArrayMap;
+import android.view.Display;
+import android.view.WindowManager;
import androidx.test.filters.SmallTest;
-import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.ShellExecutor;
-import com.android.wm.shell.common.TaskStackListenerImpl;
import org.junit.Before;
import org.junit.Test;
@@ -39,62 +46,94 @@
@SmallTest
@RunWith(AndroidTestingRunner.class)
public class OneHandedTutorialHandlerTest extends OneHandedTestCase {
+ Display mDisplay;
+ DisplayLayout mDisplayLayout;
OneHandedTimeoutHandler mTimeoutHandler;
- OneHandedController mOneHandedController;
OneHandedState mSpiedTransitionState;
+ OneHandedTutorialHandler mSpiedTutorialHandler;
@Mock
- OneHandedTouchHandler mMockTouchHandler;
- @Mock
- OneHandedTutorialHandler mMockTutorialHandler;
- @Mock
- DisplayController mMockDisplayController;
- @Mock
- OneHandedBackgroundPanelOrganizer mMockBackgroundOrganizer;
- @Mock
- OneHandedDisplayAreaOrganizer mMockDisplayAreaOrganizer;
- @Mock
- IOverlayManager mMockOverlayManager;
- @Mock
- TaskStackListenerImpl mMockTaskStackListener;
- @Mock
ShellExecutor mMockShellMainExecutor;
@Mock
- Handler mMockShellMainHandler;
- @Mock
- OneHandedUiEventLogger mMockUiEventLogger;
- @Mock
OneHandedSettingsUtil mMockSettingsUtil;
@Mock
- OneHandedAccessibilityUtil mMockAccessibilityUtil;
+ WindowManager mMockWindowManager;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mTimeoutHandler = new OneHandedTimeoutHandler(mMockShellMainExecutor);
- mSpiedTransitionState = new OneHandedState();
+ when(mMockSettingsUtil.getTutorialShownCounts(any(), anyInt())).thenReturn(0);
- when(mMockDisplayAreaOrganizer.getDisplayAreaTokenMap()).thenReturn(new ArrayMap<>());
- mOneHandedController = new OneHandedController(
- mContext,
- mMockDisplayController,
- mMockBackgroundOrganizer,
- mMockDisplayAreaOrganizer,
- mMockTouchHandler,
- mMockTutorialHandler,
- mMockSettingsUtil,
- mMockAccessibilityUtil,
- mTimeoutHandler,
- mSpiedTransitionState,
- mMockUiEventLogger,
- mMockOverlayManager,
- mMockTaskStackListener,
- mMockShellMainExecutor,
- mMockShellMainHandler);
+ mDisplay = mContext.getDisplay();
+ mDisplayLayout = new DisplayLayout(mContext, mDisplay);
+ mSpiedTransitionState = spy(new OneHandedState());
+ mSpiedTutorialHandler = spy(
+ new OneHandedTutorialHandler(mContext, mDisplayLayout, mMockWindowManager,
+ mMockSettingsUtil, mMockShellMainExecutor));
+ mTimeoutHandler = new OneHandedTimeoutHandler(mMockShellMainExecutor);
}
@Test
- public void testRegisterForDisplayAreaOrganizer() {
- verify(mMockDisplayAreaOrganizer).registerTransitionCallback(mMockTutorialHandler);
+ public void testDefaultZeroShownCounts_canShowTutorial() {
+ assertThat(mSpiedTutorialHandler.canShowTutorial()).isTrue();
+ verify(mMockShellMainExecutor, never()).execute(any());
+ }
+
+ @Test
+ public void testDefaultZeroShownCounts_doNotAttachWindow() {
+ verify(mMockShellMainExecutor, never()).execute(any());
+ }
+
+ @Test
+ public void testOnStateChangedEntering_createViewAndAttachToWindow() {
+ when(mSpiedTutorialHandler.canShowTutorial()).thenReturn(true);
+ try {
+ mSpiedTutorialHandler.onStateChanged(STATE_ENTERING);
+ } catch (ClassCastException e) {
+ // no-op, just assert createViewAndAttachToWindow() to be called
+ }
+
+ verify(mSpiedTutorialHandler).createViewAndAttachToWindow(any());
+ }
+
+ @Test
+ public void testOnStateChangedNone_removeViewAndAttachToWindow() {
+ when(mSpiedTutorialHandler.canShowTutorial()).thenReturn(true);
+ try {
+ mSpiedTutorialHandler.onStateChanged(STATE_NONE);
+ } catch (ClassCastException e) {
+ // no-op, just assert removeTutorialFromWindowManager() to be called
+ }
+
+ verify(mSpiedTutorialHandler).removeTutorialFromWindowManager(true);
+ }
+
+ @Test
+ public void testOnStateChangedNone_shouldNotAttachWindow() {
+ when(mSpiedTutorialHandler.canShowTutorial()).thenReturn(true);
+ try {
+ mSpiedTutorialHandler.onStateChanged(STATE_NONE);
+ } catch (ClassCastException e) {
+ // no-op, just assert setTutorialShownCountIncrement() never be called
+ }
+
+ verify(mSpiedTutorialHandler, never()).setTutorialShownCountIncrement();
+ }
+
+ @Test
+ public void testOnConfigurationChanged_shouldUpdateViewContent() {
+ when(mSpiedTutorialHandler.canShowTutorial()).thenReturn(true);
+ try {
+ mSpiedTutorialHandler.onStateChanged(STATE_ENTERING);
+ } catch (ClassCastException e) {
+ // no-op, set current state for test onConfigurationChanged()
+ }
+ try {
+ mSpiedTutorialHandler.onConfigurationChanged();
+ } catch (ClassCastException e) {
+ // no-op, just assert removeTutorialFromWindowManager() be called
+ }
+
+ verify(mSpiedTutorialHandler).removeTutorialFromWindowManager(false);
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/MainStageTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/MainStageTests.java
index 702e894..1bb5fd1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/MainStageTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/MainStageTests.java
@@ -22,6 +22,7 @@
import android.app.ActivityManager;
import android.view.SurfaceControl;
+import android.view.SurfaceSession;
import android.window.WindowContainerTransaction;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -36,7 +37,6 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.mockito.Spy;
/** Tests for {@link MainStage} */
@SmallTest
@@ -47,14 +47,16 @@
@Mock private SyncTransactionQueue mSyncQueue;
@Mock private ActivityManager.RunningTaskInfo mRootTaskInfo;
@Mock private SurfaceControl mRootLeash;
- @Spy private WindowContainerTransaction mWct;
+ private WindowContainerTransaction mWct = new WindowContainerTransaction();
+ private SurfaceSession mSurfaceSession = new SurfaceSession();
private MainStage mMainStage;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mRootTaskInfo = new TestRunningTaskInfoBuilder().build();
- mMainStage = new MainStage(mTaskOrganizer, DEFAULT_DISPLAY, mCallbacks, mSyncQueue);
+ mMainStage = new MainStage(mTaskOrganizer, DEFAULT_DISPLAY, mCallbacks, mSyncQueue,
+ mSurfaceSession);
mMainStage.onTaskAppeared(mRootTaskInfo, mRootLeash);
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SideStageTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SideStageTests.java
index 01888b7..56a0056 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SideStageTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SideStageTests.java
@@ -26,6 +26,7 @@
import android.app.ActivityManager;
import android.view.SurfaceControl;
+import android.view.SurfaceSession;
import android.window.WindowContainerTransaction;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -52,13 +53,15 @@
@Mock private ActivityManager.RunningTaskInfo mRootTask;
@Mock private SurfaceControl mRootLeash;
@Spy private WindowContainerTransaction mWct;
+ private SurfaceSession mSurfaceSession = new SurfaceSession();
private SideStage mSideStage;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mRootTask = new TestRunningTaskInfoBuilder().build();
- mSideStage = new SideStage(mTaskOrganizer, DEFAULT_DISPLAY, mCallbacks, mSyncQueue);
+ mSideStage = new SideStage(mTaskOrganizer, DEFAULT_DISPLAY, mCallbacks, mSyncQueue,
+ mSurfaceSession);
mSideStage.onTaskAppeared(mRootTask, mRootLeash);
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
index 08ac2a6..aca80f3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
@@ -43,6 +43,7 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.view.SurfaceControl;
+import android.view.SurfaceSession;
import android.window.IRemoteTransition;
import android.window.IRemoteTransitionFinishedCallback;
import android.window.TransitionInfo;
@@ -80,6 +81,7 @@
@Mock private DisplayImeController mDisplayImeController;
@Mock private TransactionPool mTransactionPool;
@Mock private Transitions mTransitions;
+ @Mock private SurfaceSession mSurfaceSession;
private SplitLayout mSplitLayout;
private MainStage mMainStage;
private SideStage mSideStage;
@@ -98,10 +100,10 @@
doReturn(mock(SurfaceControl.Transaction.class)).when(mTransactionPool).acquire();
mSplitLayout = SplitTestUtils.createMockSplitLayout();
mMainStage = new MainStage(mTaskOrganizer, DEFAULT_DISPLAY, mock(
- StageTaskListener.StageListenerCallbacks.class), mSyncQueue);
+ StageTaskListener.StageListenerCallbacks.class), mSyncQueue, mSurfaceSession);
mMainStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
mSideStage = new SideStage(mTaskOrganizer, DEFAULT_DISPLAY, mock(
- StageTaskListener.StageListenerCallbacks.class), mSyncQueue);
+ StageTaskListener.StageListenerCallbacks.class), mSyncQueue, mSurfaceSession);
mSideStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
mStageCoordinator = new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY,
mSyncQueue, mRootTDAOrganizer, mTaskOrganizer, mMainStage, mSideStage,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
index 924e946..06b0868 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
@@ -18,7 +18,7 @@
import static android.view.Display.DEFAULT_DISPLAY;
-import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_POSITION_BOTTOM_OR_RIGHT;
+import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
@@ -73,7 +73,7 @@
public void testMoveToSideStage() {
final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder().build();
- mStageCoordinator.moveToSideStage(task, STAGE_POSITION_BOTTOM_OR_RIGHT);
+ mStageCoordinator.moveToSideStage(task, SPLIT_POSITION_BOTTOM_OR_RIGHT);
verify(mMainStage).activate(any(Rect.class), any(WindowContainerTransaction.class));
verify(mSideStage).addTask(eq(task), any(Rect.class),
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
index b3d2be9..90b5b37 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
@@ -27,6 +27,7 @@
import android.app.ActivityManager;
import android.view.SurfaceControl;
+import android.view.SurfaceSession;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -38,6 +39,8 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -52,6 +55,8 @@
@Mock private ShellTaskOrganizer mTaskOrganizer;
@Mock private StageTaskListener.StageListenerCallbacks mCallbacks;
@Mock private SyncTransactionQueue mSyncQueue;
+ @Captor private ArgumentCaptor<SyncTransactionQueue.TransactionRunnable> mRunnableCaptor;
+ private SurfaceSession mSurfaceSession = new SurfaceSession();
private ActivityManager.RunningTaskInfo mRootTask;
private StageTaskListener mStageTaskListener;
@@ -62,13 +67,24 @@
mTaskOrganizer,
DEFAULT_DISPLAY,
mCallbacks,
- mSyncQueue);
+ mSyncQueue,
+ mSurfaceSession);
mRootTask = new TestRunningTaskInfoBuilder().build();
mRootTask.parentTaskId = INVALID_TASK_ID;
mStageTaskListener.onTaskAppeared(mRootTask, new SurfaceControl());
}
@Test
+ public void testInitsDimLayer() {
+ verify(mSyncQueue).runInSync(mRunnableCaptor.capture());
+ final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ mRunnableCaptor.getValue().runWithTransaction(t);
+ t.apply();
+
+ assertThat(mStageTaskListener.mDimLayer).isNotNull();
+ }
+
+ @Test
public void testRootTaskAppeared() {
assertThat(mStageTaskListener.mRootTaskInfo.taskId).isEqualTo(mRootTask.taskId);
verify(mCallbacks).onRootTaskAppeared();
diff --git a/libs/hwui/pipeline/skia/AnimatedDrawables.h b/libs/hwui/pipeline/skia/AnimatedDrawables.h
index 10889e7..d173782 100644
--- a/libs/hwui/pipeline/skia/AnimatedDrawables.h
+++ b/libs/hwui/pipeline/skia/AnimatedDrawables.h
@@ -77,6 +77,7 @@
setUniform(effectBuilder, "in_radius", params.radius);
setUniform(effectBuilder, "in_progress", params.progress);
setUniform(effectBuilder, "in_turbulencePhase", params.turbulencePhase);
+ setUniform(effectBuilder, "in_noisePhase", params.turbulencePhase->value * 0.001);
SkRuntimeShaderBuilder::BuilderUniform uniform = effectBuilder.uniform("in_color");
if (uniform.fVar != nullptr) {
@@ -120,17 +121,24 @@
static constexpr float PI_ROTATE_LEFT = PI * -0.0078125;
static constexpr float SCALE = 1.5;
- static void setUniform(SkRuntimeShaderBuilder& effectBuilder, std::string name,
+ static void setUniform(SkRuntimeShaderBuilder& effectBuilder, const char* name,
sp<uirenderer::CanvasPropertyPrimitive> property) {
- SkRuntimeShaderBuilder::BuilderUniform uniform = effectBuilder.uniform(name.c_str());
+ SkRuntimeShaderBuilder::BuilderUniform uniform = effectBuilder.uniform(name);
if (uniform.fVar != nullptr) {
uniform = property->value;
}
}
- static void setUniform2f(SkRuntimeShaderBuilder& effectBuilder, std::string name, float a,
+ static void setUniform(SkRuntimeShaderBuilder& effectBuilder, const char* name, float value) {
+ SkRuntimeShaderBuilder::BuilderUniform uniform = effectBuilder.uniform(name);
+ if (uniform.fVar != nullptr) {
+ uniform = value;
+ }
+ }
+
+ static void setUniform2f(SkRuntimeShaderBuilder& effectBuilder, const char* name, float a,
float b) {
- SkRuntimeShaderBuilder::BuilderUniform uniform = effectBuilder.uniform(name.c_str());
+ SkRuntimeShaderBuilder::BuilderUniform uniform = effectBuilder.uniform(name);
if (uniform.fVar != nullptr) {
uniform = SkV2{a, b};
}
diff --git a/location/java/android/location/SatellitePvt.java b/location/java/android/location/SatellitePvt.java
index 1456f74..bb9ae6e 100644
--- a/location/java/android/location/SatellitePvt.java
+++ b/location/java/android/location/SatellitePvt.java
@@ -45,8 +45,41 @@
*/
@SystemApi
public final class SatellitePvt implements Parcelable {
+ /**
+ * Bit mask for {@link #mFlags} indicating valid satellite position, velocity and clock info
+ * fields are stored in the SatellitePvt.
+ */
+ private static final int HAS_POSITION_VELOCITY_CLOCK_INFO = 1 << 0;
+
+ /**
+ * Bit mask for {@link #mFlags} indicating a valid iono delay field is stored in the
+ * SatellitePvt.
+ */
+ private static final int HAS_IONO = 1 << 1;
+
+ /**
+ * Bit mask for {@link #mFlags} indicating a valid tropo delay field is stored in the
+ * SatellitePvt.
+ */
+ private static final int HAS_TROPO = 1 << 2;
+
+ /**
+ * A bitfield of flags indicating the validity of the fields in this SatellitePvt.
+ * The bit masks are defined in the constants with prefix HAS_*
+ *
+ * <p>Fields for which there is no corresponding flag must be filled in with a valid value.
+ * For convenience, these are marked as mandatory.
+ *
+ * <p>Others fields may have invalid information in them, if not marked as valid by the
+ * corresponding bit in flags.
+ */
+ private final int mFlags;
+
+ @Nullable
private final PositionEcef mPositionEcef;
+ @Nullable
private final VelocityEcef mVelocityEcef;
+ @Nullable
private final ClockInfo mClockInfo;
private final double mIonoDelayMeters;
private final double mTropoDelayMeters;
@@ -351,20 +384,13 @@
}
private SatellitePvt(
- @NonNull PositionEcef positionEcef,
- @NonNull VelocityEcef velocityEcef,
- @NonNull ClockInfo clockInfo,
+ int flags,
+ @Nullable PositionEcef positionEcef,
+ @Nullable VelocityEcef velocityEcef,
+ @Nullable ClockInfo clockInfo,
double ionoDelayMeters,
double tropoDelayMeters) {
- if (positionEcef == null) {
- throw new IllegalArgumentException("Position Ecef cannot be null.");
- }
- if (velocityEcef == null) {
- throw new IllegalArgumentException("Velocity Ecef cannot be null.");
- }
- if (clockInfo == null) {
- throw new IllegalArgumentException("Clock Info cannot be null.");
- }
+ mFlags = flags;
mPositionEcef = positionEcef;
mVelocityEcef = velocityEcef;
mClockInfo = clockInfo;
@@ -373,10 +399,17 @@
}
/**
+ * Gets a bitmask of fields present in this object
+ */
+ public int getFlags() {
+ return mFlags;
+ }
+
+ /**
* Returns a {@link PositionEcef} object that contains estimates of the satellite
* position fields in ECEF coordinate frame.
*/
- @NonNull
+ @Nullable
public PositionEcef getPositionEcef() {
return mPositionEcef;
}
@@ -385,7 +418,7 @@
* Returns a {@link VelocityEcef} object that contains estimates of the satellite
* velocity fields in the ECEF coordinate frame.
*/
- @NonNull
+ @Nullable
public VelocityEcef getVelocityEcef() {
return mVelocityEcef;
}
@@ -394,7 +427,7 @@
* Returns a {@link ClockInfo} object that contains estimates of the satellite
* clock info.
*/
- @NonNull
+ @Nullable
public ClockInfo getClockInfo() {
return mClockInfo;
}
@@ -415,11 +448,29 @@
return mTropoDelayMeters;
}
+ /** Returns {@code true} if {@link #getPositionEcef()}, {@link #getVelocityEcef()},
+ * and {@link #getClockInfo()} are valid.
+ */
+ public boolean hasPositionVelocityClockInfo() {
+ return (mFlags & HAS_POSITION_VELOCITY_CLOCK_INFO) != 0;
+ }
+
+ /** Returns {@code true} if {@link #getIonoDelayMeters()} is valid. */
+ public boolean hasIono() {
+ return (mFlags & HAS_IONO) != 0;
+ }
+
+ /** Returns {@code true} if {@link #getTropoDelayMeters()} is valid. */
+ public boolean hasTropo() {
+ return (mFlags & HAS_TROPO) != 0;
+ }
+
public static final @android.annotation.NonNull Creator<SatellitePvt> CREATOR =
new Creator<SatellitePvt>() {
@Override
@Nullable
public SatellitePvt createFromParcel(Parcel in) {
+ int flags = in.readInt();
ClassLoader classLoader = getClass().getClassLoader();
PositionEcef positionEcef = in.readParcelable(classLoader);
VelocityEcef velocityEcef = in.readParcelable(classLoader);
@@ -428,6 +479,7 @@
double tropoDelayMeters = in.readDouble();
return new SatellitePvt(
+ flags,
positionEcef,
velocityEcef,
clockInfo,
@@ -448,6 +500,7 @@
@Override
public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeInt(mFlags);
parcel.writeParcelable(mPositionEcef, flags);
parcel.writeParcelable(mVelocityEcef, flags);
parcel.writeParcelable(mClockInfo, flags);
@@ -458,7 +511,8 @@
@Override
public String toString() {
return "SatellitePvt{"
- + "PositionEcef=" + mPositionEcef
+ + "Flags=" + mFlags
+ + ", PositionEcef=" + mPositionEcef
+ ", VelocityEcef=" + mVelocityEcef
+ ", ClockInfo=" + mClockInfo
+ ", IonoDelayMeters=" + mIonoDelayMeters
@@ -470,13 +524,30 @@
* Builder class for SatellitePvt.
*/
public static final class Builder {
- private PositionEcef mPositionEcef;
- private VelocityEcef mVelocityEcef;
- private ClockInfo mClockInfo;
+ /**
+ * For documentation of below fields, see corresponding fields in {@link
+ * SatellitePvt}.
+ */
+ private int mFlags;
+ @Nullable private PositionEcef mPositionEcef;
+ @Nullable private VelocityEcef mVelocityEcef;
+ @Nullable private ClockInfo mClockInfo;
private double mIonoDelayMeters;
private double mTropoDelayMeters;
/**
+ * Sets a bitmask of fields present in this object
+ *
+ * @param flags int flags
+ * @return Builder builder object
+ */
+ @NonNull
+ public Builder setFlags(int flags) {
+ mFlags = flags;
+ return this;
+ }
+
+ /**
* Set position ECEF.
*
* @param positionEcef position ECEF object
@@ -546,7 +617,7 @@
*/
@NonNull
public SatellitePvt build() {
- return new SatellitePvt(mPositionEcef, mVelocityEcef, mClockInfo,
+ return new SatellitePvt(mFlags, mPositionEcef, mVelocityEcef, mClockInfo,
mIonoDelayMeters, mTropoDelayMeters);
}
}
diff --git a/packages/Connectivity/framework/api/current.txt b/packages/Connectivity/framework/api/current.txt
index 13ecb12..33f4d14 100644
--- a/packages/Connectivity/framework/api/current.txt
+++ b/packages/Connectivity/framework/api/current.txt
@@ -70,7 +70,7 @@
method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.Network getActiveNetwork();
method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getActiveNetworkInfo();
method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo[] getAllNetworkInfo();
- method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.Network[] getAllNetworks();
+ method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.Network[] getAllNetworks();
method @Deprecated public boolean getBackgroundDataSetting();
method @Nullable public android.net.Network getBoundNetworkForProcess();
method public int getConnectionOwnerUid(int, @NonNull java.net.InetSocketAddress, @NonNull java.net.InetSocketAddress);
@@ -406,6 +406,7 @@
method @NonNull public android.net.NetworkRequest.Builder clearCapabilities();
method public android.net.NetworkRequest.Builder removeCapability(int);
method public android.net.NetworkRequest.Builder removeTransportType(int);
+ method @NonNull public android.net.NetworkRequest.Builder setIncludeOtherUidNetworks(boolean);
method @Deprecated public android.net.NetworkRequest.Builder setNetworkSpecifier(String);
method public android.net.NetworkRequest.Builder setNetworkSpecifier(android.net.NetworkSpecifier);
}
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
index 5a53af4..93455bc 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
@@ -1433,10 +1433,18 @@
* Returns an array of all {@link Network} currently tracked by the
* framework.
*
+ * @deprecated This method does not provide any notification of network state changes, forcing
+ * apps to call it repeatedly. This is inefficient and prone to race conditions.
+ * Apps should use methods such as
+ * {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} instead.
+ * Apps that desire to obtain information about networks that do not apply to them
+ * can use {@link NetworkRequest.Builder#setIncludeOtherUidNetworks}.
+ *
* @return an array of {@link Network} objects.
*/
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
@NonNull
+ @Deprecated
public Network[] getAllNetworks() {
try {
return mService.getAllNetworks();
diff --git a/packages/Connectivity/framework/src/android/net/NetworkRequest.java b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
index a384109..a71dbbf 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkRequest.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
@@ -287,10 +287,15 @@
}
/**
- * Set the watched UIDs for this request. This will be reset and wiped out unless
- * the calling app holds the CHANGE_NETWORK_STATE permission.
+ * Sets this request to match only networks that apply to the specified UIDs.
*
- * @param uids The watched UIDs as a set of {@code Range<Integer>}, or null for everything.
+ * By default, the set of UIDs is the UID of the calling app, and this request will match
+ * any network that applies to the app. Setting it to {@code null} will observe any
+ * network on the system, even if it does not apply to this app. In this case, any
+ * {@link NetworkSpecifier} set on this request will be redacted or removed to prevent the
+ * application deducing restricted information such as location.
+ *
+ * @param uids The UIDs as a set of {@code Range<Integer>}, or null for everything.
* @return The builder to facilitate chaining.
* @hide
*/
@@ -517,6 +522,30 @@
mNetworkCapabilities.setSubscriptionIds(subIds);
return this;
}
+
+ /**
+ * Specifies whether the built request should also match networks that do not apply to the
+ * calling UID.
+ *
+ * By default, the built request will only match networks that apply to the calling UID.
+ * If this method is called with {@code true}, the built request will match any network on
+ * the system that matches the other parameters of the request. In this case, any
+ * information in the built request that is subject to redaction for security or privacy
+ * purposes, such as a {@link NetworkSpecifier}, will be redacted or removed to prevent the
+ * application deducing sensitive information.
+ *
+ * @param include Whether to match networks that do not apply to the calling UID.
+ * @return The builder to facilitate chaining.
+ */
+ @NonNull
+ public Builder setIncludeOtherUidNetworks(boolean include) {
+ if (include) {
+ mNetworkCapabilities.setUids(null);
+ } else {
+ mNetworkCapabilities.setSingleUid(Process.myUid());
+ }
+ return this;
+ }
}
// implement the Parcelable interface
diff --git a/packages/Connectivity/service/src/com/android/server/ConnectivityService.java b/packages/Connectivity/service/src/com/android/server/ConnectivityService.java
index 197226a..daf231f 100644
--- a/packages/Connectivity/service/src/com/android/server/ConnectivityService.java
+++ b/packages/Connectivity/service/src/com/android/server/ConnectivityService.java
@@ -1045,14 +1045,10 @@
} else {
// ConnectivityService publishes binder service using publishBinderService() with
// no priority assigned will be treated as NORMAL priority. Dumpsys does not send
- // "--dump-priority" arguments to the service. Thus, dump both NORMAL and HIGH to
- // align the legacy design.
+ // "--dump-priority" arguments to the service. Thus, dump NORMAL only to align the
+ // legacy output for dumpsys connectivity.
// TODO: Integrate into signal dump.
dumpNormal(fd, pw, args);
- pw.println();
- pw.println("DUMP OF SERVICE HIGH connectivity");
- pw.println();
- dumpHigh(fd, pw);
}
}
}
@@ -2156,10 +2152,22 @@
private void restrictRequestUidsForCallerAndSetRequestorInfo(NetworkCapabilities nc,
int callerUid, String callerPackageName) {
+ // There is no need to track the effective UID of the request here. If the caller
+ // lacks the settings permission, the effective UID is the same as the calling ID.
if (!checkSettingsPermission()) {
- // There is no need to track the effective UID of the request here. If the caller lacks
- // the settings permission, the effective UID is the same as the calling ID.
- nc.setSingleUid(callerUid);
+ // Unprivileged apps can only pass in null or their own UID.
+ if (nc.getUids() == null) {
+ // If the caller passes in null, the callback will also match networks that do not
+ // apply to its UID, similarly to what it would see if it called getAllNetworks.
+ // In this case, redact everything in the request immediately. This ensures that the
+ // app is not able to get any redacted information by filing an unredacted request
+ // and observing whether the request matches something.
+ if (nc.getNetworkSpecifier() != null) {
+ nc.setNetworkSpecifier(nc.getNetworkSpecifier().redact());
+ }
+ } else {
+ nc.setSingleUid(callerUid);
+ }
}
nc.setRequestorUidAndPackageName(callerUid, callerPackageName);
nc.setAdministratorUids(new int[0]);
diff --git a/packages/Connectivity/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/packages/Connectivity/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index 97ff3af..29a411e 100644
--- a/packages/Connectivity/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/packages/Connectivity/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -4277,6 +4277,124 @@
mCm.unregisterNetworkCallback(callback);
}
+ @Test
+ public void testNetworkCallbackWithNullUids() throws Exception {
+ final NetworkRequest request = new NetworkRequest.Builder()
+ .removeCapability(NET_CAPABILITY_NOT_VPN)
+ .build();
+ final TestNetworkCallback callback = new TestNetworkCallback();
+ mCm.registerNetworkCallback(request, callback);
+
+ // Attempt to file a callback for networks applying to another UID. This does not actually
+ // work, because this code does not currently have permission to do so. The callback behaves
+ // exactly the same as the one registered just above.
+ final int otherUid = UserHandle.getUid(RESTRICTED_USER, VPN_UID);
+ final NetworkRequest otherUidRequest = new NetworkRequest.Builder()
+ .removeCapability(NET_CAPABILITY_NOT_VPN)
+ .setUids(UidRange.toIntRanges(uidRangesForUids(otherUid)))
+ .build();
+ final TestNetworkCallback otherUidCallback = new TestNetworkCallback();
+ mCm.registerNetworkCallback(otherUidRequest, otherUidCallback);
+
+ final NetworkRequest includeOtherUidsRequest = new NetworkRequest.Builder()
+ .removeCapability(NET_CAPABILITY_NOT_VPN)
+ .setIncludeOtherUidNetworks(true)
+ .build();
+ final TestNetworkCallback includeOtherUidsCallback = new TestNetworkCallback();
+ mCm.registerNetworkCallback(includeOtherUidsRequest, includeOtherUidsCallback);
+
+ // Both callbacks see a network with no specifier that applies to their UID.
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+ mWiFiNetworkAgent.connect(false /* validated */);
+ callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+ otherUidCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+ includeOtherUidsCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+ mWiFiNetworkAgent.disconnect();
+ callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ otherUidCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ includeOtherUidsCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+
+ // Only the includeOtherUidsCallback sees a VPN that does not apply to its UID.
+ final UidRange range = UidRange.createForUser(UserHandle.of(RESTRICTED_USER));
+ final Set<UidRange> vpnRanges = Collections.singleton(range);
+ mMockVpn.establish(new LinkProperties(), VPN_UID, vpnRanges);
+ includeOtherUidsCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
+ callback.assertNoCallback();
+ otherUidCallback.assertNoCallback();
+
+ mMockVpn.disconnect();
+ includeOtherUidsCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
+ callback.assertNoCallback();
+ otherUidCallback.assertNoCallback();
+ }
+
+ private static class RedactableNetworkSpecifier extends NetworkSpecifier {
+ public static final int ID_INVALID = -1;
+
+ public final int networkId;
+
+ RedactableNetworkSpecifier(int networkId) {
+ this.networkId = networkId;
+ }
+
+ @Override
+ public boolean canBeSatisfiedBy(NetworkSpecifier other) {
+ return other instanceof RedactableNetworkSpecifier
+ && this.networkId == ((RedactableNetworkSpecifier) other).networkId;
+ }
+
+ @Override
+ public NetworkSpecifier redact() {
+ return new RedactableNetworkSpecifier(ID_INVALID);
+ }
+ }
+
+ @Test
+ public void testNetworkCallbackWithNullUidsRedactsSpecifier() throws Exception {
+ final RedactableNetworkSpecifier specifier = new RedactableNetworkSpecifier(42);
+ final NetworkRequest request = new NetworkRequest.Builder()
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .addTransportType(TRANSPORT_WIFI)
+ .setNetworkSpecifier(specifier)
+ .build();
+ final TestNetworkCallback callback = new TestNetworkCallback();
+ mCm.registerNetworkCallback(request, callback);
+
+ // Attempt to file a callback for networks applying to another UID. This does not actually
+ // work, because this code does not currently have permission to do so. The callback behaves
+ // exactly the same as the one registered just above.
+ final int otherUid = UserHandle.getUid(RESTRICTED_USER, VPN_UID);
+ final NetworkRequest otherUidRequest = new NetworkRequest.Builder()
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .addTransportType(TRANSPORT_WIFI)
+ .setNetworkSpecifier(specifier)
+ .setUids(UidRange.toIntRanges(uidRangesForUids(otherUid)))
+ .build();
+ final TestNetworkCallback otherUidCallback = new TestNetworkCallback();
+ mCm.registerNetworkCallback(otherUidRequest, otherUidCallback);
+
+ final NetworkRequest includeOtherUidsRequest = new NetworkRequest.Builder()
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .addTransportType(TRANSPORT_WIFI)
+ .setNetworkSpecifier(specifier)
+ .setIncludeOtherUidNetworks(true)
+ .build();
+ final TestNetworkCallback includeOtherUidsCallback = new TestNetworkCallback();
+ mCm.registerNetworkCallback(includeOtherUidsRequest, callback);
+
+ // Only the regular callback sees the network, because callbacks filed with no UID have
+ // their specifiers redacted.
+ final LinkProperties emptyLp = new LinkProperties();
+ final NetworkCapabilities ncTemplate = new NetworkCapabilities()
+ .addTransportType(TRANSPORT_WIFI)
+ .setNetworkSpecifier(specifier);
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, emptyLp, ncTemplate);
+ mWiFiNetworkAgent.connect(false /* validated */);
+ callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+ otherUidCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+ includeOtherUidsCallback.assertNoCallback();
+ }
+
private void setCaptivePortalMode(int mode) {
ContentResolver cr = mServiceContext.getContentResolver();
Settings.Global.putInt(cr, ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE, mode);
diff --git a/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml b/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml
index a19f7af..22b25a3 100644
--- a/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml
@@ -23,4 +23,15 @@
column="15"/>
</issue>
+ <issue
+ id="NewApi"
+ message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 21)"
+ errorLine1=" android:radius="?android:attr/dialogCornerRadius""
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/drawable/settingslib_rounded_background.xml"
+ line="23"
+ column="9"/>
+ </issue>
+
</issues>
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/settingslib_rounded_background.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/settingslib_rounded_background.xml
new file mode 100644
index 0000000..ae3834d
--- /dev/null
+++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/settingslib_rounded_background.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="?android:attr/dialogCornerRadius"
+ />
+</shape>
\ 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
new file mode 100644
index 0000000..ba612d7
--- /dev/null
+++ b/packages/SettingsLib/ActionButtonsPreference/res/layout-v31/settingslib_action_buttons.xml
@@ -0,0 +1,78 @@
+<?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:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="8dp"
+ android:paddingHorizontal="8dp"
+ android:orientation="horizontal"
+ android:background="@drawable/settingslib_rounded_background">
+
+ <Button
+ android:id="@+id/button1"
+ style="@style/SettingsLibActionButton"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"/>
+
+ <View
+ android:id="@+id/divider1"
+ android:layout_width="1dp"
+ android:layout_height="match_parent"
+ android:paddingHorizontal="4dp"
+ android:visibility="gone"
+ android:background="?android:colorBackground" />
+
+ <Button
+ android:id="@+id/button2"
+ style="@style/SettingsLibActionButton"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"/>
+
+ <View
+ android:id="@+id/divider2"
+ android:layout_width="1dp"
+ android:layout_height="match_parent"
+ android:paddingHorizontal="4dp"
+ android:visibility="gone"
+ android:background="?android:colorBackground" />
+
+ <Button
+ android:id="@+id/button3"
+ style="@style/SettingsLibActionButton"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"/>
+
+ <View
+ android:id="@+id/divider3"
+ android:layout_width="1dp"
+ android:layout_height="match_parent"
+ android:paddingHorizontal="4dp"
+ android:visibility="gone"
+ android:background="?android:colorBackground" />
+
+ <Button
+ android:id="@+id/button4"
+ style="@style/SettingsLibActionButton"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"/>
+</LinearLayout>
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/layout/settings_action_buttons.xml b/packages/SettingsLib/ActionButtonsPreference/res/layout/settingslib_action_buttons.xml
similarity index 88%
rename from packages/SettingsLib/ActionButtonsPreference/res/layout/settings_action_buttons.xml
rename to packages/SettingsLib/ActionButtonsPreference/res/layout/settingslib_action_buttons.xml
index 4f47113..55df34f 100644
--- a/packages/SettingsLib/ActionButtonsPreference/res/layout/settings_action_buttons.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/res/layout/settingslib_action_buttons.xml
@@ -24,29 +24,29 @@
<Button
android:id="@+id/button1"
- style="@style/SettingsActionButton"
+ style="@style/SettingsLibActionButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:id="@+id/button2"
- style="@style/SettingsActionButton"
+ style="@style/SettingsLibActionButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:id="@+id/button3"
- style="@style/SettingsActionButton"
+ style="@style/SettingsLibActionButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:id="@+id/button4"
- style="@style/SettingsActionButton"
+ style="@style/SettingsLibActionButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml b/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml
index efa508d..42c7d76 100644
--- a/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml
@@ -16,11 +16,10 @@
-->
<resources>
- <style name="SettingsActionButton" parent="android:Widget.DeviceDefault.Button.Borderless.Colored">
+ <style name="SettingsLibActionButton" parent="android:Widget.DeviceDefault.Button.Borderless.Colored">
<item name="android:drawablePadding">4dp</item>
<item name="android:drawableTint">@*android:color/btn_colored_borderless_text_material</item>
- <item name="android:layout_marginEnd">8dp</item>
<item name="android:paddingTop">20dp</item>
<item name="android:paddingBottom">20dp</item>
</style>
-</resources>
\ No newline at end of file
+</resources>
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 8b46cc6..aeda7ac 100644
--- a/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java
+++ b/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java
@@ -27,16 +27,20 @@
import androidx.annotation.DrawableRes;
import androidx.annotation.StringRes;
+import androidx.core.os.BuildCompat;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* This preference provides a four buttons layout with Settings style.
* It looks like below
*
- * --------------------------------------------------
- * button1 | button2 | button3 | button4 |
- * --------------------------------------------------
+ * ---------------------------------------
+ * - button1 | button2 | button3 | button4 -
+ * ---------------------------------------
*
* User can set title / icon / click listener for each button.
*
@@ -49,10 +53,16 @@
public class ActionButtonsPreference extends Preference {
private static final String TAG = "ActionButtonPreference";
+
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 View mDivider1;
+ private View mDivider2;
+ private View mDivider3;
public ActionButtonsPreference(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
@@ -76,25 +86,49 @@
}
private void init() {
- setLayoutResource(R.layout.settings_action_buttons);
+ setLayoutResource(R.layout.settingslib_action_buttons);
setSelectable(false);
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
- holder.setDividerAllowedAbove(true);
- holder.setDividerAllowedBelow(true);
+ if (!BuildCompat.isAtLeastS()) {
+ holder.setDividerAllowedAbove(true);
+ holder.setDividerAllowedBelow(true);
+ }
mButton1Info.mButton = (Button) holder.findViewById(R.id.button1);
mButton2Info.mButton = (Button) holder.findViewById(R.id.button2);
mButton3Info.mButton = (Button) holder.findViewById(R.id.button3);
mButton4Info.mButton = (Button) holder.findViewById(R.id.button4);
+ mDivider1 = holder.findViewById(R.id.divider1);
+ mDivider2 = holder.findViewById(R.id.divider2);
+ mDivider3 = holder.findViewById(R.id.divider3);
+
mButton1Info.setUpButton();
mButton2Info.setUpButton();
mButton3Info.setUpButton();
mButton4Info.setUpButton();
+
+ // Add visible button into list only
+ if (mButton1Info.isVisible()) {
+ mVisibleButtonInfos.add(mButton1Info);
+ }
+ if (mButton2Info.isVisible()) {
+ mVisibleButtonInfos.add(mButton2Info);
+ }
+ if (mButton3Info.isVisible()) {
+ mVisibleButtonInfos.add(mButton3Info);
+ }
+ if (mButton4Info.isVisible()) {
+ mVisibleButtonInfos.add(mButton4Info);
+ }
+
+ setupDivider1();
+ setupDivider2();
+ setupDivider3();
}
/**
@@ -357,6 +391,28 @@
return this;
}
+ private void setupDivider1() {
+ // Display divider1 only if button1 and button2 is visible
+ if (mDivider1 != null && mButton1Info.isVisible() && mButton2Info.isVisible()) {
+ mDivider1.setVisibility(View.VISIBLE);
+ }
+ }
+
+ private void setupDivider2() {
+ // Display divider2 only if button3 is visible and button2 or button3 is visible
+ if (mDivider2 != null && mButton3Info.isVisible()
+ && (mButton1Info.isVisible() || mButton2Info.isVisible())) {
+ mDivider2.setVisibility(View.VISIBLE);
+ }
+ }
+
+ private void setupDivider3() {
+ // Display divider3 only if button4 is visible and 2 visible buttons at least
+ if (mDivider3 != null && mVisibleButtonInfos.size() > 1 && mButton4Info.isVisible()) {
+ mDivider3.setVisibility(View.VISIBLE);
+ }
+ }
+
static class ButtonInfo {
private Button mButton;
private CharSequence mText;
@@ -379,6 +435,10 @@
}
}
+ boolean isVisible() {
+ return mButton.getVisibility() == View.VISIBLE;
+ }
+
/**
* By default, four buttons are visible.
* However, there are two cases which button should be invisible.
diff --git a/packages/SettingsLib/IllustrationPreference/res/layout/illustration_preference.xml b/packages/SettingsLib/IllustrationPreference/res/layout/illustration_preference.xml
index 2cbb888..7d65aae 100644
--- a/packages/SettingsLib/IllustrationPreference/res/layout/illustration_preference.xml
+++ b/packages/SettingsLib/IllustrationPreference/res/layout/illustration_preference.xml
@@ -23,20 +23,13 @@
android:gravity="center"
android:orientation="horizontal">
- <View
- android:id="@+id/protection_layer"
- android:layout_width="412dp"
- android:layout_height="300dp"
- android:layout_gravity="center"
- android:padding="@dimen/settingslib_illustration_padding"
- android:background="@drawable/protection_background"/>
-
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lottie_view"
android:layout_width="412dp"
android:layout_height="300dp"
android:layout_gravity="center"
- android:padding="@dimen/settingslib_illustration_padding"
+ android:clipToOutline="true"
+ android:background="@drawable/protection_background"
android:importantForAccessibility="no"/>
<ImageView
diff --git a/packages/SettingsLib/TwoTargetPreference/res/layout/preference_two_target.xml b/packages/SettingsLib/TwoTargetPreference/res/layout/preference_two_target.xml
index f6a64c6..21fcedc 100644
--- a/packages/SettingsLib/TwoTargetPreference/res/layout/preference_two_target.xml
+++ b/packages/SettingsLib/TwoTargetPreference/res/layout/preference_two_target.xml
@@ -23,16 +23,16 @@
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:gravity="center_vertical"
- android:background="?android:attr/selectableItemBackground"
+ android:background="@android:color/transparent"
android:clipToPadding="false">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
+ android:background="?android:attr/selectableItemBackground"
android:gravity="start|center_vertical"
android:clipToPadding="false"
- android:duplicateParentState="true"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
@@ -44,14 +44,12 @@
android:minWidth="56dp"
android:orientation="horizontal"
android:clipToPadding="false"
- android:duplicateParentState="true"
android:paddingTop="4dp"
android:paddingBottom="4dp">
<androidx.preference.internal.PreferenceImageView
android:id="@android:id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:duplicateParentState="true"
settings:maxWidth="48dp"
settings:maxHeight="48dp" />
</LinearLayout>
@@ -60,7 +58,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:duplicateParentState="true"
android:paddingTop="16dp"
android:paddingBottom="16dp">
@@ -69,7 +66,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
- android:duplicateParentState="true"
android:textAppearance="?android:attr/textAppearanceListItem"
android:ellipsize="marquee" />
@@ -79,7 +75,6 @@
android:layout_height="wrap_content"
android:layout_below="@android:id/title"
android:layout_alignStart="@android:id/title"
- android:duplicateParentState="true"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorSecondary"
android:maxLines="10" />
@@ -95,7 +90,6 @@
android:id="@android:id/widget_frame"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:duplicateParentState="true"
android:minWidth="64dp"
android:gravity="center"
android:orientation="vertical" />
diff --git a/packages/SettingsLib/TwoTargetPreference/res/layout/preference_two_target_divider.xml b/packages/SettingsLib/TwoTargetPreference/res/layout/preference_two_target_divider.xml
index 44732e5..bd477f8 100644
--- a/packages/SettingsLib/TwoTargetPreference/res/layout/preference_two_target_divider.xml
+++ b/packages/SettingsLib/TwoTargetPreference/res/layout/preference_two_target_divider.xml
@@ -22,12 +22,10 @@
android:layout_height="match_parent"
android:gravity="start|center_vertical"
android:orientation="horizontal"
- android:duplicateParentState="true"
android:paddingTop="16dp"
android:paddingBottom="16dp">
<View
android:layout_width="1dp"
android:layout_height="match_parent"
- android:duplicateParentState="true"
android:background="?android:attr/listDivider" />
</LinearLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java
index e24b525..9f31cef 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java
@@ -48,7 +48,7 @@
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
- mRootView = View.inflate(mContext, R.layout.settings_action_buttons, null /* parent */);
+ mRootView = View.inflate(mContext, R.layout.settingslib_action_buttons, null /* parent */);
mHolder = PreferenceViewHolder.createInstanceForTests(mRootView);
mPref = new ActionButtonsPreference(mContext);
}
@@ -251,6 +251,114 @@
assertThat(drawablesAroundText[1 /* top */]).isNull();
}
+ @Test
+ public void onBindViewHolder_setAllButton_shouldShowAllDivider() {
+ mPref.setButton1Text(R.string.install_other_apps);
+ mPref.setButton2Text(R.string.install_other_apps);
+ mPref.setButton3Text(R.string.install_other_apps);
+ mPref.setButton4Text(R.string.install_other_apps);
+
+ mPref.onBindViewHolder(mHolder);
+
+ assertThat(mRootView.findViewById(R.id.divider1).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ assertThat(mRootView.findViewById(R.id.divider2).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ assertThat(mRootView.findViewById(R.id.divider3).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ }
+
+ @Test
+ public void onBindViewHolder_setAllButtonWithoutButton2_shouldHideDivider1() {
+ mPref.setButton1Text(R.string.install_other_apps);
+ mPref.setButton3Text(R.string.install_other_apps);
+ mPref.setButton4Text(R.string.install_other_apps);
+
+ mPref.onBindViewHolder(mHolder);
+
+ assertThat(mRootView.findViewById(R.id.divider1).getVisibility())
+ .isEqualTo(View.GONE);
+ assertThat(mRootView.findViewById(R.id.divider2).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ assertThat(mRootView.findViewById(R.id.divider3).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ }
+
+ @Test
+ public void onBindViewHolder_setAllButtonWithoutButton3_shouldHideDivider2() {
+ mPref.setButton1Text(R.string.install_other_apps);
+ mPref.setButton2Text(R.string.install_other_apps);
+ mPref.setButton4Text(R.string.install_other_apps);
+
+ mPref.onBindViewHolder(mHolder);
+
+ assertThat(mRootView.findViewById(R.id.divider1).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ assertThat(mRootView.findViewById(R.id.divider2).getVisibility())
+ .isEqualTo(View.GONE);
+ assertThat(mRootView.findViewById(R.id.divider3).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ }
+
+ @Test
+ public void onBindViewHolder_setButton1And4_shouldShowDivider3Only() {
+ mPref.setButton1Text(R.string.install_other_apps);
+ mPref.setButton4Text(R.string.install_other_apps);
+
+ mPref.onBindViewHolder(mHolder);
+
+ assertThat(mRootView.findViewById(R.id.divider1).getVisibility())
+ .isEqualTo(View.GONE);
+ assertThat(mRootView.findViewById(R.id.divider2).getVisibility())
+ .isEqualTo(View.GONE);
+ assertThat(mRootView.findViewById(R.id.divider3).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ }
+
+ @Test
+ public void onBindViewHolder_setOneButtonOnly_noDivider() {
+ mPref.setButton4Text(R.string.install_other_apps);
+
+ mPref.onBindViewHolder(mHolder);
+
+ assertThat(mRootView.findViewById(R.id.divider1).getVisibility())
+ .isEqualTo(View.GONE);
+ assertThat(mRootView.findViewById(R.id.divider2).getVisibility())
+ .isEqualTo(View.GONE);
+ assertThat(mRootView.findViewById(R.id.divider3).getVisibility())
+ .isEqualTo(View.GONE);
+ }
+
+ @Test
+ public void onBindViewHolder_setButton1And2_shouldShowDivider1Only() {
+ mPref.setButton1Text(R.string.install_other_apps);
+ mPref.setButton2Text(R.string.install_other_apps);
+
+ mPref.onBindViewHolder(mHolder);
+
+ assertThat(mRootView.findViewById(R.id.divider1).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ assertThat(mRootView.findViewById(R.id.divider2).getVisibility())
+ .isEqualTo(View.GONE);
+ assertThat(mRootView.findViewById(R.id.divider3).getVisibility())
+ .isEqualTo(View.GONE);
+ }
+
+ @Test
+ public void onBindViewHolder_setButton1And3_shouldShowDivider2Only() {
+ mPref.setButton1Text(R.string.install_other_apps);
+ mPref.setButton3Text(R.string.install_other_apps);
+
+ mPref.onBindViewHolder(mHolder);
+
+ assertThat(mRootView.findViewById(R.id.divider1).getVisibility())
+ .isEqualTo(View.GONE);
+ assertThat(mRootView.findViewById(R.id.divider2).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ assertThat(mRootView.findViewById(R.id.divider3).getVisibility())
+ .isEqualTo(View.GONE);
+ }
+
public static ActionButtonsPreference createMock() {
final ActionButtonsPreference pref = mock(ActionButtonsPreference.class);
when(pref.setButton1Text(anyInt())).thenReturn(pref);
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
index b7560d2..c9c3db8 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
@@ -73,6 +73,7 @@
Settings.Global.CUSTOM_BUGREPORT_HANDLER_USER,
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED,
Settings.Global.USER_DISABLED_HDR_FORMATS,
- Settings.Global.ARE_USER_DISABLED_HDR_FORMATS_ALLOWED
+ Settings.Global.ARE_USER_DISABLED_HDR_FORMATS_ALLOWED,
+ Settings.Global.DEVICE_CONFIG_SYNC_DISABLED,
};
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
index 8f7f1fa..5220a04 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
@@ -139,6 +139,7 @@
/* first= */Global.ONE_HANDED_KEYGUARD_SIDE_LEFT,
/* last= */Global.ONE_HANDED_KEYGUARD_SIDE_RIGHT));
VALIDATORS.put(Global.DISABLE_WINDOW_BLURS, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.DEVICE_CONFIG_SYNC_DISABLED, BOOLEAN_VALIDATOR);
}
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
index df6ff73..00fd19c 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
@@ -16,7 +16,11 @@
package com.android.providers.settings;
-import android.annotation.SystemApi;
+import static android.provider.Settings.Config.SYNC_DISABLED_MODE_NONE;
+import static android.provider.Settings.Config.SYNC_DISABLED_MODE_PERSISTENT;
+import static android.provider.Settings.Config.SYNC_DISABLED_MODE_UNTIL_REBOOT;
+
+import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.content.AttributionSource;
import android.content.IContentProvider;
@@ -41,10 +45,7 @@
/**
* Receives shell commands from the command line related to device config flags, and dispatches them
* to the SettingsProvider.
- *
- * @hide
*/
-@SystemApi
public final class DeviceConfigService extends Binder {
final SettingsProvider mProvider;
@@ -62,18 +63,20 @@
final SettingsProvider mProvider;
enum CommandVerb {
- UNSPECIFIED,
GET,
PUT,
DELETE,
LIST,
RESET,
+ SET_SYNC_DISABLED_FOR_TESTS,
+ IS_SYNC_DISABLED_FOR_TESTS,
}
MyShellCommand(SettingsProvider provider) {
mProvider = provider;
}
+ @SuppressLint("AndroidFrameworkRequiresPermission")
@Override
public int onCommand(String cmd) {
if (cmd == null || "help".equals(cmd) || "-h".equals(cmd)) {
@@ -83,6 +86,7 @@
final PrintWriter perr = getErrPrintWriter();
boolean isValid = false;
+
CommandVerb verb;
if ("get".equalsIgnoreCase(cmd)) {
verb = CommandVerb.GET;
@@ -97,21 +101,33 @@
}
} else if ("reset".equalsIgnoreCase(cmd)) {
verb = CommandVerb.RESET;
+ } else if ("set_sync_disabled_for_tests".equalsIgnoreCase(cmd)) {
+ verb = CommandVerb.SET_SYNC_DISABLED_FOR_TESTS;
+ } else if ("is_sync_disabled_for_tests".equalsIgnoreCase(cmd)) {
+ verb = CommandVerb.IS_SYNC_DISABLED_FOR_TESTS;
+ if (peekNextArg() != null) {
+ perr.println("Bad arguments");
+ return -1;
+ }
+ isValid = true;
} else {
// invalid
perr.println("Invalid command: " + cmd);
return -1;
}
+ // Parse args for those commands that have them.
+ int disableSyncMode = -1;
int resetMode = -1;
boolean makeDefault = false;
String namespace = null;
String key = null;
String value = null;
- String arg = null;
+ String arg;
while ((arg = getNextArg()) != null) {
if (verb == CommandVerb.RESET) {
if (resetMode == -1) {
+ // RESET 1st arg (required)
if ("untrusted_defaults".equalsIgnoreCase(arg)) {
resetMode = Settings.RESET_MODE_UNTRUSTED_DEFAULTS;
} else if ("untrusted_clear".equalsIgnoreCase(arg)) {
@@ -127,6 +143,7 @@
isValid = true;
}
} else {
+ // RESET 2nd arg (optional)
namespace = arg;
if (peekNextArg() == null) {
isValid = true;
@@ -136,7 +153,26 @@
return -1;
}
}
+ } else if (verb == CommandVerb.SET_SYNC_DISABLED_FOR_TESTS) {
+ if (disableSyncMode == -1) {
+ // DISABLE_SYNC_FOR_TESTS 1st arg (required)
+ if ("none".equalsIgnoreCase(arg)) {
+ disableSyncMode = SYNC_DISABLED_MODE_NONE;
+ } else if ("persistent".equalsIgnoreCase(arg)) {
+ disableSyncMode = SYNC_DISABLED_MODE_PERSISTENT;
+ } else if ("until_reboot".equalsIgnoreCase(arg)) {
+ disableSyncMode = SYNC_DISABLED_MODE_UNTIL_REBOOT;
+ } else {
+ // invalid
+ perr.println("Invalid sync disabled mode: " + arg);
+ return -1;
+ }
+ if (peekNextArg() == null) {
+ isValid = true;
+ }
+ }
} else if (namespace == null) {
+ // GET, PUT, DELETE, LIST 1st arg
namespace = arg;
if (verb == CommandVerb.LIST) {
if (peekNextArg() == null) {
@@ -148,8 +184,10 @@
}
}
} else if (key == null) {
+ // GET, PUT, DELETE 2nd arg
key = arg;
if ((verb == CommandVerb.GET || verb == CommandVerb.DELETE)) {
+ // GET, DELETE only have 2 args
if (peekNextArg() == null) {
isValid = true;
} else {
@@ -159,11 +197,13 @@
}
}
} else if (value == null) {
+ // PUT 3rd arg (required)
value = arg;
if (verb == CommandVerb.PUT && peekNextArg() == null) {
isValid = true;
}
} else if ("default".equalsIgnoreCase(arg)) {
+ // PUT 4th arg (optional)
makeDefault = true;
if (verb == CommandVerb.PUT && peekNextArg() == null) {
isValid = true;
@@ -211,6 +251,12 @@
case RESET:
DeviceConfig.resetToDefaults(resetMode, namespace);
break;
+ case SET_SYNC_DISABLED_FOR_TESTS:
+ DeviceConfig.setSyncDisabled(disableSyncMode);
+ break;
+ case IS_SYNC_DISABLED_FOR_TESTS:
+ pout.println(DeviceConfig.isSyncDisabled());
+ break;
default:
perr.println("Unspecified command");
return -1;
@@ -241,6 +287,16 @@
+ "trusted_defaults}");
pw.println(" NAMESPACE limits which flags are reset if provided, otherwise all "
+ "flags are reset");
+ pw.println(" set_sync_disabled_for_tests SYNC_DISABLED_MODE");
+ pw.println(" Modifies bulk property setting behavior for tests. When in one of the"
+ + " disabled modes this ensures that config isn't overwritten.");
+ pw.println(" SYNC_DISABLED_MODE is one of:");
+ pw.println(" none: Sync is not disabled. A reboot may be required to restart"
+ + " syncing.");
+ pw.println(" persistent: Sync is disabled, this state will survive a reboot.");
+ pw.println(" until_reboot: Sync is disabled until the next reboot.");
+ pw.println(" is_sync_disabled_for_tests");
+ pw.println(" Prints 'true' if sync is disabled, 'false' otherwise.");
}
private boolean delete(IContentProvider provider, String namespace, String key) {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 3219b2b..959b6ba 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -19,6 +19,12 @@
import static android.os.Process.ROOT_UID;
import static android.os.Process.SHELL_UID;
import static android.os.Process.SYSTEM_UID;
+import static android.provider.Settings.Config.SYNC_DISABLED_MODE_NONE;
+import static android.provider.Settings.Config.SYNC_DISABLED_MODE_PERSISTENT;
+import static android.provider.Settings.Config.SYNC_DISABLED_MODE_UNTIL_REBOOT;
+import static android.provider.Settings.SET_ALL_RESULT_DISABLED;
+import static android.provider.Settings.SET_ALL_RESULT_FAILURE;
+import static android.provider.Settings.SET_ALL_RESULT_SUCCESS;
import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER;
import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY;
@@ -83,8 +89,10 @@
import android.os.UserManager;
import android.provider.DeviceConfig;
import android.provider.Settings;
+import android.provider.Settings.Config.SyncDisabledMode;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
+import android.provider.Settings.SetAllResult;
import android.provider.settings.validators.SystemSettingsValidators;
import android.provider.settings.validators.Validator;
import android.text.TextUtils;
@@ -338,6 +346,9 @@
// We have to call in the package manager with no lock held,
private volatile IPackageManager mPackageManager;
+ @GuardedBy("mLock")
+ private boolean mSyncConfigDisabledUntilReboot;
+
public static int makeKey(int type, int userId) {
return SettingsState.makeKey(type, userId);
}
@@ -446,11 +457,24 @@
String prefix = getSettingPrefix(args);
Map<String, String> flags = getSettingFlags(args);
Bundle result = new Bundle();
- result.putBoolean(Settings.KEY_CONFIG_SET_RETURN,
+ result.putInt(Settings.KEY_CONFIG_SET_ALL_RETURN,
setAllConfigSettings(prefix, flags));
return result;
}
+ case Settings.CALL_METHOD_SET_SYNC_DISABLED_CONFIG: {
+ final int mode = getSyncDisabledMode(args);
+ setSyncDisabledConfig(mode);
+ break;
+ }
+
+ case Settings.CALL_METHOD_IS_SYNC_DISABLED_CONFIG: {
+ Bundle result = new Bundle();
+ result.putBoolean(Settings.KEY_CONFIG_IS_SYNC_DISABLED_RETURN,
+ isSyncDisabledConfig());
+ return result;
+ }
+
case Settings.CALL_METHOD_RESET_CONFIG: {
final int mode = getResetModeEnforcingPermission(args);
String prefix = getSettingPrefix(args);
@@ -1105,7 +1129,8 @@
MUTATION_OPERATION_INSERT, 0);
}
- private boolean setAllConfigSettings(String prefix, Map<String, String> keyValues) {
+
+ private @SetAllResult int setAllConfigSettings(String prefix, Map<String, String> keyValues) {
if (DEBUG) {
Slog.v(LOG_TAG, "setAllConfigSettings for prefix: " + prefix);
}
@@ -1113,9 +1138,95 @@
enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG);
synchronized (mLock) {
+ if (isSyncDisabledConfigLocked()) {
+ return SET_ALL_RESULT_DISABLED;
+ }
final int key = makeKey(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM);
- return mSettingsRegistry.setConfigSettingsLocked(key, prefix, keyValues,
+ boolean success = mSettingsRegistry.setConfigSettingsLocked(key, prefix, keyValues,
resolveCallingPackage());
+ return success ? SET_ALL_RESULT_SUCCESS : SET_ALL_RESULT_FAILURE;
+ }
+ }
+
+ private void setSyncDisabledConfig(@SyncDisabledMode int syncDisabledMode) {
+ if (DEBUG) {
+ Slog.v(LOG_TAG, "setSyncDisabledConfig(" + syncDisabledMode + ")");
+ }
+
+ enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG);
+
+ synchronized (mLock) {
+ setSyncDisabledConfigLocked(syncDisabledMode);
+ }
+ }
+
+ private boolean isSyncDisabledConfig() {
+ if (DEBUG) {
+ Slog.v(LOG_TAG, "isSyncDisabledConfig");
+ }
+
+ enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG);
+
+ synchronized (mLock) {
+ return isSyncDisabledConfigLocked();
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void setSyncDisabledConfigLocked(@SyncDisabledMode int syncDisabledMode) {
+ boolean persistentValue;
+ boolean inMemoryValue;
+ if (syncDisabledMode == SYNC_DISABLED_MODE_NONE) {
+ persistentValue = false;
+ inMemoryValue = false;
+ } else if (syncDisabledMode == SYNC_DISABLED_MODE_PERSISTENT) {
+ persistentValue = true;
+ inMemoryValue = false;
+ } else if (syncDisabledMode == SYNC_DISABLED_MODE_UNTIL_REBOOT) {
+ persistentValue = false;
+ inMemoryValue = true;
+ } else {
+ throw new IllegalArgumentException(Integer.toString(syncDisabledMode));
+ }
+
+ mSyncConfigDisabledUntilReboot = inMemoryValue;
+
+ CallingIdentity callingIdentity = clearCallingIdentity();
+ try {
+ String globalSettingValue = persistentValue ? "1" : "0";
+ mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_GLOBAL,
+ UserHandle.USER_SYSTEM, Settings.Global.DEVICE_CONFIG_SYNC_DISABLED,
+ globalSettingValue, /*tag=*/null, /*makeDefault=*/false,
+ SettingsState.SYSTEM_PACKAGE_NAME, /*forceNotify=*/false,
+ /*criticalSettings=*/null, Settings.DEFAULT_OVERRIDEABLE_BY_RESTORE);
+ } finally {
+ restoreCallingIdentity(callingIdentity);
+ }
+ }
+
+ @GuardedBy("mLock")
+ private boolean isSyncDisabledConfigLocked() {
+ // Check the values used for both SYNC_DISABLED_MODE_PERSISTENT and
+ // SYNC_DISABLED_MODE_UNTIL_REBOOT.
+
+ // The SYNC_DISABLED_MODE_UNTIL_REBOOT value is cheap to check first.
+ if (mSyncConfigDisabledUntilReboot) {
+ return true;
+ }
+
+ // Now check the global setting used to implement SYNC_DISABLED_MODE_PERSISTENT.
+ CallingIdentity callingIdentity = clearCallingIdentity();
+ try {
+ Setting settingLocked = mSettingsRegistry.getSettingLocked(
+ SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM,
+ Global.DEVICE_CONFIG_SYNC_DISABLED);
+ if (settingLocked == null) {
+ return false;
+ }
+ String settingValue = settingLocked.getValue();
+ return settingValue != null && !"0".equals(settingValue);
+ } finally {
+ restoreCallingIdentity(callingIdentity);
}
}
@@ -2227,6 +2338,16 @@
return (args != null) && args.getBoolean(Settings.CALL_METHOD_OVERRIDEABLE_BY_RESTORE_KEY);
}
+ private static int getSyncDisabledMode(Bundle args) {
+ final int mode = (args != null)
+ ? args.getInt(Settings.CALL_METHOD_SYNC_DISABLED_MODE_KEY) : -1;
+ if (mode == SYNC_DISABLED_MODE_NONE || mode == SYNC_DISABLED_MODE_UNTIL_REBOOT
+ || mode == SYNC_DISABLED_MODE_PERSISTENT) {
+ return mode;
+ }
+ throw new IllegalArgumentException("Invalid sync disabled mode: " + mode);
+ }
+
private static int getResetModeEnforcingPermission(Bundle args) {
final int mode = (args != null) ? args.getInt(Settings.CALL_METHOD_RESET_MODE_KEY) : 0;
switch (mode) {
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
index 7c5459c1..35eebac 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
@@ -81,5 +81,6 @@
android:layout_height="@dimen/notification_shelf_height"
android:layout_below="@id/keyguard_status_area"
android:paddingStart="@dimen/below_clock_padding_start_extra"
+ android:visibility="invisible"
/>
</com.android.keyguard.KeyguardClockSwitch>
diff --git a/packages/SystemUI/res/layout/qs_carrier.xml b/packages/SystemUI/res/layout/qs_carrier.xml
index c521dc2..d4594d1 100644
--- a/packages/SystemUI/res/layout/qs_carrier.xml
+++ b/packages/SystemUI/res/layout/qs_carrier.xml
@@ -33,7 +33,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:textAppearance="@style/TextAppearance.QS.Status"
+ android:textAppearance="@style/TextAppearance.QS.Status.Carriers"
android:textDirection="locale"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
diff --git a/packages/SystemUI/res/layout/qs_carrier_group.xml b/packages/SystemUI/res/layout/qs_carrier_group.xml
index 810c959..6e13ab9 100644
--- a/packages/SystemUI/res/layout/qs_carrier_group.xml
+++ b/packages/SystemUI/res/layout/qs_carrier_group.xml
@@ -32,7 +32,7 @@
android:minWidth="48dp"
android:minHeight="48dp"
android:gravity="center_vertical"
- android:textAppearance="@style/TextAppearance.QS.Status.NoCarrierText"
+ android:textAppearance="@style/TextAppearance.QS.Status.Carriers.NoCarrierText"
android:textDirection="locale"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
diff --git a/packages/SystemUI/res/layout/qs_customize_divider.xml b/packages/SystemUI/res/layout/qs_customize_divider.xml
index 035f493..b4e3010 100644
--- a/packages/SystemUI/res/layout/qs_customize_divider.xml
+++ b/packages/SystemUI/res/layout/qs_customize_divider.xml
@@ -24,5 +24,5 @@
android:gravity="center"
android:paddingTop="24dp"
android:paddingBottom="24dp"
- android:textAppearance="@style/TextAppearance.QSEdit.Headers"
+ android:textAppearance="@style/TextAppearance.QSEdit"
android:text="@string/drag_to_add_tiles" />
diff --git a/packages/SystemUI/res/layout/qs_customize_header.xml b/packages/SystemUI/res/layout/qs_customize_header.xml
index 481561d..626d53a 100644
--- a/packages/SystemUI/res/layout/qs_customize_header.xml
+++ b/packages/SystemUI/res/layout/qs_customize_header.xml
@@ -22,5 +22,5 @@
android:layout_height="wrap_content"
android:gravity="center"
android:minHeight="@dimen/qs_customize_header_min_height"
- android:textAppearance="@style/TextAppearance.QSEdit.Headers"
+ android:textAppearance="@style/TextAppearance.QSEdit"
android:text="@string/drag_to_rearrange_tiles" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/qs_footer_impl.xml b/packages/SystemUI/res/layout/qs_footer_impl.xml
index 609fc6d..0a9feb8 100644
--- a/packages/SystemUI/res/layout/qs_footer_impl.xml
+++ b/packages/SystemUI/res/layout/qs_footer_impl.xml
@@ -51,7 +51,7 @@
android:focusable="true"
android:gravity="center_vertical"
android:singleLine="true"
- android:textAppearance="@style/TextAppearance.QS.Build"
+ android:textAppearance="@style/TextAppearance.QS.Status.Build"
android:visibility="gone" />
<com.android.systemui.qs.PageIndicator
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 059cec7..3c936a0 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -136,6 +136,7 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Foon"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Stembystand"</string>
+ <string name="accessibility_wallet_button" msgid="1458258783460555507">"Beursie"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"Ontsluit"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Toestel is gesluit"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Wat tans vir vingerafdruk"</string>
@@ -1150,6 +1151,6 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"staaf"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"gaan by toestel in"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Gebruik vingerafdruk om oop te maak"</string>
- <!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
- <skip />
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Stawing word vereis. Raak die vingerafdruksensor om te staaf."</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"Oproep aan die gang"</string>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index ca97b18..c77dd57 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -136,6 +136,7 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"ካሜራ"</string>
<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_lock_icon" msgid="661492842417875775">"መሣሪያ ተቆልፏል"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"የጣት አሻራን በመጠባበቅ ላይ"</string>
@@ -1150,6 +1151,6 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ያረጋግጡ"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"መሣሪያን ያስገቡ"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ለመክፈት የጣት አሻራ ይጠቀሙ"</string>
- <!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
- <skip />
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"ማረጋገጥ ያስፈልጋል። ለማረጋገጥ የጣት አሻራ ዳሳሹን ይንኩ።"</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"በመካሄድ ላይ የስልክ ጥሪ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 9a30ac2c..a3a00ed 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"الكاميرا"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"الهاتف"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"المساعد الصوتي"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1174,6 +1176,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"المصادقة"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"الدخول إلى الجهاز"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"يمكنك استخدام بصمة الإصبع للفتح"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 9d3eaae..0fba949 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"কেমেৰা"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ফ\'ন"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"কণ্ঠধ্বনিৰে সহায়"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -289,11 +291,9 @@
<string name="accessibility_quick_settings_hotspot_changed_off" msgid="7002061268910095176">"ম’বাইল হটস্পট অফ কৰা হ’ল।"</string>
<string name="accessibility_quick_settings_hotspot_changed_on" msgid="2576895346762408840">"ম’বাইল হটস্পট অন কৰা হ’ল।"</string>
<string name="accessibility_casting_turned_off" msgid="1387906158563374962">"স্ক্ৰীণ কাষ্টিং বন্ধ কৰা হ’ল।"</string>
- <!-- no translation found for accessibility_quick_settings_work_mode_off (9106217884005620744) -->
- <skip />
+ <string name="accessibility_quick_settings_work_mode_off" msgid="9106217884005620744">"কৰ্মস্থান ম’ড পজ হৈ আছে।"</string>
<string name="accessibility_quick_settings_work_mode_on" msgid="2779253456042059110">"কৰ্মস্থান ম\'ড অন হৈ আছে।"</string>
- <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (6422896967647049692) -->
- <skip />
+ <string name="accessibility_quick_settings_work_mode_changed_off" msgid="6422896967647049692">"কৰ্মস্থান ম’ড পজ হৈ আছে।"</string>
<string name="accessibility_quick_settings_work_mode_changed_on" msgid="1105258550138313384">"কৰ্মস্থান ম\'ড অন কৰা হ’ল।"</string>
<string name="accessibility_quick_settings_data_saver_changed_off" msgid="4910847127871603832">"ডেটা সঞ্চয়কাৰী সুবিধা অফ কৰা হ’ল।"</string>
<string name="accessibility_quick_settings_data_saver_changed_on" msgid="6370606590802623078">"ডেটা সঞ্চয়কাৰী সুবিধা অন কৰা হ’ল।"</string>
@@ -412,8 +412,7 @@
<string name="quick_settings_cellular_detail_data_limit" msgid="1791389609409211628">"<xliff:g id="DATA_LIMIT">%s</xliff:g> সীমা"</string>
<string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"<xliff:g id="DATA_LIMIT">%s</xliff:g> সকীয়নি"</string>
<string name="quick_settings_work_mode_label" msgid="2754212289804324685">"কৰ্মস্থানৰ প্ৰ\'ফাইল"</string>
- <!-- no translation found for quick_settings_work_mode_paused (4841109346916998613) -->
- <skip />
+ <string name="quick_settings_work_mode_paused" msgid="4841109346916998613">"পজ হৈ আছে"</string>
<string name="quick_settings_night_display_label" msgid="8180030659141778180">"ৰাতিৰ পোহৰ"</string>
<string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"সূৰ্যাস্তত অন কৰক"</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"সূৰ্যোদয়ৰ লৈকে"</string>
@@ -672,12 +671,10 @@
<string name="wallet_title" msgid="5369767670735827105">"ৱালেট"</string>
<string name="wallet_app_button_label" msgid="7123784239111190992">"আটাইবোৰ দেখুৱাওক"</string>
<string name="wallet_action_button_label_unlock" msgid="8663239748726774487">"পৰিশোধ কৰিবলৈ আনলক কৰক"</string>
- <!-- no translation found for wallet_secondary_label_no_card (1282609666895946317) -->
- <skip />
+ <string name="wallet_secondary_label_no_card" msgid="1282609666895946317">"ছেট আপ কৰা হোৱা নাই"</string>
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ব্যৱহাৰ কৰিবলৈ আনলক কৰক"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"আপোনাৰ কাৰ্ড লাভ কৰোঁতে এটা সমস্যা হৈছে, অনুগ্ৰহ কৰি পাছত পুনৰ চেষ্টা কৰক"</string>
- <!-- no translation found for wallet_lockscreen_settings_label (3539105300870383570) -->
- <skip />
+ <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"লক স্ক্ৰীনৰ ছেটিং"</string>
<string name="status_bar_work" msgid="5238641949837091056">"কৰ্মস্থানৰ প্ৰ\'ফাইল"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"এয়াৰপ্লেইন ম\'ড"</string>
<string name="add_tile" msgid="6239678623873086686">"টাইল যোগ দিয়ক"</string>
@@ -867,8 +864,7 @@
<string name="switch_bar_on" msgid="1770868129120096114">"অন"</string>
<string name="switch_bar_off" msgid="5669805115416379556">"অফ"</string>
<string name="tile_unavailable" msgid="3095879009136616920">"উপলব্ধ নহয়"</string>
- <!-- no translation found for tile_disabled (373212051546573069) -->
- <skip />
+ <string name="tile_disabled" msgid="373212051546573069">"অক্ষম কৰা আছে"</string>
<string name="nav_bar" msgid="4642708685386136807">"নেভিগেশ্বন দণ্ড"</string>
<string name="nav_bar_layout" msgid="4716392484772899544">"লেআউট"</string>
<string name="left_nav_bar_button_type" msgid="2634852842345192790">"বাওঁ বুটামৰ অতিৰিক্ত প্ৰকাৰ"</string>
@@ -1156,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"বিশ্বাসযোগ্যতা প্ৰমাণ কৰক"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ডিভাইচ আনলক কৰক"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"খুলিবলৈ ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index f04b5bd..7babf41 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Səs Yardımçısı"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Kiliddən çıxarın"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Cihaz kilidlənib"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Barmaq izi gözlənilir"</string>
@@ -291,8 +293,7 @@
<string name="accessibility_casting_turned_off" msgid="1387906158563374962">"Ekran yayımı dayandırıldı."</string>
<string name="accessibility_quick_settings_work_mode_off" msgid="9106217884005620744">"İş rejiminə pauza verilib."</string>
<string name="accessibility_quick_settings_work_mode_on" msgid="2779253456042059110">"İş rejimi aktivdir."</string>
- <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (6422896967647049692) -->
- <skip />
+ <string name="accessibility_quick_settings_work_mode_changed_off" msgid="6422896967647049692">"İş rejiminə pauza verilib."</string>
<string name="accessibility_quick_settings_work_mode_changed_on" msgid="1105258550138313384">"İş rejimi yanılıdır."</string>
<string name="accessibility_quick_settings_data_saver_changed_off" msgid="4910847127871603832">"Trafikə qənaət edilmir."</string>
<string name="accessibility_quick_settings_data_saver_changed_on" msgid="6370606590802623078">"Trafikə qənaət edilir."</string>
@@ -1151,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"doğrulayın"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"cihaz daxil edin"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Açmaq üçün barmaq izindən istifadə edin"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 0d1a4ad..4451304 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Glasovna pomoć"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Otključajte"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Uređaj je zaključan"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Čeka se otisak prsta"</string>
@@ -1156,6 +1158,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"potvrdite identitet"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"unesite uređaj"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Otvorite pomoću otiska prsta"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index c43ba46..26d4dff6e 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Камера"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Тэлефон"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Галасавая дапамога"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Разблакiраваць"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Прылада заблакіравана"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Чаканне ўводу даных адбітка пальца"</string>
@@ -291,8 +293,7 @@
<string name="accessibility_casting_turned_off" msgid="1387906158563374962">"Трансляцыя экрана спынена."</string>
<string name="accessibility_quick_settings_work_mode_off" msgid="9106217884005620744">"Працоўны рэжым прыпынены."</string>
<string name="accessibility_quick_settings_work_mode_on" msgid="2779253456042059110">"Рэжым працы ўкл."</string>
- <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (6422896967647049692) -->
- <skip />
+ <string name="accessibility_quick_settings_work_mode_changed_off" msgid="6422896967647049692">"Працоўны рэжым прыпынены."</string>
<string name="accessibility_quick_settings_work_mode_changed_on" msgid="1105258550138313384">"Рэжым працы ўключаны."</string>
<string name="accessibility_quick_settings_data_saver_changed_off" msgid="4910847127871603832">"Эканомія трафіка адключана."</string>
<string name="accessibility_quick_settings_data_saver_changed_on" msgid="6370606590802623078">"Эканомія трафіка ўключана."</string>
@@ -1163,6 +1164,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"правесці аўтэнтыфікацыю"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"вызначыць прыладу"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Каб адкрыць, скарыстайце адбітак пальца"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index c80d984..9f4c899 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Камера"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Телефон"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Гласова помощ"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"удостоверяване"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"вход в устройството"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Използвайте отпечатък за отваряне"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index ee87769..66c03b2 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"ক্যামেরা"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ফোন"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ভয়েস সহায়তা"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -289,8 +291,7 @@
<string name="accessibility_quick_settings_hotspot_changed_off" msgid="7002061268910095176">"মোবাইল হটস্পট বন্ধ হয়েছে।"</string>
<string name="accessibility_quick_settings_hotspot_changed_on" msgid="2576895346762408840">"মোবাইল হটস্পট চালু হয়েছে।"</string>
<string name="accessibility_casting_turned_off" msgid="1387906158563374962">"স্ক্রিন কাস্ট করা থেমেছে।"</string>
- <!-- no translation found for accessibility_quick_settings_work_mode_off (9106217884005620744) -->
- <skip />
+ <string name="accessibility_quick_settings_work_mode_off" msgid="9106217884005620744">"\'অফিস\' মোড পজ করা আছে।"</string>
<string name="accessibility_quick_settings_work_mode_on" msgid="2779253456042059110">"কাজের মোড চালু আছে"</string>
<!-- no translation found for accessibility_quick_settings_work_mode_changed_off (6422896967647049692) -->
<skip />
@@ -412,8 +413,7 @@
<string name="quick_settings_cellular_detail_data_limit" msgid="1791389609409211628">"সীমা <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"<xliff:g id="DATA_LIMIT">%s</xliff:g> সতর্কতা"</string>
<string name="quick_settings_work_mode_label" msgid="2754212289804324685">"কাজের প্রোফাইল"</string>
- <!-- no translation found for quick_settings_work_mode_paused (4841109346916998613) -->
- <skip />
+ <string name="quick_settings_work_mode_paused" msgid="4841109346916998613">"পজ করা আছে"</string>
<string name="quick_settings_night_display_label" msgid="8180030659141778180">"নাইট লাইট"</string>
<string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"সূর্যাস্তে চালু হবে"</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"সূর্যোদয় পর্যন্ত"</string>
@@ -672,12 +672,10 @@
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
<string name="wallet_app_button_label" msgid="7123784239111190992">"সবকটি দেখুন"</string>
<string name="wallet_action_button_label_unlock" msgid="8663239748726774487">"পেমেন্ট করতে ডিভাইস আনলক করুন"</string>
- <!-- no translation found for wallet_secondary_label_no_card (1282609666895946317) -->
- <skip />
+ <string name="wallet_secondary_label_no_card" msgid="1282609666895946317">"সেট আপ করা নেই"</string>
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ব্যবহার করতে আনলক করুন"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"আপনার কার্ড সংক্রান্ত তথ্য পেতে সমস্যা হয়েছে, পরে আবার চেষ্টা করুন"</string>
- <!-- no translation found for wallet_lockscreen_settings_label (3539105300870383570) -->
- <skip />
+ <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"লক স্ক্রিন সেটিংস"</string>
<string name="status_bar_work" msgid="5238641949837091056">"কাজের প্রোফাইল"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"বিমান মোড"</string>
<string name="add_tile" msgid="6239678623873086686">"টাইল যোগ করুন"</string>
@@ -867,8 +865,7 @@
<string name="switch_bar_on" msgid="1770868129120096114">"চালু আছে"</string>
<string name="switch_bar_off" msgid="5669805115416379556">"বন্ধ আছে"</string>
<string name="tile_unavailable" msgid="3095879009136616920">"উপলভ্য নয়"</string>
- <!-- no translation found for tile_disabled (373212051546573069) -->
- <skip />
+ <string name="tile_disabled" msgid="373212051546573069">"বন্ধ করা আছে"</string>
<string name="nav_bar" msgid="4642708685386136807">"নেভিগেশন বার"</string>
<string name="nav_bar_layout" msgid="4716392484772899544">"লেআউট"</string>
<string name="left_nav_bar_button_type" msgid="2634852842345192790">"অতিরিক্ত বাঁদিকের বোতামের ধরণ"</string>
@@ -1156,6 +1153,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"যাচাই করিয়ে নিন"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ডিভাইস আনলক করুন"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"খুলতে ফিঙ্গারপ্রিন্ট ব্যবহার করুন"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index e1ca309..e536e67 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Glasovna pomoć"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Otključaj"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Uređaj je zaključan"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Čeka se otisak prsta"</string>
@@ -1156,6 +1158,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentificiranje"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"pristup uređaju"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Otvorite pomoću otiska prsta"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index a39bf49..ec2a0a0 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Càmera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telèfon"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Assistència per veu"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Desbloqueja"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositiu bloquejat"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"S\'està esperant l\'empremta digital"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"accedir al dispositiu"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Utilitza l\'empremta digital per obrir"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 4868a03..db334f2 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Fotoaparát"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Hlasová asistence"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Odemknout"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Zařízení uzamčeno"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Čeká se na použití otisku"</string>
@@ -1162,6 +1164,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ověříte"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"zadáte zařízení"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"K otevření použijte otisk prstu"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index ddcd5486..de4deff 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Taleassistent"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Lås op"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Enheden er låst"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Venter på fingeraftryk"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"godkende"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"få adgang til enheden"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Brug fingeraftryk for at åbne"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 150bc25..e6334e0 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefonnummer"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Sprachassistent"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Entsperren"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Gerät gesperrt"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Auf Fingerabdruck wird gewartet"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"Authentifizieren"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"Eingeben des Geräts"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Mit Fingerabdruck öffnen"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 4403f2d..8bc1765 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Φωτογραφική μηχανή"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Τηλέφωνο"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Φωνητική υποβοήθηση"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"έλεγχος ταυτότητας"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"εισαγωγή συσκευής"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Χρήση δακτυλικού αποτυπώματος για άνοιγμα"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index f83468d..428a565 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -136,6 +136,7 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Camera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Phone"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Voice Assist"</string>
+ <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"Unlock"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Waiting for fingerprint"</string>
@@ -1150,6 +1151,6 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"Authenticate"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Use fingerprint to open"</string>
- <!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
- <skip />
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Authentication required. Touch the fingerprint sensor to authenticate."</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"Ongoing phone call"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index a7edecc..99ec519 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -136,6 +136,7 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Camera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Phone"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Voice Assist"</string>
+ <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"Unlock"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Waiting for fingerprint"</string>
@@ -1150,6 +1151,6 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"Authenticate"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Use fingerprint to open"</string>
- <!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
- <skip />
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Authentication required. Touch the fingerprint sensor to authenticate."</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"Ongoing phone call"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index f83468d..428a565 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -136,6 +136,7 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Camera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Phone"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Voice Assist"</string>
+ <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"Unlock"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Waiting for fingerprint"</string>
@@ -1150,6 +1151,6 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"Authenticate"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Use fingerprint to open"</string>
- <!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
- <skip />
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Authentication required. Touch the fingerprint sensor to authenticate."</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"Ongoing phone call"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index f83468d..428a565 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -136,6 +136,7 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Camera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Phone"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Voice Assist"</string>
+ <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"Unlock"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Waiting for fingerprint"</string>
@@ -1150,6 +1151,6 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"Authenticate"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Use fingerprint to open"</string>
- <!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
- <skip />
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Authentication required. Touch the fingerprint sensor to authenticate."</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"Ongoing phone call"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 1b34a61..11e32a759 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -136,6 +136,7 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Camera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Phone"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Voice Assist"</string>
+ <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"Unlock"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Waiting for fingerprint"</string>
@@ -1150,6 +1151,6 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"authenticate"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Use fingerprint to open"</string>
- <!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
- <skip />
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Authentication required. Touch the fingerprint sensor to authenticate."</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"Ongoing phone call"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 31b25b3..1b0e816 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -136,6 +136,7 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Cámara"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Teléfono"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Asistente voz"</string>
+ <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"Desbloquear"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Esperando huella dactilar"</string>
@@ -1150,6 +1151,6 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ingresar al dispositivo"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Usa la huella dactilar para abrir"</string>
- <!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
- <skip />
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Se requiere de una autenticación. Toca el sensor de huellas dactilares para autenticarte."</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"Llamada en curso"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 1f22cbd..33a8660 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Cámara"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Teléfono"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Asistente voz"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Desbloquear"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Esperando huella digital"</string>
@@ -1001,7 +1003,7 @@
<string name="auto_saver_enabled_text" msgid="7889491183116752719">"El modo Ahorro de batería se activará automáticamente cuando quede menos de un <xliff:g id="PERCENTAGE">%d</xliff:g> %% de batería."</string>
<string name="open_saver_setting_action" msgid="2111461909782935190">"Ajustes"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Entendido"</string>
- <string name="heap_dump_tile_name" msgid="2464189856478823046">"Volcar pila de SysUI"</string>
+ <string name="heap_dump_tile_name" msgid="2464189856478823046">"Volcar montículo de SysUI"</string>
<string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> está usando tu <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Hay aplicaciones que usan tu <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
@@ -1120,7 +1122,7 @@
<string name="timestamp" msgid="6577851592534538533">"Hace <xliff:g id="DURATION">%1$s</xliff:g>"</string>
<string name="less_than_timestamp" msgid="6598972791137724517">"Hace menos de <xliff:g id="DURATION">%1$s</xliff:g>"</string>
<string name="over_timestamp" msgid="4765793502859358634">"Hace más de <xliff:g id="DURATION">%1$s</xliff:g>"</string>
- <string name="birthday_status" msgid="2596961629465396761">"Fecha de nacimiento"</string>
+ <string name="birthday_status" msgid="2596961629465396761">"Cumpleaños"</string>
<string name="birthday_status_content_description" msgid="682836371128282925">"Es el cumpleaños de <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="upcoming_birthday_status" msgid="2005452239256870351">"Cumpleaños en breve"</string>
<string name="upcoming_birthday_status_content_description" msgid="2165036816803797148">"Se acerca el cumpleaños de <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -1134,7 +1136,7 @@
<string name="audio_status" msgid="4237055636967709208">"Escuchando"</string>
<string name="game_status" msgid="1340694320630973259">"Reproduciendo"</string>
<string name="empty_user_name" msgid="3389155775773578300">"Amigos"</string>
- <string name="empty_status" msgid="5938893404951307749">"Charlemos esta noche"</string>
+ <string name="empty_status" msgid="5938893404951307749">"¿Hablamos luego?"</string>
<string name="status_before_loading" msgid="1500477307859631381">"El contenido se mostrará en breve"</string>
<string name="missed_call" msgid="4228016077700161689">"Llamada perdida"</string>
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticarte"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"acceder al dispositivo"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Usa la huella digital para abrir"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 80071ae..3d3a09b 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Kaamera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Häälabi"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Luku avamine"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Seade on lukustatud"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Sõrmejälje ootel"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentimiseks"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"seadmesse sisenemiseks"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Kasutage avamiseks sõrmejälge"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 3173ec6..eb2bde3 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefonoa"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Ahots-laguntza"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Desblokeatu"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Gailua blokeatuta dago"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Hatz-markaren zain"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentifikatu"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"sartu gailuan"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Erabili hatz-marka irekitzeko"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index b8dfb0b..aacf905 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -136,6 +136,7 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"دوربین"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"تلفن"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"دستیار صوتی"</string>
+ <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</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>
@@ -1150,6 +1151,6 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"اصالتسنجی کردن"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"وارد شدن به دستگاه"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"از اثر انگشت برای باز کردن قفل استفاده کنید"</string>
- <!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
- <skip />
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"اصالتسنجی لازم است. برای اصالتسنجی، حسگر اثر انگشت را لمس کنید."</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"تماس تلفنی درحال انجام"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index bbe32dd..674a4be 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Puhelin"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Ääniapuri"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Avaa lukitus"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Laite lukittu"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Odotetaan sormenjälkeä"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"todentaaksesi"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"avataksesi laitteen"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Avaa sormenjäljellä"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 912e2a1..7bc9db9 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Appareil photo"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Téléphone"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Assistance vocale"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Déverrouiller"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Appareil verrouillé"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"En attente de l\'empreinte digitale"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"authentifier"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"accéder à l\'appareil"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Servez-vous de votre empreinte digitale pour ouvrir"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index d055197..d7adaba 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Appareil photo"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Téléphoner"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Assistance vocale"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Déverrouiller"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Appareil verrouillé"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Attente de l\'empreinte digitale"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"s\'authentifier"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"accéder à l\'appareil"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Utilisez votre empreinte pour ouvrir"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 9147329..851c79a 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Cámara"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Teléfono"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Asistente de voz"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Desbloquear"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Agardando pola impresión dixital"</string>
@@ -291,8 +293,7 @@
<string name="accessibility_casting_turned_off" msgid="1387906158563374962">"Detívose a emisión en pantalla."</string>
<string name="accessibility_quick_settings_work_mode_off" msgid="9106217884005620744">"Púxose en pausa o modo de traballo."</string>
<string name="accessibility_quick_settings_work_mode_on" msgid="2779253456042059110">"Modo de traballo activado."</string>
- <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (6422896967647049692) -->
- <skip />
+ <string name="accessibility_quick_settings_work_mode_changed_off" msgid="6422896967647049692">"Púxose en pausa o modo de traballo."</string>
<string name="accessibility_quick_settings_work_mode_changed_on" msgid="1105258550138313384">"Activouse o modo de traballo."</string>
<string name="accessibility_quick_settings_data_saver_changed_off" msgid="4910847127871603832">"Desactivouse o aforro de datos."</string>
<string name="accessibility_quick_settings_data_saver_changed_on" msgid="6370606590802623078">"Activouse o aforro de datos."</string>
@@ -1151,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"poñer o dispositivo"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Usa a impresión dixital para abrir"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 3ea9ebc..167817c 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"કૅમેરો"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ફોન"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"વૉઇસ સહાય"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -473,14 +475,10 @@
<string name="interruption_level_none_twoline" msgid="8579382742855486372">"સાવ\nશાંતિ"</string>
<string name="interruption_level_priority_twoline" msgid="8523482736582498083">"ફક્ત\nપ્રાધાન્યતા"</string>
<string name="interruption_level_alarms_twoline" msgid="2045067991335708767">"ફક્ત\nએલાર્મ્સ"</string>
- <!-- no translation found for keyguard_indication_charging_time_wireless (577856646141738675) -->
- <skip />
- <!-- no translation found for keyguard_indication_charging_time (6492711711891071502) -->
- <skip />
- <!-- no translation found for keyguard_indication_charging_time_fast (8390311020603859480) -->
- <skip />
- <!-- no translation found for keyguard_indication_charging_time_slowly (301936949731705417) -->
- <skip />
+ <string name="keyguard_indication_charging_time_wireless" msgid="577856646141738675">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • વાયરલેસથી ચાર્જ થઈ રહ્યું છે • <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> • ચાર્જ થઈ રહ્યું છે • <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> • ઝડપથી ચાર્જ થઈ રહ્યું છે • <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> • ધીમેથી ચાર્જ થઈ રહ્યું છે • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>માં ચાર્જ થઈ જશે"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"વપરાશકર્તા સ્વિચ કરો"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="5759855008166759399">"વપરાશકર્તાને સ્વિચ કરો, વર્તમાન વપરાશકર્તા <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="383168614528618402">"વર્તમાન વપરાશકર્તા <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -1160,6 +1158,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ખાતરી કરો"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ડિવાઇસ અનલૉક કરો"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ખોલવા માટે ફિંગરપ્રિન્ટનો ઉપયોગ કરો"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index ae9a841..1160b9f 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"कैमरा"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"फ़ोन"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"आवाज़ से डिवाइस का इस्तेमाल"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"पुष्टि करें"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"डिवाइस की होम स्क्रीन पर जाएं"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"खोलने के लिए, फ़िंगरप्रिंट का इस्तेमाल करें"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 768b995..672b7db 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Fotoaparat"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Glasovna pomoć"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Otključavanje"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Uređaj je zaključan"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Čekanje na otisak prsta"</string>
@@ -1156,6 +1158,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentificirali"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"pristupili uređaju"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Otvorite pomoću otiska prsta"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 6a64eff..b17d040 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Hangsegéd"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Feloldás"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Az eszköz zárolva van"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Várakozás az ujjlenyomatra"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"a hitelesítéshez"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"eszköz megadásához"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Ujjlenyomat használata a megnyitáshoz"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index ba8f838..61ed6e6 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Տեսախցիկ"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Հեռախոս"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Ձայնային հուշումներ"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1113,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="7362374212649891057">"Վերադարձեք այստեղ, երբ հաղորդագրություններ ստանաք"</string>
<string name="priority_conversations" msgid="3967482288896653039">"Կարևոր զրույցներ"</string>
<string name="recent_conversations" msgid="8531874684782574622">"Վերջին հաղորդագրությունները"</string>
<string name="okay" msgid="6490552955618608554">"Եղավ"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"նույնականացնել"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"նշել սարքը"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Բացելու համար օգտագործեք մատնահետքը"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index b8abad2..880ca64 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telepon"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Bantuan Suara"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Buka kunci"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Perangkat terkunci"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Menunggu sidik jari"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentikasi"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"masukkan perangkat"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Gunakan sidik jari untuk membuka"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index afd4c05..eb7e4ec 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Myndavél"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Sími"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Raddaðstoð"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Taka úr lás"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Tækið er læst"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Bíður eftir fingrafari"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"auðkenna"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"opna tæki"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Opna með fingrafari"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 5ce8293..600d8b7 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -136,6 +136,7 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Fotocamera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefono"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Voice Assist"</string>
+ <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"Sblocca"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloccato"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"In attesa dell\'impronta"</string>
@@ -1150,6 +1151,6 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"effettuare l\'autenticazione"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"accedere al dispositivo"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Usa l\'impronta per aprire"</string>
- <!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
- <skip />
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autenticazione obbligatoria. Eseguila toccando il sensore di impronte digitali."</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"Telefonata in corso"</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index f14c95a..c9be358 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -136,6 +136,7 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"מצלמה"</string>
<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_lock_icon" msgid="661492842417875775">"המכשיר נעול"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"בהמתנה לטביעת אצבע"</string>
@@ -1162,6 +1163,6 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"אימות"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"הזנת מכשיר"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"שימוש בטביעת אצבע כדי לפתוח"</string>
- <!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
- <skip />
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"נדרש אימות. יש לגעת בחיישן טביעות האצבע כדי לבצע אימות."</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"מתקיימת שיחה"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 9ffc010..6465b44 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"カメラ"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"電話"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"音声アシスト"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"認証"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"デバイスを入力"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"指紋を使って開いてください"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index afcd219..63205e3 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -136,6 +136,7 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"კამერა"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ტელეფონი"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ხმოვანი დახმარება"</string>
+ <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</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>
@@ -1117,9 +1118,9 @@
<string name="priority_conversations" msgid="3967482288896653039">"პრიორიტეტული საუბრები"</string>
<string name="recent_conversations" msgid="8531874684782574622">"ბოლო მიმოწერები"</string>
<string name="okay" msgid="6490552955618608554">"კარგი"</string>
- <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g>-ს წინ"</string>
+ <string name="timestamp" msgid="6577851592534538533">"<xliff:g id="DURATION">%1$s</xliff:g>ს წინ"</string>
<string name="less_than_timestamp" msgid="6598972791137724517">"<xliff:g id="DURATION">%1$s</xliff:g>-ზე ნაკლები ხნის წინ"</string>
- <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g>-ზე მეტი ხნის წინ"</string>
+ <string name="over_timestamp" msgid="4765793502859358634">"<xliff:g id="DURATION">%1$s</xliff:g>ზე მეტი ხნის წინ"</string>
<string name="birthday_status" msgid="2596961629465396761">"დაბადების დღე"</string>
<string name="birthday_status_content_description" msgid="682836371128282925">"<xliff:g id="NAME">%1$s</xliff:g> დღეს იუბილარია"</string>
<string name="upcoming_birthday_status" msgid="2005452239256870351">"მალე დაბადების დღეა"</string>
@@ -1150,6 +1151,6 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ავტორიზაცია"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"მოწყობილობის შეყვანა"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"გასახსნელად გამოიყენეთ თითის ანაბეჭდი"</string>
- <!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
- <skip />
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"საჭიროა ავტორიზაცია. ავტორიზაციისთვის შეეხეთ თითის ანაბეჭდის სენსორს."</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"მიმდინარე სატელეფონო ზარი"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index d6e403d..bb5d51f 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Камера"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Телефон"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Дауыс көмекшісі"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -291,8 +293,7 @@
<string name="accessibility_casting_turned_off" msgid="1387906158563374962">"Экранды трансляциялау тоқтатылды."</string>
<string name="accessibility_quick_settings_work_mode_off" msgid="9106217884005620744">"Жұмыс режимі кідіртілді."</string>
<string name="accessibility_quick_settings_work_mode_on" msgid="2779253456042059110">"Жұмыс режимі қосулы."</string>
- <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (6422896967647049692) -->
- <skip />
+ <string name="accessibility_quick_settings_work_mode_changed_off" msgid="6422896967647049692">"Жұмыс режимі кідіртілді."</string>
<string name="accessibility_quick_settings_work_mode_changed_on" msgid="1105258550138313384">"Жұмыс режимі қосылды."</string>
<string name="accessibility_quick_settings_data_saver_changed_off" msgid="4910847127871603832">"Трафикті үнемдеу режимі өшірілді."</string>
<string name="accessibility_quick_settings_data_saver_changed_on" msgid="6370606590802623078">"Трафикті үнемдеу режимі қосылды."</string>
@@ -1151,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"аутентификациялау"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"құрылғыны енгізу"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Ашу үшін саусақ ізін пайдаланыңыз."</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index a15ab8b..ed7bbe9 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"ម៉ាស៊ីនថត"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ទូរសព្ទ"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ជំនួយសំឡេង"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ផ្ទៀងផ្ទាត់"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"បញ្ចូលឧបករណ៍"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ប្រើស្នាមម្រាមដៃ ដើម្បីបើក"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 418130a..cef9e3f 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"ಕ್ಯಾಮರಾ"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ಫೋನ್"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ಧ್ವನಿ ಸಹಾಯಕ"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -291,8 +293,7 @@
<string name="accessibility_casting_turned_off" msgid="1387906158563374962">"ಸ್ಕ್ರೀನ್ ಪ್ರಸಾರವನ್ನು ನಿಲ್ಲಿಸಲಾಗಿದೆ."</string>
<string name="accessibility_quick_settings_work_mode_off" msgid="9106217884005620744">"ಕೆಲಸದ ಮೋಡ್ ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ."</string>
<string name="accessibility_quick_settings_work_mode_on" msgid="2779253456042059110">"ಕೆಲಸದ ಮೋಡ್ ಆನ್ ಆಗಿದೆ."</string>
- <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (6422896967647049692) -->
- <skip />
+ <string name="accessibility_quick_settings_work_mode_changed_off" msgid="6422896967647049692">"ಕೆಲಸದ ಮೋಡ್ ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ."</string>
<string name="accessibility_quick_settings_work_mode_changed_on" msgid="1105258550138313384">"ಕೆಲಸದ ಮೋಡ್ ಆನ್ ಮಾಡಲಾಗಿದೆ."</string>
<string name="accessibility_quick_settings_data_saver_changed_off" msgid="4910847127871603832">"ಡೇಟಾ ಸೇವರ್ ಆಫ್ ಮಾಡಲಾಗಿದೆ."</string>
<string name="accessibility_quick_settings_data_saver_changed_on" msgid="6370606590802623078">"ಡೇಟಾ ಸೇವರ್ ಆನ್ ಮಾಡಲಾಗಿದೆ."</string>
@@ -1151,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ದೃಢೀಕರಿಸಿ"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ಸಾಧನವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ತೆರೆಯುವುದಕ್ಕಾಗಿ ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಅನ್ನು ಬಳಸಿ"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 2137478..ea45bd9 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"카메라"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"전화"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"음성 지원"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1134,7 +1136,7 @@
<string name="audio_status" msgid="4237055636967709208">"듣는 중"</string>
<string name="game_status" msgid="1340694320630973259">"플레이 중"</string>
<string name="empty_user_name" msgid="3389155775773578300">"친구"</string>
- <string name="empty_status" msgid="5938893404951307749">"오늘 밤에 채팅"</string>
+ <string name="empty_status" msgid="5938893404951307749">"오늘 밤에 채팅하자!"</string>
<string name="status_before_loading" msgid="1500477307859631381">"곧 콘텐츠가 표시됩니다."</string>
<string name="missed_call" msgid="4228016077700161689">"부재중 전화"</string>
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"인증"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"기기 입력"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"지문으로 열기"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 66e6ab0..d2db2c3 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Камера"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Телефон"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Үн жардамчысы"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -291,8 +293,7 @@
<string name="accessibility_casting_turned_off" msgid="1387906158563374962">"Тышкы экранга чыгаруу аракети токтотулду."</string>
<string name="accessibility_quick_settings_work_mode_off" msgid="9106217884005620744">"Иштөө режими тындырылган."</string>
<string name="accessibility_quick_settings_work_mode_on" msgid="2779253456042059110">"Иштөө режими күйүк."</string>
- <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (6422896967647049692) -->
- <skip />
+ <string name="accessibility_quick_settings_work_mode_changed_off" msgid="6422896967647049692">"Иштөө режими тындырылган."</string>
<string name="accessibility_quick_settings_work_mode_changed_on" msgid="1105258550138313384">"Иштөө режими күйгүзүлдү."</string>
<string name="accessibility_quick_settings_data_saver_changed_off" msgid="4910847127871603832">"Трафикти үнөмдөө режими өчүрүлдү."</string>
<string name="accessibility_quick_settings_data_saver_changed_on" msgid="6370606590802623078">"Трафикти үнөмдөө режими күйгүзүлдү."</string>
@@ -1151,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"аныктыгын текшерүү"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"түзмөккө кирүү"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Манжаңыздын изи менен ачыңыз"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index f9ac214..c162c54 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"ກ້ອງ"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ໂທລະສັບ"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ຊ່ວຍເຫຼືອທາງສຽງ"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ພິສູດຢືນຢັນ"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ເຂົ້າອຸປະກອນ"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ໃຊ້ລາຍນິ້ວມືເພື່ອເປີດ"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index a87a927..3a9ccf0 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Fotoaparatas"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefonas"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Voice Assist"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Atrakinti"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Įrenginys užrakintas"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Laukiama piršto antspaudo"</string>
@@ -1162,6 +1164,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"nustatytumėte tapatybę"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"pasiektumėte įrenginį"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Naudokite kontrolinį kodą, kad atidarytumėte"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index c1a3d60..c583cba 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Tālruņa numurs"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Balss palīgs"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Atbloķēt"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Ierīce ir bloķēta"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Tiek gaidīts pirksta nospiedums."</string>
@@ -1156,6 +1158,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"veiktu autentificēšanu"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"izmantotu ierīci"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Atvēršanai izmantojiet pirksta nospiedumu"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 198e733..d306e1f 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Камера"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Телефон"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Гласовна помош"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"автентицирате"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"внесете уред"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Користете отпечаток за да се отвори"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 3e5b91d..750d834 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"ക്യാമറ"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ഫോണ്"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"വോയ്സ് സഹായം"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1151,6 +1153,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"പരിശോധിച്ചുറപ്പിക്കുക"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ഉപകരണം നൽകുക"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"തുറക്കുന്നതിന് നിങ്ങളുടെ ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കുക"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index ea769ce..583b083 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Камер"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Утас"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Дуут туслах"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"баталгаажуулах"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"төхөөрөмж оруулах"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Нээхийн тулд хурууны хээг ашиглана уу"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index f20d336..8fe5af0 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"कॅमेरा"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"फोन"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"व्हॉइस सहाय्य"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -289,8 +291,7 @@
<string name="accessibility_quick_settings_hotspot_changed_off" msgid="7002061268910095176">"मोबाइल हॉटस्पॉट बंद केला."</string>
<string name="accessibility_quick_settings_hotspot_changed_on" msgid="2576895346762408840">"मोबाइल हॉटस्पॉट सुरू केला."</string>
<string name="accessibility_casting_turned_off" msgid="1387906158563374962">"स्क्रीन कास्ट करणे थांबले."</string>
- <!-- no translation found for accessibility_quick_settings_work_mode_off (9106217884005620744) -->
- <skip />
+ <string name="accessibility_quick_settings_work_mode_off" msgid="9106217884005620744">"कार्य मोड थांबवला."</string>
<string name="accessibility_quick_settings_work_mode_on" msgid="2779253456042059110">"कार्य मोड सुरू."</string>
<!-- no translation found for accessibility_quick_settings_work_mode_changed_off (6422896967647049692) -->
<skip />
@@ -412,8 +413,7 @@
<string name="quick_settings_cellular_detail_data_limit" msgid="1791389609409211628">"<xliff:g id="DATA_LIMIT">%s</xliff:g> मर्यादा"</string>
<string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"<xliff:g id="DATA_LIMIT">%s</xliff:g> चेतावणी"</string>
<string name="quick_settings_work_mode_label" msgid="2754212289804324685">"कार्य प्रोफाइल"</string>
- <!-- no translation found for quick_settings_work_mode_paused (4841109346916998613) -->
- <skip />
+ <string name="quick_settings_work_mode_paused" msgid="4841109346916998613">"थाबंवला"</string>
<string name="quick_settings_night_display_label" msgid="8180030659141778180">"रात्रीचा प्रकाश"</string>
<string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"संध्याकाळी सुरू असते"</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"सूर्योदयापर्यंत"</string>
@@ -672,12 +672,10 @@
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
<string name="wallet_app_button_label" msgid="7123784239111190992">"सर्व दाखवा"</string>
<string name="wallet_action_button_label_unlock" msgid="8663239748726774487">"पैसे देण्यासाठी अनलॉक करा"</string>
- <!-- no translation found for wallet_secondary_label_no_card (1282609666895946317) -->
- <skip />
+ <string name="wallet_secondary_label_no_card" msgid="1282609666895946317">"सेट केलेले नाही"</string>
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"वापरण्यासाठी अनलॉक करा"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"तुमची कार्ड मिळवताना समस्या आली, कृपया नंतर पुन्हा प्रयत्न करा"</string>
- <!-- no translation found for wallet_lockscreen_settings_label (3539105300870383570) -->
- <skip />
+ <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"लॉक स्क्रीन सेटिंग्ज"</string>
<string name="status_bar_work" msgid="5238641949837091056">"कार्य प्रोफाईल"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"विमान मोड"</string>
<string name="add_tile" msgid="6239678623873086686">"टाइल जोडा"</string>
@@ -867,8 +865,7 @@
<string name="switch_bar_on" msgid="1770868129120096114">"सुरू"</string>
<string name="switch_bar_off" msgid="5669805115416379556">"बंद"</string>
<string name="tile_unavailable" msgid="3095879009136616920">"उपलब्ध नाही"</string>
- <!-- no translation found for tile_disabled (373212051546573069) -->
- <skip />
+ <string name="tile_disabled" msgid="373212051546573069">"बंद केली"</string>
<string name="nav_bar" msgid="4642708685386136807">"नॅव्हिगेशन बार"</string>
<string name="nav_bar_layout" msgid="4716392484772899544">"लेआउट"</string>
<string name="left_nav_bar_button_type" msgid="2634852842345192790">"अतिरिक्त डाव्या बटणाचा प्रकार"</string>
@@ -1156,6 +1153,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ऑथेंटिकेट करा"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"डिव्हाइस एंटर करा"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"उघडण्यासाठी फिंगरप्रिंट वापरा"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index c721ba5..791863a 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Bantuan Suara"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Buka kunci"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Peranti dikunci"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Menunggu cap jari"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"sahkan"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"akses peranti"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Gunakan cap jari untuk membuka"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index e565c7d..769c962 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"ကင်မရာ"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ဖုန်း"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"အသံ အကူအညီ"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"အထောက်အထားစိစစ်ရန်"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"စက်ပစ္စည်းသို့ ဝင်ရန်"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ဖွင့်ရန် လက်ဗွေကို သုံးပါ"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 3700d04..c0aefb0 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -136,6 +136,7 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefonnummer"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Talehjelp"</string>
+ <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"Lås opp"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Enheten er låst"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Venger på fingeravtrykk"</string>
@@ -1150,6 +1151,6 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentiser"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"åpne enheten"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Bruk fingeravtrykk for å åpne"</string>
- <!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
- <skip />
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autentisering kreves. Trykk på fingeravtrykkssensoren for å autentisere."</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"Pågående telefonsamtale"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index b0afbcc..de375d3 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"क्यामेरा"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"फोन"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"आवाज सहायता"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -471,14 +473,10 @@
<string name="interruption_level_none_twoline" msgid="8579382742855486372">"पूरै\nशान्त"</string>
<string name="interruption_level_priority_twoline" msgid="8523482736582498083">"प्राथमिकता \nमात्र"</string>
<string name="interruption_level_alarms_twoline" msgid="2045067991335708767">"अलार्महरू \nमात्र"</string>
- <!-- no translation found for keyguard_indication_charging_time_wireless (577856646141738675) -->
- <skip />
- <!-- no translation found for keyguard_indication_charging_time (6492711711891071502) -->
- <skip />
- <!-- no translation found for keyguard_indication_charging_time_fast (8390311020603859480) -->
- <skip />
- <!-- no translation found for keyguard_indication_charging_time_slowly (301936949731705417) -->
- <skip />
+ <string name="keyguard_indication_charging_time_wireless" msgid="577856646141738675">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • तारविनै चार्ज हुँदै छ • <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> • चार्ज हुँदै छ • <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> • छिटो चार्ज हुँदै छ • <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> • बिस्तारै चार्ज हुँदै छ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> मा पूरै चार्ज हुन्छ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"प्रयोगकर्ता फेर्नुहोस्"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="5759855008166759399">"प्रयोगकर्ता, हालको प्रयोगकर्ता <xliff:g id="CURRENT_USER_NAME">%s</xliff:g> मा स्विच गर्नुहोस्"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="383168614528618402">"हालको प्रयोगकर्ता <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -1155,6 +1153,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"प्रमाणित गर्नुहोस्"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"डिभाइस हाल्नुहोस्"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"फिंगरप्रिन्ट प्रयोग गरी खोल्नुहोस्"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index bd8e8ca..52b58b8 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Camera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefoon"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Spraakassistent"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Ontgrendelen"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Apparaat vergrendeld"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Wachten op vingerafdruk"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"verifiëren"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"apparaat opgeven"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Gebruik vingerafdruk om te openen"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 3181a9a..20a66b3 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"କ୍ୟାମେରା"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ଫୋନ୍"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ଭଏସ୍ ସହାୟକ"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ପ୍ରମାଣୀକରଣ କରନ୍ତୁ"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ଡିଭାଇସ୍ ବିଷୟରେ ସୂଚନା ଲେଖନ୍ତୁ"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ଖୋଲିବାକୁ ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 15a3f1a..df2caea 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"ਕੈਮਰਾ"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ਫ਼ੋਨ ਕਰੋ"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ਅਵਾਜ਼ੀ ਸਹਾਇਕ"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -291,8 +293,7 @@
<string name="accessibility_casting_turned_off" msgid="1387906158563374962">"ਸਕ੍ਰੀਨ ਜੋੜਨਾ ਬੰਦ ਹੋਇਆ।"</string>
<string name="accessibility_quick_settings_work_mode_off" msgid="9106217884005620744">"ਕਾਰਜ ਮੋਡ ਰੁਕਿਆ ਹੋਇਆ ਹੈ।"</string>
<string name="accessibility_quick_settings_work_mode_on" msgid="2779253456042059110">"ਕੰਮ ਮੋਡ ਚਾਲੂ ਹੈ।"</string>
- <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (6422896967647049692) -->
- <skip />
+ <string name="accessibility_quick_settings_work_mode_changed_off" msgid="6422896967647049692">"ਕਾਰਜ ਮੋਡ ਰੁਕਿਆ ਹੋਇਆ ਹੈ।"</string>
<string name="accessibility_quick_settings_work_mode_changed_on" msgid="1105258550138313384">"ਕੰਮ ਮੋਡ ਚਾਲੂ ਕੀਤਾ ਗਿਆ।"</string>
<string name="accessibility_quick_settings_data_saver_changed_off" msgid="4910847127871603832">"ਡਾਟਾ ਸੇਵਰ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string>
<string name="accessibility_quick_settings_data_saver_changed_on" msgid="6370606590802623078">"ਡਾਟਾ ਸੇਵਰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ।"</string>
@@ -1151,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ਪ੍ਰਮਾਣਿਤ ਕਰੋ"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ਡੀਵਾਈਸ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ਖੋਲ੍ਹਣ ਲਈ ਫਿੰਗਰਪ੍ਰਿੰਟ ਵਰਤੋ"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index e035932..1a9c868 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Aparat"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Asystent głosowy"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Odblokuj"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Urządzenie zablokowane"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Czekam na odcisk palca"</string>
@@ -1162,6 +1164,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"uwierzytelnij"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"otwórz urządzenie"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"By otworzyć, użyj odcisku palca"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index e2a27f6..fa10f0f 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -136,6 +136,7 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Câmera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefone"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Assistência de voz"</string>
+ <string name="accessibility_wallet_button" msgid="1458258783460555507">"Carteira"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"Desbloquear"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Aguardando impressão digital"</string>
@@ -1150,6 +1151,6 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"acessar o dispositivo"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Use a impressão digital para abrir"</string>
- <!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
- <skip />
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autenticação obrigatória. Toque no sensor de impressão digital para autenticar."</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"Chamada em andamento"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index c93170c..1723de6 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Câmara"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telemóvel"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Assistente de voz"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Desbloquear"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"A aguardar a impressão digital…"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"entrar no dispositivo"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Utilize a impressão digital para abrir"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index e2a27f6..fa10f0f 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -136,6 +136,7 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Câmera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefone"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Assistência de voz"</string>
+ <string name="accessibility_wallet_button" msgid="1458258783460555507">"Carteira"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"Desbloquear"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Aguardando impressão digital"</string>
@@ -1150,6 +1151,6 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"acessar o dispositivo"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Use a impressão digital para abrir"</string>
- <!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
- <skip />
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autenticação obrigatória. Toque no sensor de impressão digital para autenticar."</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"Chamada em andamento"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 735ae55..1fb5514 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Cameră foto"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Asistent vocal"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Deblocați"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispozitiv blocat"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Se așteaptă amprenta"</string>
@@ -1156,6 +1158,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"Autentificați-vă"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"Accesați dispozitivul"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Folosiți amprenta ca să deschideți"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 358e8c3..805e16e 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Камера"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Телефон."</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Аудиоподсказки"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1162,6 +1164,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"выполнить аутентификацию"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"указать устройство"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Используйте отпечаток пальца для входа."</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index dae509e..71e9077 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -136,6 +136,7 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"කැමරාව"</string>
<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_lock_icon" msgid="661492842417875775">"උපාංගය අගුලු දමා ඇත"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"ඇඟිලි සලකුණ සඳහා බලා සිටිමින්"</string>
@@ -1150,6 +1151,6 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"සත්යාපනය කරන්න"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"උපාංගය ඇතුළු කරන්න"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"විවෘත කිරීමට ඇඟිලි සලකුණ භාවිත කරන්න"</string>
- <!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
- <skip />
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"සත්යාපනය අවශ්යයි. සත්යාපනය කිරීමට ඇඟිලි සලකුණු සංවේදකය ස්පර්ශ කරන්න."</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"ක්රියාත්මක වන දුරකථන ඇමතුම"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 0e0f6e5..79e1cfb 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Fotoaparát"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefón"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Hlasový asistent"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Odomknúť"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Zariadenie je uzamknuté"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Čaká sa na odtlačok prsta"</string>
@@ -1125,7 +1127,7 @@
<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">"Sem sa vráťte, keď dostanete nejaké správy"</string>
+ <string name="no_conversations_text" msgid="7362374212649891057">"Vráťte sa sem, až dostanete nejaké správy"</string>
<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>
@@ -1146,7 +1148,7 @@
<string name="audio_status" msgid="4237055636967709208">"Počúvam"</string>
<string name="game_status" msgid="1340694320630973259">"Hrá sa hra"</string>
<string name="empty_user_name" msgid="3389155775773578300">"Priatelia"</string>
- <string name="empty_status" msgid="5938893404951307749">"Porozprávajme sa."</string>
+ <string name="empty_status" msgid="5938893404951307749">"Poďme sa rozprávať."</string>
<string name="status_before_loading" msgid="1500477307859631381">"Obsah sa čoskoro zobrazí"</string>
<string name="missed_call" msgid="4228016077700161689">"Zmeškaný hovor"</string>
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
@@ -1162,6 +1164,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"overte"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"vstúpte do zariadenia"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Otvorte odtlačkom prsta"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 49c9982..6500e05 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Fotoaparat"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Glasovni pomočnik"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Odkleni"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Naprava je zaklenjena."</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Čakanje na prstni odtis"</string>
@@ -1162,6 +1164,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"preverjanje pristnosti"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"vstop v napravo"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Odprite s prstnim odtisom"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 9153edc..9df3c98 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefoni"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Ndihma zanore"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Shkyç"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Pajisja është e kyçur"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Në pritje për gjurmën e gishtit"</string>
@@ -1156,6 +1158,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"për ta vërtetuar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"për të hyrë në pajisje"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Përdor gjurmën e gishtit për ta hapur"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index dbc3b90..055acfa 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Камера"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Телефон"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Гласовна помоћ"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1156,6 +1158,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"потврдите идентитет"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"унесите уређај"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Отворите помоћу отиска прста"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index e2b94ee..a74b2ec 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Mobil"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Röstassistent"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Lås upp"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Enheten är låst"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Väntar på fingeravtryck"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentisera"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ange enhet"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Öppna med fingeravtryck"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 9a7fa60..e60d575 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -136,6 +136,7 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Simu"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Mapendekezo ya Sauti"</string>
+ <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"Fungua"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Kifaa kimefungwa"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Inasubiri alama ya kidole"</string>
@@ -1150,6 +1151,6 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"thibitisha"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"weka kifaa"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Tumia alama ya kidole kufungua"</string>
- <!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
- <skip />
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Uthibitishaji unahitajika. Gusa kitambua alama ya kidole ili uthibitishe."</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"Simu inayoendelea"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index f4721a2..0b56d3b 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"கேமரா"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ஃபோன்"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"குரல் உதவி"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"அங்கீகரி"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"சாதனத்தைத் திற"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"கைரேகையைப் பயன்படுத்தி திறந்திடுங்கள்"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index efa9840..7c797b7 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"కెమెరా"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"ఫోన్"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"వాయిస్ అసిస్టెంట్"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1151,6 +1153,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ప్రామాణీకరించండి"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"పరికరాన్ని ఎంటర్ చేయండి"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"తెరవడానికి వేలిముద్రను ఉపయోగించండి"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 96e837a..e7c20d2 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"กล้องถ่ายรูป"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"โทรศัพท์"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ตัวช่วยเสียง"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ตรวจสอบสิทธิ์"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"เข้าถึงอุปกรณ์"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ใช้ลายนิ้วมือเพื่อเปิด"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 7887883..d94e7a6 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Camera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telepono"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Voice Assist"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"I-unlock"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Naka-lock ang device"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Naghihintay ng fingerprint"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"i-authenticate"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ilagay ang device"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Gamitin ang fingerprint para buksan"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 75dbb08..d5185fb 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -136,6 +136,7 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Sesli Yardım"</string>
+ <string name="accessibility_wallet_button" msgid="1458258783460555507">"Cüzdan"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"Kilidi aç"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Cihaz kilitlendi"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Parmak izi bekleniyor"</string>
@@ -1150,6 +1151,6 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"kimlik doğrulaması yapın"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"cihaz girin"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Açmak için parmak izi kullanın"</string>
- <!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
- <skip />
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Kimlik doğrulaması gerekiyor. Kimlik doğrulaması için parmak izi sensörüne dokunun."</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"Devam eden telefon görüşmesi"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 5f69f55..df9c5bf 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Камера"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Номер телефону"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Голосові підказки"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1162,6 +1164,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"пройти автентифікацію"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"відкрити пристрій"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Щоб відкрити, використайте відбиток пальця"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 88b8c77..be8fafb 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"کیمرا"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"فون"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"صوتی معاون"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1151,6 +1153,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"تصدیق کریں"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"آلہ درج کریں"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"کھولنے کے لیے فنگر پرنٹ کا استعمال کریں"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 274b7a3..131373c 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -136,6 +136,7 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Ovozli yordam"</string>
+ <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"Qulfdan chiqarish"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Qurilma qulflandi"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Barmoq izingizni skanerlang"</string>
@@ -1150,6 +1151,6 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentifikatsiya"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"qurilmani ochish"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Ochish uchun barmoq izidan foydalaning"</string>
- <!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
- <skip />
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Haqiqiylikni tekshirish talab etiladi. Autentifikatsiya uchun barmoq izi skaneriga tegining."</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"Joriy telefon chaqiruvi"</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 359fe54..7a381c5 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Máy ảnh"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Điện thoại"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Trợ lý thoại"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<string name="accessibility_unlock_button" msgid="122785427241471085">"Mở khóa"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Đã khóa thiết bị"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Đang chờ vân tay"</string>
@@ -1134,7 +1136,7 @@
<string name="audio_status" msgid="4237055636967709208">"Đang nghe"</string>
<string name="game_status" msgid="1340694320630973259">"Đang chơi"</string>
<string name="empty_user_name" msgid="3389155775773578300">"Bạn bè"</string>
- <string name="empty_status" msgid="5938893404951307749">"Cùng trò chuyện tối nay nhé!"</string>
+ <string name="empty_status" msgid="5938893404951307749">"Tối nay nói chuyện nhé!"</string>
<string name="status_before_loading" msgid="1500477307859631381">"Nội dung sẽ sớm hiển thị"</string>
<string name="missed_call" msgid="4228016077700161689">"Cuộc gọi nhỡ"</string>
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"Hơn <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"xác thực"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"truy cập thiết bị"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Dùng vân tay để mở"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index f3760ab..0f162be 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"相机"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"电话"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"语音助理"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"身份验证"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"进入设备"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"使用指纹即可打开"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 081ec16..cd02e78 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"相機"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"電話"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"語音助手"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -470,10 +472,10 @@
<string name="interruption_level_none_twoline" msgid="8579382742855486372">"完全\n靜音"</string>
<string name="interruption_level_priority_twoline" msgid="8523482736582498083">"僅限\n優先"</string>
<string name="interruption_level_alarms_twoline" msgid="2045067991335708767">"僅限\n鬧鐘"</string>
- <string name="keyguard_indication_charging_time_wireless" msgid="577856646141738675">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 正在無線充電 • <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> • 正在充電 • <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> • 正在快速充電 • <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> • 正在慢速充電 • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>後完成充電"</string>
+ <string name="keyguard_indication_charging_time_wireless" msgid="577856646141738675">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 無線充電中 • <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> • 充電中 • <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> • 快速充電中 • <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> • 慢速充電中 • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>後充滿電"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切換使用者"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="5759855008166759399">"切換使用者,目前使用者是<xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="383168614528618402">"目前的使用者是 <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -1113,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="7362374212649891057">"等你收到一些訊息後再回來查看吧"</string>
<string name="priority_conversations" msgid="3967482288896653039">"優先對話"</string>
<string name="recent_conversations" msgid="8531874684782574622">"最近的對話"</string>
<string name="okay" msgid="6490552955618608554">"確定"</string>
@@ -1134,7 +1136,7 @@
<string name="audio_status" msgid="4237055636967709208">"正在聽取音訊"</string>
<string name="game_status" msgid="1340694320630973259">"正在玩遊戲"</string>
<string name="empty_user_name" msgid="3389155775773578300">"朋友"</string>
- <string name="empty_status" msgid="5938893404951307749">"今晚聊天吧!"</string>
+ <string name="empty_status" msgid="5938893404951307749">"今晚傾下偈啦!"</string>
<string name="status_before_loading" msgid="1500477307859631381">"即將顯示內容"</string>
<string name="missed_call" msgid="4228016077700161689">"未接來電"</string>
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"驗證"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"進入裝置"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"使用指紋即可開啟"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 66a5678..043cf43 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -136,6 +136,8 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"相機"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"電話"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"語音小幫手"</string>
+ <!-- no translation found for accessibility_wallet_button (1458258783460555507) -->
+ <skip />
<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>
@@ -1150,6 +1152,8 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"驗證"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"進入裝置"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"使用指紋即可開啟"</string>
+ <!-- no translation found for accessibility_fingerprint_bouncer (7189102492498735519) -->
+ <skip />
<!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 0fdc7d1..a444cd0 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -136,6 +136,7 @@
<string name="accessibility_camera_button" msgid="2938898391716647247">"Ikhamela"</string>
<string name="accessibility_phone_button" msgid="4256353121703100427">"Ifoni"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Isisekeli sezwi"</string>
+ <string name="accessibility_wallet_button" msgid="1458258783460555507">"I-wallet"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"Vula"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Idivayisi ikhiyiwe"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"Ilindele izigxivizo zeminwe"</string>
@@ -1150,6 +1151,6 @@
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"gunyaza"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"faka idivayisi"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Sebenzisa izigxivizo zeminwe ukuvula"</string>
- <!-- no translation found for ongoing_phone_call_content_description (5332334388483099947) -->
- <skip />
+ <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Ukufakazela ubuqiniso budingekile. Thinta inzwa yezigxivizo zeminwe ukuze uqinisekise."</string>
+ <string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"Ikholi yefoni eqhubekayo"</string>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 427ede5..36a1bb3 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -691,10 +691,6 @@
<string name="accessibility_quick_settings_hotspot_changed_on">Mobile hotspot turned on.</string>
<!-- Announcement made when the screen stopped casting (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_casting_turned_off">Screen casting stopped.</string>
- <!-- Content description of the work mode title in quick settings when off (not shown on the screen). Paused is used as an adjective [CHAR LIMIT=NONE] -->
- <string name="accessibility_quick_settings_work_mode_off">Work mode paused.</string>
- <!-- Content description of the work mode title in quick settings when on (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_quick_settings_work_mode_on">Work mode on.</string>
<!-- Announcement made when the work mode changes to off (not shown on the screen). Paused is used as a verb. [CHAR LIMIT=NONE] -->
<string name="accessibility_quick_settings_work_mode_changed_off">Work mode paused.</string>
<!-- Announcement made when the work mode changes to on (not shown on the screen). [CHAR LIMIT=NONE] -->
@@ -953,11 +949,9 @@
<string name="quick_settings_cellular_detail_data_warning"><xliff:g id="data_limit" example="2.0 GB">%s</xliff:g> warning</string>
<!-- QuickSettings: This string is in the easy-to-view settings that a user can pull down from
the top of their phone's screen. This is a label for a toggle to turn the work profile on and
- off. "Work profile" means a separate profile on a user's phone that's specifically for their
+ off. This means a separate profile on a user's phone that's specifically for their
work apps and managed by their company. "Work" is used as an adjective. [CHAR LIMIT=NONE] -->
- <string name="quick_settings_work_mode_label">Work profile</string>
- <!-- QuickSettings: Secondary label for work mode tile when it's off. [CHAR LIMIT=NONE] -->
- <string name="quick_settings_work_mode_paused">Paused</string>
+ <string name="quick_settings_work_mode_label">Work apps</string>
<!-- QuickSettings: Label for the toggle to activate Night display (renamed "Night Light" with title caps). [CHAR LIMIT=20] -->
<string name="quick_settings_night_display_label">Night Light</string>
<!-- QuickSettings: Secondary text for when the Night Light will be enabled at sunset. [CHAR LIMIT=20] -->
@@ -2724,15 +2718,8 @@
<string name="accessibility_floating_button_action_double_tap_to_toggle">toggle</string>
<!-- Device Controls strings -->
- <!-- Device Controls empty state, title [CHAR LIMIT=30] -->
- <string name="quick_controls_title">Device controls</string>
- <!-- Device Controls empty state, subtitle [CHAR LIMIT=100] -->
- <string name="quick_controls_subtitle">Add controls for your connected devices</string>
-
- <!-- Device Controls setup, title [CHAR LIMIT=50] -->
- <string name="quick_controls_setup_title">Set up device controls</string>
- <!-- Device Controls setup, subtitle [CHAR LIMIT=100] -->
- <string name="quick_controls_setup_subtitle">Hold the Power button to access your controls</string>
+ <!-- Device Controls, Quick Settings tile title [CHAR LIMIT=30] -->
+ <string name="quick_controls_title">Home controls</string>
<!-- Controls management providers screen title [CHAR LIMIT=60]-->
<string name="controls_providers_title">Choose app to add controls</string>
@@ -2761,7 +2748,7 @@
<!-- Controls management controls screen default title [CHAR LIMIT=30] -->
<string name="controls_favorite_default_title">Controls</string>
<!-- Controls management controls screen subtitle [CHAR LIMIT=NONE] -->
- <string name="controls_favorite_subtitle">Choose controls to access from the power menu</string>
+ <string name="controls_favorite_subtitle">Choose controls to access from Quick Settings</string>
<!-- Controls management editing screen, user direction for rearranging controls [CHAR LIMIT=NONE] -->
<string name="controls_favorite_rearrange">Hold & drag to rearrange controls</string>
@@ -2853,7 +2840,7 @@
<!-- Stateless control message informing the user that a routine has started [CHAR_LIMIT=30] -->
<string name="controls_in_progress">In progress</string>
<!-- Tooltip informing user where the recently added controls are [CHAR_LIMIT=100] -->
- <string name="controls_added_tooltip">Hold Power button to see new controls</string>
+ <string name="controls_added_tooltip">Open Quick Settings to see new controls</string>
<!-- Controls menu, add [CHAR_LIMIT=30] -->
<string name="controls_menu_add">Add controls</string>
@@ -2952,8 +2939,6 @@
[CHAR LIMIT=NONE] -->
<string name="battery_state_unknown_notification_text">Tap for more information</string>
- <string name="qs_tile_label_fontFamily" translatable="false">@*android:string/config_headlineFontFamilyMedium</string>
-
<!-- Secondary label for alarm tile when there is no next alarm information [CHAR LIMIT=20] -->
<string name="qs_alarm_tile_no_alarm">No alarm set</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 06ba03d..9ce7589 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -197,12 +197,13 @@
<style name="TextAppearance.QS.TileLabel">
<item name="android:textSize">@dimen/qs_tile_text_size</item>
- <item name="android:fontFamily">@string/qs_tile_label_fontFamily</item>
+ <item name="android:letterSpacing">0.01</item>
+ <item name="android:lineHeight">20sp</item>
+ <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
</style>
<style name="TextAppearance.QS.TileLabel.Secondary">
- <item name="android:textSize">@dimen/qs_tile_text_size</item>
- <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
+ <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
</style>
<style name="TextAppearance.QS.UserSwitcher">
@@ -221,11 +222,6 @@
<item name="android:textSize">@dimen/celltile_rat_type_size</item>
</style>
- <style name="TextAppearance.QS.SecurityFooter">
- <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
- <item name="android:textSize">@dimen/qs_tile_text_size</item>
- </style>
-
<style name="TextAppearance.QS.Status">
<item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
@@ -234,14 +230,22 @@
<item name="android:lineHeight">20sp</item>
</style>
- <style name="TextAppearance.QS.Status.NoCarrierText">
+ <style name="TextAppearance.QS.SecurityFooter" parent="@style/TextAppearance.QS.Status">
+ <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:textColor">?android:attr/textColorSecondary</item>
</style>
- <style name="TextAppearance.QS.Build">
+ <style name="TextAppearance.QS.Status.Carriers">
+ <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+ </style>
+
+ <style name="TextAppearance.QS.Status.Carriers.NoCarrierText">
+ <item name="android:textColor">?android:attr/textColorSecondary</item>
+ </style>
+
+ <style name="TextAppearance.QS.Status.Build">
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:textColor">?android:attr/textColorSecondary</item>
- <item name="android:textSize">14sp</item>
</style>
<style name="TextAppearance.DeviceManagementDialog">
@@ -603,11 +607,12 @@
parent="@*android:style/TextAppearance.DeviceDefault.Notification.Info">
</style>
- <style name="TextAppearance.QSEdit.Headers"
- parent="@*android:style/TextAppearance.DeviceDefault.Body2">
- <item name="android:textSize">11sp</item>
+ <style name="TextAppearance.QSEdit" >
+ <item name="android:textSize">14sp</item>
+ <item name="android:letterSpacing">0.01</item>
+ <item name="android:lineHeight">20sp</item>
+ <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:textColor">?android:attr/textColorSecondary</item>
- <item name="android:textAllCaps">true</item>
</style>
<style name="QSCustomizeToolbar" parent="@*android:style/Widget.DeviceDefault.Toolbar">
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
index 1e98f86..f61cadb 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
@@ -134,5 +134,8 @@
*/
void onBackPressed() = 44;
- // Next id = 45
+ /** Sets home rotation enabled. */
+ void setHomeRotationEnabled(boolean enabled) = 45;
+
+ // Next id = 46
}
diff --git a/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java b/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
index 4b9bf8c..e6ec04b 100644
--- a/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
@@ -37,7 +37,8 @@
import java.util.TimeZone;
/**
- * Controller for an AnimatableClockView. Instantiated by {@link KeyguardClockSwitchController}.
+ * Controller for an AnimatableClockView on the keyguard. Instantiated by
+ * {@link KeyguardClockSwitchController}.
*/
public class AnimatableClockController extends ViewController<AnimatableClockView> {
private static final int FORMAT_NUMBER = 1234567890;
@@ -46,6 +47,7 @@
private final BroadcastDispatcher mBroadcastDispatcher;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final KeyguardBypassController mBypassController;
+ private final BatteryController mBatteryController;
private final int mDozingColor = Color.WHITE;
private int mLockScreenColor;
@@ -53,6 +55,7 @@
private boolean mIsCharging;
private float mDozeAmount;
private Locale mLocale;
+ private boolean mAttached; // if keyguard isn't showing, mAttached = false
private final NumberFormat mBurmeseNf = NumberFormat.getInstance(Locale.forLanguageTag("my"));
private final String mBurmeseNumerals;
@@ -73,44 +76,47 @@
mBroadcastDispatcher = broadcastDispatcher;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mBypassController = bypassController;
+ mBatteryController = batteryController;
mBurmeseNumerals = mBurmeseNf.format(FORMAT_NUMBER);
mBurmeseLineSpacing = getContext().getResources().getFloat(
R.dimen.keyguard_clock_line_spacing_scale_burmese);
mDefaultLineSpacing = getContext().getResources().getFloat(
R.dimen.keyguard_clock_line_spacing_scale);
-
- batteryController.addCallback(new BatteryController.BatteryStateChangeCallback() {
- @Override
- public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
- if (!mIsCharging && charging) {
- mView.animateCharge(mIsDozing);
- }
- mIsCharging = charging;
- }
- });
}
- private BroadcastReceiver mLocaleBroadcastReceiver = new BroadcastReceiver() {
+ private final BatteryController.BatteryStateChangeCallback mBatteryCallback =
+ new BatteryController.BatteryStateChangeCallback() {
+ @Override
+ public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
+ if (!mIsCharging && charging) {
+ mView.animateCharge(mIsDozing);
+ }
+ mIsCharging = charging;
+ }
+ };
+
+ private final BroadcastReceiver mLocaleBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateLocale();
}
};
- @Override
- protected void onViewAttached() {
- updateLocale();
- mBroadcastDispatcher.registerReceiver(mLocaleBroadcastReceiver,
- new IntentFilter(Intent.ACTION_LOCALE_CHANGED));
- mStatusBarStateController.addCallback(mStatusBarStateListener);
- mIsDozing = mStatusBarStateController.isDozing();
- mDozeAmount = mStatusBarStateController.getDozeAmount();
- mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback);
-
- refreshTime();
- initColors();
- }
+ private final KeyguardUpdateMonitorCallback mKeyguardPersistentCallback =
+ new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onKeyguardVisibilityChanged(boolean showing) {
+ // call attached/detached methods on visibility changes. benefits include:
+ // - no animations when keyguard/clock view aren't visible
+ // - resets state when keyguard is visible again (ie: font weight)
+ if (showing) {
+ onViewAttached();
+ } else {
+ onViewDetached();
+ }
+ }
+ };
private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback =
new KeyguardUpdateMonitorCallback() {
@@ -125,10 +131,41 @@
};
@Override
+ protected void onViewAttached() {
+ if (mAttached) {
+ return;
+ }
+ mAttached = true;
+ updateLocale();
+ mBroadcastDispatcher.registerReceiver(mLocaleBroadcastReceiver,
+ new IntentFilter(Intent.ACTION_LOCALE_CHANGED));
+ mStatusBarStateController.addCallback(mStatusBarStateListener);
+ mIsDozing = mStatusBarStateController.isDozing();
+ mDozeAmount = mStatusBarStateController.getDozeAmount();
+ mBatteryController.addCallback(mBatteryCallback);
+ mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback);
+
+ mKeyguardUpdateMonitor.removeCallback(mKeyguardPersistentCallback);
+ mKeyguardUpdateMonitor.registerCallback(mKeyguardPersistentCallback);
+
+ refreshTime();
+ initColors();
+ }
+
+ @Override
protected void onViewDetached() {
+ if (!mAttached) {
+ return;
+ }
+
+ mAttached = false;
mBroadcastDispatcher.unregisterReceiver(mLocaleBroadcastReceiver);
mStatusBarStateController.removeCallback(mStatusBarStateListener);
mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback);
+ mBatteryController.removeCallback(mBatteryCallback);
+ if (!mView.isAttachedToWindow()) {
+ mKeyguardUpdateMonitor.removeCallback(mKeyguardPersistentCallback);
+ }
}
/** Animate the clock appearance */
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 4245fbc..aa7f9a2 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -124,16 +124,6 @@
@Override
public void onInit() {
mKeyguardSliceViewController.init();
- }
-
- @Override
- protected void onViewAttached() {
- if (CUSTOM_CLOCKS_ENABLED) {
- mClockManager.addOnClockChangedListener(mClockChangedListener);
- }
- mColorExtractor.addOnColorsChangedListener(mColorsListener);
- mView.updateColors(getGradientColors());
- updateAodIcons();
mClockFrame = mView.findViewById(R.id.lockscreen_clock_view);
mLargeClockFrame = mView.findViewById(R.id.lockscreen_clock_view_large);
@@ -157,6 +147,16 @@
mKeyguardUpdateMonitor,
mBypassController);
mLargeClockViewController.init();
+ }
+
+ @Override
+ protected void onViewAttached() {
+ if (CUSTOM_CLOCKS_ENABLED) {
+ mClockManager.addOnClockChangedListener(mClockChangedListener);
+ }
+ mColorExtractor.addOnColorsChangedListener(mColorsListener);
+ mView.updateColors(getGradientColors());
+ updateAodIcons();
if (mSmartspaceController.isEnabled()) {
mSmartspaceView = mSmartspaceController.buildAndConnectView(mView);
@@ -259,6 +259,9 @@
mClockViewController.refreshTime();
mLargeClockViewController.refreshTime();
}
+ if (mSmartspaceController != null) {
+ mSmartspaceController.requestSmartspaceUpdate();
+ }
mView.refresh();
}
@@ -307,8 +310,6 @@
NotificationIconContainer nic = (NotificationIconContainer)
mView.findViewById(
com.android.systemui.R.id.left_aligned_notification_icon_container);
-
- // alt icon area is set in KeyguardClockSwitchController
mNotificationIconAreaController.setupAodIcons(nic);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 4523fee..44df02a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -252,7 +252,6 @@
@Override
public void onStateChanged(int newState) {
mStatusBarState = newState;
- updateBiometricListeningState();
}
@Override
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 55f3981..e85bd88 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
@@ -544,9 +544,8 @@
final int currentX = (int) event.getX();
final int currentY = (int) event.getY();
- final int menuHalfWidth = getLayoutWidth() / 2;
final Rect touchDelegateBounds =
- new Rect(mMargin, mMargin, mMargin + menuHalfWidth, mMargin + getLayoutHeight());
+ new Rect(mMargin, mMargin, mMargin + getLayoutWidth(), mMargin + getLayoutHeight());
if (action == MotionEvent.ACTION_DOWN
&& touchDelegateBounds.contains(currentX, currentY)) {
mIsDownInEnlargedTouchArea = true;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/BaseTooltipView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/BaseTooltipView.java
index 1abf559..3085854 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/BaseTooltipView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/BaseTooltipView.java
@@ -77,7 +77,6 @@
mAnchorView = anchorView;
mCurrentLayoutParams = createDefaultLayoutParams();
- updateDimensions();
initViews();
}
@@ -85,14 +84,8 @@
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- updateDimensions();
- updateTextView();
-
mAnchorView.onConfigurationChanged(newConfig);
- final Rect anchorViewLocation = mAnchorView.getWindowLocationOnScreen();
- updateArrowWith(anchorViewLocation);
- updateWidthWith(anchorViewLocation);
- updateLocationWith(anchorViewLocation);
+ updateTooltipView();
mWindowManager.updateViewLayout(this, mCurrentLayoutParams);
}
@@ -129,10 +122,7 @@
}
mIsShowing = true;
- final Rect anchorViewLocation = mAnchorView.getWindowLocationOnScreen();
- updateArrowWith(anchorViewLocation);
- updateWidthWith(anchorViewLocation);
- updateLocationWith(anchorViewLocation);
+ updateTooltipView();
mWindowManager.addView(this, mCurrentLayoutParams);
}
@@ -207,6 +197,16 @@
R.dimen.accessibility_floating_tooltip_text_corner_radius);
}
+ private void updateTooltipView() {
+ updateDimensions();
+ updateTextView();
+
+ final Rect anchorViewLocation = mAnchorView.getWindowLocationOnScreen();
+ updateArrowWith(anchorViewLocation);
+ updateWidthWith(anchorViewLocation);
+ updateLocationWith(anchorViewLocation);
+ }
+
private void updateTextView() {
mTextView.setTextSize(COMPLEX_UNIT_PX, mFontSize);
mTextView.setPadding(mTextViewPadding, mTextViewPadding, mTextViewPadding,
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
index cba3dab..8ad5099 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
@@ -55,8 +55,9 @@
companion object {
private const val TAG = "ControlsProviderSelectorActivity"
+ const val BACK_SHOULD_EXIT = "back_should_exit"
}
-
+ private var backShouldExit = false
private lateinit var recyclerView: RecyclerView
private val currentUserTracker = object : CurrentUserTracker(broadcastDispatcher) {
private val startingUser = listingController.currentUserId
@@ -102,13 +103,17 @@
}
}
requireViewById<View>(R.id.done).visibility = View.GONE
+
+ backShouldExit = intent.getBooleanExtra(BACK_SHOULD_EXIT, false)
}
override fun onBackPressed() {
- val i = Intent().apply {
- component = ComponentName(applicationContext, ControlsActivity::class.java)
+ if (!backShouldExit) {
+ val i = Intent().apply {
+ component = ComponentName(applicationContext, ControlsActivity::class.java)
+ }
+ startActivity(i, ActivityOptions.makeSceneTransitionAnimation(this).toBundle())
}
- startActivity(i, ActivityOptions.makeSceneTransitionAnimation(this).toBundle())
animateExitAndFinish()
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
index 43607dd..b15bb45 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
@@ -46,6 +46,7 @@
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
+import androidx.annotation.ColorInt
import com.android.internal.graphics.ColorUtils
import com.android.systemui.R
import com.android.systemui.animation.Interpolators
@@ -313,7 +314,8 @@
@ColorRes bgColor: Int
) {
val bg = context.resources.getColor(R.color.control_default_background, context.theme)
- var (newClipColor, newAlpha) = if (enabled) {
+
+ val (newClipColor, newAlpha) = if (enabled) {
// allow color overrides for the enabled state only
val color = cws.control?.getCustomColor()?.let {
val state = intArrayOf(android.R.attr.state_enabled)
@@ -326,58 +328,87 @@
ALPHA_DISABLED
)
}
+ val newBaseColor = if (behavior is ToggleRangeBehavior) {
+ ColorUtils.blendARGB(bg, newClipColor, toggleBackgroundIntensity)
+ } else {
+ bg
+ }
- clipLayer.getDrawable().apply {
+ clipLayer.drawable?.apply {
clipLayer.alpha = ALPHA_DISABLED
-
- val newBaseColor = if (behavior is ToggleRangeBehavior) {
- ColorUtils.blendARGB(bg, newClipColor, toggleBackgroundIntensity)
- } else {
- bg
- }
stateAnimator?.cancel()
if (animated) {
- val oldColor = if (this is GradientDrawable) {
- this.color?.defaultColor ?: newClipColor
- } else {
- newClipColor
- }
- val oldBaseColor = baseLayer.color?.defaultColor ?: newBaseColor
- val oldAlpha = layout.alpha
-
- // Animate both alpha and background colors. Only animate colors for
- // GradientDrawables and not static images as used for the ThumbnailTemplate.
- stateAnimator = ValueAnimator.ofInt(clipLayer.alpha, newAlpha).apply {
- addUpdateListener {
- alpha = it.animatedValue as Int
- if (this is GradientDrawable) {
- this.setColor(ColorUtils.blendARGB(oldColor, newClipColor,
- it.animatedFraction))
- }
- baseLayer.setColor(ColorUtils.blendARGB(oldBaseColor, newBaseColor,
- it.animatedFraction))
- layout.alpha = MathUtils.lerp(oldAlpha, 1f, it.animatedFraction)
- }
- addListener(object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator?) {
- stateAnimator = null
- }
- })
- duration = STATE_ANIMATION_DURATION
- interpolator = Interpolators.CONTROL_STATE
- start()
- }
+ startBackgroundAnimation(this, newAlpha, newClipColor, newBaseColor)
} else {
- alpha = newAlpha
- if (this is GradientDrawable) {
- this.setColor(newClipColor)
- }
- baseLayer.setColor(newBaseColor)
- layout.alpha = 1f
+ applyBackgroundChange(
+ this, newAlpha, newClipColor, newBaseColor, newLayoutAlpha = 1f
+ )
}
}
}
+ private fun startBackgroundAnimation(
+ clipDrawable: Drawable,
+ newAlpha: Int,
+ @ColorInt newClipColor: Int,
+ @ColorInt newBaseColor: Int
+ ) {
+ val oldClipColor = if (clipDrawable is GradientDrawable) {
+ clipDrawable.color?.defaultColor ?: newClipColor
+ } else {
+ newClipColor
+ }
+ val oldBaseColor = baseLayer.color?.defaultColor ?: newBaseColor
+ val oldAlpha = layout.alpha
+
+ stateAnimator = ValueAnimator.ofInt(clipLayer.alpha, newAlpha).apply {
+ addUpdateListener {
+ val updatedAlpha = it.animatedValue as Int
+ val updatedClipColor = ColorUtils.blendARGB(oldClipColor, newClipColor,
+ it.animatedFraction)
+ val updatedBaseColor = ColorUtils.blendARGB(oldBaseColor, newBaseColor,
+ it.animatedFraction)
+ val updatedLayoutAlpha = MathUtils.lerp(oldAlpha, 1f, it.animatedFraction)
+ applyBackgroundChange(
+ clipDrawable,
+ updatedAlpha,
+ updatedClipColor,
+ updatedBaseColor,
+ updatedLayoutAlpha
+ )
+ }
+ addListener(object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator?) {
+ stateAnimator = null
+ }
+ })
+ duration = STATE_ANIMATION_DURATION
+ interpolator = Interpolators.CONTROL_STATE
+ start()
+ }
+ }
+
+ /**
+ * Applies a change in background.
+ *
+ * Updates both alpha and background colors. Only updates colors for GradientDrawables and not
+ * static images as used for the ThumbnailTemplate.
+ */
+ private fun applyBackgroundChange(
+ clipDrawable: Drawable,
+ newAlpha: Int,
+ @ColorInt newClipColor: Int,
+ @ColorInt newBaseColor: Int,
+ newLayoutAlpha: Float
+ ) {
+ clipDrawable.alpha = newAlpha
+ if (clipDrawable is GradientDrawable) {
+ clipDrawable.setColor(newClipColor)
+ }
+ baseLayer.setColor(newBaseColor)
+ layout.alpha = newLayoutAlpha
+ }
+
private fun animateStatusChange(animated: Boolean, statusRowUpdater: () -> Unit) {
statusAnimator?.cancel()
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
index 26be987..c322f45 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -217,22 +217,8 @@
}
private fun showInitialSetupView(items: List<SelectionItem>) {
- val inflater = LayoutInflater.from(context)
- inflater.inflate(R.layout.controls_no_favorites, parent, true)
-
- val viewGroup = parent.requireViewById(R.id.controls_no_favorites_group) as ViewGroup
- viewGroup.setOnClickListener { _: View -> startProviderSelectorActivity() }
-
- val subtitle = parent.requireViewById<TextView>(R.id.controls_subtitle)
- subtitle.setText(context.resources.getString(R.string.quick_controls_subtitle))
-
- val iconRowGroup = parent.requireViewById(R.id.controls_icon_row) as ViewGroup
- items.forEach {
- val imageView = inflater.inflate(R.layout.controls_icon, viewGroup, false) as ImageView
- imageView.setContentDescription(it.getTitle())
- imageView.setImageDrawable(it.icon)
- iconRowGroup.addView(imageView)
- }
+ startProviderSelectorActivity()
+ onDismiss.run()
}
private fun startFavoritingActivity(si: StructureInfo) {
@@ -261,7 +247,9 @@
}
private fun startProviderSelectorActivity() {
- startActivity(Intent(activityContext, ControlsProviderSelectorActivity::class.java))
+ val i = Intent(activityContext, ControlsProviderSelectorActivity::class.java)
+ i.putExtra(ControlsProviderSelectorActivity.BACK_SHOULD_EXIT, true)
+ startActivity(i)
}
private fun startActivity(intent: Intent) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
index ef53233..25e6e94 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
@@ -3,6 +3,7 @@
import android.app.smartspace.SmartspaceTarget
import android.content.Context
import android.content.Intent
+import android.content.res.ColorStateList
import android.content.res.Configuration
import android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS
import android.util.Log
@@ -380,6 +381,7 @@
private fun recreatePlayers() {
bgColor = getBackgroundColor()
+ pageIndicator.tintList = ColorStateList.valueOf(getForegroundColor())
MediaPlayerData.mediaData().forEach { (key, data) ->
removePlayer(key, dismissMediaData = false)
@@ -391,6 +393,10 @@
return context.getColor(android.R.color.system_accent2_50)
}
+ private fun getForegroundColor(): Int {
+ return context.getColor(android.R.color.system_accent2_900)
+ }
+
private fun updatePageIndicator() {
val numPages = mediaContent.getChildCount()
pageIndicator.setNumPages(numPages)
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index 4e41d75..04f5199 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -364,6 +364,11 @@
}
@Override
+ public void onHomeRotationEnabled(boolean enabled) {
+ mNavigationBarView.getRotationButtonController().setHomeRotationEnabled(enabled);
+ }
+
+ @Override
public void onOverviewShown(boolean fromHome) {
// If the overview has fixed orientation that may change display to natural rotation,
// we don't want the user rotation to be reset. So after user returns to application,
@@ -951,6 +956,7 @@
if (running) {
mNavbarOverlayController.setButtonState(/* visible */false, /* force */true);
}
+ mNavigationBarView.getRotationButtonController().setRecentsAnimationRunning(running);
}
/** Restores the appearance and the transient saved state to {@link NavigationBar}. */
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/RotationButtonController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/RotationButtonController.java
index ddf089b..649ac87 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/RotationButtonController.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/RotationButtonController.java
@@ -71,6 +71,8 @@
private final ViewRippler mViewRippler = new ViewRippler();
private RotationButton mRotationButton;
+ private boolean mIsRecentsAnimationRunning;
+ private boolean mHomeRotationEnabled;
private int mLastRotationSuggestion;
private boolean mPendingRotationSuggestion;
private boolean mHoveringRotationSuggestion;
@@ -92,7 +94,6 @@
() -> mPendingRotationSuggestion = false;
private Animator mRotateHideAnimator;
-
private final Stub mRotationWatcher = new Stub() {
@Override
public void onRotationChanged(final int rotation) throws RemoteException {
@@ -105,7 +106,7 @@
if (shouldOverrideUserLockPrefs(rotation)) {
setRotationLockedAtAngle(rotation);
}
- setRotateSuggestionButtonState(false /* visible */, true /* forced */);
+ setRotateSuggestionButtonState(false /* visible */, true /* hideImmediately */);
}
if (mRotWatcherListener != null) {
@@ -192,10 +193,14 @@
}
void setRotateSuggestionButtonState(boolean visible) {
- setRotateSuggestionButtonState(visible, false /* force */);
+ setRotateSuggestionButtonState(visible, false /* hideImmediately */);
}
- void setRotateSuggestionButtonState(final boolean visible, final boolean force) {
+ /**
+ * Change the visibility of rotate suggestion button. If {@code hideImmediately} is true,
+ * it doesn't wait until the completion of the running animation.
+ */
+ void setRotateSuggestionButtonState(final boolean visible, final boolean hideImmediately) {
// At any point the the button can become invisible because an a11y service became active.
// Similarly, a call to make the button visible may be rejected because an a11y service is
// active. Must account for this.
@@ -236,7 +241,7 @@
} else { // Hide
mViewRippler.stop(); // Prevent any pending ripples, force hide or not
- if (force) {
+ if (hideImmediately) {
// If a hide animator is running stop it and make invisible
if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) {
mRotateHideAnimator.pause();
@@ -263,12 +268,29 @@
}
}
+ void setRecentsAnimationRunning(boolean running) {
+ mIsRecentsAnimationRunning = running;
+ updateRotationButtonStateInOverview();
+ }
+
+ void setHomeRotationEnabled(boolean enabled) {
+ mHomeRotationEnabled = enabled;
+ updateRotationButtonStateInOverview();
+ }
+
+ private void updateRotationButtonStateInOverview() {
+ if (mIsRecentsAnimationRunning && !mHomeRotationEnabled) {
+ setRotateSuggestionButtonState(false, true /* hideImmediately */ );
+ }
+ }
+
void setDarkIntensity(float darkIntensity) {
mRotationButton.setDarkIntensity(darkIntensity);
}
void onRotationProposal(int rotation, int windowRotation, boolean isValid) {
- if (!mRotationButton.acceptRotationProposal()) {
+ if (!mRotationButton.acceptRotationProposal() || (!mHomeRotationEnabled
+ && mIsRecentsAnimationRunning)) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
index 7bde64b..8df8c63 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -125,25 +125,14 @@
} else {
state.slash.isSlashed = true;
}
- state.label = mContext.getString(R.string.quick_settings_work_mode_label);
+ state.label = getTileLabel();
state.contentDescription = state.label;
state.expandedAccessibilityClassName = Switch.class.getName();
state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
- state.secondaryLabel = state.value ? "" :
- mContext.getString(R.string.quick_settings_work_mode_paused);
}
@Override
public int getMetricsCategory() {
return MetricsEvent.QS_WORKMODE;
}
-
- @Override
- protected String composeChangeAnnouncement() {
- if (mState.value) {
- return mContext.getString(R.string.accessibility_quick_settings_work_mode_changed_on);
- } else {
- return mContext.getString(R.string.accessibility_quick_settings_work_mode_changed_off);
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 63adbd0..20c3e81 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -259,6 +259,21 @@
}
}
+ @Override
+ public void setHomeRotationEnabled(boolean enabled) {
+ if (!verifyCaller("setHomeRotationEnabled")) {
+ return;
+ }
+ final long token = Binder.clearCallingIdentity();
+ try {
+ mHandler.post(() -> {
+ mHandler.post(() -> notifyHomeRotationEnabled(enabled));
+ });
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
private boolean sendEvent(int action, int code) {
long when = SystemClock.uptimeMillis();
final KeyEvent ev = new KeyEvent(when, when, action, code, 0 /* repeat */,
@@ -847,6 +862,12 @@
}
}
+ private void notifyHomeRotationEnabled(boolean enabled) {
+ for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
+ mConnectionCallbacks.get(i).onHomeRotationEnabled(enabled);
+ }
+ }
+
private void notifyConnectionChanged() {
for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
mConnectionCallbacks.get(i).onConnectionChanged(mOverviewProxy != null);
@@ -994,6 +1015,7 @@
default void onToggleRecentApps() {}
/** Notify changes in the nav bar button alpha */
default void onNavBarButtonAlphaChanged(float alpha, boolean animate) {}
+ default void onHomeRotationEnabled(boolean enabled) {}
default void onSystemUiStateChanged(int sysuiStateFlags) {}
default void onAssistantProgress(@FloatRange(from = 0.0, to = 1.0) float progress) {}
default void onAssistantGestureCompletion(float velocity) {}
diff --git a/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java b/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java
index 1a5c9ee..7530681 100644
--- a/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java
+++ b/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java
@@ -294,7 +294,6 @@
/**
* Make bottom edge concave so overlap between layers is not visible for alphas between 0 and 1
- * @return height of concavity
*/
public void enableBottomEdgeConcave(boolean clipScrim) {
if (mDrawable instanceof ScrimDrawable) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
index a0d5eef..71546ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
@@ -106,6 +106,10 @@
return view
}
+ fun requestSmartspaceUpdate() {
+ session?.requestSmartspaceUpdate()
+ }
+
private fun buildView(parent: ViewGroup) {
if (plugin == null) {
return
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java
index 9482c17..a0ccd57 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java
@@ -19,6 +19,8 @@
import android.annotation.Nullable;
import android.util.ArraySet;
+import androidx.annotation.VisibleForTesting;
+
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -76,8 +78,9 @@
}
}
- private boolean isDynamicPrivacyEnabled() {
- return !mLockscreenUserManager.shouldHideNotifications(
+ @VisibleForTesting
+ boolean isDynamicPrivacyEnabled() {
+ return !mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(
mLockscreenUserManager.getCurrentUserId());
}
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 3244ff9..a804ae6 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
@@ -1142,7 +1142,7 @@
if (mQsExpansionFraction <= 0) {
final float scrimTopPadding = mAmbientState.isOnKeyguard() ? 0 : mSidePaddings;
final float stackEndHeight = Math.max(0f,
- getHeight() - getEmptyBottomMargin() - stackY);
+ getHeight() - getEmptyBottomMargin() - mTopPadding);
mAmbientState.setStackEndHeight(stackEndHeight);
mAmbientState.setStackHeight(
MathUtils.lerp(stackEndHeight * StackScrollAlgorithm.START_FRACTION,
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 b2d39a9..e931ec4 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
@@ -225,6 +225,8 @@
// already accounted for by the top padding and doesn't need an additional adaption
scrollY = Math.max(0, scrollY);
state.scrollY = (int) (scrollY + bottomOverScroll);
+ state.mCurrentYPosition = -state.scrollY;
+ state.mCurrentExpandedYPosition = -state.scrollY;
//now init the visible children and update paddings
int childCount = hostView.getChildCount();
@@ -321,14 +323,14 @@
*/
private void updatePositionsForState(StackScrollAlgorithmState algorithmState,
AmbientState ambientState) {
- // The y coordinate of the current child.
- float currentYPosition = -algorithmState.scrollY;
if (!ambientState.isOnKeyguard()) {
- currentYPosition += mNotificationScrimPadding;
+ algorithmState.mCurrentYPosition += mNotificationScrimPadding;
+ algorithmState.mCurrentExpandedYPosition += mNotificationScrimPadding;
}
+
int childCount = algorithmState.visibleChildren.size();
for (int i = 0; i < childCount; i++) {
- currentYPosition = updateChild(i, algorithmState, ambientState, currentYPosition);
+ updateChild(i, algorithmState, ambientState);
}
}
@@ -348,14 +350,14 @@
StackScrollAlgorithmState algorithmState,
AmbientState ambientState) {
- final boolean isShowingShelf = ambientState.getShelf() != null
+ final boolean showingShelf = ambientState.getShelf() != null
&& algorithmState.firstViewInShelf != null;
- final float stackHeight = ambientState.getStackHeight()
- - (isShowingShelf ? ambientState.getShelf().getIntrinsicHeight() : 0f);
+ final float shelfHeight = showingShelf ? ambientState.getShelf().getIntrinsicHeight() : 0f;
+ final float scrimPadding = ambientState.isOnKeyguard() ? 0 : mNotificationScrimPadding;
- float stackEndHeight = ambientState.getStackEndHeight()
- - (isShowingShelf ? ambientState.getShelf().getIntrinsicHeight() : 0f);
+ final float stackHeight = ambientState.getStackHeight() - shelfHeight - scrimPadding;
+ final float stackEndHeight = ambientState.getStackEndHeight() - shelfHeight - scrimPadding;
return stackHeight / stackEndHeight;
}
@@ -368,17 +370,11 @@
* {@link StackScrollAlgorithmState#visibleChildren}.
* @param algorithmState The overall output state of the algorithm.
* @param ambientState The input state provided to the algorithm.
- * @param currentYPosition The Y position of the current pass of the algorithm. For a forward
- * pass, this should be the top of the child; for a reverse pass, the
- * bottom of the child.
- * @return The Y position after laying out the child. This will be the {@code currentYPosition}
- * for the next call to this method, after adjusting for any gaps between children.
*/
- protected float updateChild(
+ protected void updateChild(
int i,
StackScrollAlgorithmState algorithmState,
- AmbientState ambientState,
- float currentYPosition) {
+ AmbientState ambientState) {
ExpandableView view = algorithmState.visibleChildren.get(i);
ExpandableViewState viewState = view.getViewState();
@@ -407,10 +403,11 @@
ambientState.getSectionProvider(), i,
view, getPreviousView(i, algorithmState));
if (applyGapHeight) {
- currentYPosition += expansionFraction * mGapHeight;
+ algorithmState.mCurrentYPosition += expansionFraction * mGapHeight;
+ algorithmState.mCurrentExpandedYPosition += mGapHeight;
}
- viewState.yTranslation = currentYPosition;
+ viewState.yTranslation = algorithmState.mCurrentYPosition;
if (view instanceof SectionHeaderView) {
// Add padding before sections for overscroll effect.
viewState.yTranslation += expansionFraction * ambientState.getSectionPadding();
@@ -419,12 +416,11 @@
if (view instanceof FooterView) {
final boolean isShelfShowing = algorithmState.firstViewInShelf != null;
- final float footerEnd = viewState.yTranslation + view.getIntrinsicHeight();
- final boolean noSpaceForFooter = footerEnd > ambientState.getStackHeight();
+ final float footerEnd = algorithmState.mCurrentExpandedYPosition
+ + view.getIntrinsicHeight();
+ final boolean noSpaceForFooter = footerEnd > ambientState.getStackEndHeight();
- viewState.hidden = isShelfShowing
- || (!ambientState.isExpansionChanging() && noSpaceForFooter);
-
+ viewState.hidden = isShelfShowing || noSpaceForFooter;
} else if (view != ambientState.getTrackedHeadsUpRow()) {
if (ambientState.isExpansionChanging()) {
// Show all views. Views below the shelf will later be clipped (essentially hidden)
@@ -459,14 +455,16 @@
maxViewHeight = algorithmState.viewHeightBeforeShelf;
}
}
- viewState.height = (int) MathUtils.lerp(maxViewHeight * START_FRACTION, maxViewHeight,
- expansionFraction);
+ viewState.height = (int) (maxViewHeight * expansionFraction);
}
- currentYPosition += viewState.height + expansionFraction * mPaddingBetweenElements;
- setLocation(view.getViewState(), currentYPosition, i);
+ algorithmState.mCurrentYPosition += viewState.height
+ + expansionFraction * mPaddingBetweenElements;
+ algorithmState.mCurrentExpandedYPosition += view.getIntrinsicHeight()
+ + mPaddingBetweenElements;
+
+ setLocation(view.getViewState(), algorithmState.mCurrentYPosition, i);
viewState.yTranslation += ambientState.getStackY();
- return currentYPosition;
}
/**
@@ -739,6 +737,18 @@
* The children from the host view which are not gone.
*/
public final ArrayList<ExpandableView> visibleChildren = new ArrayList<>();
+
+ /**
+ * Y position of the current view during updating children
+ * with expansion factor applied.
+ */
+ private int mCurrentYPosition;
+
+ /**
+ * Y position of the current view during updating children
+ * without applying the expansion factor.
+ */
+ private int mCurrentExpandedYPosition;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index bbde3c3..b94b5d3c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -547,9 +547,12 @@
* Set bounds for notifications background, all coordinates are absolute
*/
public void setNotificationsBounds(float left, float top, float right, float bottom) {
- mNotificationsScrim.setDrawableBounds(left, top, right, bottom);
if (mClipsQsScrim) {
+ // "top - 1" to have 1 px of scrims overlap, see: b/186644628
+ mNotificationsScrim.setDrawableBounds(left, top - 1, right, bottom);
mScrimBehind.setBottomEdgePosition((int) top);
+ } else {
+ mNotificationsScrim.setDrawableBounds(left, top, right, bottom);
}
}
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 ec012bf..9c6d623 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -3706,7 +3706,7 @@
private void showBouncerIfKeyguard() {
if ((mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)
&& !mKeyguardViewMediator.isHiding()) {
- mStatusBarKeyguardViewManager.showBouncer(true /* scrimmed */);
+ mStatusBarKeyguardViewManager.showGenericBouncer(true /* scrimmed */);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 41bd710..91d1bd7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -365,6 +365,26 @@
return false;
}
+ /**
+ * If applicable, shows the alternate authentication bouncer. Else, shows the input
+ * (pin/password/pattern) bouncer.
+ * @param scrimmed true when the input bouncer should show scrimmed, false when the user will be
+ * dragging it and translation should be deferred {@see KeyguardBouncer#show(boolean, boolean)}
+ */
+ public void showGenericBouncer(boolean scrimmed) {
+ if (mAlternateAuthInterceptor != null) {
+ if (mAlternateAuthInterceptor.showAlternateAuthBouncer()) {
+ mStatusBar.updateScrimController();
+ }
+ return;
+ }
+
+ showBouncer(scrimmed);
+ }
+
+ /**
+ * Hides the input bouncer (pin/password/pattern).
+ */
@VisibleForTesting
void hideBouncer(boolean destroyView) {
if (mBouncer == null) {
@@ -380,7 +400,7 @@
}
/**
- * Shows the keyguard bouncer - the password challenge on the lock screen
+ * Shows the keyguard input bouncer - the password challenge on the lock screen
*
* @param scrimmed true when the bouncer should show scrimmed, false when the user will be
* dragging it and translation should be deferred {@see KeyguardBouncer#show(boolean, boolean)}
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
index 4cba432..83aa01f 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
@@ -16,6 +16,9 @@
package com.android.systemui.wallet.ui;
+import static android.provider.Settings.ACTION_LOCKSCREEN_SETTINGS;
+
+import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
@@ -178,7 +181,10 @@
finish();
return true;
} else if (itemId == R.id.wallet_lockscreen_settings) {
- // TODO(b/186496392): Navigate to Lock Screen Settings page when the item is clicked.
+ Intent intent =
+ new Intent(ACTION_LOCKSCREEN_SETTINGS)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ mActivityStarter.startActivity(intent, true);
return true;
}
return super.onOptionsItemSelected(item);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
index 98467d4..10322f2 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
@@ -232,6 +232,13 @@
verify(mView).removeView(mFakeSmartspaceView);
}
+ @Test
+ public void testRefresh() {
+ mController.refresh();
+
+ verify(mSmartspaceController).requestSmartspaceUpdate();
+ }
+
private void verifyAttachment(VerificationMode times) {
verify(mClockManager, times).addOnClockChangedListener(
any(ClockManager.ClockChangedListener.class));
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index f779305..29b4405 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -943,6 +943,34 @@
}
@Test
+ public void testShouldNotUpdateBiometricListeningStateOnStatusBarStateChange() {
+ // GIVEN state for face auth should run aside from StatusBarState
+ when(mDevicePolicyManager.getKeyguardDisabledFeatures(null,
+ KeyguardUpdateMonitor.getCurrentUser())).thenReturn(0);
+ mStatusBarStateListener.onStateChanged(StatusBarState.SHADE_LOCKED);
+ setKeyguardBouncerVisibility(false /* isVisible */);
+ mKeyguardUpdateMonitor.dispatchStartedWakingUp();
+ when(mKeyguardBypassController.canBypass()).thenReturn(true);
+ mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
+
+ // WHEN status bar state reports a change to the keyguard that would normally indicate to
+ // start running face auth
+ mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
+ assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isEqualTo(true);
+
+ // THEN face unlock is not running b/c status bar state changes don't cause biometric
+ // listening state to update
+ assertThat(mKeyguardUpdateMonitor.isFaceUnlockRunning(
+ KeyguardUpdateMonitor.getCurrentUser())).isEqualTo(false);
+
+ // WHEN biometric listening state is updated
+ mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
+
+ // THEN face unlock is running
+ assertThat(mKeyguardUpdateMonitor.isFaceDetectionRunning()).isEqualTo(true);
+ }
+
+ @Test
public void testRequireUnlockForNfc_Broadcast() {
KeyguardUpdateMonitorCallback callback = mock(KeyguardUpdateMonitorCallback.class);
mKeyguardUpdateMonitor.registerCallback(callback);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java
index 68cf66d..7d06abf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.notification;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
@@ -60,13 +62,15 @@
mDynamicPrivacyController.setStatusBarKeyguardViewManager(
mock(StatusBarKeyguardViewManager.class));
mDynamicPrivacyController.addListener(mListener);
+ // Disable dynamic privacy by default
+ allowPrivateNotificationsInPublic(true);
}
@Test
public void testDynamicFalseWhenCannotSkipBouncer() {
enableDynamicPrivacy();
when(mKeyguardStateController.canDismissLockScreen()).thenReturn(false);
- Assert.assertFalse("can't skip bouncer but is dynamically unlocked",
+ assertFalse("can't skip bouncer but is dynamically unlocked",
mDynamicPrivacyController.isDynamicallyUnlocked());
}
@@ -102,9 +106,26 @@
verify(mListener).onDynamicPrivacyChanged();
}
- private void enableDynamicPrivacy() {
+ @Test
+ public void dynamicPrivacyOnlyWhenHidingPrivate() {
+ // Verify that when only hiding notifications, this isn't enabled
+ allowPrivateNotificationsInPublic(true);
when(mLockScreenUserManager.shouldHideNotifications(any())).thenReturn(
false);
+ assertFalse("Dynamic privacy shouldn't be enabled when only hiding notifications",
+ mDynamicPrivacyController.isDynamicPrivacyEnabled());
+ allowPrivateNotificationsInPublic(false);
+ assertTrue("Should be enabled when hiding notification contents",
+ mDynamicPrivacyController.isDynamicPrivacyEnabled());
+ }
+
+ private void enableDynamicPrivacy() {
+ allowPrivateNotificationsInPublic(false);
+ }
+
+ private void allowPrivateNotificationsInPublic(boolean allow) {
+ when(mLockScreenUserManager.userAllowsPrivateNotificationsInPublic(anyInt())).thenReturn(
+ allow);
}
@Test
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 3bb6e08..85084f4 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -1839,8 +1839,6 @@
// For a full update we replace the RemoteViews completely.
widget.views = views;
}
- widget.views.setProviderInstanceId(UPDATE_COUNTER.get());
-
int memoryUsage;
if ((UserHandle.getAppId(Binder.getCallingUid()) != Process.SYSTEM_UID) &&
(widget.views != null) &&
@@ -1942,13 +1940,14 @@
return;
}
if (updateViews != null) {
+ updateViews = new RemoteViews(updateViews);
updateViews.setProviderInstanceId(requestId);
}
SomeArgs args = SomeArgs.obtain();
args.arg1 = widget.host;
args.arg2 = widget.host.callbacks;
- args.arg3 = (updateViews != null) ? updateViews.clone() : null;
+ args.arg3 = updateViews;
args.arg4 = requestId;
args.argi1 = widget.appWidgetId;
diff --git a/services/core/java/com/android/server/SensorPrivacyService.java b/services/core/java/com/android/server/SensorPrivacyService.java
index ca59ce3..baec544 100644
--- a/services/core/java/com/android/server/SensorPrivacyService.java
+++ b/services/core/java/com/android/server/SensorPrivacyService.java
@@ -1320,12 +1320,12 @@
private void setUserRestriction(int userId, int sensor, boolean enabled) {
if (sensor == CAMERA) {
mAppOpsManager.setUserRestrictionForUser(OP_CAMERA, enabled,
- mAppOpsRestrictionToken, new String[]{}, userId);
+ mAppOpsRestrictionToken, null, userId);
} else if (sensor == MICROPHONE) {
mAppOpsManager.setUserRestrictionForUser(OP_RECORD_AUDIO, enabled,
- mAppOpsRestrictionToken, new String[]{}, userId);
+ mAppOpsRestrictionToken, null, userId);
mAppOpsManager.setUserRestrictionForUser(OP_RECORD_AUDIO_HOTWORD, enabled,
- mAppOpsRestrictionToken, new String[]{}, userId);
+ mAppOpsRestrictionToken, null, userId);
}
}
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 7a0a3a7..670f557 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -699,7 +699,7 @@
if (mActivity != null) {
mActivity.addErrorToDropBox(
"watchdog", null, "system_server", null, null, null,
- localSubject, report.toString(), stack, null, null, null);
+ localSubject, report.toString(), stack, null, null, null, null);
}
FrameworkStatsLog.write(FrameworkStatsLog.SYSTEM_SERVER_WATCHDOG_OCCURRED,
localSubject);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6661f88..d3955eb 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -351,6 +351,7 @@
import com.android.internal.util.function.NonaFunction;
import com.android.internal.util.function.OctFunction;
import com.android.internal.util.function.QuadFunction;
+import com.android.internal.util.function.QuintFunction;
import com.android.internal.util.function.TriFunction;
import com.android.server.AlarmManagerInternal;
import com.android.server.DeviceIdleInternal;
@@ -420,6 +421,7 @@
import java.util.Locale;
import java.util.Map;
import java.util.Set;
+import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
@@ -621,6 +623,8 @@
@GuardedBy("this")
BroadcastStats mCurBroadcastStats;
+ TraceErrorLogger mTraceErrorLogger;
+
BroadcastQueue broadcastQueueForIntent(Intent intent) {
if (isOnOffloadQueue(intent.getFlags())) {
if (DEBUG_BROADCAST_BACKGROUND) {
@@ -2336,6 +2340,7 @@
mInternal = new LocalService();
mPendingStartActivityUids = new PendingStartActivityUids(mContext);
+ mTraceErrorLogger = new TraceErrorLogger();
}
public void setSystemServiceManager(SystemServiceManager mgr) {
@@ -7810,7 +7815,7 @@
addErrorToDropBox(
eventType, r, processName, null, null, null, null, null, null, crashInfo,
- new Float(loadingProgress), incrementalMetrics);
+ new Float(loadingProgress), incrementalMetrics, null);
mAppErrors.crashApplication(r, crashInfo);
}
@@ -7993,7 +7998,7 @@
callingPid, (r != null) ? r.getProcessClassEnum() : 0);
addErrorToDropBox("wtf", r, processName, null, null, null, tag, null, null, crashInfo,
- null, null);
+ null, null, null);
return r;
}
@@ -8018,7 +8023,7 @@
for (Pair<String, ApplicationErrorReport.CrashInfo> p = list.poll();
p != null; p = list.poll()) {
addErrorToDropBox("wtf", proc, "system_server", null, null, null, p.first, null, null,
- p.second, null, null);
+ p.second, null, null, null);
}
}
@@ -8109,13 +8114,15 @@
* @param crashInfo giving an application stack trace, null if absent
* @param loadingProgress the loading progress of an installed package, range in [0, 1].
* @param incrementalMetrics metrics for apps installed on Incremental.
+ * @param errorId a unique id to append to the dropbox headers.
*/
public void addErrorToDropBox(String eventType,
ProcessRecord process, String processName, String activityShortComponentName,
String parentShortComponentName, ProcessRecord parentProcess,
String subject, final String report, final File dataFile,
final ApplicationErrorReport.CrashInfo crashInfo,
- @Nullable Float loadingProgress, @Nullable IncrementalMetrics incrementalMetrics) {
+ @Nullable Float loadingProgress, @Nullable IncrementalMetrics incrementalMetrics,
+ @Nullable UUID errorId) {
// NOTE -- this must never acquire the ActivityManagerService lock,
// otherwise the watchdog may be prevented from resetting the system.
@@ -8169,6 +8176,9 @@
if (subject != null) {
sb.append("Subject: ").append(subject).append("\n");
}
+ if (errorId != null) {
+ sb.append("ErrorId: ").append(errorId.toString()).append("\n");
+ }
sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
if (Debug.isDebuggerConnected()) {
sb.append("Debugger: Connected\n");
@@ -16741,19 +16751,20 @@
}
@Override
- public int checkOperation(int code, int uid, String packageName, boolean raw,
- QuadFunction<Integer, Integer, String, Boolean, Integer> superImpl) {
+ public int checkOperation(int code, int uid, String packageName,
+ String attributionTag, boolean raw,
+ QuintFunction<Integer, Integer, String, String, Boolean, Integer> superImpl) {
if (uid == mTargetUid && isTargetOp(code)) {
final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
Process.SHELL_UID);
final long identity = Binder.clearCallingIdentity();
try {
- return superImpl.apply(code, shellUid, "com.android.shell", raw);
+ return superImpl.apply(code, shellUid, "com.android.shell", null, raw);
} finally {
Binder.restoreCallingIdentity(identity);
}
}
- return superImpl.apply(code, uid, packageName, raw);
+ return superImpl.apply(code, uid, packageName, attributionTag, raw);
}
@Override
diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java
index 074e8fe..74094e5 100644
--- a/services/core/java/com/android/server/am/AppProfiler.java
+++ b/services/core/java/com/android/server/am/AppProfiler.java
@@ -1627,7 +1627,7 @@
dropBuilder.append(catSw.toString());
FrameworkStatsLog.write(FrameworkStatsLog.LOW_MEM_REPORTED);
mService.addErrorToDropBox("lowmem", null, "system_server", null,
- null, null, tag.toString(), dropBuilder.toString(), null, null, null, null);
+ null, null, tag.toString(), dropBuilder.toString(), null, null, null, null, null);
synchronized (mService) {
long now = SystemClock.uptimeMillis();
if (mLastMemUsageReportTime < now) {
diff --git a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
index 88bd010..66d4779 100644
--- a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
+++ b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
@@ -55,7 +55,7 @@
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
-
+import java.util.UUID;
/**
* The error state of the process, such as if it's crashing/ANR etc.
*/
@@ -235,6 +235,7 @@
final boolean isSilentAnr;
final int pid = mApp.getPid();
+ final UUID errorId;
synchronized (mService) {
// PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
if (mService.mAtmInternal.isShuttingDown()) {
@@ -264,6 +265,13 @@
EventLog.writeEvent(EventLogTags.AM_ANR, mApp.userId, pid, mApp.processName,
mApp.info.flags, annotation);
+ if (mService.mTraceErrorLogger.isAddErrorIdEnabled()) {
+ errorId = mService.mTraceErrorLogger.generateErrorId();
+ mService.mTraceErrorLogger.addErrorIdToTrace(errorId);
+ } else {
+ errorId = null;
+ }
+
// Dump thread traces as quickly as we can, starting with "interesting" processes.
firstPids.add(pid);
@@ -315,6 +323,9 @@
&& parentShortComponentName.equals(activityShortComponentName)) {
info.append("Parent: ").append(parentShortComponentName).append("\n");
}
+ if (errorId != null) {
+ info.append("ErrorId: ").append(errorId.toString()).append("\n");
+ }
// Retrieve controller with max ANR delay from AnrControllers
// Note that we retrieve the controller before dumping stacks because dumping stacks can
@@ -457,7 +468,7 @@
? (ProcessRecord) parentProcess.mOwner : null;
mService.addErrorToDropBox("anr", mApp, mApp.processName, activityShortComponentName,
parentShortComponentName, parentPr, annotation, report.toString(), tracesFile,
- null, new Float(loadingProgress), incrementalMetrics);
+ null, new Float(loadingProgress), incrementalMetrics, errorId);
if (mApp.getWindowProcessController().appNotResponding(info.toString(),
() -> {
diff --git a/services/core/java/com/android/server/am/TraceErrorLogger.java b/services/core/java/com/android/server/am/TraceErrorLogger.java
new file mode 100644
index 0000000..f055be2
--- /dev/null
+++ b/services/core/java/com/android/server/am/TraceErrorLogger.java
@@ -0,0 +1,58 @@
+/*
+ * 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.am;
+
+import android.os.Trace;
+import android.provider.DeviceConfig;
+
+import java.util.UUID;
+
+/**
+ * Adds a unique id to a trace.
+ *
+ * @hide
+ */
+class TraceErrorLogger {
+ private static final String COUNTER_PREFIX = "ErrorId:";
+ private static final String ADD_ERROR_ID = "add_error_id";
+ private static final int PLACEHOLDER_VALUE = 1;
+
+ public boolean isAddErrorIdEnabled() {
+ return DeviceConfig
+ .getBoolean(DeviceConfig.NAMESPACE_TRACE_ERROR_LOGGER, ADD_ERROR_ID,
+ false);
+ }
+
+ /**
+ * Generates a unique id with which to tag a trace.
+ */
+ public UUID generateErrorId() {
+ return UUID.randomUUID();
+ }
+
+ /**
+ * Pushes a counter containing a unique id and a label {@link #COUNTER_PREFIX} so that traces
+ * 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.
+ */
+ public void addErrorIdToTrace(UUID errorId) {
+ Trace.traceCounter(Trace.TRACE_TAG_ACTIVITY_MANAGER, COUNTER_PREFIX + errorId.toString(),
+ PLACEHOLDER_VALUE);
+ }
+}
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 13dc444..b6aec836 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -3063,16 +3063,20 @@
}
@Override
- public int checkOperationRaw(int code, int uid, String packageName) {
- return mCheckOpsDelegateDispatcher.checkOperation(code, uid, packageName, true /*raw*/);
+ public int checkOperationRaw(int code, int uid, String packageName,
+ @Nullable String attributionTag) {
+ return mCheckOpsDelegateDispatcher.checkOperation(code, uid, packageName, attributionTag,
+ true /*raw*/);
}
@Override
public int checkOperation(int code, int uid, String packageName) {
- return mCheckOpsDelegateDispatcher.checkOperation(code, uid, packageName, false /*raw*/);
+ return mCheckOpsDelegateDispatcher.checkOperation(code, uid, packageName, null,
+ false /*raw*/);
}
- private int checkOperationImpl(int code, int uid, String packageName, boolean raw) {
+ private int checkOperationImpl(int code, int uid, String packageName,
+ @Nullable String attributionTag, boolean raw) {
verifyIncomingOp(code);
verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
@@ -3080,7 +3084,7 @@
if (resolvedPackageName == null) {
return AppOpsManager.MODE_IGNORED;
}
- return checkOperationUnchecked(code, uid, resolvedPackageName, raw);
+ return checkOperationUnchecked(code, uid, resolvedPackageName, attributionTag, raw);
}
/**
@@ -3094,7 +3098,7 @@
* @return The mode of the op
*/
private @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName,
- boolean raw) {
+ @Nullable String attributionTag, boolean raw) {
RestrictionBypass bypass;
try {
bypass = verifyAndGetBypass(uid, packageName, null);
@@ -3107,7 +3111,7 @@
return AppOpsManager.MODE_IGNORED;
}
synchronized (this) {
- if (isOpRestrictedLocked(uid, code, packageName, bypass)) {
+ if (isOpRestrictedLocked(uid, code, packageName, attributionTag, bypass)) {
return AppOpsManager.MODE_IGNORED;
}
code = AppOpsManager.opToSwitch(code);
@@ -3326,7 +3330,7 @@
final int switchCode = AppOpsManager.opToSwitch(code);
final UidState uidState = ops.uidState;
- if (isOpRestrictedLocked(uid, code, packageName, bypass)) {
+ if (isOpRestrictedLocked(uid, code, packageName, attributionTag, bypass)) {
attributedOp.rejected(uidState.state, flags);
scheduleOpNotedIfNeededLocked(code, uid, packageName, attributionTag, flags,
AppOpsManager.MODE_IGNORED);
@@ -3813,7 +3817,7 @@
final Op op = getOpLocked(ops, code, uid, true);
final AttributedOp attributedOp = op.getOrCreateAttribution(op, attributionTag);
final UidState uidState = ops.uidState;
- isRestricted = isOpRestrictedLocked(uid, code, packageName, bypass);
+ isRestricted = isOpRestrictedLocked(uid, code, packageName, attributionTag, bypass);
final int switchCode = AppOpsManager.opToSwitch(code);
// If there is a non-default per UID policy (we set UID op mode only if
// non-default) it takes over, otherwise use the per package policy.
@@ -4555,7 +4559,7 @@
}
private boolean isOpRestrictedLocked(int uid, int code, String packageName,
- @Nullable RestrictionBypass appBypass) {
+ String attributionTag, @Nullable RestrictionBypass appBypass) {
int userHandle = UserHandle.getUserId(uid);
final int restrictionSetCount = mOpUserRestrictions.size();
@@ -4563,7 +4567,7 @@
// For each client, check that the given op is not restricted, or that the given
// package is exempt from the restriction.
ClientRestrictionState restrictionState = mOpUserRestrictions.valueAt(i);
- if (restrictionState.hasRestriction(code, packageName, userHandle)) {
+ if (restrictionState.hasRestriction(code, packageName, attributionTag, userHandle)) {
RestrictionBypass opBypass = opAllowSystemBypassRestriction(code);
if (opBypass != null) {
// If we are the system, bypass user restrictions for certain codes
@@ -6177,25 +6181,20 @@
}
}
- final int excludedPackageCount = restrictionState.perUserExcludedPackages != null
- ? restrictionState.perUserExcludedPackages.size() : 0;
+ final int excludedPackageCount = restrictionState.perUserExcludedPackageTags != null
+ ? restrictionState.perUserExcludedPackageTags.size() : 0;
if (excludedPackageCount > 0 && dumpOp < 0) {
boolean printedPackagesHeader = false;
for (int j = 0; j < excludedPackageCount; j++) {
- int userId = restrictionState.perUserExcludedPackages.keyAt(j);
- String[] packageNames = restrictionState.perUserExcludedPackages.valueAt(j);
+ int userId = restrictionState.perUserExcludedPackageTags.keyAt(j);
+ Map<String, String[]> packageNames =
+ restrictionState.perUserExcludedPackageTags.valueAt(j);
if (packageNames == null) {
continue;
}
boolean hasPackage;
if (dumpPackage != null) {
- hasPackage = false;
- for (String pkg : packageNames) {
- if (dumpPackage.equals(pkg)) {
- hasPackage = true;
- break;
- }
- }
+ hasPackage = packageNames.containsKey(dumpPackage);
} else {
hasPackage = true;
}
@@ -6210,8 +6209,24 @@
pw.println(" Excluded packages:");
printedPackagesHeader = true;
}
- pw.print(" "); pw.print("user: "); pw.print(userId);
- pw.print(" packages: "); pw.println(Arrays.toString(packageNames));
+ pw.print(" ");
+ pw.print("user: ");
+ pw.print(userId);
+ pw.println(" packages: ");
+ for (Map.Entry<String, String[]> entry : packageNames.entrySet()) {
+ if (entry.getValue() == null) {
+ continue;
+ }
+ pw.print(" ");
+ pw.print(entry.getKey());
+ pw.print(": ");
+ if (entry.getValue().length == 0) {
+ pw.print("*");
+ } else {
+ pw.print(Arrays.toString(entry.getValue()));
+ }
+ pw.println();
+ }
}
}
}
@@ -6245,7 +6260,7 @@
@Override
public void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle,
- String[] exceptionPackages) {
+ Map<String, String[]> excludedPackageTags) {
if (Binder.getCallingPid() != Process.myPid()) {
mContext.enforcePermission(Manifest.permission.MANAGE_APP_OPS_RESTRICTIONS,
Binder.getCallingPid(), Binder.getCallingUid(), null);
@@ -6261,11 +6276,11 @@
}
verifyIncomingOp(code);
Objects.requireNonNull(token);
- setUserRestrictionNoCheck(code, restricted, token, userHandle, exceptionPackages);
+ setUserRestrictionNoCheck(code, restricted, token, userHandle, excludedPackageTags);
}
private void setUserRestrictionNoCheck(int code, boolean restricted, IBinder token,
- int userHandle, String[] exceptionPackages) {
+ int userHandle, Map<String, String[]> excludedPackageTags) {
synchronized (AppOpsService.this) {
ClientRestrictionState restrictionState = mOpUserRestrictions.get(token);
@@ -6278,7 +6293,8 @@
mOpUserRestrictions.put(token, restrictionState);
}
- if (restrictionState.setRestriction(code, restricted, exceptionPackages, userHandle)) {
+ if (restrictionState.setRestriction(code, restricted, excludedPackageTags,
+ userHandle)) {
mHandler.sendMessage(PooledLambda.obtainMessage(
AppOpsService::notifyWatchersOfChange, this, code, UID_ANY));
mHandler.sendMessage(PooledLambda.obtainMessage(
@@ -6454,6 +6470,7 @@
"offsetHistory");
// Must not hold the appops lock
mHistoricalRegistry.offsetHistory(offsetMillis);
+ mHistoricalRegistry.offsetDiscreteHistory(offsetMillis);
}
@Override
@@ -6808,7 +6825,7 @@
private final class ClientRestrictionState implements DeathRecipient {
private final IBinder token;
SparseArray<boolean[]> perUserRestrictions;
- SparseArray<String[]> perUserExcludedPackages;
+ SparseArray<Map<String, String[]>> perUserExcludedPackageTags;
public ClientRestrictionState(IBinder token)
throws RemoteException {
@@ -6817,7 +6834,7 @@
}
public boolean setRestriction(int code, boolean restricted,
- String[] excludedPackages, int userId) {
+ Map<String, String[]> excludedPackageTags, int userId) {
boolean changed = false;
if (perUserRestrictions == null && restricted) {
@@ -6859,19 +6876,27 @@
}
if (userRestrictions != null) {
- final boolean noExcludedPackages = ArrayUtils.isEmpty(excludedPackages);
- if (perUserExcludedPackages == null && !noExcludedPackages) {
- perUserExcludedPackages = new SparseArray<>();
+ final boolean noExcludedPackages = ArrayUtils.isEmpty(excludedPackageTags);
+ if (perUserExcludedPackageTags == null && !noExcludedPackages) {
+ perUserExcludedPackageTags = new SparseArray<>();
}
- if (perUserExcludedPackages != null && !Arrays.equals(excludedPackages,
- perUserExcludedPackages.get(thisUserId))) {
+ if (perUserExcludedPackageTags != null) {
if (noExcludedPackages) {
- perUserExcludedPackages.remove(thisUserId);
- if (perUserExcludedPackages.size() <= 0) {
- perUserExcludedPackages = null;
+ perUserExcludedPackageTags.remove(thisUserId);
+ if (perUserExcludedPackageTags.size() <= 0) {
+ perUserExcludedPackageTags = null;
}
} else {
- perUserExcludedPackages.put(thisUserId, excludedPackages);
+ Map<String, String[]> userExcludedPackageTags =
+ perUserExcludedPackageTags.get(thisUserId);
+ if (userExcludedPackageTags == null) {
+ userExcludedPackageTags = new ArrayMap<>(
+ excludedPackageTags.size());
+ perUserExcludedPackageTags.put(thisUserId,
+ userExcludedPackageTags);
+ }
+ userExcludedPackageTags.clear();
+ userExcludedPackageTags.putAll(excludedPackageTags);
}
changed = true;
}
@@ -6882,7 +6907,8 @@
return changed;
}
- public boolean hasRestriction(int restriction, String packageName, int userId) {
+ public boolean hasRestriction(int restriction, String packageName, String attributionTag,
+ int userId) {
if (perUserRestrictions == null) {
return false;
}
@@ -6893,21 +6919,29 @@
if (!restrictions[restriction]) {
return false;
}
- if (perUserExcludedPackages == null) {
+ if (perUserExcludedPackageTags == null) {
return true;
}
- String[] perUserExclusions = perUserExcludedPackages.get(userId);
+ Map<String, String[]> perUserExclusions = perUserExcludedPackageTags.get(userId);
if (perUserExclusions == null) {
return true;
}
- return !ArrayUtils.contains(perUserExclusions, packageName);
+ String[] excludedTags = perUserExclusions.get(packageName);
+ if (excludedTags == null) {
+ return true;
+ }
+ if (excludedTags.length == 0) {
+ // all attribution tags within the package are excluded
+ return false;
+ }
+ return !ArrayUtils.contains(excludedTags, attributionTag);
}
public void removeUser(int userId) {
- if (perUserExcludedPackages != null) {
- perUserExcludedPackages.remove(userId);
- if (perUserExcludedPackages.size() <= 0) {
- perUserExcludedPackages = null;
+ if (perUserExcludedPackageTags != null) {
+ perUserExcludedPackageTags.remove(userId);
+ if (perUserExcludedPackageTags.size() <= 0) {
+ perUserExcludedPackageTags = null;
}
}
if (perUserRestrictions != null) {
@@ -7139,23 +7173,25 @@
return mCheckOpsDelegate;
}
- public int checkOperation(int code, int uid, String packageName, boolean raw) {
+ public int checkOperation(int code, int uid, String packageName,
+ @Nullable String attributionTag, boolean raw) {
if (mPolicy != null) {
if (mCheckOpsDelegate != null) {
- return mPolicy.checkOperation(code, uid, packageName, raw,
+ return mPolicy.checkOperation(code, uid, packageName, attributionTag, raw,
this::checkDelegateOperationImpl);
} else {
- return mPolicy.checkOperation(code, uid, packageName, raw,
+ return mPolicy.checkOperation(code, uid, packageName, attributionTag, raw,
AppOpsService.this::checkOperationImpl);
}
} else if (mCheckOpsDelegate != null) {
- return checkDelegateOperationImpl(code, uid, packageName, raw);
+ return checkDelegateOperationImpl(code, uid, packageName, attributionTag, raw);
}
- return checkOperationImpl(code, uid, packageName, raw);
+ return checkOperationImpl(code, uid, packageName, attributionTag, raw);
}
- private int checkDelegateOperationImpl(int code, int uid, String packageName, boolean raw) {
- return mCheckOpsDelegate.checkOperation(code, uid, packageName, raw,
+ private int checkDelegateOperationImpl(int code, int uid, String packageName,
+ @Nullable String attributionTag, boolean raw) {
+ return mCheckOpsDelegate.checkOperation(code, uid, packageName, attributionTag, raw,
AppOpsService.this::checkOperationImpl);
}
diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java
index 35e8d34..0ab6c4a 100644
--- a/services/core/java/com/android/server/appop/HistoricalRegistry.java
+++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java
@@ -212,6 +212,7 @@
}
void systemReady(@NonNull ContentResolver resolver) {
+ mDiscreteRegistry.systemReady();
final Uri uri = Settings.Global.getUriFor(Settings.Global.APPOP_HISTORY_PARAMETERS);
resolver.registerContentObserver(uri, false, new ContentObserver(
FgThread.getHandler()) {
@@ -249,7 +250,6 @@
}
}
}
- mDiscreteRegistry.systemReady();
}
private boolean isPersistenceInitializedMLocked() {
@@ -594,6 +594,9 @@
mPersistence.persistHistoricalOpsDLocked(history);
}
}
+ }
+
+ void offsetDiscreteHistory(long offsetMillis) {
mDiscreteRegistry.offsetHistory(offsetMillis);
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index a3c5904..136916a 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -413,6 +413,26 @@
AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY
AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT
};
+ /**
+ * Using Volume groups configuration allows to control volume per attributes
+ * and group definition may differ from stream aliases.
+ * So, do not alias any stream on one another when using volume groups.
+ * TODO(b/181140246): volume group definition hosting alias definition.
+ */
+ private final int[] STREAM_VOLUME_ALIAS_NONE = new int[] {
+ AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL
+ AudioSystem.STREAM_SYSTEM, // STREAM_SYSTEM
+ AudioSystem.STREAM_RING, // STREAM_RING
+ AudioSystem.STREAM_MUSIC, // STREAM_MUSIC
+ AudioSystem.STREAM_ALARM, // STREAM_ALARM
+ AudioSystem.STREAM_NOTIFICATION, // STREAM_NOTIFICATION
+ AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO
+ AudioSystem.STREAM_SYSTEM_ENFORCED, // STREAM_SYSTEM_ENFORCED
+ AudioSystem.STREAM_DTMF, // STREAM_DTMF
+ AudioSystem.STREAM_TTS, // STREAM_TTS
+ AudioSystem.STREAM_ACCESSIBILITY, // STREAM_ACCESSIBILITY
+ AudioSystem.STREAM_ASSISTANT // STREAM_ASSISTANT
+ };
private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] {
AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL
AudioSystem.STREAM_RING, // STREAM_SYSTEM
@@ -428,6 +448,7 @@
AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT
};
protected static int[] mStreamVolumeAlias;
+ private static final int UNSET_INDEX = -1;
/**
* Map AudioSystem.STREAM_* constants to app ops. This should be used
@@ -449,6 +470,7 @@
};
private final boolean mUseFixedVolume;
+ private final boolean mUseVolumeGroupAliases;
// If absolute volume is supported in AVRCP device
private volatile boolean mAvrcpAbsVolSupported = false;
@@ -849,6 +871,9 @@
mSupportsMicPrivacyToggle = context.getSystemService(SensorPrivacyManager.class)
.supportsSensorToggle(SensorPrivacyManager.Sensors.MICROPHONE);
+ mUseVolumeGroupAliases = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_handleVolumeAliasesUsingVolumeGroups);
+
// Initialize volume
// Priority 1 - Android Property
// Priority 2 - Audio Policy Service
@@ -869,6 +894,12 @@
MIN_STREAM_VOLUME[streamType] = minVolume;
}
}
+ if (mUseVolumeGroupAliases) {
+ // Set all default to uninitialized.
+ for (int stream = 0; stream < AudioSystem.DEFAULT_STREAM_VOLUME.length; stream++) {
+ AudioSystem.DEFAULT_STREAM_VOLUME[stream] = UNSET_INDEX;
+ }
+ }
}
int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1);
@@ -1705,18 +1736,42 @@
updateDefaultVolumes();
}
- // Update default indexes from aliased streams. Must be called after mStreamStates is created
+ /**
+ * Update default indexes from aliased streams. Must be called after mStreamStates is created
+ * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for default
+ * index. Need to make default index configurable and independent of streams.
+ * Fallback on music stream for default initialization to take benefit of property based default
+ * initialization.
+ * For other volume groups not linked to any streams, default music stream index is considered.
+ */
private void updateDefaultVolumes() {
for (int stream = 0; stream < mStreamStates.length; stream++) {
- if (stream != mStreamVolumeAlias[stream]) {
- AudioSystem.DEFAULT_STREAM_VOLUME[stream] = (rescaleIndex(
- AudioSystem.DEFAULT_STREAM_VOLUME[mStreamVolumeAlias[stream]] * 10,
- mStreamVolumeAlias[stream],
- stream) + 5) / 10;
+ int streamVolumeAlias = mStreamVolumeAlias[stream];
+ if (mUseVolumeGroupAliases) {
+ if (AudioSystem.DEFAULT_STREAM_VOLUME[stream] != UNSET_INDEX) {
+ // Already initialized through default property based mecanism.
+ continue;
+ }
+ streamVolumeAlias = AudioSystem.STREAM_MUSIC;
+ int defaultAliasVolume = getUiDefaultRescaledIndex(streamVolumeAlias, stream);
+ if ((defaultAliasVolume >= MIN_STREAM_VOLUME[stream])
+ && (defaultAliasVolume <= MAX_STREAM_VOLUME[stream])) {
+ AudioSystem.DEFAULT_STREAM_VOLUME[stream] = defaultAliasVolume;
+ continue;
+ }
+ }
+ if (stream != streamVolumeAlias) {
+ AudioSystem.DEFAULT_STREAM_VOLUME[stream] =
+ getUiDefaultRescaledIndex(streamVolumeAlias, stream);
}
}
}
+ private int getUiDefaultRescaledIndex(int srcStream, int dstStream) {
+ return (rescaleIndex(AudioSystem.DEFAULT_STREAM_VOLUME[srcStream] * 10,
+ srcStream, dstStream) + 5) / 10;
+ }
+
private void dumpStreamStates(PrintWriter pw) {
pw.println("\nStream volumes (device: index)");
int numStreamTypes = AudioSystem.getNumStreamTypes();
@@ -1740,6 +1795,9 @@
if (mIsSingleVolume) {
mStreamVolumeAlias = STREAM_VOLUME_ALIAS_TELEVISION;
dtmfStreamAlias = AudioSystem.STREAM_MUSIC;
+ } else if (mUseVolumeGroupAliases) {
+ mStreamVolumeAlias = STREAM_VOLUME_ALIAS_NONE;
+ dtmfStreamAlias = AudioSystem.STREAM_DTMF;
} else {
switch (mPlatformType) {
case AudioSystem.PLATFORM_VOICE:
@@ -2768,7 +2826,7 @@
// If either the client forces allowing ringer modes for this adjustment,
// or the stream type is one that is affected by ringer modes
if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
- (streamTypeAlias == getUiSoundsStreamType())) {
+ (isUiSoundsStreamType(streamTypeAlias))) {
int ringerMode = getRingerModeInternal();
// do not vibrate if already in vibrate mode
if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
@@ -3570,7 +3628,7 @@
case Settings.Global.ZEN_MODE_ALARMS:
case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
return !isStreamMutedByRingerOrZenMode(streamTypeAlias)
- || streamTypeAlias == getUiSoundsStreamType()
+ || isUiSoundsStreamType(streamTypeAlias)
|| (flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0;
}
@@ -3987,9 +4045,26 @@
return (mStreamStates[streamType].getIndex(device) + 5) / 10;
}
- /** @see AudioManager#getUiSoundsStreamType() */
+ /** @see AudioManager#getUiSoundsStreamType()
+ * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for
+ * UI Sounds identification.
+ * Fallback on Voice configuration to ensure correct behavior of DnD feature.
+ */
public int getUiSoundsStreamType() {
- return mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
+ return mUseVolumeGroupAliases ? STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM]
+ : mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
+ }
+
+ /**
+ * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for
+ * UI Sounds identification.
+ * Fallback on Voice configuration to ensure correct behavior of DnD feature.
+ */
+ private boolean isUiSoundsStreamType(int aliasStreamType) {
+ return mUseVolumeGroupAliases
+ ? STREAM_VOLUME_ALIAS_VOICE[aliasStreamType]
+ == STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM]
+ : aliasStreamType == mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
}
/** @see AudioManager#setMicrophoneMute(boolean) */
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index ab67b13..093ecd5 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -379,7 +379,15 @@
return null;
}
synchronized (mLock) {
- addActiveOwnerLocked(intendingUid, pkg);
+ try {
+ addActiveOwnerLocked(intendingUid, pkg);
+ } catch (SecurityException e) {
+ // Permission could not be granted - URI may be invalid
+ Slog.i(TAG, "Could not grant permission to primary clip. Clearing clipboard.");
+ setPrimaryClipInternalLocked(null, intendingUid, pkg);
+ return null;
+ }
+
PerUserClipboard clipboard = getClipboardLocked(intendingUserId);
showAccessNotificationLocked(pkg, intendingUid, intendingUserId, clipboard);
notifyTextClassifierLocked(clipboard, pkg, intendingUid);
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index 8829fa9..1e8d904 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -139,6 +139,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -1405,21 +1406,28 @@
Preconditions.checkArgument(userId >= 0);
-
boolean enabled = mInjector.getSettingsHelper().isLocationEnabled(userId);
- String[] allowedPackages = null;
+ ArrayMap<String, String[]> allowedPackages = null;
if (!enabled) {
- ArraySet<String> packages = new ArraySet<>();
+ ArrayMap<String, ArraySet<String>> packages = new ArrayMap<>();
for (LocationProviderManager manager : mProviderManagers) {
CallerIdentity identity = manager.getIdentity();
if (identity != null) {
- packages.add(identity.getPackageName());
+ packages.computeIfAbsent(identity.getPackageName(), k -> new ArraySet<>()).add(
+ identity.getAttributionTag());
}
}
- packages.add(mContext.getPackageName());
- packages.addAll(mInjector.getSettingsHelper().getIgnoreSettingsPackageWhitelist());
- allowedPackages = packages.toArray(new String[0]);
+ for (String packageName :
+ mInjector.getSettingsHelper().getIgnoreSettingsPackageWhitelist()) {
+ packages.computeIfAbsent(packageName, k -> new ArraySet<>());
+ }
+ packages.computeIfAbsent(mContext.getPackageName(), k -> new ArraySet<>());
+
+ allowedPackages = new ArrayMap<>();
+ for (Map.Entry<String, ArraySet<String>> entry : packages.entrySet()) {
+ allowedPackages.put(entry.getKey(), entry.getValue().toArray(new String[0]));
+ }
}
AppOpsManager appOpsManager = Objects.requireNonNull(
diff --git a/services/core/java/com/android/server/location/LocationShellCommand.java b/services/core/java/com/android/server/location/LocationShellCommand.java
index 5dc3ed8..9378493 100644
--- a/services/core/java/com/android/server/location/LocationShellCommand.java
+++ b/services/core/java/com/android/server/location/LocationShellCommand.java
@@ -20,6 +20,7 @@
import android.location.Criteria;
import android.location.Location;
import android.location.provider.ProviderProperties;
+import android.os.SystemClock;
import android.os.UserHandle;
import com.android.modules.utils.BasicShellCommandHandler;
@@ -236,7 +237,7 @@
Location location = new Location(provider);
location.setAccuracy(DEFAULT_TEST_LOCATION_ACCURACY);
location.setTime(System.currentTimeMillis());
- location.setElapsedRealtimeNanos(System.nanoTime());
+ location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
do {
String option = getNextOption();
diff --git a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
index 1d73abc..8fc5fbe 100644
--- a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
+++ b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
@@ -288,7 +288,9 @@
if (targetUserProfiles.isEmpty()) {
return false;
}
- return hasCallerGotInteractAcrossProfilesPermission(callingPackage);
+ return hasCallerGotInteractAcrossProfilesPermission(callingPackage)
+ && haveProfilesGotInteractAcrossProfilesPermission(
+ callingPackage, targetUserProfiles);
}
private boolean hasCallerGotInteractAcrossProfilesPermission(String callingPackage) {
@@ -296,6 +298,28 @@
callingPackage, mInjector.getCallingUid(), mInjector.getCallingPid());
}
+ private boolean haveProfilesGotInteractAcrossProfilesPermission(
+ String packageName, List<UserHandle> profiles) {
+ for (UserHandle profile : profiles) {
+ final int uid = mInjector.withCleanCallingIdentity(() -> {
+ try {
+ return mInjector.getPackageManager().getPackageUidAsUser(
+ packageName, /* flags= */ 0, profile.getIdentifier());
+ } catch (PackageManager.NameNotFoundException e) {
+ return -1;
+ }
+ });
+ if (uid == -1) {
+ return false;
+ }
+ if (!hasInteractAcrossProfilesPermission(
+ packageName, uid, PermissionChecker.PID_UNKNOWN)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
private boolean isCrossProfilePackageAllowlisted(String packageName) {
return mInjector.withCleanCallingIdentity(() ->
mInjector.getDevicePolicyManagerInternal()
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 6f4ec82..83eb093 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -3762,13 +3762,6 @@
}
}
- final DataLoaderManager dataLoaderManager = mContext.getSystemService(
- DataLoaderManager.class);
- if (dataLoaderManager == null) {
- throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE,
- "Failed to find data loader manager service");
- }
-
final DataLoaderParams params = this.params.dataLoaderParams;
final boolean manualStartAndDestroy = !isIncrementalInstallation();
final boolean systemDataLoader = isSystemDataLoaderInstallation();
@@ -3793,20 +3786,13 @@
return;
}
try {
- IDataLoader dataLoader = dataLoaderManager.getDataLoader(dataLoaderId);
- if (dataLoader == null) {
- mDataLoaderFinished = true;
- dispatchSessionValidationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
- "Failure to obtain data loader");
- return;
- }
-
switch (status) {
case IDataLoaderStatusListener.DATA_LOADER_BOUND: {
if (manualStartAndDestroy) {
FileSystemControlParcel control = new FileSystemControlParcel();
control.callback = new FileSystemConnector(addedFiles);
- dataLoader.create(dataLoaderId, params.getData(), control, this);
+ getDataLoader(dataLoaderId).create(dataLoaderId, params.getData(),
+ control, this);
}
break;
@@ -3815,12 +3801,12 @@
if (manualStartAndDestroy) {
// IncrementalFileStorages will call start after all files are
// created in IncFS.
- dataLoader.start(dataLoaderId);
+ getDataLoader(dataLoaderId).start(dataLoaderId);
}
break;
}
case IDataLoaderStatusListener.DATA_LOADER_STARTED: {
- dataLoader.prepareImage(
+ getDataLoader(dataLoaderId).prepareImage(
dataLoaderId,
addedFiles.toArray(
new InstallationFileParcel[addedFiles.size()]),
@@ -3836,7 +3822,7 @@
dispatchSessionSealed();
}
if (manualStartAndDestroy) {
- dataLoader.destroy(dataLoaderId);
+ getDataLoader(dataLoaderId).destroy(dataLoaderId);
}
break;
}
@@ -3845,7 +3831,7 @@
dispatchSessionValidationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
"Failed to prepare image.");
if (manualStartAndDestroy) {
- dataLoader.destroy(dataLoaderId);
+ getDataLoader(dataLoaderId).destroy(dataLoaderId);
}
break;
}
@@ -3860,11 +3846,12 @@
break;
}
case IDataLoaderStatusListener.DATA_LOADER_UNRECOVERABLE:
- mDataLoaderFinished = true;
- dispatchSessionValidationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
+ throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE,
"DataLoader reported unrecoverable failure.");
- break;
}
+ } catch (PackageManagerException e) {
+ mDataLoaderFinished = true;
+ dispatchSessionValidationFailure(e.error, ExceptionUtils.getCompleteMessage(e));
} catch (RemoteException e) {
// In case of streaming failure we don't want to fail or commit the session.
// Just return from this method and allow caller to commit again.
@@ -3939,7 +3926,7 @@
}
final long bindDelayMs = 0;
- if (!dataLoaderManager.bindToDataLoader(sessionId, params.getData(), bindDelayMs,
+ if (!getDataLoaderManager().bindToDataLoader(sessionId, params.getData(), bindDelayMs,
statusListener)) {
throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE,
"Failed to initialize data loader");
@@ -3948,6 +3935,24 @@
return false;
}
+ private DataLoaderManager getDataLoaderManager() throws PackageManagerException {
+ DataLoaderManager dataLoaderManager = mContext.getSystemService(DataLoaderManager.class);
+ if (dataLoaderManager == null) {
+ throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE,
+ "Failed to find data loader manager service");
+ }
+ return dataLoaderManager;
+ }
+
+ private IDataLoader getDataLoader(int dataLoaderId) throws PackageManagerException {
+ IDataLoader dataLoader = getDataLoaderManager().getDataLoader(dataLoaderId);
+ if (dataLoader == null) {
+ throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE,
+ "Failure to obtain data loader");
+ }
+ return dataLoader;
+ }
+
private void dispatchSessionValidationFailure(int error, String detailMessage) {
mHandler.obtainMessage(MSG_SESSION_VALIDATION_FAILURE, error, -1,
detailMessage).sendToTarget();
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java b/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java
index 1814a8e..a1e5153 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java
@@ -33,9 +33,12 @@
import java.io.IOException;
import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Collection;
+import java.util.concurrent.atomic.AtomicLong;
/**
* Callback data loader for PackageManagerShellCommand installations.
@@ -136,6 +139,12 @@
private final byte mMode;
private final String mData;
+ private final String mSalt;
+
+ private static AtomicLong sGlobalSalt = new AtomicLong((new SecureRandom()).nextLong());
+ private static Long nextGlobalSalt() {
+ return sGlobalSalt.incrementAndGet();
+ }
static Metadata forStdIn(String fileId) {
return new Metadata(STDIN, fileId);
@@ -144,7 +153,7 @@
/** @hide */
@VisibleForTesting
public static Metadata forLocalFile(String filePath) {
- return new Metadata(LOCAL_FILE, filePath);
+ return new Metadata(LOCAL_FILE, filePath, nextGlobalSalt().toString());
}
static Metadata forDataOnlyStreaming(String fileId) {
@@ -156,26 +165,71 @@
}
private Metadata(byte mode, String data) {
+ this(mode, data, null);
+ }
+
+ private Metadata(byte mode, String data, String salt) {
this.mMode = mode;
this.mData = (data == null) ? "" : data;
+ this.mSalt = salt;
}
static Metadata fromByteArray(byte[] bytes) throws IOException {
- if (bytes == null || bytes.length == 0) {
+ if (bytes == null || bytes.length < 5) {
return null;
}
- byte mode = bytes[0];
- String data = new String(bytes, 1, bytes.length - 1, StandardCharsets.UTF_8);
- return new Metadata(mode, data);
+ int offset = 0;
+ final byte mode = bytes[offset];
+ offset += 1;
+ final String data;
+ final String salt;
+ switch (mode) {
+ case LOCAL_FILE: {
+ int dataSize = ByteBuffer.wrap(bytes, offset, 4).order(
+ ByteOrder.LITTLE_ENDIAN).getInt();
+ offset += 4;
+ data = new String(bytes, offset, dataSize, StandardCharsets.UTF_8);
+ offset += dataSize;
+ salt = new String(bytes, offset, bytes.length - offset,
+ StandardCharsets.UTF_8);
+ break;
+ }
+ default:
+ data = new String(bytes, offset, bytes.length - offset,
+ StandardCharsets.UTF_8);
+ salt = null;
+ break;
+ }
+ return new Metadata(mode, data, salt);
}
/** @hide */
@VisibleForTesting
public byte[] toByteArray() {
- byte[] dataBytes = this.mData.getBytes(StandardCharsets.UTF_8);
- byte[] result = new byte[1 + dataBytes.length];
- result[0] = this.mMode;
- System.arraycopy(dataBytes, 0, result, 1, dataBytes.length);
+ final byte[] result;
+ final byte[] dataBytes = this.mData.getBytes(StandardCharsets.UTF_8);
+ switch (this.mMode) {
+ case LOCAL_FILE: {
+ int dataSize = dataBytes.length;
+ byte[] saltBytes = this.mSalt.getBytes(StandardCharsets.UTF_8);
+ result = new byte[1 + 4 + dataSize + saltBytes.length];
+ int offset = 0;
+ result[offset] = this.mMode;
+ offset += 1;
+ ByteBuffer.wrap(result, offset, 4).order(ByteOrder.LITTLE_ENDIAN).putInt(
+ dataSize);
+ offset += 4;
+ System.arraycopy(dataBytes, 0, result, offset, dataSize);
+ offset += dataSize;
+ System.arraycopy(saltBytes, 0, result, offset, saltBytes.length);
+ break;
+ }
+ default:
+ result = new byte[1 + dataBytes.length];
+ result[0] = this.mMode;
+ System.arraycopy(dataBytes, 0, result, 1, dataBytes.length);
+ break;
+ }
return result;
}
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 20f35f2..1e9d7e1 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -1213,7 +1213,9 @@
final String pkg = shortcutInfo.getPackage();
final int userId = shortcutInfo.getUserId();
final String id = shortcutInfo.getId();
- getPackageShortcutsLocked(pkg, userId).mutateShortcut(id, shortcutInfo, cb);
+ synchronized (mLock) {
+ getPackageShortcutsLocked(pkg, userId).mutateShortcut(id, shortcutInfo, cb);
+ }
}
/** Return the last reset time. */
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java
index 3a097a7..2cfbf26 100644
--- a/services/core/java/com/android/server/policy/AppOpsPolicy.java
+++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java
@@ -44,6 +44,7 @@
import com.android.internal.util.function.NonaFunction;
import com.android.internal.util.function.OctFunction;
import com.android.internal.util.function.QuadFunction;
+import com.android.internal.util.function.QuintFunction;
import com.android.internal.util.function.TriFunction;
import com.android.server.LocalServices;
@@ -140,9 +141,10 @@
}
@Override
- public int checkOperation(int code, int uid, String packageName, boolean raw,
- QuadFunction<Integer, Integer, String, Boolean, Integer> superImpl) {
- return superImpl.apply(code, uid, packageName, raw);
+ public int checkOperation(int code, int uid, String packageName,
+ @Nullable String attributionTag, boolean raw,
+ QuintFunction<Integer, Integer, String, String, Boolean, Integer> superImpl) {
+ return superImpl.apply(code, uid, packageName, attributionTag, raw);
}
@Override
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
index 457dc43..b1b537b 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
@@ -304,6 +304,13 @@
mHandler.post(() -> mTimeZoneDetectorStrategy.suggestTelephonyTimeZone(timeZoneSuggestion));
}
+ boolean isTelephonyTimeZoneDetectionSupported() {
+ enforceManageTimeZoneDetectorPermission();
+
+ return ServiceConfigAccessor.getInstance(mContext)
+ .isTelephonyTimeZoneDetectionFeatureSupported();
+ }
+
boolean isGeoTimeZoneDetectionSupported() {
enforceManageTimeZoneDetectorPermission();
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorShellCommand.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorShellCommand.java
index 9899b448b..a4a46a3 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorShellCommand.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorShellCommand.java
@@ -18,6 +18,7 @@
import static android.app.timezonedetector.TimeZoneDetector.SHELL_COMMAND_IS_AUTO_DETECTION_ENABLED;
import static android.app.timezonedetector.TimeZoneDetector.SHELL_COMMAND_IS_GEO_DETECTION_ENABLED;
import static android.app.timezonedetector.TimeZoneDetector.SHELL_COMMAND_IS_GEO_DETECTION_SUPPORTED;
+import static android.app.timezonedetector.TimeZoneDetector.SHELL_COMMAND_IS_TELEPHONY_DETECTION_SUPPORTED;
import static android.app.timezonedetector.TimeZoneDetector.SHELL_COMMAND_SERVICE_NAME;
import static android.app.timezonedetector.TimeZoneDetector.SHELL_COMMAND_SET_AUTO_DETECTION_ENABLED;
import static android.app.timezonedetector.TimeZoneDetector.SHELL_COMMAND_SET_GEO_DETECTION_ENABLED;
@@ -61,6 +62,8 @@
return runIsAutoDetectionEnabled();
case SHELL_COMMAND_SET_AUTO_DETECTION_ENABLED:
return runSetAutoDetectionEnabled();
+ case SHELL_COMMAND_IS_TELEPHONY_DETECTION_SUPPORTED:
+ return runIsTelephonyDetectionSupported();
case SHELL_COMMAND_IS_GEO_DETECTION_SUPPORTED:
return runIsGeoDetectionSupported();
case SHELL_COMMAND_IS_GEO_DETECTION_ENABLED:
@@ -89,6 +92,13 @@
return 0;
}
+ private int runIsTelephonyDetectionSupported() {
+ final PrintWriter pw = getOutPrintWriter();
+ boolean enabled = mInterface.isTelephonyTimeZoneDetectionSupported();
+ pw.println(enabled);
+ return 0;
+ }
+
private int runIsGeoDetectionSupported() {
final PrintWriter pw = getOutPrintWriter();
boolean enabled = mInterface.isGeoTimeZoneDetectionSupported();
@@ -169,6 +179,9 @@
pw.printf(" Prints true/false according to the automatic time zone detection setting\n");
pw.printf(" %s true|false\n", SHELL_COMMAND_SET_AUTO_DETECTION_ENABLED);
pw.printf(" Sets the automatic time zone detection setting.\n");
+ pw.printf(" %s\n", SHELL_COMMAND_IS_TELEPHONY_DETECTION_SUPPORTED);
+ pw.printf(" Prints true/false according to whether telephony time zone detection is"
+ + " supported on this device.\n");
pw.printf(" %s\n", SHELL_COMMAND_IS_GEO_DETECTION_SUPPORTED);
pw.printf(" Prints true/false according to whether geolocation time zone detection is"
+ " supported on this device.\n");
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index ae873e2..2ac50b6 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -66,7 +66,6 @@
import com.android.server.LocalServices;
import com.android.server.SystemConfig;
import com.android.server.SystemService;
-import com.android.server.SystemService.TargetUser;
import com.android.server.utils.ManagedApplicationService;
import com.android.server.utils.ManagedApplicationService.BinderChecker;
import com.android.server.utils.ManagedApplicationService.LogEvent;
@@ -86,6 +85,7 @@
import java.util.Collection;
import java.util.Date;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
/**
@@ -856,12 +856,15 @@
// If user changed drop restrictions for the old user.
if (oldUserId != newUserId) {
appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
- false, mOverlayToken, null, oldUserId);
+ false, mOverlayToken, (Map<String, String[]>) null, oldUserId);
}
// Apply the restrictions for the current user based on vr state
- String[] exemptions = (exemptedPackage == null) ? new String[0] :
- new String[] { exemptedPackage };
+ ArrayMap<String, String[]> exemptions = null;
+ if (exemptedPackage != null) {
+ exemptions = new ArrayMap<>(1);
+ exemptions.put(exemptedPackage, new String[0]);
+ }
appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
mVrModeEnabled, mOverlayToken, exemptions, newUserId);
diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java
index 9855ea5..b24ab93 100644
--- a/services/core/java/com/android/server/wm/DisplayArea.java
+++ b/services/core/java/com/android/server/wm/DisplayArea.java
@@ -25,6 +25,9 @@
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.internal.util.Preconditions.checkState;
+import static com.android.server.wm.DisplayAreaProto.FEATURE_ID;
+import static com.android.server.wm.DisplayAreaProto.IS_ORGANIZED;
+import static com.android.server.wm.DisplayAreaProto.IS_ROOT_DISPLAY_AREA;
import static com.android.server.wm.DisplayAreaProto.IS_TASK_DISPLAY_AREA;
import static com.android.server.wm.DisplayAreaProto.NAME;
import static com.android.server.wm.DisplayAreaProto.WINDOW_CONTAINER;
@@ -273,6 +276,9 @@
super.dumpDebug(proto, WINDOW_CONTAINER, logLevel);
proto.write(NAME, mName);
proto.write(IS_TASK_DISPLAY_AREA, isTaskDisplayArea());
+ proto.write(IS_ROOT_DISPLAY_AREA, asRootDisplayArea() != null);
+ proto.write(FEATURE_ID, mFeatureId);
+ proto.write(IS_ORGANIZED, isOrganized());
proto.end(token);
}
@@ -515,7 +521,7 @@
return true;
}
- protected boolean isTaskDisplayArea() {
+ boolean isTaskDisplayArea() {
return false;
}
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index ccfdb8c..ae90a7d 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -2131,7 +2131,7 @@
}
@Override
- protected boolean isTaskDisplayArea() {
+ boolean isTaskDisplayArea() {
return true;
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index c24cb63..b93312a 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2409,18 +2409,22 @@
final boolean startingWindow = mAttrs.type == TYPE_APPLICATION_STARTING;
if (startingWindow) {
ProtoLog.d(WM_DEBUG_STARTING_WINDOW, "Starting window removed %s", this);
- }
-
- if (startingWindow && StartingSurfaceController.DEBUG_ENABLE_SHELL_DRAWER) {
// Cancel the remove starting window animation on shell. The main window might changed
// during animating, checking for all windows would be safer.
if (mActivityRecord != null) {
- mActivityRecord.forAllWindows(w -> {
+ mActivityRecord.forAllWindowsUnchecked(w -> {
if (w.isSelfAnimating(0, ANIMATION_TYPE_STARTING_REVEAL)) {
w.cancelAnimation();
+ return true;
}
+ return false;
}, true);
}
+ } else if (mAttrs.type == TYPE_BASE_APPLICATION
+ && isSelfAnimating(0, ANIMATION_TYPE_STARTING_REVEAL)) {
+ // Cancel the remove starting window animation in case the binder dead before remove
+ // splash window.
+ cancelAnimation();
}
ProtoLog.v(WM_DEBUG_FOCUS, "Remove client=%x, surfaceController=%s Callers=%s",
@@ -2428,7 +2432,6 @@
mWinAnimator.mSurfaceController,
Debug.getCallers(5));
-
final long origId = Binder.clearCallingIdentity();
try {
diff --git a/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp b/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp
index db52683..f439777 100644
--- a/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp
+++ b/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp
@@ -293,8 +293,8 @@
auto mode = read<int8_t>(metadata).value_or(STDIN);
if (mode == LOCAL_FILE) {
// local file and possibly signature
- return openLocalFile(env, jni, shellCommand, size,
- std::string(metadata.data, metadata.size));
+ auto dataSize = le32toh(read<int32_t>(metadata).value_or(0));
+ return openLocalFile(env, jni, shellCommand, size, std::string(metadata.data, dataSize));
}
if (!shellCommand) {
diff --git a/services/core/jni/gnss/GnssMeasurementCallback.cpp b/services/core/jni/gnss/GnssMeasurementCallback.cpp
index 646aabd..dd9a525 100644
--- a/services/core/jni/gnss/GnssMeasurementCallback.cpp
+++ b/services/core/jni/gnss/GnssMeasurementCallback.cpp
@@ -54,6 +54,7 @@
jmethodID method_reportMeasurementData;
jmethodID method_satellitePvtBuilderBuild;
jmethodID method_satellitePvtBuilderCtor;
+jmethodID method_satellitePvtBuilderSetFlags;
jmethodID method_satellitePvtBuilderSetPositionEcef;
jmethodID method_satellitePvtBuilderSetVelocityEcef;
jmethodID method_satellitePvtBuilderSetClockInfo;
@@ -89,6 +90,9 @@
jclass satellitePvtBuilder = env->FindClass("android/location/SatellitePvt$Builder");
class_satellitePvtBuilder = (jclass)env->NewGlobalRef(satellitePvtBuilder);
method_satellitePvtBuilderCtor = env->GetMethodID(class_satellitePvtBuilder, "<init>", "()V");
+ method_satellitePvtBuilderSetFlags =
+ env->GetMethodID(class_satellitePvtBuilder, "setFlags",
+ "(I)Landroid/location/SatellitePvt$Builder;");
method_satellitePvtBuilderSetPositionEcef =
env->GetMethodID(class_satellitePvtBuilder, "setPositionEcef",
"(Landroid/location/SatellitePvt$PositionEcef;)"
@@ -313,22 +317,33 @@
if (measurement.flags & static_cast<uint32_t>(GnssMeasurement::HAS_SATELLITE_PVT)) {
const SatellitePvt& satellitePvt = measurement.satellitePvt;
- jobject positionEcef = env->NewObject(class_positionEcef, method_positionEcef,
- satellitePvt.satPosEcef.posXMeters,
- satellitePvt.satPosEcef.posYMeters,
- satellitePvt.satPosEcef.posZMeters,
- satellitePvt.satPosEcef.ureMeters);
- jobject velocityEcef =
- env->NewObject(class_velocityEcef, method_velocityEcef,
- satellitePvt.satVelEcef.velXMps, satellitePvt.satVelEcef.velYMps,
- satellitePvt.satVelEcef.velZMps, satellitePvt.satVelEcef.ureRateMps);
- jobject clockInfo = env->NewObject(class_clockInfo, method_clockInfo,
- satellitePvt.satClockInfo.satHardwareCodeBiasMeters,
- satellitePvt.satClockInfo.satTimeCorrectionMeters,
- satellitePvt.satClockInfo.satClkDriftMps);
+ uint16_t satFlags = static_cast<uint16_t>(satellitePvt.flags);
+ jobject positionEcef = nullptr;
+ jobject velocityEcef = nullptr;
+ jobject clockInfo = nullptr;
+
+ if (satFlags & SatellitePvt::HAS_POSITION_VELOCITY_CLOCK_INFO) {
+ positionEcef = env->NewObject(class_positionEcef, method_positionEcef,
+ satellitePvt.satPosEcef.posXMeters,
+ satellitePvt.satPosEcef.posYMeters,
+ satellitePvt.satPosEcef.posZMeters,
+ satellitePvt.satPosEcef.ureMeters);
+ velocityEcef =
+ env->NewObject(class_velocityEcef, method_velocityEcef,
+ satellitePvt.satVelEcef.velXMps, satellitePvt.satVelEcef.velYMps,
+ satellitePvt.satVelEcef.velZMps,
+ satellitePvt.satVelEcef.ureRateMps);
+ clockInfo = env->NewObject(class_clockInfo, method_clockInfo,
+ satellitePvt.satClockInfo.satHardwareCodeBiasMeters,
+ satellitePvt.satClockInfo.satTimeCorrectionMeters,
+ satellitePvt.satClockInfo.satClkDriftMps);
+ }
+
jobject satellitePvtBuilderObject =
env->NewObject(class_satellitePvtBuilder, method_satellitePvtBuilderCtor);
+ env->CallObjectMethod(satellitePvtBuilderObject, method_satellitePvtBuilderSetFlags,
+ satellitePvt.flags);
env->CallObjectMethod(satellitePvtBuilderObject, method_satellitePvtBuilderSetPositionEcef,
positionEcef);
env->CallObjectMethod(satellitePvtBuilderObject, method_satellitePvtBuilderSetVelocityEcef,
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index 24699d9..8b816d0 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -1174,7 +1174,8 @@
return -EINVAL;
}
if (auto err = mIncFs->makeFile(ifs->control, normPath, mode, id, params); err) {
- LOG(ERROR) << "Internal error: storageId " << storage << " failed to makeFile: " << err;
+ LOG(ERROR) << "Internal error: storageId " << storage << " failed to makeFile [" << normPath
+ << "]: " << err;
return err;
}
if (params.size > 0) {
diff --git a/services/incremental/path.cpp b/services/incremental/path.cpp
index bf4e9616..73e00ae 100644
--- a/services/incremental/path.cpp
+++ b/services/incremental/path.cpp
@@ -171,7 +171,9 @@
}
details::CStrWrapper::CStrWrapper(std::string_view sv) {
- if (sv[sv.size()] == '\0') {
+ if (!sv.data()) {
+ mCstr = "";
+ } else if (sv[sv.size()] == '\0') {
mCstr = sv.data();
} else {
mCopy.emplace(sv);
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 0e5c77c..b6bb394 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
@@ -193,8 +193,7 @@
public void testAppSearchLoggerHelper_testCopyNativeStats_search() {
int nativeLatencyMillis = 4;
int nativeNumTerms = 5;
- // TODO(b/185804196) query length needs to be added in the native stats.
- // int nativeQueryLength = 6;
+ int nativeQueryLength = 6;
int nativeNumNamespacesFiltered = 7;
int nativeNumSchemaTypesFiltered = 8;
int nativeRequestedPageSize = 9;
@@ -211,6 +210,7 @@
QueryStatsProto.newBuilder()
.setLatencyMs(nativeLatencyMillis)
.setNumTerms(nativeNumTerms)
+ .setQueryLength(nativeQueryLength)
.setNumNamespacesFiltered(nativeNumNamespacesFiltered)
.setNumSchemaTypesFiltered(nativeNumSchemaTypesFiltered)
.setRequestedPageSize(nativeRequestedPageSize)
@@ -235,7 +235,7 @@
SearchStats sStats = qBuilder.build();
assertThat(sStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
assertThat(sStats.getTermCount()).isEqualTo(nativeNumTerms);
- // assertThat(sStats.getNativeQueryLength()).isEqualTo(nativeQueryLength);
+ assertThat(sStats.getQueryLength()).isEqualTo(nativeQueryLength);
assertThat(sStats.getFilteredNamespaceCount()).isEqualTo(nativeNumNamespacesFiltered);
assertThat(sStats.getFilteredSchemaTypeCount()).isEqualTo(nativeNumSchemaTypesFiltered);
assertThat(sStats.getRequestedPageSize()).isEqualTo(nativeRequestedPageSize);
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 0fe3903..77e0135 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
@@ -110,7 +110,7 @@
.TOKENIZER_TYPE_PLAIN)
.build())
.addProperty(
- new AppSearchSchema.Int64PropertyConfig.Builder("pubDate")
+ new AppSearchSchema.LongPropertyConfig.Builder("pubDate")
.setCardinality(
AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.build())
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/stats/AppSearchStatsTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/stats/AppSearchStatsTest.java
index edb683b..a71e532 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/stats/AppSearchStatsTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/stats/AppSearchStatsTest.java
@@ -301,4 +301,28 @@
assertThat(sStats.getBackwardsIncompatibleTypeChangeCount())
.isEqualTo(backwardsIncompatibleTypeChangeCount);
}
+
+ @Test
+ public void testAppSearchStats_RemoveStats() {
+ int nativeLatencyMillis = 1;
+ @RemoveStats.DeleteType int deleteType = 2;
+ int documentDeletedCount = 3;
+
+ final RemoveStats rStats =
+ new RemoveStats.Builder(TEST_PACKAGE_NAME, TEST_DATA_BASE)
+ .setStatusCode(TEST_STATUS_CODE)
+ .setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS)
+ .setNativeLatencyMillis(nativeLatencyMillis)
+ .setDeleteType(deleteType)
+ .setDeletedDocumentCount(documentDeletedCount)
+ .build();
+
+ assertThat(rStats.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
+ assertThat(rStats.getDatabase()).isEqualTo(TEST_DATA_BASE);
+ assertThat(rStats.getStatusCode()).isEqualTo(TEST_STATUS_CODE);
+ assertThat(rStats.getTotalLatencyMillis()).isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
+ assertThat(rStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
+ assertThat(rStats.getDeleteType()).isEqualTo(deleteType);
+ assertThat(rStats.getDeletedDocumentCount()).isEqualTo(documentDeletedCount);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/CompatibilityModeTest.java b/services/tests/servicestests/src/com/android/server/pm/CompatibilityModeTest.java
new file mode 100644
index 0000000..94ac9be
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/CompatibilityModeTest.java
@@ -0,0 +1,234 @@
+/*
+ * 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.pm;
+
+import static android.content.pm.ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS;
+import static android.content.pm.ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
+import static android.content.pm.ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS;
+import static android.content.pm.ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES;
+import static android.content.pm.ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS;
+import static android.content.pm.ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageParser;
+import android.content.pm.PackageUserState;
+import android.content.pm.parsing.PackageInfoWithoutStateUtils;
+import android.os.Build;
+
+import com.android.server.pm.parsing.pkg.AndroidPackage;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CompatibilityModeTest {
+
+ private boolean mCompatibilityModeEnabled;;
+ private AndroidPackage mMockAndroidPackage;
+ private PackageUserState mMockUserState;
+
+ @Before
+ public void setUp() {
+ mCompatibilityModeEnabled = PackageParser.sCompatibilityModeEnabled;
+ mMockAndroidPackage = mock(AndroidPackage.class);
+ mMockUserState = mock(PackageUserState.class);
+ mMockUserState.installed = true;
+ when(mMockUserState.isAvailable(anyInt())).thenReturn(true);
+ when(mMockUserState.getAllOverlayPaths()).thenReturn(null);
+ }
+
+ @After
+ public void tearDown() {
+ setGlobalCompatibilityMode(mCompatibilityModeEnabled);
+ }
+
+ // The following tests ensure that apps with target SDK of Cupcake always use compat mode.
+
+ @Test
+ public void testGlobalCompatModeEnabled_oldApp_supportAllScreens_usesCompatMode() {
+ setGlobalCompatibilityMode(true);
+ final int flags = (FLAG_SUPPORTS_LARGE_SCREENS | FLAG_SUPPORTS_NORMAL_SCREENS
+ | FLAG_SUPPORTS_SMALL_SCREENS | FLAG_RESIZEABLE_FOR_SCREENS
+ | FLAG_SUPPORTS_SCREEN_DENSITIES | FLAG_SUPPORTS_XLARGE_SCREENS);
+ final ApplicationInfo info =
+ generateMockApplicationInfo(Build.VERSION_CODES.CUPCAKE, flags);
+ assertThat(info.usesCompatibilityMode(), is(true));
+ }
+
+ @Test
+ public void testGlobalCompatModeEnabled_oldApp_supportSomeScreens_usesCompatMode() {
+ setGlobalCompatibilityMode(true);
+ final int flags = (FLAG_SUPPORTS_LARGE_SCREENS
+ | FLAG_SUPPORTS_SMALL_SCREENS | FLAG_RESIZEABLE_FOR_SCREENS
+ | FLAG_SUPPORTS_SCREEN_DENSITIES | FLAG_SUPPORTS_XLARGE_SCREENS);
+ final ApplicationInfo info =
+ generateMockApplicationInfo(Build.VERSION_CODES.CUPCAKE, flags);
+ assertThat(info.usesCompatibilityMode(), is(true));
+ }
+
+ @Test
+ public void testGlobalCompatModeEnabled_oldApp_supportOnlyOneScreen_usesCompatMode() {
+ setGlobalCompatibilityMode(true);
+ final int flags = FLAG_SUPPORTS_NORMAL_SCREENS;
+ final ApplicationInfo info =
+ generateMockApplicationInfo(Build.VERSION_CODES.CUPCAKE, flags);
+ assertThat(info.usesCompatibilityMode(), is(true));
+ }
+
+ @Test
+ public void testGlobalCompatModeEnabled_oldApp_DoesntSupportAllScreens_usesCompatMode() {
+ setGlobalCompatibilityMode(true);
+ final ApplicationInfo info =
+ generateMockApplicationInfo(Build.VERSION_CODES.CUPCAKE, 0 /*flags*/);
+ assertThat(info.usesCompatibilityMode(), is(true));
+ }
+
+ @Test
+ public void testGlobalCompatModeDisabled_oldApp_supportAllScreens_usesCompatMode() {
+ setGlobalCompatibilityMode(false);
+ final int flags = (FLAG_SUPPORTS_LARGE_SCREENS | FLAG_SUPPORTS_NORMAL_SCREENS
+ | FLAG_SUPPORTS_SMALL_SCREENS | FLAG_RESIZEABLE_FOR_SCREENS
+ | FLAG_SUPPORTS_SCREEN_DENSITIES | FLAG_SUPPORTS_XLARGE_SCREENS);
+ final ApplicationInfo info =
+ generateMockApplicationInfo(Build.VERSION_CODES.CUPCAKE, flags);
+ assertThat(info.usesCompatibilityMode(), is(true));
+ }
+
+ @Test
+ public void testGlobalCompatModeDisabled_oldApp_supportSomeScreens_usesCompatMode() {
+ setGlobalCompatibilityMode(false);
+ final int flags = (FLAG_SUPPORTS_LARGE_SCREENS
+ | FLAG_SUPPORTS_SMALL_SCREENS | FLAG_RESIZEABLE_FOR_SCREENS
+ | FLAG_SUPPORTS_SCREEN_DENSITIES | FLAG_SUPPORTS_XLARGE_SCREENS);
+ final ApplicationInfo info =
+ generateMockApplicationInfo(Build.VERSION_CODES.CUPCAKE, flags);
+ assertThat(info.usesCompatibilityMode(), is(true));
+ }
+
+ @Test
+ public void testGlobalCompatModeDisabled_oldApp_supportOnlyOneScreen_usesCompatMode() {
+ setGlobalCompatibilityMode(false);
+ final int flags = FLAG_SUPPORTS_NORMAL_SCREENS;
+ final ApplicationInfo info =
+ generateMockApplicationInfo(Build.VERSION_CODES.CUPCAKE, flags);
+ assertThat(info.usesCompatibilityMode(), is(true));
+ }
+
+ @Test
+ public void testGlobalCompatModeDisabled_oldApp_doesntSupportAllScreens_usesCompatMode() {
+ setGlobalCompatibilityMode(false);
+ final ApplicationInfo info =
+ generateMockApplicationInfo(Build.VERSION_CODES.CUPCAKE, 0 /*flags*/);
+ assertThat(info.usesCompatibilityMode(), is(true));
+ }
+
+ // The following tests ensure that apps with newer target SDK use compat mode as expected.
+
+ @Test
+ public void testGlobalCompatModeEnabled_newApp_supportAllScreens_doesntUseCompatMode() {
+ setGlobalCompatibilityMode(true);
+ final int flags = (FLAG_SUPPORTS_LARGE_SCREENS | FLAG_SUPPORTS_NORMAL_SCREENS
+ | FLAG_SUPPORTS_SMALL_SCREENS | FLAG_RESIZEABLE_FOR_SCREENS
+ | FLAG_SUPPORTS_SCREEN_DENSITIES | FLAG_SUPPORTS_XLARGE_SCREENS);
+ final ApplicationInfo info = generateMockApplicationInfo(Build.VERSION_CODES.DONUT, flags);
+ assertThat(info.usesCompatibilityMode(), is(false));
+ }
+
+ @Test
+ public void testGlobalCompatModeEnabled_newApp_supportSomeScreens_doesntUseCompatMode() {
+ setGlobalCompatibilityMode(true);
+ final int flags = (FLAG_SUPPORTS_LARGE_SCREENS
+ | FLAG_SUPPORTS_SMALL_SCREENS | FLAG_RESIZEABLE_FOR_SCREENS
+ | FLAG_SUPPORTS_SCREEN_DENSITIES | FLAG_SUPPORTS_XLARGE_SCREENS);
+ final ApplicationInfo info = generateMockApplicationInfo(Build.VERSION_CODES.DONUT, flags);
+ assertThat(info.usesCompatibilityMode(), is(false));
+ }
+
+ @Test
+ public void testGlobalCompatModeEnabled_newApp_supportOnlyOneScreen_doesntUseCompatMode() {
+ setGlobalCompatibilityMode(true);
+ final int flags = FLAG_SUPPORTS_NORMAL_SCREENS;
+ final ApplicationInfo info = generateMockApplicationInfo(Build.VERSION_CODES.DONUT, flags);
+ assertThat(info.usesCompatibilityMode(), is(false));
+ }
+
+ @Test
+ public void testGlobalCompatModeEnabled_newApp_doesntSupportAllScreens_usesCompatMode() {
+ setGlobalCompatibilityMode(true);
+ final ApplicationInfo info =
+ generateMockApplicationInfo(Build.VERSION_CODES.DONUT, 0 /*flags*/);
+ assertThat(info.usesCompatibilityMode(), is(true));
+ }
+
+ @Test
+ public void testGlobalCompatModeDisabled_newApp_supportAllScreens_doesntUseCompatMode() {
+ setGlobalCompatibilityMode(false);
+ final int flags = (FLAG_SUPPORTS_LARGE_SCREENS | FLAG_SUPPORTS_NORMAL_SCREENS
+ | FLAG_SUPPORTS_SMALL_SCREENS | FLAG_RESIZEABLE_FOR_SCREENS
+ | FLAG_SUPPORTS_SCREEN_DENSITIES | FLAG_SUPPORTS_XLARGE_SCREENS);
+ final ApplicationInfo info = generateMockApplicationInfo(Build.VERSION_CODES.DONUT, flags);
+ assertThat(info.usesCompatibilityMode(), is(false));
+ }
+
+ @Test
+ public void testGlobalCompatModeDisabled_newApp_supportSomeScreens_doesntUseCompatMode() {
+ setGlobalCompatibilityMode(false);
+ final int flags = (FLAG_SUPPORTS_LARGE_SCREENS
+ | FLAG_SUPPORTS_SMALL_SCREENS | FLAG_RESIZEABLE_FOR_SCREENS
+ | FLAG_SUPPORTS_SCREEN_DENSITIES | FLAG_SUPPORTS_XLARGE_SCREENS);
+ final ApplicationInfo info = generateMockApplicationInfo(Build.VERSION_CODES.DONUT, flags);
+ assertThat(info.usesCompatibilityMode(), is(false));
+ }
+
+ @Test
+ public void testGlobalCompatModeDisabled_newApp_supportOnlyOneScreen_doesntUseCompatMode() {
+ setGlobalCompatibilityMode(false);
+ final int flags = FLAG_SUPPORTS_NORMAL_SCREENS;
+ final ApplicationInfo info = generateMockApplicationInfo(Build.VERSION_CODES.DONUT, flags);
+ assertThat(info.usesCompatibilityMode(), is(false));
+ }
+
+ @Test
+ public void testGlobalCompatModeDisabled_newApp_doesntSupportAllScreens_doesntUseCompatMode() {
+ setGlobalCompatibilityMode(false);
+ final ApplicationInfo info =
+ generateMockApplicationInfo(Build.VERSION_CODES.DONUT, 0 /*flags*/);
+ assertThat(info.usesCompatibilityMode(), is(false));
+ }
+
+ private ApplicationInfo generateMockApplicationInfo(int targetSdkVersion, int flags) {
+ final ApplicationInfo info = new ApplicationInfo();
+ info.targetSdkVersion = targetSdkVersion;
+ info.flags |= flags;
+ when(mMockAndroidPackage.toAppInfoWithoutState()).thenReturn(info);
+ return PackageInfoWithoutStateUtils.generateApplicationInfoUnchecked(mMockAndroidPackage,
+ 0 /*flags*/, mMockUserState, 0 /*userId*/, false /*assignUserFields*/);
+ }
+
+ private void setGlobalCompatibilityMode(boolean enabled) {
+ if (PackageParser.sCompatibilityModeEnabled == enabled) {
+ return;
+ }
+ PackageParser.setCompatibilityModeEnabled(enabled);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt b/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt
index 57436f8..581ff54 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt
+++ b/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt
@@ -509,7 +509,13 @@
.ignored("Checked separately in test")}
reqFeatures=${this.reqFeatures?.joinToString { it.dumpToString() }}
requestedPermissions=${this.requestedPermissions?.contentToString()}
- requestedPermissionsFlags=${this.requestedPermissionsFlags?.contentToString()}
+ requestedPermissionsFlags=${
+ this.requestedPermissionsFlags?.map {
+ // Newer flags are stripped
+ it and (PackageInfo.REQUESTED_PERMISSION_REQUIRED
+ or PackageInfo.REQUESTED_PERMISSION_GRANTED)
+ }?.joinToString()
+ }
requiredAccountType=${this.requiredAccountType}
requiredForAllUsers=${this.requiredForAllUsers}
restrictedAccountType=${this.restrictedAccountType}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 33a9a96..1e9e0bd 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -5549,7 +5549,7 @@
sDefaults.putBoolean(KEY_STORE_SIM_PIN_FOR_UNATTENDED_REBOOT_BOOL, true);
sDefaults.putBoolean(KEY_HIDE_ENABLE_2G, false);
sDefaults.putStringArray(KEY_ALLOWED_INITIAL_ATTACH_APN_TYPES_STRING_ARRAY,
- new String[]{"ia", "default", "ims", "mms", "dun", "emergency"});
+ new String[]{"ia", "default", "mms", "dun"});
sDefaults.putBoolean(KEY_CARRIER_PROVISIONS_WIFI_MERGED_NETWORKS_BOOL, false);
sDefaults.putBoolean(KEY_USE_IP_FOR_CALLING_INDICATOR_BOOL, false);
sDefaults.putBoolean(KEY_DISPLAY_CALL_STRENGTH_INDICATOR_BOOL, true);
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 4cd59a2..91ecbf0 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -2352,6 +2352,12 @@
void setActiveDeviceToDeviceTransport(String transport);
/**
+ * Forces Device to Device communication to be enabled, even if the device config has it
+ * disabled.
+ */
+ void setDeviceToDeviceForceEnabled(boolean isForceEnabled);
+
+ /**
* Gets the config of RCS VoLTE single registration enabled for the carrier/subscription.
*/
boolean getCarrierSingleRegistrationEnabled(int subId);
diff --git a/tests/Input/src/com/android/test/input/InputEventSenderAndReceiverTest.kt b/tests/Input/src/com/android/test/input/InputEventSenderAndReceiverTest.kt
index fc1d839..014efc2 100644
--- a/tests/Input/src/com/android/test/input/InputEventSenderAndReceiverTest.kt
+++ b/tests/Input/src/com/android/test/input/InputEventSenderAndReceiverTest.kt
@@ -145,4 +145,21 @@
val received = mSender.getTimeline()
assertEquals(sent, received)
}
+
+ // If an invalid timeline is sent, the channel should get closed. This helps surface any
+ // app-originating bugs early, and forces the work-around to happen in the early stages of the
+ // event processing.
+ @Test
+ fun testSendAndReceiveInvalidTimeline() {
+ val sent = TestInputEventSender.Timeline(
+ inputEventId = 1, gpuCompletedTime = 3, presentTime = 2)
+ mReceiver.reportTimeline(sent.inputEventId, sent.gpuCompletedTime, sent.presentTime)
+ val received = mSender.getTimeline()
+ assertEquals(null, received)
+ // Sender will no longer receive callbacks for this fd, even if receiver sends a valid
+ // timeline later
+ mReceiver.reportTimeline(2 /*inputEventId*/, 3 /*gpuCompletedTime*/, 4 /*presentTime*/)
+ val receivedSecondTimeline = mSender.getTimeline()
+ assertEquals(null, receivedSecondTimeline)
+ }
}