Merge "Guard against NPE" into sc-dev
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb
index 78c4820..3258514c 100644
--- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb
@@ -1,6 +1,6 @@
drops {
android_build_drop {
- build_id: "7471822"
+ build_id: "7533747"
target: "CtsShim"
source_file: "aosp_arm64/CtsShimPriv.apk"
}
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb
index a9632ad..4fb50e2 100644
--- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb
@@ -1,6 +1,6 @@
drops {
android_build_drop {
- build_id: "7471822"
+ build_id: "7533747"
target: "CtsShim"
source_file: "aosp_arm64/CtsShim.apk"
}
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb
index df3a0bb..1a0e318 100644
--- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb
@@ -1,6 +1,6 @@
drops {
android_build_drop {
- build_id: "7471822"
+ build_id: "7533747"
target: "CtsShim"
source_file: "aosp_x86_64/CtsShimPriv.apk"
}
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb
index 1bc6cb8..d72f62e 100644
--- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb
@@ -1,6 +1,6 @@
drops {
android_build_drop {
- build_id: "7471822"
+ build_id: "7533747"
target: "CtsShim"
source_file: "aosp_x86_64/CtsShim.apk"
}
diff --git a/apex/appsearch/service/Android.bp b/apex/appsearch/service/Android.bp
index 5ab7ff9..b101895 100644
--- a/apex/appsearch/service/Android.bp
+++ b/apex/appsearch/service/Android.bp
@@ -51,6 +51,7 @@
],
libs: [
"framework-appsearch.impl",
+ "framework-statsd.stubs.module_lib",
"unsupportedappusage", // TODO(b/181887768) should be removed
],
defaults: ["framework-system-server-module-defaults"],
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchConfig.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchConfig.java
index 689aa1f..c44fd40 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchConfig.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchConfig.java
@@ -64,6 +64,12 @@
static final int DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES = 512 * 1024; // 512KiB
@VisibleForTesting
static final int DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_COUNT = 20_000;
+ @VisibleForTesting
+ static final int DEFAULT_BYTES_OPTIMIZE_THRESHOLD = 1 * 1024 * 1024; // 1 MiB
+ @VisibleForTesting
+ static final int DEFAULT_TIME_OPTIMIZE_THRESHOLD_MILLIS = Integer.MAX_VALUE;
+ @VisibleForTesting
+ static final int DEFAULT_DOC_COUNT_OPTIMIZE_THRESHOLD = 10_000;
/*
* Keys for ALL the flags stored in DeviceConfig.
@@ -79,6 +85,9 @@
"limit_config_max_document_size_bytes";
public static final String KEY_LIMIT_CONFIG_MAX_DOCUMENT_COUNT =
"limit_config_max_document_docunt";
+ public static final String KEY_BYTES_OPTIMIZE_THRESHOLD = "bytes_optimize_threshold";
+ public static final String KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS = "time_optimize_threshold";
+ public static final String KEY_DOC_COUNT_OPTIMIZE_THRESHOLD = "doc_count_optimize_threshold";
// Array contains all the corresponding keys for the cached values.
private static final String[] KEYS_TO_ALL_CACHED_VALUES = {
@@ -88,6 +97,9 @@
KEY_SAMPLING_INTERVAL_FOR_PUT_DOCUMENT_STATS,
KEY_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES,
KEY_LIMIT_CONFIG_MAX_DOCUMENT_COUNT,
+ KEY_BYTES_OPTIMIZE_THRESHOLD,
+ KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS,
+ KEY_DOC_COUNT_OPTIMIZE_THRESHOLD
};
// Lock needed for all the operations in this class.
@@ -251,6 +263,48 @@
}
}
+ /**
+ * Returns the cached optimize byte size threshold.
+ *
+ * An AppSearch Optimize job will be triggered if the bytes size of garbage resource exceeds
+ * this threshold.
+ */
+ int getCachedBytesOptimizeThreshold() {
+ synchronized (mLock) {
+ throwIfClosedLocked();
+ return mBundleLocked.getInt(KEY_BYTES_OPTIMIZE_THRESHOLD,
+ DEFAULT_BYTES_OPTIMIZE_THRESHOLD);
+ }
+ }
+
+ /**
+ * Returns the cached optimize time interval threshold.
+ *
+ * An AppSearch Optimize job will be triggered if the time since last optimize job exceeds
+ * this threshold.
+ */
+ int getCachedTimeOptimizeThresholdMs() {
+ synchronized (mLock) {
+ throwIfClosedLocked();
+ return mBundleLocked.getInt(KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS,
+ DEFAULT_TIME_OPTIMIZE_THRESHOLD_MILLIS);
+ }
+ }
+
+ /**
+ * Returns the cached optimize document count threshold threshold.
+ *
+ * An AppSearch Optimize job will be triggered if the number of document of garbage resource
+ * exceeds this threshold.
+ */
+ int getCachedDocCountOptimizeThreshold() {
+ synchronized (mLock) {
+ throwIfClosedLocked();
+ return mBundleLocked.getInt(KEY_DOC_COUNT_OPTIMIZE_THRESHOLD,
+ DEFAULT_DOC_COUNT_OPTIMIZE_THRESHOLD);
+ }
+ }
+
@GuardedBy("mLock")
private void throwIfClosedLocked() {
if (mIsClosedLocked) {
@@ -307,6 +361,24 @@
properties.getInt(key, DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_COUNT));
}
break;
+ case KEY_BYTES_OPTIMIZE_THRESHOLD:
+ synchronized (mLock) {
+ mBundleLocked.putInt(key, properties.getInt(key,
+ DEFAULT_BYTES_OPTIMIZE_THRESHOLD));
+ }
+ break;
+ case KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS:
+ synchronized (mLock) {
+ mBundleLocked.putInt(key, properties.getInt(key,
+ DEFAULT_TIME_OPTIMIZE_THRESHOLD_MILLIS));
+ }
+ break;
+ case KEY_DOC_COUNT_OPTIMIZE_THRESHOLD:
+ synchronized (mLock) {
+ mBundleLocked.putInt(key, properties.getInt(key,
+ DEFAULT_DOC_COUNT_OPTIMIZE_THRESHOLD));
+ }
+ break;
default:
break;
}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
index ec37c3f..b52a503 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -61,6 +61,7 @@
import com.android.server.SystemService;
import com.android.server.appsearch.external.localstorage.stats.CallStats;
import com.android.server.appsearch.external.localstorage.visibilitystore.VisibilityStore;
+import com.android.server.appsearch.stats.StatsCollector;
import com.android.server.appsearch.util.PackageUtil;
import com.android.server.usage.StorageStatsManagerLocal;
import com.android.server.usage.StorageStatsManagerLocal.StorageStatsAugmenter;
@@ -123,6 +124,13 @@
.registerStorageStatsAugmenter(new AppSearchStorageStatsAugmenter(), TAG);
}
+ @Override
+ public void onBootPhase(/* @BootPhase */ int phase) {
+ if (phase == PHASE_BOOT_COMPLETED) {
+ StatsCollector.getInstance(mContext, EXECUTOR);
+ }
+ }
+
private void registerReceivers() {
mContext.registerReceiverForAllUsers(
new UserActionReceiver(),
@@ -364,6 +372,12 @@
++operationSuccessCount;
invokeCallbackOnResult(callback,
AppSearchResult.newSuccessfulResult(setSchemaResponse.getBundle()));
+
+ // setSchema will sync the schemas in the request to AppSearch, any existing
+ // schemas which is not included in the request will be delete if we force
+ // override incompatible schemas. And all documents of these types will be
+ // deleted as well. We should checkForOptimize for these deletion.
+ checkForOptimize(instance);
} catch (Throwable t) {
++operationFailureCount;
statusCode = throwableToFailedResult(t).getResultCode();
@@ -505,6 +519,10 @@
// Now that the batch has been written. Persist the newly written data.
instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE);
invokeCallbackOnResult(callback, resultBuilder.build());
+
+ // The existing documents with same ID will be deleted, so there may be some
+ // resources that could be released after optimize().
+ checkForOptimize(instance, /*mutateBatchSize=*/ documentBundles.size());
} catch (Throwable t) {
++operationFailureCount;
statusCode = throwableToFailedResult(t).getResultCode();
@@ -1023,6 +1041,8 @@
// Now that the batch has been written. Persist the newly written data.
instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE);
invokeCallbackOnResult(callback, resultBuilder.build());
+
+ checkForOptimize(instance, ids.size());
} catch (Throwable t) {
++operationFailureCount;
statusCode = throwableToFailedResult(t).getResultCode();
@@ -1092,6 +1112,8 @@
instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE);
++operationSuccessCount;
invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
+
+ checkForOptimize(instance);
} catch (Throwable t) {
++operationFailureCount;
statusCode = throwableToFailedResult(t).getResultCode();
@@ -1472,4 +1494,24 @@
}
}
}
+
+ private void checkForOptimize(AppSearchUserInstance instance, int mutateBatchSize) {
+ EXECUTOR.execute(() -> {
+ try {
+ instance.getAppSearchImpl().checkForOptimize(mutateBatchSize);
+ } catch (AppSearchException e) {
+ Log.w(TAG, "Error occurred when check for optimize", e);
+ }
+ });
+ }
+
+ private void checkForOptimize(AppSearchUserInstance instance) {
+ EXECUTOR.execute(() -> {
+ try {
+ instance.getAppSearchImpl().checkForOptimize();
+ } catch (AppSearchException e) {
+ Log.w(TAG, "Error occurred when check for optimize", e);
+ }
+ });
+ }
}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java
index d0d2e89..529f2b0 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java
@@ -27,12 +27,13 @@
import com.android.internal.annotations.GuardedBy;
import com.android.server.appsearch.external.localstorage.AppSearchImpl;
-import com.android.server.appsearch.external.localstorage.FrameworkOptimizeStrategy;
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
import com.android.server.appsearch.stats.PlatformLogger;
import com.android.server.appsearch.visibilitystore.VisibilityStoreImpl;
import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -158,6 +159,18 @@
}
}
+ /**
+ * Returns the list of all {@link UserHandle}s.
+ *
+ * <p>It can return an empty list if there is no {@link AppSearchUserInstance} created yet.
+ */
+ @NonNull
+ public List<UserHandle> getAllUserHandles() {
+ synchronized (mInstancesLocked) {
+ return new ArrayList<>(mInstancesLocked.keySet());
+ }
+ }
+
@NonNull
private AppSearchUserInstance createUserInstance(
@NonNull Context userContext,
@@ -177,7 +190,7 @@
icingDir,
new FrameworkLimitConfig(config),
initStatsBuilder,
- new FrameworkOptimizeStrategy());
+ new FrameworkOptimizeStrategy(config));
long prepareVisibilityStoreLatencyStartMillis = SystemClock.elapsedRealtime();
VisibilityStoreImpl visibilityStore =
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/FrameworkOptimizeStrategy.java b/apex/appsearch/service/java/com/android/server/appsearch/FrameworkOptimizeStrategy.java
new file mode 100644
index 0000000..d934449
--- /dev/null
+++ b/apex/appsearch/service/java/com/android/server/appsearch/FrameworkOptimizeStrategy.java
@@ -0,0 +1,48 @@
+/*
+ * 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.appsearch;
+
+import android.annotation.NonNull;
+
+import com.android.server.appsearch.external.localstorage.AppSearchImpl;
+import com.android.server.appsearch.external.localstorage.OptimizeStrategy;
+
+import com.google.android.icing.proto.GetOptimizeInfoResultProto;
+
+import java.util.Objects;
+
+/**
+ * An implementation of {@link OptimizeStrategy} will determine when to trigger {@link
+ * AppSearchImpl#optimize()} in Jetpack environment.
+ *
+ * @hide
+ */
+public class FrameworkOptimizeStrategy implements OptimizeStrategy {
+ private final AppSearchConfig mAppSearchConfig;
+ FrameworkOptimizeStrategy(@NonNull AppSearchConfig config) {
+ mAppSearchConfig = Objects.requireNonNull(config);
+ }
+
+ @Override
+ public boolean shouldOptimize(@NonNull GetOptimizeInfoResultProto optimizeInfo) {
+ return optimizeInfo.getOptimizableDocs()
+ >= mAppSearchConfig.getCachedDocCountOptimizeThreshold()
+ || optimizeInfo.getEstimatedOptimizableBytes()
+ >= mAppSearchConfig.getCachedBytesOptimizeThreshold()
+ || optimizeInfo.getTimeSinceLastOptimizeMs()
+ >= mAppSearchConfig.getCachedTimeOptimizeThresholdMs();
+ }
+}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/FrameworkOptimizeStrategy.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/FrameworkOptimizeStrategy.java
deleted file mode 100644
index 8ec30e1..0000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/FrameworkOptimizeStrategy.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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;
-
-import android.annotation.NonNull;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import com.google.android.icing.proto.GetOptimizeInfoResultProto;
-
-/**
- * An implementation of {@link OptimizeStrategy} will determine when to trigger {@link
- * AppSearchImpl#optimize()} in Jetpack environment.
- *
- * @hide
- */
-public class FrameworkOptimizeStrategy implements OptimizeStrategy {
-
- @VisibleForTesting static final int DOC_COUNT_OPTIMIZE_THRESHOLD = 100_000;
- @VisibleForTesting static final int BYTES_OPTIMIZE_THRESHOLD = 1 * 1024 * 1024 * 1024; // 1GB
-
- @VisibleForTesting
- static final long TIME_OPTIMIZE_THRESHOLD_MILLIS = 7 * 24 * 60 * 60 * 1000; // 1 week
-
- @Override
- public boolean shouldOptimize(@NonNull GetOptimizeInfoResultProto optimizeInfo) {
- return optimizeInfo.getOptimizableDocs() >= DOC_COUNT_OPTIMIZE_THRESHOLD
- || optimizeInfo.getEstimatedOptimizableBytes() >= BYTES_OPTIMIZE_THRESHOLD
- || optimizeInfo.getTimeSinceLastOptimizeMs() >= TIME_OPTIMIZE_THRESHOLD_MILLIS;
- }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java b/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java
index 5371478..2cbce10 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java
@@ -45,7 +45,7 @@
import java.util.Random;
/**
- * Logger Implementation to log to statsd.
+ * Logger Implementation for pushed atoms.
*
* <p>This class is thread-safe.
*
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/stats/StatsCollector.java b/apex/appsearch/service/java/com/android/server/appsearch/stats/StatsCollector.java
new file mode 100644
index 0000000..dd56739
--- /dev/null
+++ b/apex/appsearch/service/java/com/android/server/appsearch/stats/StatsCollector.java
@@ -0,0 +1,203 @@
+/*
+ * 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.appsearch.stats;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.app.StatsManager;
+import android.content.Context;
+import android.os.UserHandle;
+import android.util.Log;
+import android.util.StatsEvent;
+
+import com.android.server.appsearch.AppSearchUserInstance;
+import com.android.server.appsearch.AppSearchUserInstanceManager;
+
+import com.google.android.icing.proto.DocumentStorageInfoProto;
+import com.google.android.icing.proto.IndexStorageInfoProto;
+import com.google.android.icing.proto.SchemaStoreStorageInfoProto;
+import com.google.android.icing.proto.StorageInfoProto;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.Executor;
+
+/**
+ * Implements statsd pullers for AppSearch.
+ *
+ * <p>This class registers pullers to statsd, which will be called once a day to obtain AppSearch
+ * statistics that cannot be sent to statsd in real time by {@link PlatformLogger}.
+ *
+ * @hide
+ */
+public final class StatsCollector implements StatsManager.StatsPullAtomCallback {
+ private static final String TAG = "AppSearchStatsCollector";
+
+ private static volatile StatsCollector sStatsCollector;
+ private final StatsManager mStatsManager;
+
+ /**
+ * Gets an instance of {@link StatsCollector} to be used.
+ *
+ * <p>If no instance has been initialized yet, a new one will be created. Otherwise, the
+ * existing instance will be returned.
+ */
+ @NonNull
+ public static StatsCollector getInstance(@NonNull Context context,
+ @NonNull Executor executor) {
+ Objects.requireNonNull(context);
+ Objects.requireNonNull(executor);
+ if (sStatsCollector == null) {
+ synchronized (StatsCollector.class) {
+ if (sStatsCollector == null) {
+ sStatsCollector = new StatsCollector(context, executor);
+ }
+ }
+ }
+ return sStatsCollector;
+ }
+
+ private StatsCollector(@NonNull Context context, @NonNull Executor executor) {
+ mStatsManager = context.getSystemService(StatsManager.class);
+ if (mStatsManager != null) {
+ registerAtom(AppSearchStatsLog.APP_SEARCH_STORAGE_INFO, /*policy=*/ null, executor);
+ Log.d(TAG, "atoms registered");
+ } else {
+ Log.e(TAG, "could not get StatsManager, atoms not registered");
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@link StatsManager#PULL_SUCCESS} with list of atoms (potentially empty) if pull
+ * succeeded, {@link StatsManager#PULL_SKIP} if pull was too frequent or atom ID is
+ * unexpected.
+ */
+ @Override
+ public int onPullAtom(int atomTag, @NonNull List<StatsEvent> data) {
+ Objects.requireNonNull(data);
+ switch (atomTag) {
+ case AppSearchStatsLog.APP_SEARCH_STORAGE_INFO:
+ return pullAppSearchStorageInfo(data);
+ default:
+ Log.e(TAG, "unexpected atom ID " + atomTag);
+ return StatsManager.PULL_SKIP;
+ }
+ }
+
+ private static int pullAppSearchStorageInfo(@NonNull List<StatsEvent> data) {
+ AppSearchUserInstanceManager userInstanceManager =
+ AppSearchUserInstanceManager.getInstance();
+ List<UserHandle> userHandles = userInstanceManager.getAllUserHandles();
+ for (int i = 0; i < userHandles.size(); i++) {
+ UserHandle userHandle = userHandles.get(i);
+ try {
+ AppSearchUserInstance userInstance = userInstanceManager.getUserInstance(
+ userHandle);
+ StorageInfoProto storageInfoProto =
+ userInstance.getAppSearchImpl().getRawStorageInfoProto();
+ data.add(buildStatsEvent(userHandle.getIdentifier(), storageInfoProto));
+ } catch (Throwable t) {
+ Log.e(TAG,
+ "Failed to pull the storage info for user " + userHandle.toString(),
+ t);
+ }
+ }
+
+ // Skip the report if there is no data.
+ if (data.isEmpty()) {
+ return StatsManager.PULL_SKIP;
+ }
+
+ return StatsManager.PULL_SUCCESS;
+ }
+
+ /**
+ * Registers and configures the callback for the pulled atom.
+ *
+ * @param atomId The id of the atom
+ * @param policy Optional metadata specifying the timeout, cool down time etc. statsD would
+ * use default values if it is null
+ * @param executor The executor in which to run the callback
+ */
+ private void registerAtom(int atomId, @Nullable StatsManager.PullAtomMetadata policy,
+ @NonNull Executor executor) {
+ mStatsManager.setPullAtomCallback(atomId, policy, executor, /*callback=*/this);
+ }
+
+ private static StatsEvent buildStatsEvent(@UserIdInt int userId,
+ @NonNull StorageInfoProto storageInfoProto) {
+ return AppSearchStatsLog.buildStatsEvent(
+ AppSearchStatsLog.APP_SEARCH_STORAGE_INFO,
+ userId,
+ storageInfoProto.getTotalStorageSize(),
+ getDocumentStorageInfoBytes(storageInfoProto.getDocumentStorageInfo()),
+ getSchemaStoreStorageInfoBytes(storageInfoProto.getSchemaStoreStorageInfo()),
+ getIndexStorageInfoBytes(storageInfoProto.getIndexStorageInfo()));
+ }
+
+ private static byte[] getDocumentStorageInfoBytes(
+ @NonNull DocumentStorageInfoProto proto) {
+ // Make sure we only log the fields defined in the atom in case new fields are added in
+ // IcingLib
+ DocumentStorageInfoProto.Builder builder = DocumentStorageInfoProto.newBuilder();
+ builder.setNumAliveDocuments(proto.getNumAliveDocuments())
+ .setNumDeletedDocuments(proto.getNumDeletedDocuments())
+ .setNumExpiredDocuments(proto.getNumExpiredDocuments())
+ .setDocumentStoreSize(proto.getDocumentStoreSize())
+ .setDocumentLogSize(proto.getDocumentLogSize())
+ .setKeyMapperSize(proto.getKeyMapperSize())
+ .setDocumentIdMapperSize(proto.getDocumentIdMapperSize())
+ .setScoreCacheSize(proto.getScoreCacheSize())
+ .setFilterCacheSize(proto.getFilterCacheSize())
+ .setCorpusMapperSize(proto.getCorpusMapperSize())
+ .setCorpusScoreCacheSize(proto.getCorpusScoreCacheSize())
+ .setNamespaceIdMapperSize(proto.getNamespaceIdMapperSize())
+ .setNumNamespaces(proto.getNumNamespaces());
+ return builder.build().toByteArray();
+ }
+
+ private static byte[] getSchemaStoreStorageInfoBytes(
+ @NonNull SchemaStoreStorageInfoProto proto) {
+ // Make sure we only log the fields defined in the atom in case new fields are added in
+ // IcingLib
+ SchemaStoreStorageInfoProto.Builder builder = SchemaStoreStorageInfoProto.newBuilder();
+ builder.setSchemaStoreSize(proto.getSchemaStoreSize())
+ .setNumSchemaTypes(proto.getNumSchemaTypes())
+ .setNumTotalSections(proto.getNumTotalSections())
+ .setNumSchemaTypesSectionsExhausted(proto.getNumSchemaTypesSectionsExhausted());
+ return builder.build().toByteArray();
+ }
+
+ private static byte[] getIndexStorageInfoBytes(
+ @NonNull IndexStorageInfoProto proto) {
+ // Make sure we only log the fields defined in the atom in case new fields are added in
+ // IcingLib
+ IndexStorageInfoProto.Builder builder = IndexStorageInfoProto.newBuilder();
+ builder.setIndexSize(proto.getIndexSize())
+ .setLiteIndexLexiconSize(proto.getLiteIndexLexiconSize())
+ .setLiteIndexHitBufferSize(proto.getLiteIndexHitBufferSize())
+ .setMainIndexLexiconSize(proto.getMainIndexLexiconSize())
+ .setMainIndexStorageSize(proto.getMainIndexStorageSize())
+ .setMainIndexBlockSize(proto.getMainIndexBlockSize())
+ .setNumBlocks(proto.getNumBlocks())
+ .setMinFreeFraction(proto.getMinFreeFraction());
+ return builder.build().toByteArray();
+ }
+}
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 3be4004..dd7c6db 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -2068,7 +2068,7 @@
public final class PermissionManager {
method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.permission.PermGroupUsage> getIndicatorAppOpUsageData();
method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.permission.PermGroupUsage> getIndicatorAppOpUsageData(boolean);
- method public void registerAttributionSource(@NonNull android.content.AttributionSource);
+ method @NonNull public android.content.AttributionSource registerAttributionSource(@NonNull android.content.AttributionSource);
}
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 5e99c79..f52fdc5 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -3149,7 +3149,8 @@
// If we want to access protected data on behalf of another app we need to
// tell the OS that we opt in to participate in the attribution chain.
if (nextAttributionSource != null) {
- getSystemService(PermissionManager.class).registerAttributionSource(attributionSource);
+ attributionSource = getSystemService(PermissionManager.class)
+ .registerAttributionSource(attributionSource);
}
return attributionSource;
}
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 313a340..b90b9a1 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -508,7 +508,6 @@
boolean stopBinderTrackingAndDump(in ParcelFileDescriptor fd);
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
void suppressResizeConfigChanges(boolean suppress);
- boolean isAppStartModeDisabled(int uid, in String packageName);
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
boolean unlockUser(int userid, in byte[] token, in byte[] secret,
in IProgressListener listener);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 6454d20..9d149cf 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -5380,14 +5380,15 @@
private void bindExpandButton(RemoteViews contentView, StandardTemplateParams p) {
// set default colors
- int textColor = getPrimaryTextColor(p);
- int pillColor = getColors(p).getProtectionColor();
+ int bgColor = getBackgroundColor(p);
+ int pillColor = Colors.flattenAlpha(getColors(p).getProtectionColor(), bgColor);
+ int textColor = Colors.flattenAlpha(getPrimaryTextColor(p), pillColor);
contentView.setInt(R.id.expand_button, "setDefaultTextColor", textColor);
contentView.setInt(R.id.expand_button, "setDefaultPillColor", pillColor);
// Use different highlighted colors for conversations' unread count
if (p.mHighlightExpander) {
- textColor = getBackgroundColor(p);
- pillColor = getPrimaryAccentColor(p);
+ pillColor = Colors.flattenAlpha(getPrimaryAccentColor(p), bgColor);
+ textColor = Colors.flattenAlpha(bgColor, pillColor);
}
contentView.setInt(R.id.expand_button, "setHighlightTextColor", textColor);
contentView.setInt(R.id.expand_button, "setHighlightPillColor", pillColor);
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 20afffc..198c33e 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -1158,9 +1158,15 @@
} else {
activityResources.overrideConfig.unset();
}
+
// Update the Activity's override display id.
activityResources.overrideDisplayId = displayId;
+ // If a application info update was scheduled to occur in this process but has not
+ // occurred yet, apply it now so the resources objects will have updated paths if
+ // the assets sequence changed.
+ applyAllPendingAppInfoUpdates();
+
if (DEBUG) {
Throwable here = new Throwable();
here.fillInStackTrace();
diff --git a/core/java/android/content/AttributionSource.java b/core/java/android/content/AttributionSource.java
index c499f69..d63ce0f 100644
--- a/core/java/android/content/AttributionSource.java
+++ b/core/java/android/content/AttributionSource.java
@@ -88,6 +88,8 @@
public final class AttributionSource implements Parcelable {
private static final String DESCRIPTOR = "android.content.AttributionSource";
+ private static final Binder sDefaultToken = new Binder(DESCRIPTOR);
+
private final @NonNull AttributionSourceState mAttributionSourceState;
private @Nullable AttributionSource mNextCached;
@@ -97,7 +99,7 @@
@TestApi
public AttributionSource(int uid, @Nullable String packageName,
@Nullable String attributionTag) {
- this(uid, packageName, attributionTag, new Binder(DESCRIPTOR));
+ this(uid, packageName, attributionTag, sDefaultToken);
}
/** @hide */
@@ -132,7 +134,7 @@
AttributionSource(int uid, @Nullable String packageName, @Nullable String attributionTag,
@Nullable String[] renouncedPermissions, @Nullable AttributionSource next) {
- this(uid, packageName, attributionTag, new Binder(DESCRIPTOR), renouncedPermissions, next);
+ this(uid, packageName, attributionTag, sDefaultToken, renouncedPermissions, next);
}
AttributionSource(int uid, @Nullable String packageName, @Nullable String attributionTag,
@@ -170,6 +172,12 @@
}
/** @hide */
+ public AttributionSource withToken(@NonNull Binder token) {
+ return new AttributionSource(getUid(), getPackageName(), getAttributionTag(),
+ token, mAttributionSourceState.renouncedPermissions, getNext());
+ }
+
+ /** @hide */
public @NonNull AttributionSourceState asState() {
return mAttributionSourceState;
}
@@ -543,7 +551,9 @@
if ((mBuilderFieldsSet & 0x10) == 0) {
mAttributionSourceState.next = null;
}
- mAttributionSourceState.token = new Binder(DESCRIPTOR);
+
+ mAttributionSourceState.token = sDefaultToken;
+
if (mAttributionSourceState.next == null) {
// The NDK aidl backend doesn't support null parcelable arrays.
mAttributionSourceState.next = new AttributionSourceState[0];
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 09fe102..6cbe107 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -1869,40 +1869,28 @@
@FastNative
private static native void nativeUpdate(long dst, long src);
- @FastNative
- private static native void nativeWriteToParcel(Parcel dest, long ptr);
- @FastNative
- private static native void nativeReadFromParcel(Parcel source, long ptr);
- @FastNative
- private static native void nativeSwap(long ptr, long otherPtr)
+ private static synchronized native void nativeWriteToParcel(Parcel dest, long ptr);
+ private static synchronized native void nativeReadFromParcel(Parcel source, long ptr);
+ private static synchronized native void nativeSwap(long ptr, long otherPtr)
throws NullPointerException;
@FastNative
- private static native void nativeClose(long ptr);
- @FastNative
- private static native boolean nativeIsEmpty(long ptr);
- @FastNative
- private static native int nativeGetEntryCount(long ptr);
- @FastNative
- private static native long nativeGetBufferSize(long ptr);
- @FastNative
private static native void nativeSetVendorId(long ptr, long vendorId);
+ private static synchronized native void nativeClose(long ptr);
+ private static synchronized native boolean nativeIsEmpty(long ptr);
+ private static synchronized native int nativeGetEntryCount(long ptr);
+ private static synchronized native long nativeGetBufferSize(long ptr);
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- @FastNative
- private static native byte[] nativeReadValues(int tag, long ptr);
- @FastNative
- private static native void nativeWriteValues(int tag, byte[] src, long ptr);
+ private static synchronized native byte[] nativeReadValues(int tag, long ptr);
+ private static synchronized native void nativeWriteValues(int tag, byte[] src, long ptr);
private static synchronized native void nativeDump(long ptr) throws IOException; // dump to LOGD
- @FastNative
- private static native ArrayList nativeGetAllVendorKeys(long ptr, Class keyClass);
+ private static synchronized native ArrayList nativeGetAllVendorKeys(long ptr, Class keyClass);
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- @FastNative
- private static native int nativeGetTagFromKeyLocal(long ptr, String keyName)
+ private static synchronized native int nativeGetTagFromKeyLocal(long ptr, String keyName)
throws IllegalArgumentException;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- @FastNative
- private static native int nativeGetTypeFromTagLocal(long ptr, int tag)
+ private static synchronized native int nativeGetTypeFromTagLocal(long ptr, int tag)
throws IllegalArgumentException;
@FastNative
private static native int nativeGetTagFromKey(String keyName, long vendorId)
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 0cb996b..dc1a50f 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -1382,12 +1382,7 @@
String[] msgArray = context.getResources().getStringArray(
com.android.internal.R.array.fingerprint_error_vendor);
if (vendorCode < msgArray.length) {
- if (Build.IS_ENG || Build.IS_USERDEBUG) {
- return msgArray[vendorCode];
- } else {
- return context.getString(
- com.android.internal.R.string.fingerprint_error_unable_to_process);
- }
+ return msgArray[vendorCode];
}
}
}
@@ -1427,12 +1422,7 @@
String[] msgArray = context.getResources().getStringArray(
com.android.internal.R.array.fingerprint_acquired_vendor);
if (vendorCode < msgArray.length) {
- if (Build.IS_ENG || Build.IS_USERDEBUG) {
- return msgArray[vendorCode];
- } else {
- return context.getString(
- com.android.internal.R.string.fingerprint_error_unable_to_process);
- }
+ return msgArray[vendorCode];
}
}
break;
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index 4ef0e6e..a52ede8 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -44,6 +44,7 @@
import android.content.pm.PermissionInfo;
import android.content.pm.permission.SplitPermissionInfoParcelable;
import android.media.AudioManager;
+import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
@@ -1163,18 +1164,24 @@
* that doesn't participate in an attribution chain.
*
* @param source The attribution source to register.
+ * @return The registered new attribution source.
*
* @see #isRegisteredAttributionSource(AttributionSource)
*
* @hide
*/
@TestApi
- public void registerAttributionSource(@NonNull AttributionSource source) {
+ public @NonNull AttributionSource registerAttributionSource(@NonNull AttributionSource source) {
+ // We use a shared static token for sources that are not registered since the token's
+ // only used for process death detection. If we are about to use the source for security
+ // enforcement we need to replace the binder with a unique one.
+ final AttributionSource registeredSource = source.withToken(new Binder());
try {
- mPermissionManager.registerAttributionSource(source);
+ mPermissionManager.registerAttributionSource(registeredSource);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
+ return registeredSource;
}
/**
diff --git a/core/java/android/service/voice/AbstractHotwordDetector.java b/core/java/android/service/voice/AbstractHotwordDetector.java
index 54ccf30..dbe1089 100644
--- a/core/java/android/service/voice/AbstractHotwordDetector.java
+++ b/core/java/android/service/voice/AbstractHotwordDetector.java
@@ -20,7 +20,9 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.ActivityThread;
import android.media.AudioFormat;
+import android.media.permission.Identity;
import android.os.Handler;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
@@ -111,8 +113,10 @@
if (DEBUG) {
Slog.d(TAG, "updateStateLocked()");
}
+ Identity identity = new Identity();
+ identity.packageName = ActivityThread.currentOpPackageName();
try {
- mManagerService.updateState(options, sharedMemory, callback);
+ mManagerService.updateState(identity, options, sharedMemory, callback);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 145607a..6f915c9 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -128,6 +128,10 @@
*/
@Appearance int getSystemBarsAppearance();
+ default boolean isSystemBarsAppearanceControlled() {
+ return false;
+ }
+
/**
* @see WindowInsetsController#setSystemBarsBehavior
*/
@@ -138,6 +142,10 @@
*/
@Behavior int getSystemBarsBehavior();
+ default boolean isSystemBarsBehaviorControlled() {
+ return false;
+ }
+
/**
* Releases a surface and ensure that this is done after {@link #applySurfaceParams} has
* finished applying params.
@@ -1520,6 +1528,10 @@
@Override
public @Appearance int getSystemBarsAppearance() {
+ if (!mHost.isSystemBarsAppearanceControlled()) {
+ // We only return the requested appearance, not the implied one.
+ return 0;
+ }
return mHost.getSystemBarsAppearance();
}
@@ -1544,6 +1556,10 @@
@Override
public @Behavior int getSystemBarsBehavior() {
+ if (!mHost.isSystemBarsBehaviorControlled()) {
+ // We only return the requested behavior, not the implied one.
+ return 0;
+ }
return mHost.getSystemBarsBehavior();
}
diff --git a/core/java/android/view/ViewRootInsetsControllerHost.java b/core/java/android/view/ViewRootInsetsControllerHost.java
index 27821fd..ce882da 100644
--- a/core/java/android/view/ViewRootInsetsControllerHost.java
+++ b/core/java/android/view/ViewRootInsetsControllerHost.java
@@ -180,14 +180,15 @@
@Override
public int getSystemBarsAppearance() {
- if ((mViewRoot.mWindowAttributes.privateFlags & PRIVATE_FLAG_APPEARANCE_CONTROLLED) == 0) {
- // We only return the requested appearance, not the implied one.
- return 0;
- }
return mViewRoot.mWindowAttributes.insetsFlags.appearance;
}
@Override
+ public boolean isSystemBarsAppearanceControlled() {
+ return (mViewRoot.mWindowAttributes.privateFlags & PRIVATE_FLAG_APPEARANCE_CONTROLLED) != 0;
+ }
+
+ @Override
public void setSystemBarsBehavior(int behavior) {
mViewRoot.mWindowAttributes.privateFlags |= PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
if (mViewRoot.mWindowAttributes.insetsFlags.behavior != behavior) {
@@ -199,14 +200,15 @@
@Override
public int getSystemBarsBehavior() {
- if ((mViewRoot.mWindowAttributes.privateFlags & PRIVATE_FLAG_BEHAVIOR_CONTROLLED) == 0) {
- // We only return the requested behavior, not the implied one.
- return 0;
- }
return mViewRoot.mWindowAttributes.insetsFlags.behavior;
}
@Override
+ public boolean isSystemBarsBehaviorControlled() {
+ return (mViewRoot.mWindowAttributes.privateFlags & PRIVATE_FLAG_BEHAVIOR_CONTROLLED) != 0;
+ }
+
+ @Override
public void releaseSurfaceControlFromRt(SurfaceControl surfaceControl) {
// At the time we receive new leashes (e.g. InsetsSourceConsumer is processing
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index dddc08a..c8a4425 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -231,6 +231,9 @@
/**
* Set configuration and pass read-only data to hotword detection service.
+ * Caller must provide an identity, used for permission tracking purposes.
+ * The uid/pid elements of the identity will be ignored by the server and replaced with the ones
+ * provided by binder.
*
* @param options Application configuration data to provide to the
* {@link HotwordDetectionService}. PersistableBundle does not allow any remotable objects or
@@ -241,6 +244,7 @@
* @param callback Use this to report {@link HotwordDetectionService} status.
*/
void updateState(
+ in Identity originatorIdentity,
in PersistableBundle options,
in SharedMemory sharedMemory,
in IHotwordRecognitionStatusCallback callback);
diff --git a/core/java/com/android/internal/widget/NotificationExpandButton.java b/core/java/com/android/internal/widget/NotificationExpandButton.java
index 1974b0c..07ee9b5 100644
--- a/core/java/com/android/internal/widget/NotificationExpandButton.java
+++ b/core/java/com/android/internal/widget/NotificationExpandButton.java
@@ -20,7 +20,6 @@
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.ColorStateList;
-import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.RemotableViewMethod;
@@ -159,8 +158,7 @@
if (mHighlightPillColor != 0) {
mPillView.setBackgroundTintList(ColorStateList.valueOf(mHighlightPillColor));
}
- mPillView.setBackgroundTintMode(PorterDuff.Mode.SRC_IN);
- mIconView.setColorFilter(mHighlightTextColor, PorterDuff.Mode.SRC_IN);
+ mIconView.setColorFilter(mHighlightTextColor);
if (mHighlightTextColor != 0) {
mNumberView.setTextColor(mHighlightTextColor);
}
@@ -168,8 +166,7 @@
if (mDefaultPillColor != 0) {
mPillView.setBackgroundTintList(ColorStateList.valueOf(mDefaultPillColor));
}
- mPillView.setBackgroundTintMode(PorterDuff.Mode.SRC_IN);
- mIconView.setColorFilter(mDefaultTextColor, PorterDuff.Mode.SRC_IN);
+ mIconView.setColorFilter(mDefaultTextColor);
if (mDefaultTextColor != 0) {
mNumberView.setTextColor(mDefaultTextColor);
}
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index de65b89..4180448 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -880,7 +880,7 @@
continue;
}
- sizeKb += importer_info->second.size;
+ sizeKb += importer_info->second.size / 1024;
}
return sizeKb;
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 3968822..0970fc5 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -2357,7 +2357,7 @@
<string name="dismiss_action" msgid="1728820550388704784">"Адхіліць"</string>
<string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Разблакіруйце мікрафон прылады"</string>
<string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Разблакіруйце камеру прылады"</string>
- <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Для праграмы <b><xliff:g id="APP">%s</xliff:g></b> і ўсіх праграм і сэрвісаў"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Для <b><xliff:g id="APP">%s</xliff:g></b> і ўсіх праграм і сэрвісаў"</string>
<string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Разблакіраваць"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Прыватнасць інфармацыі з датчыка"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Значок праграмы"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 93c7bc1..8c465f1 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -2289,7 +2289,7 @@
<string name="dismiss_action" msgid="1728820550388704784">"Cerrar"</string>
<string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Desbloquea el micrófono del dispositivo"</string>
<string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Desbloquea la cámara del dispositivo"</string>
- <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Para <b><xliff:g id="APP">%s</xliff:g></b> y todos los servicios y las aplicaciones"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Para <b><xliff:g id="APP">%s</xliff:g></b> y todas las aplicaciones y servicios"</string>
<string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Desbloquear"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacidad del sensor"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icono de aplicación"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 5b390a3..667dd9c 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -617,7 +617,7 @@
<string name="face_setup_notification_content" msgid="5463999831057751676">"Taktu símann úr lás með því að horfa á hann"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Settu upp fleiri leiðir til að taka úr lás"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Ýttu til að bæta við fingrafari"</string>
- <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Fingrafarsopnun"</string>
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Fingrafarskenni"</string>
<string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Ekki er hægt að nota fingrafaralesara"</string>
<string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Þú verður að fara á verkstæði."</string>
<string name="face_acquired_insufficient" msgid="2150805835949162453">"Nákvæm andlitsgögn fengust ekki. Reyndu aftur."</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index d9fd103..f5d16fc 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -579,7 +579,7 @@
<string name="fingerprint_acquired_partial" msgid="694598777291084823">"지문의 일부만 감지됨"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"지문을 인식할 수 없습니다. 다시 시도해 주세요."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"센서 닦기"</string>
- <string name="fingerprint_acquired_too_fast" msgid="6038375140739678098">"조금 더 오래 기다려 주세요."</string>
+ <string name="fingerprint_acquired_too_fast" msgid="6038375140739678098">"조금 더 길게 터치하세요."</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"손가락을 너무 느리게 움직였습니다. 다시 시도해 주세요."</string>
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"다른 지문으로 시도"</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"너무 밝음"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 34da0f4..b1c0d59 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -2290,7 +2290,7 @@
<string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"ຍົກເລີກການບລັອກໄມໂຄຣໂຟນອຸປະກອນ"</string>
<string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"ຍົກເລີກການບລັອກອຸປະກອນກ້ອງຖ່າຍຮູບ"</string>
<string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"ສຳລັບ <b><xliff:g id="APP">%s</xliff:g></b> ແລະ ແອັບ ແລະ ບໍລິການທັງໝົດ"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"ຍົກເລີກການບລັອກ"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"ປົດບລັອກ"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ຄວາມເປັນສ່ວນຕົວເຊັນເຊີ"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"ໄອຄອນແອັບພລິເຄຊັນ"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ຮູບແບຣນແອັບພລິເຄຊັນ"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 794f50e..5139522 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -2287,10 +2287,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"现在您可以放大屏幕上的部分内容"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"在“设置”中开启"</string>
<string name="dismiss_action" msgid="1728820550388704784">"关闭"</string>
- <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"取消禁用设备麦克风"</string>
- <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"取消禁用设备摄像头"</string>
- <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"针对<b><xliff:g id="APP">%s</xliff:g></b>及所有应用和服务"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"取消禁用"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"解锁设备麦克风"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"解锁设备摄像头"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"允许“<b><xliff:g id="APP">%s</xliff:g></b>”及所有应用和服务使用"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"解锁"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"传感器隐私权"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"应用图标"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"应用品牌图片"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 29303ba..798e06c 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -318,7 +318,7 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"存取你的體能活動記錄"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"相機"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"拍照及錄製影片"</string>
- <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"附近的裝置"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"鄰近裝置"</string>
<string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"探索附近的裝置並進行連線"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"通話記錄"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"讀取及寫入通話記錄"</string>
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 2054a7d..2038cff 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
@@ -140,8 +140,6 @@
private final ContentObserver mActivatedObserver;
private final ContentObserver mEnabledObserver;
- private final ContentObserver mTimeoutObserver;
- private final ContentObserver mTaskChangeExitObserver;
private final ContentObserver mSwipeToNotificationEnabledObserver;
private final ContentObserver mShortcutEnabledObserver;
@@ -225,7 +223,7 @@
OneHandedTimeoutHandler timeoutHandler = new OneHandedTimeoutHandler(mainExecutor);
OneHandedState transitionState = new OneHandedState();
OneHandedTutorialHandler tutorialHandler = new OneHandedTutorialHandler(context,
- displayLayout, windowManager, settingsUtil, mainExecutor);
+ windowManager);
OneHandedAnimationController animationController =
new OneHandedAnimationController(context);
OneHandedTouchHandler touchHandler = new OneHandedTouchHandler(timeoutHandler,
@@ -292,8 +290,6 @@
mActivatedObserver = getObserver(this::onActivatedActionChanged);
mEnabledObserver = getObserver(this::onEnabledSettingChanged);
- mTimeoutObserver = getObserver(this::onTimeoutSettingChanged);
- mTaskChangeExitObserver = getObserver(this::onTaskChangeExitSettingChanged);
mSwipeToNotificationEnabledObserver =
getObserver(this::onSwipeToNotificationEnabledChanged);
mShortcutEnabledObserver = getObserver(this::onShortcutEnabledChanged);
@@ -440,10 +436,6 @@
mContext.getContentResolver(), mActivatedObserver, newUserId);
mOneHandedSettingsUtil.registerSettingsKeyObserver(Settings.Secure.ONE_HANDED_MODE_ENABLED,
mContext.getContentResolver(), mEnabledObserver, newUserId);
- mOneHandedSettingsUtil.registerSettingsKeyObserver(Settings.Secure.ONE_HANDED_MODE_TIMEOUT,
- mContext.getContentResolver(), mTimeoutObserver, newUserId);
- mOneHandedSettingsUtil.registerSettingsKeyObserver(Settings.Secure.TAPS_APP_TO_EXIT,
- mContext.getContentResolver(), mTaskChangeExitObserver, newUserId);
mOneHandedSettingsUtil.registerSettingsKeyObserver(
Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED,
mContext.getContentResolver(), mSwipeToNotificationEnabledObserver, newUserId);
@@ -456,10 +448,6 @@
mOneHandedSettingsUtil.unregisterSettingsKeyObserver(mContext.getContentResolver(),
mEnabledObserver);
mOneHandedSettingsUtil.unregisterSettingsKeyObserver(mContext.getContentResolver(),
- mTimeoutObserver);
- mOneHandedSettingsUtil.unregisterSettingsKeyObserver(mContext.getContentResolver(),
- mTaskChangeExitObserver);
- mOneHandedSettingsUtil.unregisterSettingsKeyObserver(mContext.getContentResolver(),
mSwipeToNotificationEnabledObserver);
mOneHandedSettingsUtil.unregisterSettingsKeyObserver(mContext.getContentResolver(),
mShortcutEnabledObserver);
@@ -474,6 +462,7 @@
.getSettingsTapsAppToExit(mContext.getContentResolver(), mUserId));
setSwipeToNotificationEnabled(mOneHandedSettingsUtil
.getSettingsSwipeToNotificationEnabled(mContext.getContentResolver(), mUserId));
+ onShortcutEnabledChanged();
}
private void updateDisplayLayout(int displayId) {
@@ -547,46 +536,6 @@
}
@VisibleForTesting
- void onTimeoutSettingChanged() {
- final int newTimeout = mOneHandedSettingsUtil.getSettingsOneHandedModeTimeout(
- mContext.getContentResolver(), mUserId);
- int metricsId = OneHandedUiEventLogger.OneHandedSettingsTogglesEvent.INVALID.getId();
- switch (newTimeout) {
- case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_NEVER:
- metricsId = OneHandedUiEventLogger.EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_NEVER;
- break;
- case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS:
- metricsId = OneHandedUiEventLogger.EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_4;
- break;
- case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS:
- metricsId = OneHandedUiEventLogger.EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_8;
- break;
- case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_LONG_IN_SECONDS:
- metricsId = OneHandedUiEventLogger.EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_12;
- break;
- default:
- // do nothing
- break;
- }
- mOneHandedUiEventLogger.writeEvent(metricsId);
-
- if (mTimeoutHandler != null) {
- mTimeoutHandler.setTimeout(newTimeout);
- }
- }
-
- @VisibleForTesting
- void onTaskChangeExitSettingChanged() {
- final boolean enabled = mOneHandedSettingsUtil.getSettingsTapsAppToExit(
- mContext.getContentResolver(), mUserId);
- mOneHandedUiEventLogger.writeEvent(enabled
- ? OneHandedUiEventLogger.EVENT_ONE_HANDED_SETTINGS_APP_TAPS_EXIT_ON
- : OneHandedUiEventLogger.EVENT_ONE_HANDED_SETTINGS_APP_TAPS_EXIT_OFF);
-
- setTaskChangeToExit(enabled);
- }
-
- @VisibleForTesting
void onSwipeToNotificationEnabledChanged() {
final boolean enabled =
mOneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled(
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 6cee404..0f6c4b0 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,7 +16,7 @@
package com.android.wm.shell.onehanded;
-import static android.os.UserHandle.myUserId;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static com.android.wm.shell.onehanded.OneHandedState.STATE_ACTIVE;
import static com.android.wm.shell.onehanded.OneHandedState.STATE_ENTERING;
@@ -24,7 +24,6 @@
import static com.android.wm.shell.onehanded.OneHandedState.STATE_NONE;
import android.annotation.Nullable;
-import android.content.ContentResolver;
import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.Rect;
@@ -41,7 +40,6 @@
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;
import java.io.PrintWriter;
@@ -56,57 +54,44 @@
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 float mTutorialHeightRatio;
private final WindowManager mWindowManager;
- private final OneHandedSettingsUtil mSettingsUtil;
- private final ShellExecutor mShellExecutor;
- private boolean mCanShow;
+ private boolean mIsShowing;
private @OneHandedState.State int mCurrentState;
- private int mShownCounts;
private int mTutorialAreaHeight;
private Context mContext;
- private ContentResolver mContentResolver;
private Rect mDisplayBounds;
private @Nullable View mTutorialView;
private @Nullable ViewGroup mTargetViewContainer;
- private final OneHandedAnimationCallback mAnimationCallback = new OneHandedAnimationCallback() {
- @Override
- public void onAnimationUpdate(float xPos, float yPos) {
- if (!canShowTutorial()) {
- return;
- }
- mTargetViewContainer.setTransitionGroup(true);
- mTargetViewContainer.setTranslationY(yPos - mTargetViewContainer.getHeight());
- }
- };
+ private final OneHandedAnimationCallback mAnimationCallback;
- public OneHandedTutorialHandler(Context context, DisplayLayout displayLayout,
- WindowManager windowManager, OneHandedSettingsUtil settingsUtil,
- ShellExecutor mainExecutor) {
+ public OneHandedTutorialHandler(Context context, WindowManager windowManager) {
mContext = context;
- 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;
- mShownCounts = mSettingsUtil.getTutorialShownCounts(mContentResolver, myUserId());
+ mAnimationCallback = new OneHandedAnimationCallback() {
+ @Override
+ public void onAnimationUpdate(float xPos, float yPos) {
+ if (!isShowing()) {
+ return;
+ }
+ mTargetViewContainer.setTransitionGroup(true);
+ mTargetViewContainer.setTranslationY(yPos - mTargetViewContainer.getHeight());
+ }
+ };
}
@Override
public void onStateChanged(int newState) {
mCurrentState = newState;
- if (!canShowTutorial()) {
- return;
- }
switch (newState) {
case STATE_ENTERING:
createViewAndAttachToWindow(mContext);
@@ -139,7 +124,7 @@
@VisibleForTesting
void createViewAndAttachToWindow(Context context) {
- if (!canShowTutorial()) {
+ if (isShowing()) {
return;
}
mTutorialView = LayoutInflater.from(context).inflate(R.layout.one_handed_tutorial, null);
@@ -150,15 +135,6 @@
attachTargetToWindow();
}
- @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.
*/
@@ -166,6 +142,7 @@
if (!mTargetViewContainer.isAttachedToWindow()) {
try {
mWindowManager.addView(mTargetViewContainer, getTutorialTargetLayoutParams());
+ mIsShowing = true;
} catch (IllegalStateException e) {
// This shouldn't happen, but if the target is already added, just update its
// layout params.
@@ -179,14 +156,12 @@
void removeTutorialFromWindowManager(boolean increment) {
if (mTargetViewContainer != null && mTargetViewContainer.isAttachedToWindow()) {
mWindowManager.removeViewImmediate(mTargetViewContainer);
- if (increment) {
- setTutorialShownCountIncrement();
- }
+ mIsShowing = false;
}
}
@Nullable OneHandedAnimationCallback getAnimationCallback() {
- return canShowTutorial() ? mAnimationCallback : null /* Disabled */;
+ return isShowing() ? mAnimationCallback : null /* Disabled */;
}
/**
@@ -200,6 +175,7 @@
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
lp.gravity = Gravity.TOP | Gravity.LEFT;
+ lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
lp.setFitInsetsTypes(0 /* types */);
lp.setTitle("one-handed-tutorial-overlay");
@@ -207,17 +183,14 @@
}
@VisibleForTesting
- boolean canShowTutorial() {
- return mCanShow = mShownCounts < MAX_TUTORIAL_SHOW_COUNT;
+ boolean isShowing() {
+ return mIsShowing;
}
/**
* onConfigurationChanged events for updating tutorial text.
*/
public void onConfigurationChanged() {
- if (!canShowTutorial()) {
- return;
- }
removeTutorialFromWindowManager(false /* increment */);
if (mCurrentState == STATE_ENTERING || mCurrentState == STATE_ACTIVE) {
createViewAndAttachToWindow(mContext);
@@ -227,14 +200,12 @@
void dump(@NonNull PrintWriter pw) {
final String innerPrefix = " ";
pw.println(TAG);
- pw.print(innerPrefix + "mCanShow=");
- pw.println(mCanShow);
+ pw.print(innerPrefix + "mIsShowing=");
+ pw.println(mIsShowing);
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/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 9ec7d30..b224ae6 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
@@ -238,13 +238,6 @@
}
@Test
- public void testSettingsObserverUpdateTimeout() {
- mSpiedOneHandedController.onTimeoutSettingChanged();
-
- verify(mSpiedTimeoutHandler, atLeastOnce()).setTimeout(anyInt());
- }
-
- @Test
public void testSettingsObserverUpdateSwipeToNotification() {
mSpiedOneHandedController.onSwipeToNotificationEnabledChanged();
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 1bc2a08..25bdb8e 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
@@ -19,8 +19,6 @@
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;
@@ -68,25 +66,18 @@
mDisplayLayout = new DisplayLayout(mContext, mDisplay);
mSpiedTransitionState = spy(new OneHandedState());
mSpiedTutorialHandler = spy(
- new OneHandedTutorialHandler(mContext, mDisplayLayout, mMockWindowManager,
- mMockSettingsUtil, mMockShellMainExecutor));
+ new OneHandedTutorialHandler(mContext, mMockWindowManager));
mTimeoutHandler = new OneHandedTimeoutHandler(mMockShellMainExecutor);
}
@Test
- 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);
+ when(mSpiedTutorialHandler.isShowing()).thenReturn(true);
try {
mSpiedTutorialHandler.onStateChanged(STATE_ENTERING);
} catch (ClassCastException e) {
@@ -98,7 +89,7 @@
@Test
public void testOnStateChangedNone_removeViewAndAttachToWindow() {
- when(mSpiedTutorialHandler.canShowTutorial()).thenReturn(true);
+ when(mSpiedTutorialHandler.isShowing()).thenReturn(true);
try {
mSpiedTutorialHandler.onStateChanged(STATE_NONE);
} catch (ClassCastException e) {
@@ -110,19 +101,19 @@
@Test
public void testOnStateChangedNone_shouldNotAttachWindow() {
- when(mSpiedTutorialHandler.canShowTutorial()).thenReturn(true);
+ when(mSpiedTutorialHandler.isShowing()).thenReturn(true);
try {
mSpiedTutorialHandler.onStateChanged(STATE_NONE);
} catch (ClassCastException e) {
// no-op, just assert setTutorialShownCountIncrement() never be called
}
- verify(mSpiedTutorialHandler, never()).setTutorialShownCountIncrement();
+ verify(mSpiedTutorialHandler, never()).createViewAndAttachToWindow(any());
}
@Test
public void testOnConfigurationChanged_shouldUpdateViewContent() {
- when(mSpiedTutorialHandler.canShowTutorial()).thenReturn(true);
+ when(mSpiedTutorialHandler.isShowing()).thenReturn(true);
try {
mSpiedTutorialHandler.onStateChanged(STATE_ENTERING);
} catch (ClassCastException e) {
diff --git a/libs/androidfw/CursorWindow.cpp b/libs/androidfw/CursorWindow.cpp
index 1b8db46..3527eee 100644
--- a/libs/androidfw/CursorWindow.cpp
+++ b/libs/androidfw/CursorWindow.cpp
@@ -62,7 +62,6 @@
window->clear();
window->updateSlotsData();
- LOG(DEBUG) << "Created: " << window->toString();
*outWindow = window;
return OK;
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 0a232d6..2c299fa 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -47,6 +47,7 @@
"-DATRACE_TAG=ATRACE_TAG_VIEW",
"-DLOG_TAG=\"OpenGLRenderer\"",
"-Wall",
+ "-Wthread-safety",
"-Wno-unused-parameter",
"-Wunreachable-code",
"-Werror",
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index dd977c3..34e5577 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -99,7 +99,7 @@
mFrameIntervalLegacy = frameIntervalNanos;
}
-void JankTracker::calculateLegacyJank(FrameInfo& frame) {
+void JankTracker::calculateLegacyJank(FrameInfo& frame) REQUIRES(mDataMutex) {
// Fast-path for jank-free frames
int64_t totalDuration = frame.duration(sFrameStart, FrameInfoIndex::SwapBuffersCompleted);
if (mDequeueTimeForgivenessLegacy && frame[FrameInfoIndex::DequeueBufferDuration] > 500_us) {
@@ -257,7 +257,7 @@
}
}
-void JankTracker::recomputeThresholds(int64_t frameBudget) {
+void JankTracker::recomputeThresholds(int64_t frameBudget) REQUIRES(mDataMutex) {
if (mThresholdsFrameBudget == frameBudget) {
return;
}
@@ -308,7 +308,7 @@
dprintf(fd, "\n---PROFILEDATA---\n\n");
}
-void JankTracker::reset() {
+void JankTracker::reset() REQUIRES(mDataMutex) {
mFrames.clear();
mData->reset();
(*mGlobalData)->reset();
diff --git a/libs/hwui/JankTracker.h b/libs/hwui/JankTracker.h
index 0d2574c..bdb784d 100644
--- a/libs/hwui/JankTracker.h
+++ b/libs/hwui/JankTracker.h
@@ -62,7 +62,7 @@
// Calculates the 'legacy' jank information, i.e. with outdated refresh rate information and
// without GPU completion or deadlined information.
void calculateLegacyJank(FrameInfo& frame);
- void dumpStats(int fd) { dumpData(fd, &mDescription, mData.get()); }
+ void dumpStats(int fd) NO_THREAD_SAFETY_ANALYSIS { dumpData(fd, &mDescription, mData.get()); }
void dumpFrames(int fd);
void reset();
diff --git a/libs/hwui/ProfileDataContainer.cpp b/libs/hwui/ProfileDataContainer.cpp
index 41afc0e..dd78847 100644
--- a/libs/hwui/ProfileDataContainer.cpp
+++ b/libs/hwui/ProfileDataContainer.cpp
@@ -27,7 +27,7 @@
namespace android {
namespace uirenderer {
-void ProfileDataContainer::freeData() {
+void ProfileDataContainer::freeData() REQUIRES(mJankDataMutex) {
if (mIsMapped) {
munmap(mData, sizeof(ProfileData));
} else {
diff --git a/libs/hwui/ProfileDataContainer.h b/libs/hwui/ProfileDataContainer.h
index a61b8dc..7d1b46c 100644
--- a/libs/hwui/ProfileDataContainer.h
+++ b/libs/hwui/ProfileDataContainer.h
@@ -37,8 +37,9 @@
void rotateStorage();
void switchStorageToAshmem(int ashmemfd);
- ProfileData* get() { return mData; }
- ProfileData* operator->() { return mData; }
+ ProfileData* get() NO_THREAD_SAFETY_ANALYSIS { return mData; }
+
+ ProfileData* operator->() NO_THREAD_SAFETY_ANALYSIS { return mData; }
std::mutex& getDataMutex() { return mJankDataMutex; }
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 4dcd5af..025be7b 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -614,6 +614,7 @@
mCurrentFrameInfo->markFrameCompleted();
mCurrentFrameInfo->set(FrameInfoIndex::GpuCompleted)
= mCurrentFrameInfo->get(FrameInfoIndex::FrameCompleted);
+ std::scoped_lock lock(mFrameMetricsReporterMutex);
mJankTracker.finishFrame(*mCurrentFrameInfo, mFrameMetricsReporter);
}
}
@@ -638,9 +639,12 @@
}
void CanvasContext::reportMetricsWithPresentTime() {
- if (mFrameMetricsReporter == nullptr) {
- return;
- }
+ { // acquire lock
+ std::scoped_lock lock(mFrameMetricsReporterMutex);
+ if (mFrameMetricsReporter == nullptr) {
+ return;
+ }
+ } // release lock
if (mNativeSurface == nullptr) {
return;
}
@@ -666,7 +670,22 @@
nullptr /*outReleaseTime*/);
forthBehind->set(FrameInfoIndex::DisplayPresentTime) = presentTime;
- mFrameMetricsReporter->reportFrameMetrics(forthBehind->data(), true /*hasPresentTime*/);
+ { // acquire lock
+ std::scoped_lock lock(mFrameMetricsReporterMutex);
+ if (mFrameMetricsReporter != nullptr) {
+ mFrameMetricsReporter->reportFrameMetrics(forthBehind->data(), true /*hasPresentTime*/);
+ }
+ } // release lock
+}
+
+FrameInfo* CanvasContext::getFrameInfoFromLast4(uint64_t frameNumber) {
+ std::scoped_lock lock(mLast4FrameInfosMutex);
+ for (size_t i = 0; i < mLast4FrameInfos.size(); i++) {
+ if (mLast4FrameInfos[i].second == frameNumber) {
+ return mLast4FrameInfos[i].first;
+ }
+ }
+ return nullptr;
}
void CanvasContext::onSurfaceStatsAvailable(void* context, ASurfaceControl* control,
@@ -680,22 +699,13 @@
nsecs_t gpuCompleteTime = functions.getAcquireTimeFunc(stats);
uint64_t frameNumber = functions.getFrameNumberFunc(stats);
- FrameInfo* frameInfo = nullptr;
- {
- std::lock_guard(instance->mLast4FrameInfosMutex);
- for (size_t i = 0; i < instance->mLast4FrameInfos.size(); i++) {
- if (instance->mLast4FrameInfos[i].second == frameNumber) {
- frameInfo = instance->mLast4FrameInfos[i].first;
- break;
- }
- }
- }
+ FrameInfo* frameInfo = instance->getFrameInfoFromLast4(frameNumber);
if (frameInfo != nullptr) {
frameInfo->set(FrameInfoIndex::FrameCompleted) = std::max(gpuCompleteTime,
frameInfo->get(FrameInfoIndex::SwapBuffersCompleted));
frameInfo->set(FrameInfoIndex::GpuCompleted) = gpuCompleteTime;
- std::lock_guard(instance->mFrameMetricsReporterMutex);
+ std::scoped_lock lock(instance->mFrameMetricsReporterMutex);
instance->mJankTracker.finishFrame(*frameInfo, instance->mFrameMetricsReporter);
}
}
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 85af3e4..6dbfcc3 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -160,6 +160,7 @@
void setContentDrawBounds(const Rect& bounds) { mContentDrawBounds = bounds; }
void addFrameMetricsObserver(FrameMetricsObserver* observer) {
+ std::scoped_lock lock(mFrameMetricsReporterMutex);
if (mFrameMetricsReporter.get() == nullptr) {
mFrameMetricsReporter.reset(new FrameMetricsReporter());
}
@@ -168,10 +169,10 @@
}
void removeFrameMetricsObserver(FrameMetricsObserver* observer) {
+ std::scoped_lock lock(mFrameMetricsReporterMutex);
if (mFrameMetricsReporter.get() != nullptr) {
mFrameMetricsReporter->removeObserver(observer);
if (!mFrameMetricsReporter->hasObservers()) {
- std::lock_guard lock(mFrameMetricsReporterMutex);
mFrameMetricsReporter.reset(nullptr);
}
}
@@ -245,6 +246,8 @@
*/
void reportMetricsWithPresentTime();
+ FrameInfo* getFrameInfoFromLast4(uint64_t frameNumber);
+
// The same type as Frame.mWidth and Frame.mHeight
int32_t mLastFrameWidth = 0;
int32_t mLastFrameHeight = 0;
@@ -305,7 +308,8 @@
std::string mName;
JankTracker mJankTracker;
FrameInfoVisualizer mProfiler;
- std::unique_ptr<FrameMetricsReporter> mFrameMetricsReporter;
+ std::unique_ptr<FrameMetricsReporter> mFrameMetricsReporter
+ GUARDED_BY(mFrameMetricsReporterMutex);
std::mutex mFrameMetricsReporterMutex;
std::set<RenderNode*> mPrefetchedLayers;
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 09ebb40..bd3ca5a 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -73,6 +73,7 @@
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -103,7 +104,7 @@
private static final AudioVolumeGroupChangeHandler sAudioAudioVolumeGroupChangedHandler =
new AudioVolumeGroupChangeHandler();
- private static Context sContext;
+ private static WeakReference<Context> sContext;
/**
* Broadcast intent, a hint for applications that audio is about to become
@@ -800,7 +801,7 @@
} else {
mOriginalContext = context;
}
- sContext = context;
+ sContext = new WeakReference<>(context);
}
@UnsupportedAppUsage
@@ -7256,23 +7257,27 @@
*/
public static boolean hasHapticChannels(@Nullable Context context, @NonNull Uri uri) {
Objects.requireNonNull(uri);
+
if (context != null) {
return hasHapticChannelsImpl(context, uri);
- } else if (sContext != null) {
+ }
+
+ Context cachedContext = sContext.get();
+ if (cachedContext != null) {
if (DEBUG) {
Log.d(TAG, "Try to use static context to query if having haptic channels");
}
- return hasHapticChannelsImpl(sContext, uri);
- } else {
- // Try with audio service context, this may fail to get correct result.
- if (DEBUG) {
- Log.d(TAG, "Try to use audio service context to query if having haptic channels");
- }
- try {
- return getService().hasHapticChannels(uri);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return hasHapticChannelsImpl(cachedContext, uri);
+ }
+
+ // Try with audio service context, this may fail to get correct result.
+ if (DEBUG) {
+ Log.d(TAG, "Try to use audio service context to query if having haptic channels");
+ }
+ try {
+ return getService().hasHapticChannels(uri);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 952bbf5..2ea745b 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -347,7 +347,6 @@
mHandler = createEventHandler();
}
- mHandler = createEventHandler();
int[] clientId = new int[1];
ResourceClientProfile profile = new ResourceClientProfile();
profile.tvInputSessionId = tvInputSessionId;
@@ -516,6 +515,8 @@
mDemuxHandle = null;
}
+ mTunerResourceManager.unregisterClientProfile(mClientId);
+
}
/**
diff --git a/packages/CtsShim/apk/arm/CtsShim.apk b/packages/CtsShim/apk/arm/CtsShim.apk
index da4ae56..e88e1ba 100644
--- a/packages/CtsShim/apk/arm/CtsShim.apk
+++ b/packages/CtsShim/apk/arm/CtsShim.apk
Binary files differ
diff --git a/packages/CtsShim/apk/arm/CtsShimPriv.apk b/packages/CtsShim/apk/arm/CtsShimPriv.apk
index 214d5c2..f35732c 100644
--- a/packages/CtsShim/apk/arm/CtsShimPriv.apk
+++ b/packages/CtsShim/apk/arm/CtsShimPriv.apk
Binary files differ
diff --git a/packages/CtsShim/apk/x86/CtsShim.apk b/packages/CtsShim/apk/x86/CtsShim.apk
index da4ae56..e88e1ba 100644
--- a/packages/CtsShim/apk/x86/CtsShim.apk
+++ b/packages/CtsShim/apk/x86/CtsShim.apk
Binary files differ
diff --git a/packages/CtsShim/apk/x86/CtsShimPriv.apk b/packages/CtsShim/apk/x86/CtsShimPriv.apk
index b4c625f..3d9f749 100644
--- a/packages/CtsShim/apk/x86/CtsShimPriv.apk
+++ b/packages/CtsShim/apk/x86/CtsShimPriv.apk
Binary files differ
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 3b56ce7..d9db99e 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -452,8 +452,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"Es posible que el tablet se apague pronto (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"Es posible que el dispositivo se apague pronto (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> hasta que esté completamente cargada"</string>
- <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> hasta que esté completamente cargada"</string>
+ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> hasta la carga completa"</string>
+ <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> hasta la carga completa"</string>
<string name="power_charging_limited" msgid="7956120998372505295">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carga limitada temporalmente"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Desconocido"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Cargando"</string>
diff --git a/packages/SettingsLib/res/values-eu/arrays.xml b/packages/SettingsLib/res/values-eu/arrays.xml
index 4bce1fe..9452688 100644
--- a/packages/SettingsLib/res/values-eu/arrays.xml
+++ b/packages/SettingsLib/res/values-eu/arrays.xml
@@ -218,17 +218,17 @@
</string-array>
<string-array name="overlay_display_devices_entries">
<item msgid="4497393944195787240">"Bat ere ez"</item>
- <item msgid="8461943978957133391">"480 p"</item>
- <item msgid="6923083594932909205">"480 p (segurua)"</item>
- <item msgid="1226941831391497335">"720 p"</item>
- <item msgid="7051983425968643928">"720 p (segurua)"</item>
- <item msgid="7765795608738980305">"1080 p"</item>
- <item msgid="8084293856795803592">"1080 p (segurua)"</item>
+ <item msgid="8461943978957133391">"480p"</item>
+ <item msgid="6923083594932909205">"480p (segurua)"</item>
+ <item msgid="1226941831391497335">"720p"</item>
+ <item msgid="7051983425968643928">"720p (segurua)"</item>
+ <item msgid="7765795608738980305">"1080p"</item>
+ <item msgid="8084293856795803592">"1080p (segurua)"</item>
<item msgid="938784192903353277">"4K"</item>
<item msgid="8612549335720461635">"4K (segurua)"</item>
<item msgid="7322156123728520872">"4K (hobetua)"</item>
<item msgid="7735692090314849188">"4K (hobetua, segurua)"</item>
- <item msgid="7346816300608639624">"720 p, 1080 p (bi pantaila)"</item>
+ <item msgid="7346816300608639624">"720p, 1080p (bi pantaila)"</item>
</string-array>
<string-array name="enable_opengl_traces_entries">
<item msgid="4433736508877934305">"Bat ere ez"</item>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 3814ed5..f2ab2f8 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -452,7 +452,7 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"ថេប្លេតអាចនឹងបិទក្នុងពេលបន្តិចទៀត (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"ឧបករណ៍អាចនឹងបិទក្នុងពេលបន្តិចទៀត (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"នៅសល់ <xliff:g id="TIME">%1$s</xliff:g> ទៀតទើបពេញ"</string>
+ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> ទៀតទើបពេញ"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - នៅសល់ <xliff:g id="TIME">%2$s</xliff:g> ទៀតទើបពេញ"</string>
<string name="power_charging_limited" msgid="7956120998372505295">"<xliff:g id="LEVEL">%1$s</xliff:g> - បានដាក់កម្រិតការសាកថ្មជាបណ្ដោះអាសន្ន"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"មិនស្គាល់"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 54d0176..c4ba449 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -341,7 +341,7 @@
<string name="show_hw_screen_updates" msgid="2021286231267747506">"\'ಅಪ್ಡೇಟ್ಗಳನ್ನು ವೀಕ್ಷಿಸಿ\' ತೋರಿಸಿ"</string>
<string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"ಬರೆದಾಗ ವಿಂಡೊದೊಳಗೆ ವೀಕ್ಷಣೆ ಫ್ಲ್ಯಾಶ್ ಮಾಡುತ್ತದೆ"</string>
<string name="show_hw_layers_updates" msgid="5268370750002509767">"ಹಾರ್ಡ್ವೇರ್ ಲೇಯರ್ ಅಪ್ಡೇಟ್"</string>
- <string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"ಅವುಗಳು ನವೀಕರಿಸಿದಾಗ ಹಾರ್ಡ್ವೇರ್ ಲೇಯರ್ಗಳು ಹಸಿರು ಫ್ಲ್ಯಾಶ್ ಆಗುತ್ತದೆ"</string>
+ <string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"ಅಪ್ಡೇಟ್ ಆದಾಗ ಹಾರ್ಡ್ವೇರ್ ಲೇಯರ್ಗಳು ಹಸಿರು ಬಣ್ಣದಲ್ಲಿ ಫ್ಲ್ಯಾಶ್ ಆಗುತ್ತದೆ"</string>
<string name="debug_hw_overdraw" msgid="8944851091008756796">"GPU ಓವರ್ಡ್ರಾ ಡೀಬಗ್"</string>
<string name="disable_overlays" msgid="4206590799671557143">"HW ಓವರ್ಲೇ ನಿಷ್ಕ್ರಿಯ"</string>
<string name="disable_overlays_summary" msgid="1954852414363338166">"ಸ್ಕ್ರೀನ್ ಸಂಯೋಜನೆಗಾಗಿ ಯಾವಾಗಲೂ GPU ಬಳಸಿ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 4933f4a..97ad0a0 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -462,7 +462,7 @@
<string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"무선 충전 중"</string>
<string name="battery_info_status_discharging" msgid="6962689305413556485">"충전 안함"</string>
<string name="battery_info_status_not_charging" msgid="3371084153747234837">"연결됨, 충전 중 아님"</string>
- <string name="battery_info_status_full" msgid="1339002294876531312">"청구됨"</string>
+ <string name="battery_info_status_full" msgid="1339002294876531312">"충전됨"</string>
<string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"관리자가 제어"</string>
<string name="disabled" msgid="8017887509554714950">"사용 안함"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"허용됨"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index ea67165..864f177 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -452,13 +452,13 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"टॅबलेट लवकरच बंद होऊ शकतो (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"डिव्हाइस लवकरच बंद होऊ शकते (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"पूर्ण चार्ज होण्यासाठी <xliff:g id="TIME">%1$s</xliff:g> शिल्लक आहे"</string>
+ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"पूर्ण चार्ज होण्यासाठी <xliff:g id="TIME">%1$s</xliff:g> शिल्लक आहेत"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - पूर्ण चार्ज होण्यासाठी <xliff:g id="TIME">%2$s</xliff:g> शिल्लक आहे"</string>
<string name="power_charging_limited" msgid="7956120998372505295">"<xliff:g id="LEVEL">%1$s</xliff:g> • चार्जिंग तात्पुरते मर्यादित आहे"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"अज्ञात"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"चार्ज होत आहे"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"वेगाने चार्ज होत आहे"</string>
- <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"हळूहळू चार्ज होत आहे"</string>
+ <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"हळू चार्ज होत आहे"</string>
<string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"वायरलेसने चार्ज होत आहे"</string>
<string name="battery_info_status_discharging" msgid="6962689305413556485">"चार्ज होत नाही"</string>
<string name="battery_info_status_not_charging" msgid="3371084153747234837">"कनेक्ट केले, चार्ज होत नाही"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 06525e4..5ed5f39 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -458,7 +458,7 @@
<string name="battery_info_status_unknown" msgid="268625384868401114">"Tidak diketahui"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Mengecas"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Mengecas dgn cepat"</string>
- <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Mengecas dgn prlahan"</string>
+ <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Mengecas perlahan"</string>
<string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Mengecas tanpa wayar"</string>
<string name="battery_info_status_discharging" msgid="6962689305413556485">"Tidak mengecas"</string>
<string name="battery_info_status_not_charging" msgid="3371084153747234837">"Bersambung, tidak mengecas"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 0397eb8..bb94c24 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -458,7 +458,7 @@
<string name="battery_info_status_unknown" msgid="268625384868401114">"अज्ञात"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"चार्ज हुँदै छ"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"द्रुत गतिमा चार्ज गरिँदै छ"</string>
- <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"बिस्तारै चार्ज गरिँदै"</string>
+ <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"ढिलो चार्ज हुँदै छ"</string>
<string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"वायरलेस तरिकाले चार्ज गरिँदै छ"</string>
<string name="battery_info_status_discharging" msgid="6962689305413556485">"चार्ज भइरहेको छैन"</string>
<string name="battery_info_status_not_charging" msgid="3371084153747234837">"कनेक्ट गरिएको छ, चार्ज भइरहेको छैन"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 49dd07e..fea9601 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -235,8 +235,8 @@
<string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Sparuj urządzenia przez Wi-Fi, skanując kod QR"</string>
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Połącz się z siecią Wi-Fi"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string>
- <string name="bugreport_in_power" msgid="8664089072534638709">"Skrót do zgłoszenia błędu"</string>
- <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Pokaż w menu zasilania przycisk zgłaszania błędu"</string>
+ <string name="bugreport_in_power" msgid="8664089072534638709">"Skrót do zgłaszania błędów"</string>
+ <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Pokazuj w menu zasilania przycisk zgłaszania błędów"</string>
<string name="keep_screen_on" msgid="1187161672348797558">"Pozostaw włączony ekran"</string>
<string name="keep_screen_on_summary" msgid="1510731514101925829">"Ekran nie będzie gaszony podczas ładowania telefonu"</string>
<string name="bt_hci_snoop_log" msgid="7291287955649081448">"Włącz dziennik snoop Bluetooth HCI"</string>
@@ -249,7 +249,7 @@
<string name="mock_location_app_not_set" msgid="6972032787262831155">"Nie ustawiono aplikacji do pozorowania lokalizacji"</string>
<string name="mock_location_app_set" msgid="4706722469342913843">"Aplikacja do pozorowania lokalizacji: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="debug_networking_category" msgid="6829757985772659599">"Sieci"</string>
- <string name="wifi_display_certification" msgid="1805579519992520381">"Wyświetlacz bezprzewodowy"</string>
+ <string name="wifi_display_certification" msgid="1805579519992520381">"Certyfikacja wyświetlacza bezprzewodowego"</string>
<string name="wifi_verbose_logging" msgid="1785910450009679371">"Szczegółowy dziennik Wi-Fi"</string>
<string name="wifi_scan_throttling" msgid="2985624788509913617">"Ograniczanie skanowania Wi-Fi"</string>
<string name="wifi_enhanced_mac_randomization" msgid="882650208573834301">"Nietrwała randomizacja adresów MAC w sieci Wi-Fi"</string>
@@ -281,7 +281,7 @@
<string name="private_dns_mode_provider" msgid="3619040641762557028">"Nazwa hosta dostawcy prywatnego DNS"</string>
<string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Wpisz nazwę hosta dostawcy DNS"</string>
<string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"Nie udało się połączyć"</string>
- <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Pokaż opcje certyfikacji wyświetlacza bezprzewodowego"</string>
+ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Pokazuj opcje certyfikacji wyświetlacza bezprzewodowego"</string>
<string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Zwiększ poziom rejestrowania Wi‑Fi, pokazuj według RSSI SSID w selektorze Wi‑Fi"</string>
<string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Zmniejsza zużycie baterii i zwiększa wydajność sieci"</string>
<string name="wifi_enhanced_mac_randomization_summary" msgid="1210663439867489931">"Kiedy ten tryb jest włączony, to adres MAC tego urządzenia może zmieniać się za każdym razem, kiedy urządzenie połączy się z siecią, która ma włączoną opcję randomizacji MAC"</string>
@@ -297,9 +297,9 @@
<string name="select_usb_configuration_dialog_title" msgid="3579567144722589237">"Wybierz konfigurację USB"</string>
<string name="allow_mock_location" msgid="2102650981552527884">"Pozorowanie lokalizacji"</string>
<string name="allow_mock_location_summary" msgid="179780881081354579">"Zezwalaj na pozorowanie lokalizacji"</string>
- <string name="debug_view_attributes" msgid="3539609843984208216">"Inspekcja wyświetlania atrybutu"</string>
+ <string name="debug_view_attributes" msgid="3539609843984208216">"Inspekcja atrybutu wyświetlania"</string>
<string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Nie wyłączaj transmisji danych przez sieć komórkową, nawet gdy aktywne jest połączenie Wi-Fi (aby szybko przełączać sieci)"</string>
- <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Użyj akceleracji sprzętowej tetheringu, jeśli jest dostępna"</string>
+ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Używaj akceleracji sprzętowej tetheringu, jeśli jest dostępna"</string>
<string name="adb_warning_title" msgid="7708653449506485728">"Czy zezwalać na debugowanie USB?"</string>
<string name="adb_warning_message" msgid="8145270656419669221">"Debugowanie USB jest przeznaczone wyłącznie do celów programistycznych. Może służyć do kopiowania danych między komputerem a urządzeniem, instalowania aplikacji na urządzeniu bez powiadamiania, a także odczytu danych dziennika."</string>
<string name="adbwifi_warning_title" msgid="727104571653031865">"Zezwalać na debugowanie bezprzewodowe?"</string>
@@ -307,8 +307,8 @@
<string name="adb_keys_warning_message" msgid="2968555274488101220">"Odwołać dostęp wszystkich poprzednio autoryzowanych komputerów do debugowania USB?"</string>
<string name="dev_settings_warning_title" msgid="8251234890169074553">"Zezwolić na ustawienia programistyczne?"</string>
<string name="dev_settings_warning_message" msgid="37741686486073668">"Te ustawienia są przeznaczone wyłącznie dla programistów. Ich użycie może spowodować uszkodzenie lub nieprawidłowe działanie urządzenia i zainstalowanych na nim aplikacji."</string>
- <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Zweryfikuj aplikacje przez USB"</string>
- <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Sprawdź, czy aplikacje zainstalowane przez ADB/ADT nie zachowują się w szkodliwy sposób"</string>
+ <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Weryfikuj aplikacje przez USB"</string>
+ <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Sprawdzaj, czy aplikacje zainstalowane przez ADB/ADT nie zachowują się w szkodliwy sposób"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Urządzenia Bluetooth będą wyświetlane bez nazw (tylko adresy MAC)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Wyłącza Głośność bezwzględną Bluetooth, jeśli występują problemy z urządzeniami zdalnymi, np. zbyt duża głośność lub brak kontroli"</string>
<string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Włącza funkcje Bluetooth Gabeldorsche"</string>
@@ -349,17 +349,17 @@
<string name="enable_opengl_traces_title" msgid="4638773318659125196">"Włącz śledzenie OpenGL"</string>
<string name="usb_audio_disable_routing" msgid="3367656923544254975">"Wyłącz kierowanie dźwiękowe USB"</string>
<string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"Wyłącz autokierowanie do urządzeń peryferyjnych audio USB"</string>
- <string name="debug_layout" msgid="1659216803043339741">"Pokaż granice układu"</string>
- <string name="debug_layout_summary" msgid="8825829038287321978">"Pokaż granice przycięcia, marginesy itd."</string>
+ <string name="debug_layout" msgid="1659216803043339741">"Pokazuj granice układu"</string>
+ <string name="debug_layout_summary" msgid="8825829038287321978">"Pokazuj granice przycięcia, marginesy itd."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Układ od prawej do lewej"</string>
- <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Wymuś wszędzie układ ekranu od prawej do lewej"</string>
+ <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Wymuszaj układ ekranu od prawej do lewej dla wszystkich języków"</string>
<string name="window_blurs" msgid="6831008984828425106">"Zezwól na rozmycie na poziomie okna"</string>
- <string name="force_msaa" msgid="4081288296137775550">"Wymuś 4x MSAA"</string>
- <string name="force_msaa_summary" msgid="9070437493586769500">"Włącz 4x MSAA w aplikacjach OpenGL ES 2.0"</string>
+ <string name="force_msaa" msgid="4081288296137775550">"Wymuszaj 4x MSAA"</string>
+ <string name="force_msaa_summary" msgid="9070437493586769500">"Włączaj 4x MSAA w aplikacjach OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Debuguj operacje przycinania nieprostokątnego"</string>
<string name="track_frame_time" msgid="522674651937771106">"Profil renderowania HWUI"</string>
<string name="enable_gpu_debug_layers" msgid="4986675516188740397">"Warstwy debugowania GPU"</string>
- <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Zezwól na ładowanie warstw debugowania GPU"</string>
+ <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Zezwalaj na ładowanie warstw debugowania GPU"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Włącz szczegółowe rejestrowanie dostawcy"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Dołączaj do raportów o błędach dodatkowe dane dostawcy dotyczące konkretnego urządzenia, które mogą zawierać dane prywatne oraz wykorzystywać więcej baterii lub pamięci."</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Skala animacji okna"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index aecfd62..cf6013f 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -458,7 +458,7 @@
<string name="battery_info_status_unknown" msgid="268625384868401114">"نامعلوم"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"چارج ہو رہا ہے"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"تیزی سے چارج ہو رہا ہے"</string>
- <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"آہستہ چارج ہو رہا ہے"</string>
+ <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"آہستہ چارج ہو رہی ہے"</string>
<string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"وائرلیس طریقے سے چارج ہو رہی ہے"</string>
<string name="battery_info_status_discharging" msgid="6962689305413556485">"چارج نہیں ہو رہا ہے"</string>
<string name="battery_info_status_not_charging" msgid="3371084153747234837">"منسلک ہے، چارج نہیں ہو رہی ہے"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index c3caa6d..6d8a0b0 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -458,7 +458,7 @@
<string name="battery_info_status_unknown" msgid="268625384868401114">"未知"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"充電中"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"快速充電中"</string>
- <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"正在慢速充電"</string>
+ <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"慢速充電中"</string>
<string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"無線充電中"</string>
<string name="battery_info_status_discharging" msgid="6962689305413556485">"非充電中"</string>
<string name="battery_info_status_not_charging" msgid="3371084153747234837">"已連接,非充電中"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
index 34c8926..5ecbc9d 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
@@ -37,7 +37,7 @@
<string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 無線充電中"</string>
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 正在充電"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 快速充電中"</string>
- <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> •正在慢速充電"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 慢速充電中"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="6091488837901216962">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 充電暫時受限"</string>
<string name="keyguard_low_battery" msgid="1868012396800230904">"請連接充電器。"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"按下 [選單] 即可解鎖。"</string>
diff --git a/packages/SystemUI/res/layout/long_screenshot.xml b/packages/SystemUI/res/layout/long_screenshot.xml
index 8a3a39f..04bd7b9 100644
--- a/packages/SystemUI/res/layout/long_screenshot.xml
+++ b/packages/SystemUI/res/layout/long_screenshot.xml
@@ -38,21 +38,20 @@
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/preview" />
- <ImageButton
- android:id="@+id/delete"
- style="@android:style/Widget.Material.Button.Borderless"
- android:tint="?android:textColorPrimary"
- android:layout_width="48dp"
- android:layout_height="48dp"
+ <Button
+ android:id="@+id/cancel"
+ style="@android:style/Widget.DeviceDefault.Button.Colored"
+ android:layout_width="wrap_content"
+ android:layout_height="40dp"
+ android:text="@android:string/cancel"
+ android:layout_marginStart="6dp"
android:layout_marginTop="4dp"
- android:padding="12dp"
- android:src="@drawable/ic_screenshot_delete"
- android:scaleType="fitCenter"
- android:contentDescription="@*android:string/delete"
- android:tooltipText="@*android:string/delete"
- app:layout_constraintEnd_toStartOf="@id/share"
+ android:background="@drawable/screenshot_button_background"
+ android:textColor="?android:textColorSecondary"
+ app:layout_constraintStart_toEndOf="@id/save"
app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@id/preview" />
+ app:layout_constraintBottom_toTopOf="@id/preview"
+ />
<ImageButton
android:id="@+id/share"
diff --git a/packages/SystemUI/res/layout/people_space_activity_no_conversations.xml b/packages/SystemUI/res/layout/people_space_activity_no_conversations.xml
index e87bf61..2e9ff07 100644
--- a/packages/SystemUI/res/layout/people_space_activity_no_conversations.xml
+++ b/packages/SystemUI/res/layout/people_space_activity_no_conversations.xml
@@ -15,6 +15,7 @@
-->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:id="@+id/top_level"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -55,7 +56,7 @@
android:background="@drawable/rounded_bg_full_large_radius"
android:onClick="dismissActivity"
android:text="@string/got_it"
- android:textColor="?android:attr/textColorPrimary"
+ android:textColor="?androidprv:attr/textColorOnAccent"
android:layout_marginBottom="60dp"
android:layout_alignParentBottom="true" />
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index df9230f..9598e87 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> het \'n boodskap gestuur: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> het \'n prent gestuur"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> het \'n statusopdatering: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Beskikbaar"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Kon nie jou batterymeter lees nie"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tik vir meer inligting"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Geen wekker nie"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index d4ea169..d60d082 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> መልዕክት ልከዋል፦ <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ምስል ልኳል"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> የሁኔታ ዝማኔ አለው፦ <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"የሚገኙ"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"የባትሪ መለኪያዎን የማንበብ ችግር"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ለበለጠ መረጃ መታ ያድርጉ"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ምንም ማንቂያ አልተቀናበረም"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 8d35188..bfcfd9b 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -1173,6 +1173,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"تم إرسال رسالة من <xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"تم إرسال صورة من <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="new_status_content_description" msgid="6046637888641308327">"تم تعديل حالة <xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"حدثت مشكلة أثناء قراءة مقياس مستوى شحن البطارية."</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"انقر للحصول على مزيد من المعلومات."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"لم يتم ضبط منبّه."</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 880a088..316c87b 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -1149,6 +1149,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g>এ এটা বাৰ্তা পঠিয়াইছে: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>এ এখন প্ৰতিচ্ছবি পঠিয়াইছে"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>ৰ এটা স্থিতিৰ আপডে’ট আছে: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"আপোনাৰ বেটাৰী মিটাৰ পঢ়োঁতে সমস্যা হৈছে"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"অধিক তথ্যৰ বাবে টিপক"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"কোনো এলাৰ্ম ছেট কৰা হোৱা নাই"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 96ab6e3..452164f 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -429,9 +429,9 @@
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Cihaz mikrofonu blokdan çıxarılsın?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Cihaz kamerası blokdan çıxarılsın?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Cihaz kamerası və mikrofonu blokdan çıxarılsın?"</string>
- <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Bu, mikrofonunuzdan istifadə etməyə icazə verilən bütün tətbiq və xidmətlər üçün girişi blokdan çıxarır."</string>
- <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Bu, kameranızdan istifadə etməyə icazə verilən bütün tətbiq və xidmətlər üçün girişi blokdan çıxarır."</string>
- <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Bu, kamera və ya mikrofonunuzdan istifadə etməyə icazə verilən bütün tətbiq və xidmətlər üçün girişi blokdan çıxarır."</string>
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Kamera və mikrofon istifadə edən bütün tətbiq və xidmətlərə giriş verir."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Kamera və mikrofon istifadə edən bütün tətbiq və xidmətlərə giriş verir."</string>
+ <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Kamera və mikrofon istifadə edən bütün tətbiq və xidmətlərə giriş verir."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Cihaz"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Tətbiqi dəyişmək üçün yuxarı sürüşdürün"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Tətbiqləri cəld dəyişmək üçün sağa çəkin"</string>
@@ -1149,6 +1149,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> mesaj göndərdi: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> şəkil göndərdi"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> status güncəlləməsi edib: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Batareya ölçüsünü oxuyarkən problem yarandı"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ətraflı məlumat üçün toxunun"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Siqnal ayarlanmayıb"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 8bd3b0a..d48eebc 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -1155,6 +1155,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> je poslao/la poruku: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> šalje sliku"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ima ažuriranje statusa: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Dostupno"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem sa očitavanjem merača baterije"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Alarm nije podešen"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 9db9e68..8cbc8bd 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -1161,6 +1161,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"Карыстальнік <xliff:g id="NAME">%1$s</xliff:g> прыслаў паведамленне: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"Карыстальнік <xliff:g id="NAME">%1$s</xliff:g> адправіў відарыс"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"Карыстальнік <xliff:g id="NAME">%1$s</xliff:g> абнавіў стан: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Праблема з чытаннем індыкатара зараду акумулятара"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Націсніце, каб убачыць больш"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Няма будзільнікаў"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index e361feb..da45743 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> изпрати съобщение: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> изпрати изображение"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> има актуализация на състоянието: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Налице"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Възникна проблем при четенето на данните за нивото на батерията"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Докоснете за още информация"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Няма зададен будилник"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 72eeab1..2fe583a6a 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -1146,10 +1146,10 @@
<string name="people_tile_description" msgid="8154966188085545556">"সাম্প্রতিক মেসেজ, মিসড কল এবং স্ট্যাটাস সংক্রান্ত আপডেট দেখুন"</string>
<string name="people_tile_title" msgid="6589377493334871272">"কথোপকথন"</string>
<string name="paused_by_dnd" msgid="7856941866433556428">"\'বিরক্ত করবে না\' মোডের মাধ্যমে পজ করা আছে"</string>
- <!-- no translation found for new_notification_text_content_description (2915029960094389291) -->
- <skip />
+ <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> একটি মেসেজ পাঠিয়েছেন: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> একটি ছবি পাঠিয়েছেন"</string>
- <!-- no translation found for new_status_content_description (6046637888641308327) -->
+ <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> একটি স্ট্যাটাস আপডেট করেছেন: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
<skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ব্যাটারির মিটারের রিডিং নেওয়ার সময় সমস্যা হয়েছে"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"আরও তথ্যের জন্য ট্যাপ করুন"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index c4fbd99..2dc7301 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -1155,6 +1155,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> je poslao/la poruku: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> je poslao/la sliku"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> je ažurirao/la status: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Dostupan/na je"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Došlo je do problema prilikom očitavanja mjerača stanja baterije"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nije postavljen alarm"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index cba6e91..37fdbc1 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ha enviat un missatge: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ha enviat una imatge"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> té una actualització d\'estat: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Disponible"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Hi ha hagut un problema en llegir el mesurador de la bateria"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toca per obtenir més informació"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Cap alarma configurada"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 93b6359..25f796c 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -1161,6 +1161,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> posílá zprávu: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> posílá obrázek"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> má aktualizaci stavu: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Dostupné"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problém s načtením měřiče baterie"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Klepnutím zobrazíte další informace"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Budík nenastaven"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 341f06fb..feb0dae 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> har sendt en besked: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> har sendt et billede"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> har opdateret sin status: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Tilgængelig"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Der er problemer med at aflæse dit batteriniveau"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tryk for at få flere oplysninger"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ingen alarm er indstillet"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 35b72fe..a92dd6f 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> hat eine Nachricht gesendet: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> hat ein Bild gesendet"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> hat den Status aktualisiert: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Verfügbar"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem beim Lesen des Akkustands"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Für weitere Informationen tippen"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Kein Wecker gestellt"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index e53775a..99a90cc 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"Ο χρήστης <xliff:g id="NAME">%1$s</xliff:g> έστειλε ένα μήνυμα: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"Ο χρήστης <xliff:g id="NAME">%1$s</xliff:g> έστειλε μια εικόνα"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"Ο χρήστης <xliff:g id="NAME">%1$s</xliff:g> έχει μια ενημέρωση κατάστασης: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Διαθέσιμος"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Υπάρχει κάποιο πρόβλημα με την ανάγνωση του μετρητή μπαταρίας"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Πατήστε για περισσότερες πληροφορίες."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Δεν ορίστηκε ξυπνητ."</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 111de11..fd54063 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> sent a message: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sent an image"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> has a status update: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Available"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 6b4eaba..dff3c30 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> sent a message: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sent an image"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> has a status update: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Available"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 111de11..fd54063 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> sent a message: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sent an image"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> has a status update: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Available"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 111de11..fd54063 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> sent a message: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sent an image"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> has a status update: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Available"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 7c1e09f..97976db 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> sent a message: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sent an image"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> has a status update: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Available"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 01a6f8d..540be62 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> envió un mensaje: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> envió una imagen"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> actualizó su estado: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Disponible"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problema al leer el medidor de batería"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Presiona para obtener más información"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No se estableció alarma"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 4c43ead..0fa33e7 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -429,9 +429,9 @@
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"¿Desbloquear el micrófono del dispositivo?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"¿Desbloquear la cámara del dispositivo?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"¿Desbloquear la cámara y el micrófono del dispositivo?"</string>
- <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Si lo haces, todos los servicios y todas las aplicaciones que tengan permiso podrán usar tu micrófono."</string>
- <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Si lo haces, todos los servicios y todas las aplicaciones que tengan permiso podrán usar tu cámara."</string>
- <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Si lo haces, todos los servicios y todas las aplicaciones que tengan permiso podrán usar tu cámara o tu micrófono."</string>
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Si lo haces, todas las aplicaciones y servicios que tengan permiso podrán usar tu micrófono."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Si lo haces, todas las aplicaciones y servicios que tengan permiso podrán usar tu cámara."</string>
+ <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Si lo haces, todas las aplicaciones y servicios que tengan permiso podrán usar tu cámara o tu micrófono."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Dispositivo"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Desliza el dedo hacia arriba para cambiar de aplicación"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Arrastra hacia la derecha para cambiar rápidamente de aplicación"</string>
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ha enviado un mensaje: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ha enviado una imagen"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ha cambiado su estado: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Disponible"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"No se ha podido leer el indicador de batería"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toca la pantalla para consultar más información"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ninguna alarma puesta"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 3d8659d..5e52394 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> saatis sõnumi: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> saatis pildi"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> värskendas olekut: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Saadaval"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Probleem akumõõdiku lugemisel"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Puudutage lisateabe saamiseks"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Äratust pole"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index d31157e..3e687d7 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> erabiltzaileak mezu bat bidali du: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> erabiltzaileak irudi bat bidali du"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> erabiltzaileak egoera eguneratu du: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Konektatuta"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Arazo bat gertatu da bateria-neurgailua irakurtzean"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Informazio gehiago lortzeko, sakatu hau"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ez da ezarri alarmarik"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 3a4f87c..b37a7be 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> پیامی ارسال کرد: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> تصویری ارسال کرد"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> وضعیتش را بهروزرسانی کرد: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"دردسترس"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"مشکلی در خواندن میزان باتری وجود دارد"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"برای اطلاعات بیشتر ضربه بزنید"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"هشداری تنظیم نشده است"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 62ab1f4..4a5941e 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> lähetti viestin: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> lähetti kuvan"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> on päivittänyt tilansa: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Saatavilla"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Ongelma akkumittarin lukemisessa"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Saat lisätietoja napauttamalla"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ei herätyksiä"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 6c0839a..457ab8a 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -420,9 +420,9 @@
<string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Jusqu\'à l\'aube"</string>
<string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Actif à <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Jusqu\'à <xliff:g id="TIME">%s</xliff:g>"</string>
- <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
- <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC désactivée"</string>
- <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC activée"</string>
+ <string name="quick_settings_nfc_label" msgid="1054317416221168085">"CCP"</string>
+ <string name="quick_settings_nfc_off" msgid="3465000058515424663">"CCP désactivée"</string>
+ <string name="quick_settings_nfc_on" msgid="1004976611203202230">"CCP activée"</string>
<string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Enregistrement de l\'écran"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Démarrer"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Arrêter"</string>
@@ -455,7 +455,7 @@
<string name="tap_again" msgid="1315420114387908655">"Toucher de nouveau"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Balayez l\'écran vers le haut pour ouvrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Balayez l\'écran vers le haut pour réessayer"</string>
- <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Déverrouillez l\'écran pour utiliser la NFC"</string>
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Déverrouillez l\'écran pour utiliser la CCP"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Cet appareil appartient à votre organisation"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="do_financed_disclosure_with_name" msgid="6723004643314467864">"Cet appareil est fourni par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> a envoyé un message : <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> a envoyé une image"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> a mis à jour son état : <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Disponible"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Un problème est survenu lors de la lecture du niveau de charge de la pile"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Touchez pour en savoir plus"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Aucune alarme définie"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index d898fcc..6e032ef 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> a envoyé un message : <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> a envoyé une image"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> a mis à jour son statut : <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Disponible"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Un problème est survenu au niveau de la lecture de votre outil de mesure de batterie"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Appuyer pour en savoir plus"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Pas d\'alarme définie"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 2d417a3..b5018d1 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> enviou unha mensaxe: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> enviou unha imaxe"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> cambiou de estado: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Dispoñible"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Produciuse un problema ao ler o medidor da batería"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toca para obter máis información"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Sen alarmas postas"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index f70bf30..59eceb7 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -1149,6 +1149,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા કોઈ સંદેશ મોકલવામાં આવ્યો: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા કોઈ છબી મોકલવામાં આવી"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા નવી સ્ટેટસ અપડેટ પોસ્ટ કરવામાં આવી: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"તમારું બૅટરી મીટર વાંચવામાં સમસ્યા આવી"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"વધુ માહિતી માટે ટૅપ કરો"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"કોઈ અલાર્મ સેટ નથી"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 1d4e566..9ae4721 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ने एक मैसेज भेजा है: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ने एक इमेज भेजी है"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ने स्टेटस अपडेट किया है: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"ऑनलाइन हैं"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"आपके डिवाइस के बैटरी मीटर की रीडिंग लेने में समस्या आ रही है"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ज़्यादा जानकारी के लिए टैप करें"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"कोई अलार्म सेट नहीं है"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 72ba163..689a435 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -1155,6 +1155,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> šalje poruku: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"Korisnik <xliff:g id="NAME">%1$s</xliff:g> poslao je sliku"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ima ažuriranje statusa: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Dostupan/dostupna"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem s očitavanjem mjerača baterije"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nema nijednog alarma"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index d394a84..f7728d2 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> üzenetet küldött: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> képet küldött"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> frissítette állapotát: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Elérhető"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Probléma merült fel az akkumulátor-töltésmérő olvasásakor"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Koppintással további információkat érhet el."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nincs ébresztés"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index ed07b4b..4605a98 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> օգտատերը հաղորդագրություն է ուղարկել. «<xliff:g id="NOTIFICATION">%2$s</xliff:g>»"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> օգտատերը պատկեր է ուղարկել"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> օգտատերը նոր կարգավիճակ է հրապարակել. «<xliff:g id="STATUS">%2$s</xliff:g>»"</string>
+ <string name="person_available" msgid="2318599327472755472">"Հասանելի է"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Մարտկոցի ցուցիչի ցուցմունքը կարդալու հետ կապված խնդիր կա"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Հպեք՝ ավելին իմանալու համար"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Զարթուցիչ դրված չէ"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 11ca6c3..227bf4d 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -1149,6 +1149,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> mengirim pesan: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> mengirim gambar"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> memposting pembaruan status: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Terjadi masalah saat membaca indikator baterai"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ketuk untuk informasi selengkapnya"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Alarm tidak disetel"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index fda217e..b2e2198 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> sendi skilaboð: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sendi mynd"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> er með stöðuuppfærslu: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Tiltækt"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Vandamál við að lesa stöðu rafhlöðu"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ýttu til að fá frekari upplýsingar"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Enginn vekjari"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index b485091..42e5dea 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ha inviato un messaggio: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ha inviato un\'immagine"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ha aggiornato lo stato: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Disponibile"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problema durante la lettura dell\'indicatore di livello della batteria"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tocca per ulteriori informazioni"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nessuna sveglia"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 7f7e2da..65c23d4 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -1161,6 +1161,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"התקבלה הודעה מ<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> שלח/ה תמונה"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"הסטטוס של <xliff:g id="NAME">%1$s</xliff:g> עודכן: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"בעיה בקריאת מדדי הסוללה"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"יש להקיש כדי להציג מידע נוסף"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"לא הוגדרה התראה"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index c4b5d12..d638ace 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> さんからのメッセージ: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> さんが画像を送信しました"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> さんの近況: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"オンライン"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"バッテリー残量の読み込み中に問題が発生しました"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"タップすると詳細が表示されます"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"アラーム未設定"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index bc214c7..5ce3fe5 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -1149,6 +1149,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g>-მა გაგზავნა შეტყობინება: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>-მ(ა) სურათი გამოგზავნა"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>-მა განაახლა სტატუსი: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"თქვენი ბატარეის მზომის წაკითხვასთან დაკავშირებით პრობლემა დაფიქსირდა"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"შეეხეთ მეტი ინფორმაციისთვის"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"მაღვიძარა არ არის"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 775dea7..cba176d 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -1149,6 +1149,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> хабар жіберді: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> сурет жіберді."</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ағымдағы күйін жаңартты: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Батарея зарядының дерегі алынбай жатыр"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Толығырақ ақпарат алу үшін түртіңіз."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Оятқыш орнатылмаған."</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 265d8e2..1d4b515 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> បានផ្ញើសារ៖ <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> បានផ្ញើរូបភាព"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> មានបច្ចុប្បន្នភាពស្ថានភាព៖ <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"មាន"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"មានបញ្ហាក្នុងការអានឧបករណ៍រង្វាស់កម្រិតថ្មរបស់អ្នក"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ចុចដើម្បីទទួលបានព័ត៌មានបន្ថែម"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"មិនបានកំណត់ម៉ោងរោទ៍ទេ"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index c5bd9cd..94df302 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ಅವರು ಸಂದೇಶವನ್ನು ಕಳುಹಿಸಿದ್ದಾರೆ: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ಅವರು ಚಿತ್ರವನ್ನು ಕಳುಹಿಸಿದ್ದಾರೆ"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ಅವರು ಸ್ಥಿತಿಯ ಅಪ್ಡೇಟ್ ಹೊಂದಿದ್ದಾರೆ: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"ಲಭ್ಯವಿದೆ"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ನಿಮ್ಮ ಬ್ಯಾಟರಿ ಮೀಟರ್ ಓದುವಾಗ ಸಮಸ್ಯೆ ಎದುರಾಗಿದೆ"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ಇನ್ನಷ್ಟು ಮಾಹಿತಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ಅಲಾರಾಂ ಸೆಟ್ ಆಗಿಲ್ಲ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index f43539c..db96984 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g>님이 메시지를 보냈습니다: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>님이 이미지를 보냈습니다."</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>님의 상태가 업데이트되었습니다: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"사용 가능"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"배터리 수준을 읽는 중에 문제가 발생함"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"탭하여 자세한 정보를 확인하세요."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"설정된 알람 없음"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index a029bbc..34d799c 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -1149,6 +1149,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> билдирүү жөнөттү: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> сүрөт жөнөттү"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> жаңы абалы тууралуу жарыялады: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Батареяңыздын кубаты аныкталбай жатат"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Кеңири маалымат алуу үчүн таптап коюңуз"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ойготкуч коюлган жок"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 826e45b..d6b8fa2 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -431,7 +431,7 @@
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ຍົກເລີກການບລັອກກ້ອງຖ່າຍຮູບ ຫຼື ໄມໂຄຣໂຟນອຸປະກອນບໍ?"</string>
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"ນີ້ຈະຍົກເລີກການບລັອກການເຂົ້າເຖິງແອັບ ແລະ ບໍລິການທັງໝົດທີ່ອະນຸຍາດໃຫ້ໃຊ້ໄມໂຄຣໂຟນຂອງທ່ານ."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"ນີ້ຈະຍົກເລີກການບລັອກການເຂົ້າເຖິງແອັບ ແລະ ບໍລິການທັງໝົດທີ່ອະນຸຍາດໃຫ້ໃຊ້ກ້ອງຖ່າຍຮູບຂອງທ່ານ."</string>
- <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"ນີ້ຈະຍົກເລີກການບລັອກການເຂົ້າເຖິງແອັບ ແລະ ບໍລິການທັງໝົດທີ່ອະນຸຍາດໃຫ້ໃຊ້ກ້ອງຖ່າຍຮູບ ຫຼື ໄມໂຄຣໂຟນຂອງທ່ານ."</string>
+ <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"ນີ້ຈະປົດບລັອກການເຂົ້າເຖິງແອັບ ແລະ ບໍລິການທັງໝົດທີ່ອະນຸຍາດໃຫ້ໃຊ້ກ້ອງຖ່າຍຮູບ ຫຼື ໄມໂຄຣໂຟນຂອງທ່ານ."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"ອຸປະກອນ"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ປັດຂື້ນເພື່ອສະຫຼັບແອັບ"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ລາກໄປຂວາເພື່ອສະຫຼັບແອັບດ່ວນ"</string>
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ສົ່ງຂໍ້ຄວາມ: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ສົ່ງຮູບພາບແລ້ວ"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ອັບເດດສະຖານະ: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"ອອນລາຍ"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ເກີດບັນຫາໃນການອ່ານຕົວວັດແທກແບັດເຕີຣີຂອງທ່ານ"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ແຕະເພື່ອເບິ່ງຂໍ້ມູນເພີ່ມເຕີມ"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ບໍ່ໄດ້ຕັ້ງໂມງປຸກ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 656d54c..11d363e 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -1161,6 +1161,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> išsiuntė pranešimą: „<xliff:g id="NOTIFICATION">%2$s</xliff:g>“"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> išsiuntė vaizdą"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> atnaujino būseną: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Nuskaitant akumuliatoriaus skaitiklį iškilo problema"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Palieskite, kad sužinotumėte daugiau informacijos"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenustatyta signalų"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index b4c6151..6b68297 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -1155,6 +1155,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> nosūtīja ziņojumu: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> nosūtīja attēlu"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> atjaunināja statusu: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Pieejams"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Nevar iegūt informāciju par akumulatora uzlādes līmeni."</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Pieskarieties, lai iegūtu plašāku informāciju."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nav iestatīts signāls"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 0bead0f..5392d52 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -1149,6 +1149,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> испрати порака: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> испрати слика"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> има ажурирање на статусот: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Проблем при читањето на мерачот на батеријата"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Допрете за повеќе информации"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Не е поставен аларм"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 264d2bf..cdb3a69 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ഒരു സന്ദേശം അയച്ചു: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>, ഒരു ചിത്രം അയച്ചു"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> എന്നയാൾ സ്റ്റാറ്റസ് അപ്ഡേറ്റ് ചെയ്തു: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"ലഭ്യമാണ്"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"നിങ്ങളുടെ ബാറ്ററി മീറ്റർ വായിക്കുന്നതിൽ പ്രശ്നമുണ്ട്"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"കൂടുതൽ വിവരങ്ങൾക്ക് ടാപ്പ് ചെയ്യുക"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"അലാറം സജ്ജീകരിച്ചിട്ടില്ല"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 94ffad5..d16e479 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> мессеж илгээсэн: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> зураг илгээсэн"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> төлөвийн шинэчлэлт хийсэн байна: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Боломжтой"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Таны батарей хэмжигчийг уншихад асуудал гарлаа"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Нэмэлт мэдээлэл авахын тулд товшино уу"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Сэрүүлэг тавиагүй"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 1ed5458..bf27df9 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -1149,6 +1149,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> यांनी मेसेज पाठवला: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> यांनी इमेज पाठवली"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> यांनी स्टेटस अपडेट केले: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"तुमचे बॅटरी मीटर वाचताना समस्या आली"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"अधिक माहितीसाठी टॅप करा"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"अलार्म सेट केला नाही"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index f1ce832..1d16edc 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -1149,6 +1149,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> menghantar mesej: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> menghantar imej"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> mempunyai kemaskinian status: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Masalah membaca meter bateri anda"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ketik untuk mendapatkan maklumat lanjut"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Tiada penggera"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 30efdb3..c92a45e 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> က မက်ဆေ့ဂျ်ပို့လိုက်သည်- <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> က ပုံပို့လိုက်သည်"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> က အခြေအနေ အပ်ဒိတ်လုပ်လိုက်သည်- <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"ချိတ်ဆက်နိုင်သည်"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"သင်၏ ဘက်ထရီမီတာကို ဖတ်ရာတွင် ပြဿနာရှိနေသည်"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"နောက်ထပ်အချက်အလက်များအတွက် တို့ပါ"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"နှိုးစက်ပေးမထားပါ"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 75755c6..a0db779 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> har sendt en melding: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> har sendt et bilde"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> har en statusoppdatering: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Tilgjengelig"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Kunne ikke lese batterimåleren"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Trykk for å få mer informasjon"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ingen alarm angitt"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index cace5b7..d719123 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ले एउटा म्यासेज पठाउनुभएको छ: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ले एउटा फोटो पठाउनुभयो"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ले स्ट्याटस अपडेट गर्नुभएको छ: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"उपलब्ध हुनुहुन्छ"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"डिभाइसको ब्याट्रीको मिटर रिडिङ क्रममा समस्या भयो"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"थप जानकारी प्राप्त गर्न ट्याप गर्नुहोस्"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"अलार्म राखिएको छैन"</string>
diff --git a/packages/SystemUI/res/values-night/styles.xml b/packages/SystemUI/res/values-night/styles.xml
index e6165ee..461505f 100644
--- a/packages/SystemUI/res/values-night/styles.xml
+++ b/packages/SystemUI/res/values-night/styles.xml
@@ -42,4 +42,10 @@
<item name="android:textColorPrimary">?android:attr/textColorPrimaryInverse</item>
</style>
+ <style name="Theme.PeopleTileConfigActivity" parent="@style/Theme.SystemUI">
+ <item name="android:windowActionBar">false</item>
+ <item name="android:windowNoTitle">true</item>
+ <item name="android:windowLightStatusBar">false</item>
+ </style>
+
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index da221af..b74892a 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> heeft een bericht gestuurd: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> heeft een afbeelding gestuurd"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> heeft een statusupdate: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Beschikbaar"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Probleem bij het lezen van je batterijmeter"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tik hier voor meer informatie"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Geen wekker gezet"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 53371ef..2ad54f7 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -1149,6 +1149,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ଏକ ମେସେଜ୍ ପଠାଇଛନ୍ତି: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ଏକ ଛବି ପଠାଇଛନ୍ତି"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ଏକ ସ୍ଥିତି ଅପଡେଟ୍ କରିଛନ୍ତି: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ଆପଣଙ୍କ ବ୍ୟାଟେରୀ ମିଟର୍ ପଢ଼ିବାରେ ସମସ୍ୟା ହେଉଛି"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ଅଧିକ ସୂଚନା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ଆଲାରାମ ସେଟ୍ ହୋଇନାହିଁ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 27cb319..3f2e481 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -1149,6 +1149,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ਨੇ ਸੁਨੇਹਾ ਭੇਜਿਆ: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ਨੇ ਇੱਕ ਚਿੱਤਰ ਭੇਜਿਆ ਹੈ"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ਨੇ ਸਥਿਤੀ ਅੱਪਡੇਟ ਕੀਤੀ ਹੈ: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ਤੁਹਾਡੇ ਬੈਟਰੀ ਮੀਟਰ ਨੂੰ ਪੜ੍ਹਨ ਵਿੱਚ ਸਮੱਸਿਆ ਹੋ ਰਹੀ ਹੈ"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਟੈਪ ਕਰੋ"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ਕੋਈ ਅਲਾਰਮ ਸੈੱਟ ਨਹੀਂ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 8005c81..990b461 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -1161,6 +1161,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> wysyła wiadomość: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> wysyła zdjęcie"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ma nowy stan: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Użytkownik dostępny"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem z odczytaniem pomiaru wykorzystania baterii"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Kliknij, aby uzyskać więcej informacji"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nie ustawiono alarmu"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index b175fe6..2755508 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma mensagem: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma imagem"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> atualizou o status: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Disponível"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problema para ler seu medidor de bateria"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toque para mais informações"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenhum alarme definido"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index cb5903e..15c2874 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma mensagem: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma imagem"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> tem uma atualização de estado: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Disponível"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Ocorreu um problema ao ler o medidor da bateria"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toque para obter mais informações"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenhum alarme defin."</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index b175fe6..2755508 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma mensagem: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma imagem"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> atualizou o status: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Disponível"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problema para ler seu medidor de bateria"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toque para mais informações"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenhum alarme definido"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index e0a2b9a..3463236 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -1155,6 +1155,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> a trimis un mesaj: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> a trimis o imagine"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> are o nouă stare: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problemă la citirea măsurării bateriei"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Atingeți pentru mai multe informații"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nicio alarmă setată"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index db487d4..53500b5 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -1161,7 +1161,9 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"Пользователь <xliff:g id="NAME">%1$s</xliff:g> отправил сообщение: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"Пользователь <xliff:g id="NAME">%1$s</xliff:g> отправил изображение"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"Пользователь <xliff:g id="NAME">%1$s</xliff:g> обновил статус: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
- <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Не удается получить данные об уровне заряда батареи"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
+ <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Не удалось узнать уровень заряда батареи"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Нажмите, чтобы узнать больше."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Будильников нет"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сканер отпечатков пальцев"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index d2f56c9..4235d81 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> පණිවිඩයක් එවා ඇත: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> රූපයක් යවන ලදී"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> හට තත්ත්ව යාවත්කාලීනයක් ඇත: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"තිබේ"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ඔබගේ බැටරි මනුව කියවීමේ දෝෂයකි"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"තවත් තොරතුරු සඳහා තට්ටු කරන්න"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"එලාම සකසා නැත"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index cadf2b9..4967718 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -1161,6 +1161,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> poslal(a) správu: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> poslal(a) obrázok"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> má aktualizáciu statusu: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Pri čítaní meradla batérie sa vyskytol problém"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Klepnutím si zobrazíte ďalšie informácie"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Žiadny budík"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 82a34e1..a553ff22 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -1161,6 +1161,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"Oseba <xliff:g id="NAME">%1$s</xliff:g> je poslala sporočilo: <xliff:g id="NOTIFICATION">%2$s</xliff:g>."</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"Oseba <xliff:g id="NAME">%1$s</xliff:g> je poslala sliko."</string>
<string name="new_status_content_description" msgid="6046637888641308327">"Oseba <xliff:g id="NAME">%1$s</xliff:g> je posodobila stanje: <xliff:g id="STATUS">%2$s</xliff:g>."</string>
+ <string name="person_available" msgid="2318599327472755472">"Na voljo"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Težava z branjem indikatorja stanja napolnjenosti baterije"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dotaknite se za več informacij"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ni nastavljenih alarmov"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 77bf2a8..ad8e265 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -1149,6 +1149,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> dërgoi një mesazh: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> dërgoi një imazh"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ka një përditësim të statusit: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem me leximin e matësit të baterisë"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Trokit për më shumë informacione"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nuk është caktuar asnjë alarm"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 592b90f..282d18b 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -1155,6 +1155,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> је послао/ла поруку: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> шаље слику"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> има ажурирање статуса: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Доступно"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Проблем са очитавањем мерача батерије"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Додирните за више информација"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Аларм није подешен"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 7045572..7e0dbd7 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> skickade ett meddelande: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> skickade en bild"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> har gjort en statusuppdatering: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Tillgänglig"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Batteriindikatorn visas inte"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tryck för mer information"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Inget inställt alarm"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index f803302..e603fc9 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ametuma ujumbe: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ametuma picha"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ana taarifa kuhusu hali: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Anapatikana"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Tatizo la kusoma mita ya betri yako"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Gusa ili upate maelezo zaidi"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Hujaweka kengele"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 2901f29..d1d6d0d 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ஒரு மெசேஜ் அனுப்பியுள்ளார்: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ஒரு படம் அனுப்பியுள்ளார்"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> புதிய ஸ்டேட்டஸ் வைத்துள்ளார்: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"ஆன்லைனில் இருக்கிறார்"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"பேட்டரி அளவை அறிவதில் சிக்கல்"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"மேலும் தகவல்களுக்கு தட்டவும்"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"அலாரம் எதுவுமில்லை"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 42e621c..409eced 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -1149,6 +1149,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> మెసేజ్ను పంపారు: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ఇమేజ్ను పంపారు"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>, స్టేటస్ను గురించిన అప్డేట్ను కలిగి ఉన్నారు: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"మీ బ్యాటరీ మీటర్ను చదవడంలో సమస్య"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"మరింత సమాచారం కోసం ట్యాప్ చేయండి"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"అలారం సెట్ చేయలేదు"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 37a5924..6e06626 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -1149,6 +1149,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ส่งข้อความ: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ส่งรูปภาพ"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> มีการอัปเดตสถานะ: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"พบปัญหาในการอ่านเครื่องวัดแบตเตอรี่"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"แตะดูข้อมูลเพิ่มเติม"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ไม่มีการตั้งปลุก"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index adc9aa9..9a83c22 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -1149,6 +1149,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"Nagpadala si <xliff:g id="NAME">%1$s</xliff:g> ng mensahe: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"Nagpadala si <xliff:g id="NAME">%1$s</xliff:g> ng larawan"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"May update sa status si <xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Nagkaproblema sa pagbabasa ng iyong battery meter"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"I-tap para sa higit pang impormasyon"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Walang alarm"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index eed1222..bbae9c9 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> bir mesaj gönderdi: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> bir resim gönderdi"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>, durumunu güncelledi: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Müsait"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Pil ölçeriniz okunurken sorun oluştu"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Daha fazla bilgi için dokunun"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Alarm ayarlanmadı"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 947a597..2d15009 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -1161,7 +1161,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> надсилає повідомлення: \"<xliff:g id="NOTIFICATION">%2$s</xliff:g>\""</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> надсилає зображення"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> публікує новий статус: \"<xliff:g id="STATUS">%2$s</xliff:g>\""</string>
- <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Не вдалось отримати дані лічильника акумулятора"</string>
+ <string name="person_available" msgid="2318599327472755472">"Онлайн"</string>
+ <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Не вдалось отримати дані про рівень заряду акумулятора"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Натисніть, щоб дізнатися більше"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Немає будильників"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сканер відбитків пальців"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 8ef84aa..ffcd9a7 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -1149,6 +1149,8 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> نے ایک پیغام بھیجا: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> نے ایک تصویر بھیجی"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> نے اسٹیٹس کو اپ ڈیٹ کر دیا ہے: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <!-- no translation found for person_available (2318599327472755472) -->
+ <skip />
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"آپ کے بیٹری میٹر کو پڑھنے میں دشواری"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"مزید معلومات کے لیے تھپتھپائیں"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"کوئی الارم سیٹ نہیں ہے"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index be7f45a..b722acc 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> xabar yubordi: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> rasm yubordi"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ahvolini yangiladi: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Mavjud"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Batareya quvvati aniqlanmadi"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Batafsil axborot olish uchun bosing"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Signal sozlanmagan"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 53cc87b..de7fbcbe 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> đã gửi một tin nhắn: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> đã gửi một hình ảnh"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> đã cập nhật trạng thái: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Đang trực tuyến"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Đã xảy ra vấn đề khi đọc dung lượng pin của bạn"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Nhấn để biết thêm thông tin"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Chưa đặt chuông báo"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index ab3ed4a..ea79e3c 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -426,12 +426,12 @@
<string name="quick_settings_screen_record_label" msgid="8650355346742003694">"屏幕录制"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"开始"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"停止"</string>
- <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"要取消禁用设备麦克风吗?"</string>
- <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"要取消禁用设备摄像头吗?"</string>
- <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"要取消禁用设备摄像头和麦克风吗?"</string>
+ <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"要解锁设备麦克风吗?"</string>
+ <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"要解锁设备摄像头吗?"</string>
+ <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"要解锁设备摄像头和麦克风吗?"</string>
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"这将会为所有获准使用您麦克风的应用和服务启用这项权限。"</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"这将会为所有获准使用您摄像头的应用和服务启用这项权限。"</string>
- <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"这将会为所有获准使用您摄像头或麦克风的应用和服务启用这项权限。"</string>
+ <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"这将会为所有获准使用您的摄像头或麦克风的应用和服务启用这项权限。"</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"设备"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"向上滑动可切换应用"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"向右拖动可快速切换应用"</string>
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g>发送了一条消息:<xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>发送了一张图片"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>更新了状态:<xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"在线"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"读取电池计量器时出现问题"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"点按即可了解详情"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"未设置闹钟"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index cc13dd2..ea9f1fc 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g>傳送了訊息:<xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>傳送了圖片"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>有狀態更新:<xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"有空"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"讀取電池計量器時發生問題"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"輕按即可瞭解詳情"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"未設定鬧鐘"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index aa80209..7e9d2fe 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g>傳送了一則訊息:<xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>傳送了一張圖片"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>更新了狀態:<xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"線上"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"讀取電池計量器時發生問題"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"輕觸即可瞭解詳情"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"未設定鬧鐘"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 1341f09..eac6f74 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -1149,6 +1149,7 @@
<string name="new_notification_text_content_description" msgid="2915029960094389291">"U-<xliff:g id="NAME">%1$s</xliff:g> uthumele umlayezo: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"U-<xliff:g id="NAME">%1$s</xliff:g> uthumele isithombe"</string>
<string name="new_status_content_description" msgid="6046637888641308327">"U-<xliff:g id="NAME">%1$s</xliff:g> unesibuyekezo sesimo: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
+ <string name="person_available" msgid="2318599327472755472">"Iyatholakala"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Kube khona inkinga ngokufunda imitha yakho yebhethri"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Thepha ukuze uthole olunye ulwazi"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Akukho alamu esethiwe"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 18388a9..0a3e0c8 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -681,6 +681,9 @@
<!-- The height of the divider between the individual notifications. -->
<dimen name="notification_divider_height">2dp</dimen>
+ <!-- The min distance the notifications should be from the lock icon on the lock screen. -->
+ <dimen name="min_lock_icon_padding">48dp</dimen>
+
<!-- The corner radius of the shadow behind the notification. -->
<dimen name="notification_shadow_radius">0dp</dimen>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 17a984e..70ed817 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -777,6 +777,7 @@
<style name="Theme.PeopleTileConfigActivity" parent="@style/Theme.SystemUI">
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
+ <item name="android:windowLightStatusBar">true</item>
</style>
<style name="TextAppearance.Control">
diff --git a/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java b/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
index fcf4e47..c89cda9 100644
--- a/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
@@ -21,7 +21,6 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
-import android.hardware.biometrics.BiometricSourceType;
import android.icu.text.NumberFormat;
import com.android.settingslib.Utils;
@@ -94,9 +93,7 @@
@Override
public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
if (mKeyguardShowing && !mIsCharging && charging) {
- mView.animateCharge(() -> {
- return mStatusBarStateController.isDozing();
- });
+ mView.animateCharge(mStatusBarStateController::isDozing);
}
mIsCharging = charging;
}
@@ -127,21 +124,10 @@
private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback =
new KeyguardUpdateMonitorCallback() {
@Override
- public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType,
- boolean isStrongBiometric) {
- // Strong auth will force the bouncer regardless of a successful face auth
- if (biometricSourceType == BiometricSourceType.FACE
- && mBypassController.canBypass()
- && !mKeyguardUpdateMonitor.userNeedsStrongAuth()) {
- mView.animateDisappear();
- }
- }
-
- @Override
public void onKeyguardVisibilityChanged(boolean showing) {
mKeyguardShowing = showing;
if (!mKeyguardShowing) {
- // reset state (ie: after animateDisappear)
+ // reset state (ie: after weight animations)
reset();
}
}
@@ -156,7 +142,6 @@
mDozeAmount = mStatusBarStateController.getDozeAmount();
mBatteryController.addCallback(mBatteryCallback);
mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback);
- mKeyguardShowing = true;
mStatusBarStateController.removeCallback(mStatusBarStatePersistentListener);
mStatusBarStateController.addCallback(mStatusBarStatePersistentListener);
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index 62cb4b9..7bbb63f 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -98,7 +98,8 @@
private float mHeightPixels;
private float mWidthPixels;
private float mDensity;
- private int mKgBottomAreaHeight;
+ private int mAmbientIndicationHeight; // in pixels
+ private int mKgIndicationHeight; // in pixels
private boolean mShowUnlockIcon;
private boolean mShowLockIcon;
@@ -280,7 +281,7 @@
mWidthPixels = metrics.widthPixels;
mHeightPixels = metrics.heightPixels;
mDensity = metrics.density;
- mKgBottomAreaHeight = mView.getContext().getResources().getDimensionPixelSize(
+ mKgIndicationHeight = mView.getContext().getResources().getDimensionPixelSize(
R.dimen.keyguard_indication_margin_bottom)
+ mView.getContext().getResources().getDimensionPixelSize(
R.dimen.keyguard_indication_bottom_padding);
@@ -295,15 +296,24 @@
} else {
final float distAboveKgBottomArea = 12 * mDensity;
final float radius = 36 * mDensity;
+ final int kgBottomAreaHeight = Math.max(mKgIndicationHeight, mAmbientIndicationHeight);
mView.setCenterLocation(
new PointF(mWidthPixels / 2,
- mHeightPixels - mKgBottomAreaHeight - distAboveKgBottomArea
+ mHeightPixels - kgBottomAreaHeight - distAboveKgBottomArea
- radius / 2), (int) radius);
}
mView.getHitRect(mSensorTouchLocation);
}
+ /**
+ * Set the location of ambient indication if showing (ie: now playing)
+ */
+ public void setAmbientIndicationBottomPadding(int ambientIndicationBottomPadding) {
+ mAmbientIndicationHeight = ambientIndicationBottomPadding;
+ updateLockIconLocation();
+ }
+
@Override
public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
pw.println("mUdfpsEnrolled: " + mUdfpsEnrolled);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index badad9d..71e2bb6 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -48,10 +48,7 @@
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
-import android.view.Display;
import android.view.MotionEvent;
-import android.view.OrientationEventListener;
-import android.view.Surface;
import android.view.WindowManager;
import com.android.internal.R;
@@ -72,6 +69,8 @@
import javax.inject.Inject;
import javax.inject.Provider;
+import kotlin.Unit;
+
/**
* Receives messages sent from {@link com.android.server.biometrics.BiometricService} and shows the
* appropriate biometric UI (e.g. BiometricDialogView).
@@ -107,7 +106,8 @@
TaskStackListener mTaskStackListener;
@VisibleForTesting
IBiometricSysuiReceiver mReceiver;
- @NonNull private final BiometricOrientationEventListener mOrientationListener;
+ @VisibleForTesting
+ @NonNull final BiometricOrientationEventListener mOrientationListener;
@Nullable private final List<FaceSensorPropertiesInternal> mFaceProps;
@Nullable private List<FingerprintSensorPropertiesInternal> mFpProps;
@Nullable private List<FingerprintSensorPropertiesInternal> mUdfpsProps;
@@ -120,42 +120,6 @@
}
}
- private class BiometricOrientationEventListener extends OrientationEventListener {
- @Surface.Rotation private int mLastRotation;
-
- BiometricOrientationEventListener(Context context) {
- super(context);
- mLastRotation = context.getDisplay().getRotation();
- }
-
- @Override
- public void onOrientationChanged(int orientation) {
- if (orientation == ORIENTATION_UNKNOWN) {
- return;
- }
-
- final Display display = mContext.getDisplay();
- if (display == null) {
- return;
- }
-
- final int rotation = display.getRotation();
- if (mLastRotation != rotation) {
- mLastRotation = rotation;
-
- if (mCurrentDialog != null) {
- mCurrentDialog.onOrientationChanged();
- }
- if (mUdfpsController != null) {
- mUdfpsController.onOrientationChanged();
- }
- if (mSidefpsController != null) {
- mSidefpsController.onOrientationChanged();
- }
- }
- }
- }
-
@NonNull
private final IFingerprintAuthenticatorsRegisteredCallback
mFingerprintAuthenticatorsRegisteredCallback =
@@ -468,7 +432,10 @@
mUdfpsControllerFactory = udfpsControllerFactory;
mSidefpsControllerFactory = sidefpsControllerFactory;
mWindowManager = windowManager;
- mOrientationListener = new BiometricOrientationEventListener(context);
+ mOrientationListener = new BiometricOrientationEventListener(context, () -> {
+ onOrientationChanged();
+ return Unit.INSTANCE;
+ });
mFaceProps = mFaceManager != null ? mFaceManager.getSensorPropertiesInternal() : null;
@@ -790,6 +757,12 @@
}
}
+ private void onOrientationChanged() {
+ if (mCurrentDialog != null) {
+ mCurrentDialog.onOrientationChanged();
+ }
+ }
+
protected AuthDialog buildDialog(PromptInfo promptInfo, boolean requireConfirmation,
int userId, int[] sensorIds, boolean credentialAllowed, String opPackageName,
boolean skipIntro, long operationId,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricOrientationEventListener.kt b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricOrientationEventListener.kt
new file mode 100644
index 0000000..08ea857
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricOrientationEventListener.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics
+
+import android.content.Context
+import android.view.OrientationEventListener
+
+/**
+ * An [OrientationEventListener] that invokes the [onOrientationChanged] callback whenever
+ * the orientation of the device has changed in order to keep overlays for biometric sensors
+ * aligned with the device's screen.
+ */
+class BiometricOrientationEventListener(
+ private val context: Context,
+ private val onOrientationChanged: () -> Unit
+) : OrientationEventListener(context) {
+
+ /** If actively listening (not available in base class). */
+ var enabled: Boolean = false
+ private set
+
+ private var lastRotation = context.display?.rotation ?: ORIENTATION_UNKNOWN
+
+ override fun onOrientationChanged(orientation: Int) {
+ if (orientation == ORIENTATION_UNKNOWN) {
+ return
+ }
+
+ val rotation = context.display?.rotation ?: return
+ if (lastRotation != rotation) {
+ lastRotation = rotation
+
+ onOrientationChanged()
+ }
+ }
+
+ override fun enable() {
+ enabled = true
+ super.enable()
+ }
+
+ override fun disable() {
+ enabled = false
+ super.disable()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.java
index 436e1e4..a51c2b8 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.java
@@ -41,6 +41,8 @@
import javax.inject.Inject;
+import kotlin.Unit;
+
/**
* Shows and hides the side fingerprint sensor (side-fps) overlay and handles side fps touch events.
*/
@@ -52,6 +54,8 @@
private final FingerprintManager mFingerprintManager;
private final WindowManager mWindowManager;
private final DelayableExecutor mFgExecutor;
+ @VisibleForTesting @NonNull final BiometricOrientationEventListener mOrientationListener;
+
// TODO: update mDisplayHeight and mDisplayWidth for multi-display devices
private final int mDisplayHeight;
private final int mDisplayWidth;
@@ -95,6 +99,10 @@
mFingerprintManager = checkNotNull(fingerprintManager);
mWindowManager = windowManager;
mFgExecutor = fgExecutor;
+ mOrientationListener = new BiometricOrientationEventListener(context, () -> {
+ onOrientationChanged();
+ return Unit.INSTANCE;
+ });
mSensorProps = findFirstSidefps();
checkArgument(mSensorProps != null);
@@ -119,14 +127,15 @@
mFingerprintManager.setSidefpsController(mSidefpsControllerImpl);
}
- void show() {
+ private void show() {
mView = (SidefpsView) mInflater.inflate(R.layout.sidefps_view, null, false);
mView.setSensorProperties(mSensorProps);
mWindowManager.addView(mView, computeLayoutParams());
+ mOrientationListener.enable();
}
- void hide() {
+ private void hide() {
if (mView != null) {
mWindowManager.removeView(mView);
mView.setOnTouchListener(null);
@@ -135,13 +144,16 @@
} else {
Log.v(TAG, "hideUdfpsOverlay | the overlay is already hidden");
}
+
+ mOrientationListener.disable();
}
- void onOrientationChanged() {
+ private void onOrientationChanged() {
// If mView is null or if view is hidden, then return.
if (mView == null || !mIsVisible) {
return;
}
+
// If the overlay needs to be displayed with a new configuration, destroy the current
// overlay, and re-create and show the overlay with the updated LayoutParams.
hide();
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 710aca0..0686406 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -16,6 +16,7 @@
package com.android.systemui.biometrics;
+import static android.hardware.fingerprint.IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD;
import static android.os.VibrationEffect.Composition.PRIMITIVE_LOW_TICK;
import static com.android.internal.util.Preconditions.checkArgument;
@@ -79,6 +80,8 @@
import javax.inject.Inject;
+import kotlin.Unit;
+
/**
* Shows and hides the under-display fingerprint sensor (UDFPS) overlay, handles UDFPS touch events,
* and coordinates triggering of the high-brightness mode (HBM).
@@ -118,6 +121,7 @@
@NonNull private final AccessibilityManager mAccessibilityManager;
@NonNull private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
@Nullable private final UdfpsHbmProvider mHbmProvider;
+ @VisibleForTesting @NonNull final BiometricOrientationEventListener mOrientationListener;
// Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple
// sensors, this, in addition to a lot of the code here, will be updated.
@VisibleForTesting final FingerprintSensorPropertiesInternal mSensorProps;
@@ -314,8 +318,10 @@
@Override
public void onReceive(Context context, Intent intent) {
if (mServerRequest != null
+ && mServerRequest.mRequestReason != REASON_AUTH_FPM_KEYGUARD
&& Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
- Log.d(TAG, "ACTION_CLOSE_SYSTEM_DIALOGS received");
+ Log.d(TAG, "ACTION_CLOSE_SYSTEM_DIALOGS received, mRequestReason: "
+ + mServerRequest.mRequestReason);
mServerRequest.onUserCanceled();
mServerRequest = null;
updateOverlay();
@@ -511,6 +517,10 @@
mHbmProvider = hbmProvider.orElse(null);
screenLifecycle.addObserver(mScreenObserver);
mScreenOn = screenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_ON;
+ mOrientationListener = new BiometricOrientationEventListener(context, () -> {
+ onOrientationChanged();
+ return Unit.INSTANCE;
+ });
mSensorProps = findFirstUdfps();
// At least one UDFPS sensor exists
@@ -650,7 +660,7 @@
return mCoreLayoutParams;
}
- void onOrientationChanged() {
+ private void onOrientationChanged() {
// When the configuration changes it's almost always necessary to destroy and re-create
// the overlay's window to pass it the new LayoutParams.
// Hiding the overlay will destroy its window. It's safe to hide the overlay regardless
@@ -668,6 +678,7 @@
if (mView == null) {
try {
Log.v(TAG, "showUdfpsOverlay | adding window reason=" + reason);
+
mView = (UdfpsView) mInflater.inflate(R.layout.udfps_view, null, false);
mOnFingerDown = false;
mView.setSensorProperties(mSensorProps);
@@ -675,6 +686,7 @@
UdfpsAnimationViewController animation = inflateUdfpsAnimation(reason);
animation.init();
mView.setAnimationViewController(animation);
+ mOrientationListener.enable();
// This view overlaps the sensor area, so prevent it from being selectable
// during a11y.
@@ -768,6 +780,8 @@
} else {
Log.v(TAG, "hideUdfpsOverlay | the overlay is already hidden");
}
+
+ mOrientationListener.disable();
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
index 073e886..51124fb 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
@@ -41,6 +41,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
+
/**
* Class that coordinates non-HBM animations during keyguard authentication.
*
@@ -207,7 +208,7 @@
return true;
}
- if (mInputBouncerHiddenAmount < .4f || mIsBouncerVisible) {
+ if (mInputBouncerHiddenAmount < .5f || mIsBouncerVisible) {
return true;
}
@@ -279,8 +280,9 @@
private void updateAlpha() {
// fade icon on transition to showing bouncer
int alpha = mShowingUdfpsBouncer ? 255
- : Math.abs((int) MathUtils.constrainedMap(0f, 255f, .4f, .7f,
- mInputBouncerHiddenAmount));
+ : (int) MathUtils.constrain(
+ MathUtils.map(.5f, .9f, 0f, 255f, mInputBouncerHiddenAmount),
+ 0f, 255f);
alpha *= (1.0f - mTransitionToFullShadeProgress);
mView.setUnpausedAlpha(alpha);
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
index 809e7a7..37a6cfa 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
@@ -33,7 +33,6 @@
import com.android.systemui.classifier.FalsingDataProvider.SessionListener;
import com.android.systemui.classifier.HistoryTracker.BeliefListener;
import com.android.systemui.dagger.qualifiers.TestHarness;
-import com.android.systemui.dock.DockManager;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -66,7 +65,6 @@
private static final double FALSE_BELIEF_THRESHOLD = 0.9;
private final FalsingDataProvider mDataProvider;
- private final DockManager mDockManager;
private final SingleTapClassifier mSingleTapClassifier;
private final DoubleTapClassifier mDoubleTapClassifier;
private final HistoryTracker mHistoryTracker;
@@ -173,14 +171,13 @@
@Inject
public BrightLineFalsingManager(FalsingDataProvider falsingDataProvider,
- DockManager dockManager, MetricsLogger metricsLogger,
+ MetricsLogger metricsLogger,
@Named(BRIGHT_LINE_GESTURE_CLASSIFERS) Set<FalsingClassifier> classifiers,
SingleTapClassifier singleTapClassifier, DoubleTapClassifier doubleTapClassifier,
HistoryTracker historyTracker, KeyguardStateController keyguardStateController,
AccessibilityManager accessibilityManager,
@TestHarness boolean testHarness) {
mDataProvider = falsingDataProvider;
- mDockManager = dockManager;
mMetricsLogger = metricsLogger;
mClassifiers = classifiers;
mSingleTapClassifier = singleTapClassifier;
@@ -332,7 +329,7 @@
|| !mKeyguardStateController.isShowing()
|| mTestHarness
|| mDataProvider.isJustUnlockedWithFace()
- || mDockManager.isDocked()
+ || mDataProvider.isDocked()
|| mAccessibilityManager.isEnabled();
}
@@ -400,7 +397,7 @@
ipw.print("mJustUnlockedWithFace=");
ipw.println(mDataProvider.isJustUnlockedWithFace() ? 1 : 0);
ipw.print("isDocked=");
- ipw.println(mDockManager.isDocked() ? 1 : 0);
+ ipw.println(mDataProvider.isDocked() ? 1 : 0);
ipw.print("width=");
ipw.println(mDataProvider.getWidthPixels());
ipw.print("height=");
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
index 9697369..14e5991 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
@@ -16,6 +16,8 @@
package com.android.systemui.classifier;
+import static com.android.systemui.dock.DockManager.DockEventListener;
+
import android.hardware.SensorManager;
import android.hardware.biometrics.BiometricSourceType;
import android.util.Log;
@@ -25,9 +27,12 @@
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dock.DockManager;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.sensors.ProximitySensor;
@@ -53,6 +58,8 @@
private final ProximitySensor mProximitySensor;
private final StatusBarStateController mStatusBarStateController;
private final KeyguardStateController mKeyguardStateController;
+ private final BatteryController mBatteryController;
+ private final DockManager mDockManager;
private final DelayableExecutor mMainExecutor;
private final SystemClock mSystemClock;
@@ -89,12 +96,46 @@
}
};
+
+ private final BatteryStateChangeCallback mBatteryListener = new BatteryStateChangeCallback() {
+ @Override
+ public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
+ }
+
+ @Override
+ public void onWirelessChargingChanged(boolean isWirelessCharging) {
+ if (isWirelessCharging || mDockManager.isDocked()) {
+ mProximitySensor.pause();
+ } else {
+ mProximitySensor.resume();
+ }
+ }
+ };
+
+ private final DockEventListener mDockEventListener = new DockEventListener() {
+ @Override
+ public void onEvent(int event) {
+ if (event == DockManager.STATE_NONE && !mBatteryController.isWirelessCharging()) {
+ mProximitySensor.resume();
+ } else {
+ mProximitySensor.pause();
+ }
+ }
+ };
+
@Inject
- FalsingCollectorImpl(FalsingDataProvider falsingDataProvider, FalsingManager falsingManager,
- KeyguardUpdateMonitor keyguardUpdateMonitor, HistoryTracker historyTracker,
- ProximitySensor proximitySensor, StatusBarStateController statusBarStateController,
+ FalsingCollectorImpl(
+ FalsingDataProvider falsingDataProvider,
+ FalsingManager falsingManager,
+ KeyguardUpdateMonitor keyguardUpdateMonitor,
+ HistoryTracker historyTracker,
+ ProximitySensor proximitySensor,
+ StatusBarStateController statusBarStateController,
KeyguardStateController keyguardStateController,
- @Main DelayableExecutor mainExecutor, SystemClock systemClock) {
+ BatteryController batteryController,
+ DockManager dockManager,
+ @Main DelayableExecutor mainExecutor,
+ SystemClock systemClock) {
mFalsingDataProvider = falsingDataProvider;
mFalsingManager = falsingManager;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
@@ -102,10 +143,11 @@
mProximitySensor = proximitySensor;
mStatusBarStateController = statusBarStateController;
mKeyguardStateController = keyguardStateController;
+ mBatteryController = batteryController;
+ mDockManager = dockManager;
mMainExecutor = mainExecutor;
mSystemClock = systemClock;
-
mProximitySensor.setTag(PROXIMITY_SENSOR_TAG);
mProximitySensor.setDelay(SensorManager.SENSOR_DELAY_GAME);
@@ -113,6 +155,9 @@
mState = mStatusBarStateController.getState();
mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateCallback);
+
+ mBatteryController.addCallback(mBatteryListener);
+ mDockManager.addListener(mDockEventListener);
}
@Override
@@ -312,6 +357,8 @@
unregisterSensors();
mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateCallback);
mStatusBarStateController.removeCallback(mStatusBarStateListener);
+ mBatteryController.removeCallback(mBatteryListener);
+ mDockManager.removeListener(mDockEventListener);
}
@Override
@@ -351,9 +398,7 @@
}
private void registerSensors() {
- if (!mFalsingDataProvider.isWirelessCharging()) {
- mProximitySensor.register(mSensorEventListener);
- }
+ mProximitySensor.register(mSensorEventListener);
}
private void unregisterSensors() {
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
index 2f688dd..a3ecb0c 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
@@ -22,6 +22,7 @@
import android.view.MotionEvent.PointerProperties;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dock.DockManager;
import com.android.systemui.statusbar.policy.BatteryController;
import java.util.ArrayList;
@@ -40,7 +41,8 @@
private final int mWidthPixels;
private final int mHeightPixels;
- private final BatteryController mBatteryController;
+ private BatteryController mBatteryController;
+ private final DockManager mDockManager;
private final float mXdpi;
private final float mYdpi;
private final List<SessionListener> mSessionListeners = new ArrayList<>();
@@ -59,12 +61,16 @@
private boolean mJustUnlockedWithFace;
@Inject
- public FalsingDataProvider(DisplayMetrics displayMetrics, BatteryController batteryController) {
+ public FalsingDataProvider(
+ DisplayMetrics displayMetrics,
+ BatteryController batteryController,
+ DockManager dockManager) {
mXdpi = displayMetrics.xdpi;
mYdpi = displayMetrics.ydpi;
mWidthPixels = displayMetrics.widthPixels;
mHeightPixels = displayMetrics.heightPixels;
mBatteryController = batteryController;
+ mDockManager = dockManager;
FalsingClassifier.logInfo("xdpi, ydpi: " + getXdpi() + ", " + getYdpi());
FalsingClassifier.logInfo("width, height: " + getWidthPixels() + ", " + getHeightPixels());
@@ -219,11 +225,6 @@
return mLastMotionEvent.getY() < mFirstRecentMotionEvent.getY();
}
- /** Returns true if phone is being charged without a cable. */
- public boolean isWirelessCharging() {
- return mBatteryController.isWirelessCharging();
- }
-
private void recalculateData() {
if (!mDirty) {
return;
@@ -357,6 +358,11 @@
mJustUnlockedWithFace = justUnlockedWithFace;
}
+ /** Returns true if phone is sitting in a dock or is wirelessly charging. */
+ public boolean isDocked() {
+ return mBatteryController.isWirelessCharging() || mDockManager.isDocked();
+ }
+
/** Implement to be alerted abotu the beginning and ending of falsing tracking. */
public interface SessionListener {
/** Called when the lock screen is shown and falsing-tracking begins. */
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 75f77bf..c33f4fa 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1506,8 +1506,10 @@
return;
}
- // if the keyguard is already showing, don't bother
- if (mKeyguardViewControllerLazy.get().isShowing()) {
+ // if the keyguard is already showing, don't bother. check flags in both files
+ // to account for the hiding animation which results in a delay and discrepancy
+ // between flags
+ if (mShowing && mKeyguardViewControllerLazy.get().isShowing()) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
resetStateLocked();
return;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
index bcce87a..1d6c7c9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
@@ -44,6 +44,7 @@
import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
@@ -57,6 +58,7 @@
private final UiEventLogger mUiEventLogger = QSEvents.INSTANCE.getQsUiEventsLogger();
private ViewGroup mDetailContent;
+ private FalsingManager mFalsingManager;
protected TextView mDetailSettingsButton;
protected TextView mDetailDoneButton;
@VisibleForTesting
@@ -124,12 +126,13 @@
/** */
public void setQsPanel(QSPanelController panelController, QuickStatusBarHeader header,
- QSFooter footer) {
+ QSFooter footer, FalsingManager falsingManager) {
mQsPanelController = panelController;
mHeader = header;
mFooter = footer;
mHeader.setCallback(mQsPanelCallback);
mQsPanelController.setCallback(mQsPanelCallback);
+ mFalsingManager = falsingManager;
}
public void setHost(QSTileHost host) {
@@ -273,6 +276,9 @@
final Intent settingsIntent = adapter.getSettingsIntent();
mDetailSettingsButton.setVisibility(settingsIntent != null ? VISIBLE : GONE);
mDetailSettingsButton.setOnClickListener(v -> {
+ if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
+ return;
+ }
Dependency.get(MetricsLogger.class).action(ACTION_QS_MORE_SETTINGS,
adapter.getMetricsCategory());
mUiEventLogger.log(adapter.moreSettingsEvent());
@@ -280,6 +286,9 @@
.postStartActivityDismissingKeyguard(settingsIntent, 0);
});
mDetailDoneButton.setOnClickListener(v -> {
+ if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
+ return;
+ }
announceForAccessibility(
mContext.getString(R.string.accessibility_desc_quick_settings));
if (!adapter.onDoneButtonClicked()) {
@@ -301,13 +310,13 @@
mQsDetailHeaderSwitch.setVisibility(VISIBLE);
handleToggleStateChanged(toggleState, adapter.getToggleEnabled());
mQsDetailHeader.setClickable(true);
- mQsDetailHeader.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- boolean checked = !mQsDetailHeaderSwitch.isChecked();
- mQsDetailHeaderSwitch.setChecked(checked);
- adapter.setToggleState(checked);
+ mQsDetailHeader.setOnClickListener(v -> {
+ if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
+ return;
}
+ boolean checked = !mQsDetailHeaderSwitch.isChecked();
+ mQsDetailHeaderSwitch.setChecked(checked);
+ adapter.setToggleState(checked);
});
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 36b4ee9..0a1e9d0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -39,6 +39,7 @@
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.media.MediaHost;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.customize.QSCustomizerController;
@@ -67,6 +68,7 @@
private final Rect mQsBounds = new Rect();
private final StatusBarStateController mStatusBarStateController;
+ private final FalsingManager mFalsingManager;
private boolean mQsExpanded;
private boolean mHeaderAnimating;
private boolean mStackScrollerOverscrolling;
@@ -133,7 +135,8 @@
StatusBarStateController statusBarStateController, CommandQueue commandQueue,
QSDetailDisplayer qsDetailDisplayer, @Named(QS_PANEL) MediaHost qsMediaHost,
@Named(QUICK_QS_PANEL) MediaHost qqsMediaHost,
- QSFragmentComponent.Factory qsComponentFactory, FeatureFlags featureFlags) {
+ QSFragmentComponent.Factory qsComponentFactory, FeatureFlags featureFlags,
+ FalsingManager falsingManager) {
mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
mInjectionInflater = injectionInflater;
mCommandQueue = commandQueue;
@@ -144,6 +147,7 @@
commandQueue.observe(getLifecycle(), this);
mHost = qsTileHost;
mFeatureFlags = featureFlags;
+ mFalsingManager = falsingManager;
mStatusBarStateController = statusBarStateController;
}
@@ -190,7 +194,7 @@
mQSContainerImplController.init();
mContainer = mQSContainerImplController.getView();
- mQSDetail.setQsPanel(mQSPanelController, mHeader, mFooter);
+ mQSDetail.setQsPanel(mQSPanelController, mHeader, mFooter, mFalsingManager);
mQSAnimator = qsFragmentComponent.getQSAnimator();
mQSCustomizerController = qsFragmentComponent.getQSCustomizerController();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
index 82b6c0c..ab81ac1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
@@ -153,9 +153,25 @@
});
}
+ @Nullable
+ private CharSequence getServiceLabelSafe() {
+ try {
+ return mController.getWalletClient().getServiceLabel();
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Failed to get the service label safely, recreating wallet client", e);
+ mController.reCreateWalletClient();
+ try {
+ return mController.getWalletClient().getServiceLabel();
+ } catch (RuntimeException e2) {
+ Log.e(TAG, "The QAW service label is broken.", e2);
+ return null;
+ }
+ }
+ }
+
@Override
protected void handleUpdateState(State state, Object arg) {
- CharSequence label = mController.getWalletClient().getServiceLabel();
+ CharSequence label = getServiceLabelSafe();
state.label = label == null ? mLabel : label;
state.contentDescription = state.label;
Drawable tileIcon = mController.getWalletClient().getTileIcon();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
index a972334..04437ea 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
@@ -146,7 +146,7 @@
@Override
public void onClick(View view) {
- if (mFalsingManager.isFalseTap(FalsingManager.MODERATE_PENALTY)) {
+ if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
index be0801e..0eaef72 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
@@ -80,7 +80,6 @@
private View mSave;
private View mEdit;
private View mShare;
- private View mDelete;
private CropView mCropView;
private MagnifierView mMagnifierView;
private ScrollCaptureResponse mScrollCaptureResponse;
@@ -120,24 +119,18 @@
mSave = requireViewById(R.id.save);
mEdit = requireViewById(R.id.edit);
mShare = requireViewById(R.id.share);
- mDelete = requireViewById(R.id.delete);
mCropView = requireViewById(R.id.crop_view);
mMagnifierView = requireViewById(R.id.magnifier);
mCropView.setCropInteractionListener(mMagnifierView);
mTransitionView = requireViewById(R.id.transition);
mEnterTransitionView = requireViewById(R.id.enter_transition);
+ requireViewById(R.id.cancel).setOnClickListener(v -> finishAndRemoveTask());
+
mSave.setOnClickListener(this::onClicked);
mEdit.setOnClickListener(this::onClicked);
mShare.setOnClickListener(this::onClicked);
- // Only show the delete button if we have something to delete (should typically be the case)
- if (getIntent().getData() != null) {
- mDelete.setOnClickListener(this::onClicked);
- } else {
- mDelete.setVisibility(View.GONE);
- }
-
mPreview.addOnLayoutChangeListener(
(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
updateImageDimensions());
@@ -162,6 +155,11 @@
public void onStart() {
super.onStart();
+ if (mPreview.getDrawable() != null) {
+ // We already have an image, so no need to try to load again.
+ return;
+ }
+
if (mCacheLoadFuture != null) {
Log.d(TAG, "mCacheLoadFuture != null");
final ListenableFuture<ImageLoader.Result> future = mCacheLoadFuture;
@@ -310,7 +308,6 @@
mSave.setEnabled(enabled);
mEdit.setEnabled(enabled);
mShare.setEnabled(enabled);
- mDelete.setEnabled(enabled);
}
private void doEdit(Uri uri) {
@@ -365,11 +362,6 @@
} else if (id == R.id.share) {
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_LONG_SCREENSHOT_SHARE);
startExport(PendingAction.SHARE);
- } else if (id == R.id.delete) {
- mBackgroundExecutor.execute(() -> {
- getContentResolver().delete(getIntent().getData(), null);
- finishAndRemoveTask();
- });
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 52b393f..16872b0 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -264,7 +264,6 @@
private Animator mScreenshotAnimation;
private RequestCallback mCurrentRequestCallback;
- private Uri mLatestUriSaved;
private final Handler mScreenshotHandler = new Handler(Looper.getMainLooper()) {
@Override
@@ -547,6 +546,7 @@
mAccessibilityManager.sendAccessibilityEvent(event);
}
+
if (mScreenshotView.isAttachedToWindow()) {
// if we didn't already dismiss for another reason
if (!mScreenshotView.isDismissing()) {
@@ -563,7 +563,6 @@
.getWindowInsets().getDisplayCutout());
mScreenBitmap = screenshot;
- mLatestUriSaved = null;
if (!isUserSetupComplete()) {
Log.w(TAG, "User setup not complete, displaying toast only");
@@ -701,7 +700,6 @@
longScreenshot));
final Intent intent = new Intent(mContext, LongScreenshotActivity.class);
- intent.setData(mLatestUriSaved);
intent.setFlags(
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
@@ -891,8 +889,6 @@
resetTimeout();
- mLatestUriSaved = imageData.uri;
-
if (imageData.uri != null) {
mScreenshotHandler.post(() -> {
if (mScreenshotAnimation != null && mScreenshotAnimation.isRunning()) {
diff --git a/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt b/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt
index 2477534..ef18df5 100644
--- a/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt
@@ -38,6 +38,10 @@
import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController
import com.android.systemui.statusbar.policy.KeyguardStateController
import javax.inject.Inject
+import com.android.internal.util.FrameworkStatsLog.PRIVACY_TOGGLE_DIALOG_INTERACTION
+import com.android.internal.util.FrameworkStatsLog.PRIVACY_TOGGLE_DIALOG_INTERACTION__ACTION__ENABLE
+import com.android.internal.util.FrameworkStatsLog.PRIVACY_TOGGLE_DIALOG_INTERACTION__ACTION__CANCEL
+import com.android.internal.util.FrameworkStatsLog.write
/**
* Dialog to be shown on top of apps that are attempting to use a sensor (e.g. microphone) which is
@@ -185,16 +189,25 @@
keyguardDismissUtil.executeWhenUnlocked({
bgHandler.postDelayed({
disableSensorPrivacy()
+ write(PRIVACY_TOGGLE_DIALOG_INTERACTION,
+ PRIVACY_TOGGLE_DIALOG_INTERACTION__ACTION__ENABLE,
+ sensorUsePackageName)
}, UNLOCK_DELAY_MILLIS)
false
}, false, true)
} else {
disableSensorPrivacy()
+ write(PRIVACY_TOGGLE_DIALOG_INTERACTION,
+ PRIVACY_TOGGLE_DIALOG_INTERACTION__ACTION__ENABLE,
+ sensorUsePackageName)
}
}
BUTTON_NEGATIVE -> {
unsuppressImmediately = false
+ write(PRIVACY_TOGGLE_DIALOG_INTERACTION,
+ PRIVACY_TOGGLE_DIALOG_INTERACTION__ACTION__CANCEL,
+ sensorUsePackageName)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index a32b7e3..6964838 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -70,6 +70,7 @@
import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager;
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -93,6 +94,10 @@
StackScrollAlgorithm.SectionProvider bindSectionProvider(
NotificationSectionsManager impl);
+ @Binds
+ StackScrollAlgorithm.BypassController bindBypassController(
+ KeyguardBypassController impl);
+
/** Provides an instance of {@link NotificationEntryManager} */
@SysUISingleton
@Provides
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index 197920f..9846b28 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -29,6 +29,7 @@
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
+import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.BypassController;
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider;
import javax.inject.Inject;
@@ -43,6 +44,7 @@
private static final boolean NOTIFICATIONS_HAVE_SHADOWS = false;
private final SectionProvider mSectionProvider;
+ private final BypassController mBypassController;
private int mScrollY;
private boolean mDimmed;
private ActivatableNotificationView mActivatedChild;
@@ -152,14 +154,25 @@
return mStackHeight;
}
+ /**
+ * @return Height of notifications panel, with the animation from pulseHeight accounted for.
+ */
+ // TODO(b/192348384): move this logic to getStackHeight, and remove this and getInnerHeight
+ public float getPulseStackHeight() {
+ float pulseHeight = Math.min(mPulseHeight, mStackHeight);
+ return MathUtils.lerp(mStackHeight, pulseHeight, mDozeAmount);
+ }
+
/** Tracks the state from AlertingNotificationManager#hasNotifications() */
private boolean mHasAlertEntries;
@Inject
public AmbientState(
Context context,
- @NonNull SectionProvider sectionProvider) {
+ @NonNull SectionProvider sectionProvider,
+ @NonNull BypassController bypassController) {
mSectionProvider = sectionProvider;
+ mBypassController = bypassController;
reload(context);
}
@@ -297,6 +310,13 @@
}
}
+ /**
+ * Is bypass currently enabled?
+ */
+ public boolean isBypassEnabled() {
+ return mBypassController.isBypassEnabled();
+ }
+
public float getOverScrollAmount(boolean top) {
return top ? mOverScrollTopAmount : mOverScrollBottomAmount;
}
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 3fc8b8d..e65038b 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
@@ -421,10 +421,20 @@
// When pulsing (incoming notification on AOD), innerHeight is 0; clamp all
// to shelf start, thereby hiding all notifications (except the first one, which
// we later unhide in updatePulsingState)
- final int stackBottom =
- !ambientState.isShadeExpanded() || ambientState.isDozing()
- ? ambientState.getInnerHeight()
- : (int) ambientState.getStackHeight();
+ // TODO(b/192348384): merge InnerHeight with StackHeight
+ final int stackBottom;
+ if (ambientState.isBypassEnabled()) {
+ // We want to use the stackHeight when pulse expanding, since the animation
+ // isn't currently optimized if the pulseHeight is continuously changing
+ // Let's improve this when we're merging the heights above
+ stackBottom = ambientState.isPulseExpanding()
+ ? (int) ambientState.getStackHeight()
+ : ambientState.getInnerHeight();
+ } else {
+ stackBottom = !ambientState.isShadeExpanded() || ambientState.isDozing()
+ ? ambientState.getInnerHeight()
+ : (int) ambientState.getPulseStackHeight();
+ }
final int shelfStart =
stackBottom - ambientState.getShelf().getIntrinsicHeight();
viewState.yTranslation = Math.min(viewState.yTranslation, shelfStart);
@@ -742,4 +752,14 @@
*/
boolean beginsSection(@NonNull View view, @Nullable View previous);
}
+
+ /**
+ * Interface for telling the StackScrollAlgorithm information about the bypass state
+ */
+ public interface BypassController {
+ /**
+ * True if bypass is enabled. Note that this is always false if face auth is not enabled.
+ */
+ boolean isBypassEnabled();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
index c9d0842..2cb0a3a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
@@ -28,6 +28,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.NotificationLockscreenUserManager
import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.tuner.TunerService
import java.io.FileDescriptor
@@ -35,7 +36,7 @@
import javax.inject.Inject
@SysUISingleton
-open class KeyguardBypassController : Dumpable {
+open class KeyguardBypassController : Dumpable, StackScrollAlgorithm.BypassController {
private val mKeyguardStateController: KeyguardStateController
private val statusBarStateController: StatusBarStateController
@@ -67,6 +68,9 @@
lateinit var unlockController: BiometricUnlockController
var isPulseExpanding = false
+ /** delegates to [bypassEnabled] but conforms to [StackScrollAlgorithm.BypassController] */
+ override fun isBypassEnabled() = bypassEnabled
+
/**
* If face unlock dismisses the lock screen or keeps user on keyguard for the current user.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 567318c..f52aad9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -1350,7 +1350,8 @@
float lockIconPadding = 0;
if (mLockIconViewController.getTop() != 0) {
- lockIconPadding = mStatusBar.getDisplayHeight() - mLockIconViewController.getTop();
+ lockIconPadding = mStatusBar.getDisplayHeight() - mLockIconViewController.getTop()
+ + mResources.getDimensionPixelSize(R.dimen.min_lock_icon_padding);
}
float bottomPadding = Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding);
@@ -1625,7 +1626,6 @@
mView.getParent().requestDisallowInterceptTouchEvent(true);
}
if (mQsExpansionAnimator != null) {
- onQsExpansionStarted();
mInitialHeightOnTouch = mQsExpansionHeight;
mQsTracking = true;
traceQsJank(true /* startTracing */, false /* wasCancelled */);
@@ -3627,6 +3627,8 @@
public void setAmbientIndicationBottomPadding(int ambientIndicationBottomPadding) {
if (mAmbientIndicationBottomPadding != ambientIndicationBottomPadding) {
mAmbientIndicationBottomPadding = ambientIndicationBottomPadding;
+ mLockIconViewController.setAmbientIndicationBottomPadding(
+ mAmbientIndicationBottomPadding);
updateMaxDisplayedNotifications(true);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index ed7ab6cf..7b110a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -107,7 +107,8 @@
private final String mSlotBluetooth;
private final String mSlotTty;
private final String mSlotZen;
- private final String mSlotVolume;
+ private final String mSlotMute;
+ private final String mSlotVibrate;
private final String mSlotAlarmClock;
private final String mSlotManagedProfile;
private final String mSlotRotate;
@@ -149,7 +150,8 @@
private final PrivacyLogger mPrivacyLogger;
private boolean mZenVisible;
- private boolean mVolumeVisible;
+ private boolean mVibrateVisible;
+ private boolean mMuteVisible;
private boolean mCurrentUserSetup;
private boolean mManagedProfileIconVisible = false;
@@ -207,7 +209,8 @@
mSlotBluetooth = resources.getString(com.android.internal.R.string.status_bar_bluetooth);
mSlotTty = resources.getString(com.android.internal.R.string.status_bar_tty);
mSlotZen = resources.getString(com.android.internal.R.string.status_bar_zen);
- mSlotVolume = resources.getString(com.android.internal.R.string.status_bar_volume);
+ mSlotMute = resources.getString(com.android.internal.R.string.status_bar_mute);
+ mSlotVibrate = resources.getString(com.android.internal.R.string.status_bar_volume);
mSlotAlarmClock = resources.getString(com.android.internal.R.string.status_bar_alarm_clock);
mSlotManagedProfile = resources.getString(
com.android.internal.R.string.status_bar_managed_profile);
@@ -264,9 +267,14 @@
mIconController.setIcon(mSlotZen, R.drawable.stat_sys_dnd, null);
mIconController.setIconVisibility(mSlotZen, false);
- // volume
- mIconController.setIcon(mSlotVolume, R.drawable.stat_sys_ringer_vibrate, null);
- mIconController.setIconVisibility(mSlotVolume, false);
+ // vibrate
+ mIconController.setIcon(mSlotVibrate, R.drawable.stat_sys_ringer_vibrate,
+ mResources.getString(R.string.accessibility_ringer_vibrate));
+ mIconController.setIconVisibility(mSlotVibrate, false);
+ // mute
+ mIconController.setIcon(mSlotMute, R.drawable.stat_sys_ringer_silent,
+ mResources.getString(R.string.accessibility_ringer_silent));
+ mIconController.setIconVisibility(mSlotMute, false);
updateVolumeZen();
// cast
@@ -372,9 +380,8 @@
int zenIconId = 0;
String zenDescription = null;
- boolean volumeVisible = false;
- int volumeIconId = 0;
- String volumeDescription = null;
+ boolean vibrateVisible = false;
+ boolean muteVisible = false;
int zen = mZenController.getZen();
if (DndTile.isVisible(mSharedPreferences) || DndTile.isCombinedIcon(mSharedPreferences)) {
@@ -396,13 +403,9 @@
mRingerModeTracker.getRingerModeInternal().getValue();
if (ringerModeInternal != null) {
if (ringerModeInternal == AudioManager.RINGER_MODE_VIBRATE) {
- volumeVisible = true;
- volumeIconId = R.drawable.stat_sys_ringer_vibrate;
- volumeDescription = mResources.getString(R.string.accessibility_ringer_vibrate);
+ vibrateVisible = true;
} else if (ringerModeInternal == AudioManager.RINGER_MODE_SILENT) {
- volumeVisible = true;
- volumeIconId = R.drawable.stat_sys_ringer_silent;
- volumeDescription = mResources.getString(R.string.accessibility_ringer_silent);
+ muteVisible = true;
}
}
}
@@ -415,13 +418,16 @@
mZenVisible = zenVisible;
}
- if (volumeVisible) {
- mIconController.setIcon(mSlotVolume, volumeIconId, volumeDescription);
+ if (vibrateVisible != mVibrateVisible) {
+ mIconController.setIconVisibility(mSlotVibrate, vibrateVisible);
+ mVibrateVisible = vibrateVisible;
}
- if (volumeVisible != mVolumeVisible) {
- mIconController.setIconVisibility(mSlotVolume, volumeVisible);
- mVolumeVisible = volumeVisible;
+
+ if (muteVisible != mMuteVisible) {
+ mIconController.setIconVisibility(mSlotMute, muteVisible);
+ mMuteVisible = muteVisible;
}
+
updateAlarm();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
index 1f1817c..5e70d0d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
@@ -21,7 +21,7 @@
import android.database.DataSetObserver;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
-import android.os.UserManager;
+import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
@@ -76,7 +76,6 @@
private final KeyguardVisibilityHelper mKeyguardVisibilityHelper;
private final KeyguardUserDetailAdapter mUserDetailAdapter;
private NotificationPanelViewController mNotificationPanelViewController;
- private UserManager mUserManager;
UserSwitcherController.UserRecord mCurrentUser;
// State info for the user switch and keyguard
@@ -115,7 +114,6 @@
UserAvatarView view,
Context context,
@Main Resources resources,
- UserManager userManager,
ScreenLifecycle screenLifecycle,
UserSwitcherController userSwitcherController,
KeyguardStateController keyguardStateController,
@@ -129,7 +127,6 @@
if (DEBUG) Log.d(TAG, "New KeyguardQsUserSwitchController");
mContext = context;
mResources = resources;
- mUserManager = userManager;
mScreenLifecycle = screenLifecycle;
mUserSwitcherController = userSwitcherController;
mKeyguardStateController = keyguardStateController;
@@ -227,47 +224,39 @@
return;
}
- if (mCurrentUser == null) {
- mView.setVisibility(View.GONE);
- return;
- }
-
- mView.setVisibility(View.VISIBLE);
-
- String currentUserName = mCurrentUser.info.name;
String contentDescription = null;
-
- if (!TextUtils.isEmpty(currentUserName)) {
+ if (mCurrentUser != null && mCurrentUser.info != null && !TextUtils.isEmpty(
+ mCurrentUser.info.name)) {
+ // If we know the current user's name, have TalkBack to announce "Signed in as [user
+ // name]" when the icon is selected
+ contentDescription = mContext.getString(R.string.accessibility_quick_settings_user,
+ mCurrentUser.info.name);
+ } else {
+ // As a fallback, have TalkBack announce "Switch user"
contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_user,
- currentUserName);
+ R.string.accessibility_multi_user_switch_switcher);
}
if (!TextUtils.equals(mView.getContentDescription(), contentDescription)) {
mView.setContentDescription(contentDescription);
}
- mView.setDrawableWithBadge(getCurrentUserIcon().mutate(), mCurrentUser.resolveId());
+ int userId = mCurrentUser != null ? mCurrentUser.resolveId() : UserHandle.USER_NULL;
+ mView.setDrawableWithBadge(getCurrentUserIcon().mutate(), userId);
}
Drawable getCurrentUserIcon() {
Drawable drawable;
- if (mCurrentUser.picture == null) {
- if (mCurrentUser.isCurrent && mCurrentUser.isGuest) {
+ if (mCurrentUser == null || mCurrentUser.picture == null) {
+ if (mCurrentUser != null && mCurrentUser.isGuest) {
drawable = mContext.getDrawable(R.drawable.ic_avatar_guest_user);
} else {
- drawable = mAdapter.getIconDrawable(mContext, mCurrentUser);
+ drawable = mContext.getDrawable(R.drawable.ic_avatar_user);
}
- int iconColorRes;
- if (mCurrentUser.isSwitchToEnabled) {
- iconColorRes = R.color.kg_user_switcher_avatar_icon_color;
- } else {
- iconColorRes = R.color.kg_user_switcher_restricted_avatar_icon_color;
- }
+ int iconColorRes = R.color.kg_user_switcher_avatar_icon_color;
drawable.setTint(mResources.getColor(iconColorRes, mContext.getTheme()));
} else {
- int avatarSize =
- (int) mResources.getDimension(R.dimen.kg_framed_avatar_size);
+ int avatarSize = (int) mResources.getDimension(R.dimen.kg_framed_avatar_size);
drawable = new CircleFramedDrawable(mCurrentUser.picture, avatarSize);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index e2b6895..4e921a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -67,6 +67,7 @@
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.qs.QSUserSwitcherEvent;
import com.android.systemui.qs.tiles.UserDetailView;
@@ -131,6 +132,7 @@
private final Executor mUiBgExecutor;
private final boolean mGuestUserAutoCreated;
private final AtomicBoolean mGuestCreationScheduled;
+ private FalsingManager mFalsingManager;
@Inject
public UserSwitcherController(Context context,
@@ -139,6 +141,7 @@
ActivityStarter activityStarter,
BroadcastDispatcher broadcastDispatcher,
UiEventLogger uiEventLogger,
+ FalsingManager falsingManager,
TelephonyListenerManager telephonyListenerManager,
IActivityTaskManager activityTaskManager,
UserDetailAdapter userDetailAdapter,
@@ -148,6 +151,7 @@
mTelephonyListenerManager = telephonyListenerManager;
mActivityTaskManager = activityTaskManager;
mUiEventLogger = uiEventLogger;
+ mFalsingManager = falsingManager;
mGuestResumeSessionReceiver = new GuestResumeSessionReceiver(this, mUiEventLogger);
mUserDetailAdapter = userDetailAdapter;
mUiBgExecutor = uiBgExecutor;
@@ -1031,6 +1035,11 @@
@Override
public void onClick(DialogInterface dialog, int which) {
+ int penalty = which == BUTTON_NEGATIVE ? FalsingManager.NO_PENALTY
+ : FalsingManager.HIGH_PENALTY;
+ if (mFalsingManager.isFalseTap(penalty)) {
+ return;
+ }
if (which == BUTTON_NEGATIVE) {
cancel();
} else {
@@ -1057,6 +1066,11 @@
@Override
public void onClick(DialogInterface dialog, int which) {
+ int penalty = which == BUTTON_NEGATIVE ? FalsingManager.NO_PENALTY
+ : FalsingManager.MODERATE_PENALTY;
+ if (mFalsingManager.isFalseTap(penalty)) {
+ return;
+ }
if (which == BUTTON_NEGATIVE) {
cancel();
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index 11ddbd0..81999b5 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -450,19 +450,23 @@
OverlayIdentifier systemPalette = categoryToPackage.get(OVERLAY_CATEGORY_SYSTEM_PALETTE);
if (mIsMonetEnabled && systemPalette != null && systemPalette.getPackageName() != null) {
try {
- int color = Integer.parseInt(systemPalette.getPackageName().toLowerCase(), 16);
+ String colorString = systemPalette.getPackageName().toLowerCase();
+ if (!colorString.startsWith("#")) {
+ colorString = "#" + colorString;
+ }
+ int color = Color.parseColor(colorString);
mNeutralOverlay = getOverlay(color, NEUTRAL);
mNeedsOverlayCreation = true;
categoryToPackage.remove(OVERLAY_CATEGORY_SYSTEM_PALETTE);
- } catch (NumberFormatException e) {
- Log.w(TAG, "Invalid color definition: " + systemPalette.getPackageName());
+ } catch (Exception e) {
+ // Color.parseColor doesn't catch any exceptions from the calls it makes
+ Log.w(TAG, "Invalid color definition: " + systemPalette.getPackageName(), e);
}
} else if (!mIsMonetEnabled && systemPalette != null) {
try {
// It's possible that we flipped the flag off and still have a @ColorInt in the
// setting. We need to sanitize the input, otherwise the overlay transaction will
// fail.
- Integer.parseInt(systemPalette.getPackageName().toLowerCase(), 16);
categoryToPackage.remove(OVERLAY_CATEGORY_SYSTEM_PALETTE);
} catch (NumberFormatException e) {
// This is a package name. All good, let's continue
@@ -473,12 +477,17 @@
OverlayIdentifier accentPalette = categoryToPackage.get(OVERLAY_CATEGORY_ACCENT_COLOR);
if (mIsMonetEnabled && accentPalette != null && accentPalette.getPackageName() != null) {
try {
- int color = Integer.parseInt(accentPalette.getPackageName().toLowerCase(), 16);
+ String colorString = accentPalette.getPackageName().toLowerCase();
+ if (!colorString.startsWith("#")) {
+ colorString = "#" + colorString;
+ }
+ int color = Color.parseColor(colorString);
mSecondaryOverlay = getOverlay(color, ACCENT);
mNeedsOverlayCreation = true;
categoryToPackage.remove(OVERLAY_CATEGORY_ACCENT_COLOR);
- } catch (NumberFormatException e) {
- Log.w(TAG, "Invalid color definition: " + accentPalette.getPackageName());
+ } catch (Exception e) {
+ // Color.parseColor doesn't catch any exceptions from the calls it makes
+ Log.w(TAG, "Invalid color definition: " + accentPalette.getPackageName(), e);
}
} else if (!mIsMonetEnabled && accentPalette != null) {
try {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index bfcd131..e94f836 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -20,7 +20,9 @@
import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_FACE_THEN_FINGERPRINT;
import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -55,12 +57,13 @@
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
import android.os.Bundle;
import android.os.RemoteException;
-import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableContext;
import android.testing.TestableLooper.RunWithLooper;
import android.view.WindowManager;
+import androidx.test.filters.SmallTest;
+
import com.android.internal.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.CommandQueue;
@@ -539,6 +542,17 @@
verify(mUdfpsController).onAodInterrupt(eq(pos), eq(pos), eq(majorMinor), eq(majorMinor));
}
+ @Test
+ public void testSubscribesToOrientationChangesWhenShowingDialog() {
+ assertFalse(mAuthController.mOrientationListener.getEnabled());
+
+ showDialog(new int[]{1} /* sensorIds */, false /* credentialAllowed */);
+ assertTrue(mAuthController.mOrientationListener.getEnabled());
+
+ mAuthController.hideAuthenticationDialog();
+ assertFalse(mAuthController.mOrientationListener.getEnabled());
+ }
+
// Helpers
private void showDialog(int[] sensorIds, boolean credentialAllowed) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
new file mode 100644
index 0000000..7019a4b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics
+
+import android.hardware.biometrics.SensorProperties
+import android.hardware.display.DisplayManagerGlobal
+import android.hardware.fingerprint.FingerprintManager
+import android.hardware.fingerprint.FingerprintSensorProperties
+import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
+import android.hardware.fingerprint.ISidefpsController
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.Display
+import android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS
+import android.view.DisplayInfo
+import android.view.LayoutInflater
+import android.view.WindowManager
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Mock
+import org.mockito.Mockito.`when`
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
+
+private const val DISPLAY_ID = 2
+private const val SENSOR_ID = 1
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class SidefpsControllerTest : SysuiTestCase() {
+
+ @JvmField @Rule
+ var rule = MockitoJUnit.rule()
+
+ @Mock
+ lateinit var layoutInflater: LayoutInflater
+ @Mock
+ lateinit var fingerprintManager: FingerprintManager
+ @Mock
+ lateinit var windowManager: WindowManager
+ @Mock
+ lateinit var sidefpsView: SidefpsView
+
+ private val executor = FakeExecutor(FakeSystemClock())
+ private lateinit var overlayController: ISidefpsController
+ private lateinit var sideFpsController: SidefpsController
+
+ @Before
+ fun setup() {
+ `when`(layoutInflater.inflate(R.layout.sidefps_view, null, false)).thenReturn(sidefpsView)
+ `when`(fingerprintManager.sensorPropertiesInternal).thenReturn(
+ listOf(
+ FingerprintSensorPropertiesInternal(
+ SENSOR_ID,
+ SensorProperties.STRENGTH_STRONG,
+ 5 /* maxEnrollmentsPerUser */,
+ listOf() /* componentInfo */,
+ FingerprintSensorProperties.TYPE_POWER_BUTTON,
+ true /* resetLockoutRequiresHardwareAuthToken */
+ )
+ )
+ )
+ `when`(windowManager.defaultDisplay).thenReturn(
+ Display(
+ DisplayManagerGlobal.getInstance(),
+ DISPLAY_ID,
+ DisplayInfo(),
+ DEFAULT_DISPLAY_ADJUSTMENTS
+ )
+ )
+
+ sideFpsController = SidefpsController(
+ mContext, layoutInflater, fingerprintManager, windowManager, executor
+ )
+
+ overlayController = ArgumentCaptor.forClass(ISidefpsController::class.java).apply {
+ verify(fingerprintManager).setSidefpsController(capture())
+ }.value
+ }
+
+ @Test
+ fun testSubscribesToOrientationChangesWhenShowingOverlay() {
+ assertThat(sideFpsController.mOrientationListener.enabled).isFalse()
+
+ overlayController.show()
+ executor.runAllReady()
+ assertThat(sideFpsController.mOrientationListener.enabled).isTrue()
+
+ overlayController.hide()
+ executor.runAllReady()
+ assertThat(sideFpsController.mOrientationListener.enabled).isFalse()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index 25722e1..d8d3676 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -17,6 +17,8 @@
package com.android.systemui.biometrics;
import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
@@ -236,6 +238,22 @@
}
@Test
+ public void testSubscribesToOrientationChangesWhenShowingOverlay() throws Exception {
+ assertFalse(mUdfpsController.mOrientationListener.getEnabled());
+
+ mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
+ IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
+ mFgExecutor.runAllReady();
+
+ assertTrue(mUdfpsController.mOrientationListener.getEnabled());
+
+ mOverlayController.hideUdfpsOverlay(TEST_UDFPS_SENSOR_ID);
+ mFgExecutor.runAllReady();
+
+ assertFalse(mUdfpsController.mOrientationListener.getEnabled());
+ }
+
+ @Test
public void fingerDown() throws RemoteException {
// Configure UdfpsView to accept the ACTION_DOWN event
when(mUdfpsView.isIlluminationRequested()).thenReturn(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
index 546038e..b2a9e82 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
@@ -39,7 +39,6 @@
import com.android.internal.logging.testing.FakeMetricsLogger;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingDataProvider.GestureFinalizedListener;
-import com.android.systemui.dock.DockManagerFake;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
@@ -62,7 +61,6 @@
private BrightLineFalsingManager mBrightLineFalsingManager;
@Mock
private FalsingDataProvider mFalsingDataProvider;
- private final DockManagerFake mDockManager = new DockManagerFake();
private final MetricsLogger mMetricsLogger = new FakeMetricsLogger();
private final Set<FalsingClassifier> mClassifiers = new HashSet<>();
@Mock
@@ -102,7 +100,7 @@
mClassifiers.add(mClassifierB);
when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList);
when(mKeyguardStateController.isShowing()).thenReturn(true);
- mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider, mDockManager,
+ mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider,
mMetricsLogger, mClassifiers, mSingleTapClassfier, mDoubleTapClassifier,
mHistoryTracker, mKeyguardStateController, mAccessibilityManager,
false);
@@ -168,7 +166,7 @@
// Even when the classifiers report a false, we should allow.
when(mClassifierA.classifyGesture(anyInt(), anyDouble(), anyDouble()))
.thenReturn(mPassedResult);
- mDockManager.setIsDocked(true);
+ when(mFalsingDataProvider.isDocked()).thenReturn(true);
assertThat(mBrightLineFalsingManager.isFalseTouch(0)).isFalse();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
index 86243b5..c4f480d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
@@ -32,7 +32,6 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.testing.FakeMetricsLogger;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.dock.DockManagerFake;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.Before;
@@ -52,7 +51,6 @@
private BrightLineFalsingManager mBrightLineFalsingManager;
@Mock
private FalsingDataProvider mFalsingDataProvider;
- private final DockManagerFake mDockManager = new DockManagerFake();
private final MetricsLogger mMetricsLogger = new FakeMetricsLogger();
private final Set<FalsingClassifier> mClassifiers = new HashSet<>();
@Mock
@@ -84,7 +82,7 @@
mClassifiers.add(mClassifierA);
when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList);
when(mKeyguardStateController.isShowing()).thenReturn(true);
- mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider, mDockManager,
+ mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider,
mMetricsLogger, mClassifiers, mSingleTapClassifier, mDoubleTapClassifier,
mHistoryTracker, mKeyguardStateController, mAccessibilityManager,
false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java
index 7d6ff34..5fa7214 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java
@@ -19,30 +19,35 @@
import android.util.DisplayMetrics;
import android.view.MotionEvent;
-import com.android.systemui.utils.leaks.FakeBatteryController;
-import com.android.systemui.utils.leaks.LeakCheckedTest;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dock.DockManagerFake;
+import com.android.systemui.statusbar.policy.BatteryController;
import org.junit.After;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.List;
-public class ClassifierTest extends LeakCheckedTest {
+public class ClassifierTest extends SysuiTestCase {
private FalsingDataProvider mDataProvider;
- private List<MotionEvent> mMotionEvents = new ArrayList<>();
+ private final List<MotionEvent> mMotionEvents = new ArrayList<>();
private float mOffsetX = 0;
private float mOffsetY = 0;
- private FakeBatteryController mFakeBatteryController;
+ @Mock
+ private BatteryController mBatteryController;
+ private final DockManagerFake mDockManager = new DockManagerFake();
public void setup() {
+ MockitoAnnotations.initMocks(this);
DisplayMetrics displayMetrics = new DisplayMetrics();
displayMetrics.xdpi = 100;
displayMetrics.ydpi = 100;
displayMetrics.widthPixels = 1000;
displayMetrics.heightPixels = 1000;
- mFakeBatteryController = new FakeBatteryController(getLeakCheck());
- mDataProvider = new FalsingDataProvider(displayMetrics, mFakeBatteryController);
+ mDataProvider = new FalsingDataProvider(displayMetrics, mBatteryController, mDockManager);
}
@After
@@ -54,10 +59,6 @@
return mDataProvider;
}
- FakeBatteryController getFakeBatteryController() {
- return mFakeBatteryController;
- }
-
protected void setOffsetX(float offsetX) {
mOffsetX = offsetX;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
index 3c41216..d99a553 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
@@ -32,9 +32,12 @@
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dock.DockManager;
+import com.android.systemui.dock.DockManagerFake;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.sensors.ProximitySensor;
@@ -67,6 +70,9 @@
private SysuiStatusBarStateController mStatusBarStateController;
@Mock
private KeyguardStateController mKeyguardStateController;
+ @Mock
+ private BatteryController mBatteryController;
+ private final DockManagerFake mDockManager = new DockManagerFake();
private final FakeSystemClock mFakeSystemClock = new FakeSystemClock();
private final FakeExecutor mFakeExecutor = new FakeExecutor(mFakeSystemClock);
@@ -79,8 +85,8 @@
mFalsingCollector = new FalsingCollectorImpl(mFalsingDataProvider, mFalsingManager,
mKeyguardUpdateMonitor, mHistoryTracker, mProximitySensor,
- mStatusBarStateController, mKeyguardStateController, mFakeExecutor,
- mFakeSystemClock);
+ mStatusBarStateController, mKeyguardStateController, mBatteryController,
+ mDockManager, mFakeExecutor, mFakeSystemClock);
}
@Test
@@ -91,9 +97,32 @@
@Test
public void testNoProximityWhenWirelessCharging() {
- when(mFalsingDataProvider.isWirelessCharging()).thenReturn(true);
- mFalsingCollector.onScreenTurningOn();
- verify(mProximitySensor, never()).register(any(ThresholdSensor.Listener.class));
+ ArgumentCaptor<BatteryController.BatteryStateChangeCallback> batteryCallbackCaptor =
+ ArgumentCaptor.forClass(BatteryController.BatteryStateChangeCallback.class);
+ verify(mBatteryController).addCallback(batteryCallbackCaptor.capture());
+ batteryCallbackCaptor.getValue().onWirelessChargingChanged(true);
+ verify(mProximitySensor).pause();
+ }
+
+ @Test
+ public void testProximityWhenOffWirelessCharging() {
+ ArgumentCaptor<BatteryController.BatteryStateChangeCallback> batteryCallbackCaptor =
+ ArgumentCaptor.forClass(BatteryController.BatteryStateChangeCallback.class);
+ verify(mBatteryController).addCallback(batteryCallbackCaptor.capture());
+ batteryCallbackCaptor.getValue().onWirelessChargingChanged(false);
+ verify(mProximitySensor).resume();
+ }
+
+ @Test
+ public void testNoProximityWhenDocked() {
+ mDockManager.setDockEvent(DockManager.STATE_DOCKED);
+ verify(mProximitySensor).pause();
+ }
+
+ @Test
+ public void testProximityWhenUndocked() {
+ mDockManager.setDockEvent(DockManager.STATE_NONE);
+ verify(mProximitySensor).resume();
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
index 1fe694e..5dc607f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
@@ -22,6 +22,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
import android.util.DisplayMetrics;
@@ -30,12 +31,15 @@
import androidx.test.filters.SmallTest;
import com.android.systemui.classifier.FalsingDataProvider.GestureFinalizedListener;
-import com.android.systemui.utils.leaks.FakeBatteryController;
+import com.android.systemui.dock.DockManagerFake;
+import com.android.systemui.statusbar.policy.BatteryController;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import java.util.List;
@@ -43,19 +47,21 @@
@RunWith(AndroidTestingRunner.class)
public class FalsingDataProviderTest extends ClassifierTest {
- private FakeBatteryController mFakeBatteryController;
private FalsingDataProvider mDataProvider;
+ @Mock
+ private BatteryController mBatteryController;
+ private final DockManagerFake mDockManager = new DockManagerFake();
@Before
public void setup() {
super.setup();
- mFakeBatteryController = new FakeBatteryController(getLeakCheck());
+ MockitoAnnotations.initMocks(this);
DisplayMetrics displayMetrics = new DisplayMetrics();
displayMetrics.xdpi = 100;
displayMetrics.ydpi = 100;
displayMetrics.widthPixels = 1000;
displayMetrics.heightPixels = 1000;
- mDataProvider = new FalsingDataProvider(displayMetrics, mFakeBatteryController);
+ mDataProvider = new FalsingDataProvider(displayMetrics, mBatteryController, mDockManager);
}
@After
@@ -250,10 +256,17 @@
@Test
public void test_isWirelessCharging() {
- assertThat(mDataProvider.isWirelessCharging()).isFalse();
+ assertThat(mDataProvider.isDocked()).isFalse();
- mFakeBatteryController.setWirelessCharging(true);
- assertThat(mDataProvider.isWirelessCharging()).isTrue();
+ when(mBatteryController.isWirelessCharging()).thenReturn(true);
+ assertThat(mDataProvider.isDocked()).isTrue();
+ }
+
+ @Test
+ public void test_isDocked() {
+ assertThat(mDataProvider.isDocked()).isFalse();
+ mDockManager.setIsDocked(true);
+ assertThat(mDataProvider.isDocked()).isTrue();
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
index 75cf855..c2bd024f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
@@ -41,6 +41,7 @@
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.DetailAdapter;
import org.junit.After;
@@ -76,7 +77,8 @@
mQsPanelController = mock(QSPanelController.class);
mQuickHeader = mock(QuickStatusBarHeader.class);
- mQsDetail.setQsPanel(mQsPanelController, mQuickHeader, mock(QSFooter.class));
+ mQsDetail.setQsPanel(mQsPanelController, mQuickHeader, mock(QSFooter.class),
+ mock(FalsingManager.class));
mQsDetail.mClipper = mock(QSDetailClipper.class);
mMockDetailAdapter = mock(DetailAdapter.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index 2ae4cbe..c40977b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -44,6 +44,7 @@
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.media.MediaHost;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.dagger.QSFragmentComponent;
import com.android.systemui.qs.external.CustomTileStatePersister;
@@ -92,6 +93,8 @@
private MediaHost mQQSMediaHost;
@Mock
private FeatureFlags mFeatureFlags;
+ @Mock
+ private FalsingManager mFalsingManager;
public QSFragmentTest() {
super(QSFragment.class);
@@ -182,6 +185,7 @@
mQSMediaHost,
mQQSMediaHost,
mQsComponentFactory,
- mFeatureFlags);
+ mFeatureFlags,
+ mFalsingManager);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
index a70c2be..17797b7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
@@ -30,6 +30,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -256,6 +257,19 @@
}
@Test
+ public void testGetServiceLabelUnsafe_recreateWalletClient() {
+ doAnswer(invocation -> {
+ throw new Exception("Bad service label.");
+ }).when(mQuickAccessWalletClient).getServiceLabel();
+
+ QSTile.State state = new QSTile.State();
+
+ mTile.handleUpdateState(state, null);
+
+ verify(mController).reCreateWalletClient();
+ }
+
+ @Test
public void testHandleUpdateState_updateLabelAndIcon() {
QSTile.State state = new QSTile.State();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 04d7b72..b03df880 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -64,6 +64,7 @@
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.FooterView;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.KeyguardBypassEnabledProvider;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
@@ -101,6 +102,7 @@
@Mock private RemoteInputController mRemoteInputController;
@Mock private NotificationRoundnessManager mNotificationRoundnessManager;
@Mock private KeyguardBypassEnabledProvider mKeyguardBypassEnabledProvider;
+ @Mock private KeyguardBypassController mBypassController;
@Mock private NotificationSectionsManager mNotificationSectionsManager;
@Mock private NotificationSection mNotificationSection;
@Mock private SysuiStatusBarStateController mStatusBarStateController;
@@ -132,7 +134,7 @@
when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
// Interact with real instance of AmbientState.
- mAmbientState = new AmbientState(mContext, mNotificationSectionsManager);
+ mAmbientState = new AmbientState(mContext, mNotificationSectionsManager, mBypassController);
// The actual class under test. You may need to work with this class directly when
// testing anonymous class members of mStackScroller, like mMenuEventListener,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
index 1a24c11..07d3fc2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
@@ -466,6 +466,44 @@
}
@Test
+ public void catchException_whenPackageNameIsOverlayName() {
+ mDeviceProvisionedController = mock(DeviceProvisionedController.class);
+ mThemeOverlayApplier = mock(ThemeOverlayApplier.class);
+ mWallpaperManager = mock(WallpaperManager.class);
+
+ // Assume we have some wallpaper colors at boot.
+ when(mWallpaperManager.getWallpaperColors(anyInt()))
+ .thenReturn(new WallpaperColors(Color.valueOf(Color.GRAY), null, null));
+
+ Executor executor = MoreExecutors.directExecutor();
+
+ mThemeOverlayController = new ThemeOverlayController(null /* context */,
+ mBroadcastDispatcher, mBgHandler, executor, executor, mThemeOverlayApplier,
+ mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
+ mUserTracker, mDumpManager, mFeatureFlags, mWakefulnessLifecycle) {
+ @Nullable
+ @Override
+ protected FabricatedOverlay getOverlay(int color, int type) {
+ FabricatedOverlay overlay = mock(FabricatedOverlay.class);
+ when(overlay.getIdentifier())
+ .thenReturn(new OverlayIdentifier("com.thebest.livewallpaperapp.ever"));
+
+ return overlay;
+ }
+
+ };
+ mThemeOverlayController.start();
+
+ verify(mWallpaperManager).addOnColorsChangedListener(mColorsListener.capture(), eq(null),
+ eq(UserHandle.USER_ALL));
+ verify(mDeviceProvisionedController).addCallback(mDeviceProvisionedListener.capture());
+
+ // Colors were applied during controller initialization.
+ verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ clearInvocations(mThemeOverlayApplier);
+ }
+
+ @Test
public void onWallpaperColorsChanged_defersUntilSetupIsCompleted_ifHasColors() {
mDeviceProvisionedController = mock(DeviceProvisionedController.class);
mThemeOverlayApplier = mock(ThemeOverlayApplier.class);
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 9ff1b10..b7feb63 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -865,7 +865,7 @@
Set<String> sameOemPackageCerts = new HashSet<>();
// Assume OEM may enter same package name in the parallel string array with
- // multiple ADK certs corresponding to it
+ // multiple APK certs corresponding to it
for (int i = 0; i < oemPackages.length; i++) {
if (oemPackages[i].equals(packageName)) {
sameOemPackageCerts.add(sameOemCerts[i].replaceAll(":", ""));
diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java
index 50b27a0..d04698c 100644
--- a/services/core/java/com/android/server/GestureLauncherService.java
+++ b/services/core/java/com/android/server/GestureLauncherService.java
@@ -519,15 +519,6 @@
// user has completed setup.
return intercept && isUserSetupComplete();
}
-
- public boolean isCameraDoubleTapPowerEnabled() {
- return mCameraDoubleTapPowerEnabled;
- }
-
- public boolean isEmergencyGestureEnabled() {
- return mEmergencyGestureEnabled;
- }
-
/**
* @return true if camera was launched, false otherwise.
*/
diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java
index ae1cd51..af8d7a6 100644
--- a/services/core/java/com/android/server/app/GameManagerService.java
+++ b/services/core/java/com/android/server/app/GameManagerService.java
@@ -37,6 +37,7 @@
import android.Manifest;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.app.ActivityManager;
import android.app.GameManager;
@@ -73,6 +74,7 @@
import com.android.internal.compat.IPlatformCompat;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import java.io.FileDescriptor;
import java.util.List;
@@ -196,6 +198,7 @@
final int userId = (int) msg.obj;
final String[] packageNames = getInstalledGamePackageNames(userId);
updateConfigsForUser(userId, packageNames);
+ break;
}
}
}
@@ -212,7 +215,7 @@
@Override
public void onPropertiesChanged(Properties properties) {
final String[] packageNames = properties.getKeyset().toArray(new String[0]);
- updateConfigsForUser(mContext.getUserId(), packageNames);
+ updateConfigsForUser(ActivityManager.getCurrentUser(), packageNames);
}
@Override
@@ -496,6 +499,11 @@
public void onUserStopping(@NonNull TargetUser user) {
mService.onUserStopping(user.getUserIdentifier());
}
+
+ @Override
+ public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+ mService.onUserSwitching(from, to.getUserIdentifier());
+ }
}
private boolean isValidPackageName(String packageName, int userId) {
@@ -503,7 +511,6 @@
return mPackageManager.getPackageUidAsUser(packageName, userId)
== Binder.getCallingUid();
} catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
return false;
}
}
@@ -567,7 +574,6 @@
return GameManager.GAME_MODE_UNSUPPORTED;
}
} catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
return GameManager.GAME_MODE_UNSUPPORTED;
}
@@ -606,7 +612,6 @@
return;
}
} catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
return;
}
@@ -639,14 +644,12 @@
void onUserStarting(int userId) {
synchronized (mLock) {
- if (mSettings.containsKey(userId)) {
- return;
+ if (!mSettings.containsKey(userId)) {
+ GameManagerSettings userSettings =
+ new GameManagerSettings(Environment.getDataSystemDeDirectory(userId));
+ mSettings.put(userId, userSettings);
+ userSettings.readPersistentDataLocked();
}
-
- GameManagerSettings userSettings =
- new GameManagerSettings(Environment.getDataSystemDeDirectory(userId));
- mSettings.put(userId, userSettings);
- userSettings.readPersistentDataLocked();
}
final Message msg = mHandler.obtainMessage(POPULATE_GAME_MODE_SETTINGS);
msg.obj = userId;
@@ -664,6 +667,22 @@
}
}
+ void onUserSwitching(TargetUser from, int toUserId) {
+ if (from != null) {
+ synchronized (mLock) {
+ final int fromUserId = from.getUserIdentifier();
+ if (mSettings.containsKey(fromUserId)) {
+ final Message msg = mHandler.obtainMessage(REMOVE_SETTINGS);
+ msg.obj = fromUserId;
+ mHandler.sendMessage(msg);
+ }
+ }
+ }
+ final Message msg = mHandler.obtainMessage(POPULATE_GAME_MODE_SETTINGS);
+ msg.obj = toUserId;
+ mHandler.sendMessage(msg);
+ }
+
/**
* @hide
*/
@@ -856,11 +875,25 @@
public void onReceive(@NonNull final Context context, @NonNull final Intent intent) {
final Uri data = intent.getData();
try {
+ final int userId = getSendingUserId();
+ if (userId != ActivityManager.getCurrentUser()) {
+ return;
+ }
final String packageName = data.getSchemeSpecificPart();
+ try {
+ final ApplicationInfo applicationInfo = mPackageManager
+ .getApplicationInfoAsUser(
+ packageName, PackageManager.MATCH_ALL, userId);
+ if (applicationInfo.category != ApplicationInfo.CATEGORY_GAME) {
+ return;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ // Ignore the exception.
+ }
switch (intent.getAction()) {
case ACTION_PACKAGE_ADDED:
case ACTION_PACKAGE_CHANGED:
- updateConfigsForUser(mContext.getUserId(), packageName);
+ updateConfigsForUser(userId, packageName);
break;
case ACTION_PACKAGE_REMOVED:
disableCompatScale(packageName);
@@ -873,11 +906,12 @@
break;
}
} catch (NullPointerException e) {
- Slog.e(TAG, "Failed to get package name for new package", e);
+ Slog.e(TAG, "Failed to get package name for new package");
}
}
};
- mContext.registerReceiver(packageReceiver, packageFilter);
+ mContext.registerReceiverForAllUsers(packageReceiver, packageFilter,
+ /* broadcastPermission= */ null, /* scheduler= */ null);
}
private void registerDeviceConfigListener() {
diff --git a/services/core/java/com/android/server/apphibernation/AppHibernationService.java b/services/core/java/com/android/server/apphibernation/AppHibernationService.java
index 7f1402d..db2ecc5 100644
--- a/services/core/java/com/android/server/apphibernation/AppHibernationService.java
+++ b/services/core/java/com/android/server/apphibernation/AppHibernationService.java
@@ -849,7 +849,7 @@
return DeviceConfig.getBoolean(
NAMESPACE_APP_HIBERNATION,
KEY_APP_HIBERNATION_ENABLED,
- false /* defaultValue */);
+ true /* defaultValue */);
}
/**
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 7789d60..33bc212 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -1090,8 +1090,7 @@
*/
private void finishOrPause(@NonNull IBinder clientId, boolean triggerCallbackIfNeeded,
boolean isPausing) {
- int indexOfToken = mInProgressEvents != null
- ? mInProgressEvents.indexOfKey(clientId) : -1;
+ int indexOfToken = isRunning() ? mInProgressEvents.indexOfKey(clientId) : -1;
if (indexOfToken < 0) {
finishPossiblyPaused(clientId, isPausing);
return;
@@ -1145,7 +1144,7 @@
// Finish or pause (no-op) an already paused op
private void finishPossiblyPaused(@NonNull IBinder clientId, boolean isPausing) {
- if (mPausedInProgressEvents == null) {
+ if (!isPaused()) {
Slog.wtf(TAG, "No ops running or paused");
return;
}
@@ -1186,7 +1185,7 @@
* Pause all currently started ops. This will create a HistoricalRegistry
*/
public void pause() {
- if (mInProgressEvents == null) {
+ if (!isRunning()) {
return;
}
@@ -1211,7 +1210,7 @@
* times, but keep all other values the same
*/
public void resume() {
- if (mPausedInProgressEvents == null) {
+ if (!isPaused()) {
return;
}
@@ -1245,7 +1244,7 @@
*/
void onClientDeath(@NonNull IBinder clientId) {
synchronized (AppOpsService.this) {
- if (mInProgressEvents == null && mPausedInProgressEvents == null) {
+ if (!isPaused() && !isRunning()) {
return;
}
@@ -1266,7 +1265,7 @@
* @param newState The new state
*/
public void onUidStateChanged(@AppOpsManager.UidState int newState) {
- if (mInProgressEvents == null && mPausedInProgressEvents == null) {
+ if (!isPaused() && !isRunning()) {
return;
}
@@ -1350,12 +1349,15 @@
* @param opToAdd The op to add
*/
public void add(@NonNull AttributedOp opToAdd) {
- if (opToAdd.mInProgressEvents != null) {
- Slog.w(TAG, "Ignoring " + opToAdd.mInProgressEvents.size() + " running app-ops");
+ if (opToAdd.isRunning() || opToAdd.isPaused()) {
+ ArrayMap<IBinder, InProgressStartOpEvent> ignoredEvents = opToAdd.isRunning()
+ ? opToAdd.mInProgressEvents : opToAdd.mPausedInProgressEvents;
+ Slog.w(TAG, "Ignoring " + ignoredEvents.size() + " app-ops, running: "
+ + opToAdd.isRunning());
- int numInProgressEvents = opToAdd.mInProgressEvents.size();
+ int numInProgressEvents = ignoredEvents.size();
for (int i = 0; i < numInProgressEvents; i++) {
- InProgressStartOpEvent event = opToAdd.mInProgressEvents.valueAt(i);
+ InProgressStartOpEvent event = ignoredEvents.valueAt(i);
event.finish();
mInProgressStartOpEventPool.release(event);
@@ -1367,11 +1369,11 @@
}
public boolean isRunning() {
- return mInProgressEvents != null;
+ return mInProgressEvents != null && !mInProgressEvents.isEmpty();
}
public boolean isPaused() {
- return mPausedInProgressEvents != null;
+ return mPausedInProgressEvents != null && !mPausedInProgressEvents.isEmpty();
}
boolean hasAnyTime() {
@@ -1401,7 +1403,7 @@
LongSparseArray<NoteOpEvent> accessEvents = deepClone(mAccessEvents);
// Add in progress events as access events
- if (mInProgressEvents != null) {
+ if (isRunning()) {
long now = SystemClock.elapsedRealtime();
int numInProgressEvents = mInProgressEvents.size();
@@ -2041,9 +2043,12 @@
attributionNum++) {
AttributedOp attributedOp = op.mAttributions.valueAt(attributionNum);
- while (attributedOp.mInProgressEvents != null) {
+ while (attributedOp.isRunning()) {
attributedOp.finished(attributedOp.mInProgressEvents.keyAt(0));
}
+ while (attributedOp.isPaused()) {
+ attributedOp.finished(attributedOp.mPausedInProgressEvents.keyAt(0));
+ }
}
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
index 45e93a0..5e1a245 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
@@ -30,13 +30,14 @@
import com.android.server.biometrics.BiometricsProto;
import com.android.server.biometrics.sensors.AcquisitionClient;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
+import com.android.server.biometrics.sensors.DetectionConsumer;
import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper;
/**
* Performs fingerprint detection without exposing any matching information (e.g. accept/reject
* have the same haptic, lockout counter is not increased).
*/
-class FingerprintDetectClient extends AcquisitionClient<ISession> {
+class FingerprintDetectClient extends AcquisitionClient<ISession> implements DetectionConsumer {
private static final String TAG = "FingerprintDetectClient";
@@ -88,7 +89,8 @@
}
}
- void onInteractionDetected() {
+ @Override
+ public void onInteractionDetected() {
vibrateSuccess();
try {
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index fb919fb..53c13c7 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -28,7 +28,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
-import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
import android.app.AppGlobals;
import android.app.Notification;
import android.app.NotificationManager;
@@ -323,6 +323,8 @@
private final PackageManagerInternal mPackageManagerInternal;
+ private final ActivityManagerInternal mAmi;
+
private List<UserInfo> getAllUsers() {
return mUserManager.getUsers();
}
@@ -643,6 +645,7 @@
mAccountManager = (AccountManager) mContext.getSystemService(Context.ACCOUNT_SERVICE);
mAccountManagerInternal = LocalServices.getService(AccountManagerInternal.class);
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
+ mAmi = LocalServices.getService(ActivityManagerInternal.class);
mAccountManagerInternal.addOnAppPermissionChangeListener((Account account, int uid) -> {
// If the UID gained access to the account kick-off syncs lacking account access
@@ -1115,15 +1118,11 @@
}
final int owningUid = syncAdapterInfo.uid;
final String owningPackage = syncAdapterInfo.componentName.getPackageName();
- try {
- if (ActivityManager.getService().isAppStartModeDisabled(owningUid, owningPackage)) {
- Slog.w(TAG, "Not scheduling job " + syncAdapterInfo.uid + ":"
- + syncAdapterInfo.componentName
- + " -- package not allowed to start");
- return AuthorityInfo.NOT_SYNCABLE;
- }
- } catch (RemoteException e) {
- /* ignore - local call */
+ if (mAmi.isAppStartModeDisabled(owningUid, owningPackage)) {
+ Slog.w(TAG, "Not scheduling job " + syncAdapterInfo.uid + ":"
+ + syncAdapterInfo.componentName
+ + " -- package not allowed to start");
+ return AuthorityInfo.NOT_SYNCABLE;
}
if (checkAccountAccess && !canAccessAccount(account, owningPackage, owningUid)) {
Log.w(TAG, "Access to " + logSafe(account) + " denied for package "
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 0038523..7d06d6e 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -705,10 +705,8 @@
final BrightnessPair brightnessPair =
index < 0 ? null : mDisplayBrightnesses.valueAt(index);
if (index < 0 || (mDisplayStates.valueAt(index) == state
- && BrightnessSynchronizer.floatEquals(
- brightnessPair.brightness, brightnessState)
- && BrightnessSynchronizer.floatEquals(
- brightnessPair.sdrBrightness, sdrBrightnessState))) {
+ && brightnessPair.brightness == brightnessState
+ && brightnessPair.sdrBrightness == sdrBrightnessState)) {
return; // Display no longer exists or no change.
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 8102f5d..b6d65197 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -1352,9 +1352,8 @@
final float currentBrightness = mPowerState.getScreenBrightness();
final float currentSdrBrightness = mPowerState.getSdrScreenBrightness();
if (isValidBrightnessValue(animateValue)
- && (!BrightnessSynchronizer.floatEquals(animateValue, currentBrightness)
- || !BrightnessSynchronizer.floatEquals(
- sdrAnimateValue, currentSdrBrightness))) {
+ && (animateValue != currentBrightness
+ || sdrAnimateValue != currentSdrBrightness)) {
if (initialRampSkip || hasBrightnessBuckets
|| wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) {
animateScreenBrightness(animateValue, sdrAnimateValue,
@@ -1684,11 +1683,10 @@
mHbmController.getCurrentBrightnessMin(), mHbmController.getCurrentBrightnessMax());
}
- // Checks whether the brightness is within the valid brightness range, not including the off or
- // invalid states.
- private boolean isValidBrightnessValue(float brightnessState) {
- return brightnessState >= PowerManager.BRIGHTNESS_MIN
- && brightnessState <= PowerManager.BRIGHTNESS_MAX;
+ // Checks whether the brightness is within the valid brightness range, not including off.
+ private boolean isValidBrightnessValue(float brightness) {
+ return brightness >= PowerManager.BRIGHTNESS_MIN
+ && brightness <= PowerManager.BRIGHTNESS_MAX;
}
private void animateScreenBrightness(float target, float sdrTarget, float rate) {
@@ -2018,6 +2016,9 @@
}
private void putScreenBrightnessSetting(float brightnessValue, boolean updateCurrent) {
+ if (!isValidBrightnessValue(brightnessValue)) {
+ return;
+ }
if (updateCurrent) {
setCurrentScreenBrightness(brightnessValue);
}
@@ -2064,8 +2065,7 @@
|| mPendingScreenBrightnessSetting < 0.0f)) {
return brightnessSplineChanged;
}
- if (BrightnessSynchronizer.floatEquals(
- mCurrentScreenBrightnessSetting, mPendingScreenBrightnessSetting)) {
+ if (mCurrentScreenBrightnessSetting == mPendingScreenBrightnessSetting) {
mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT;
mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
return brightnessSplineChanged;
diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java
index b58dd38..6af1923 100644
--- a/services/core/java/com/android/server/display/DisplayPowerState.java
+++ b/services/core/java/com/android/server/display/DisplayPowerState.java
@@ -26,8 +26,6 @@
import android.view.Choreographer;
import android.view.Display;
-import com.android.internal.display.BrightnessSynchronizer;
-
import java.io.PrintWriter;
/**
@@ -166,10 +164,11 @@
/**
* Sets the display's SDR brightness.
*
- * @param brightness The brightness, ranges from 0.0f (minimum / off) to 1.0f (brightest).
+ * @param brightness The brightness, ranges from 0.0f (minimum) to 1.0f (brightest), or is -1f
+ * (off).
*/
public void setSdrScreenBrightness(float brightness) {
- if (!BrightnessSynchronizer.floatEquals(mSdrScreenBrightness, brightness)) {
+ if (mSdrScreenBrightness != brightness) {
if (DEBUG) {
Slog.d(TAG, "setSdrScreenBrightness: brightness=" + brightness);
}
@@ -192,10 +191,11 @@
/**
* Sets the display brightness.
*
- * @param brightness The brightness, ranges from 0.0f (minimum / off) to 1.0f (brightest).
+ * @param brightness The brightness, ranges from 0.0f (minimum) to 1.0f (brightest), or is -1f
+ * (off).
*/
public void setScreenBrightness(float brightness) {
- if (!BrightnessSynchronizer.floatEquals(mScreenBrightness, brightness)) {
+ if (mScreenBrightness != brightness) {
if (DEBUG) {
Slog.d(TAG, "setScreenBrightness: brightness=" + brightness);
}
@@ -432,10 +432,8 @@
public boolean setState(int state, float brightnessState, float sdrBrightnessState) {
synchronized (mLock) {
boolean stateChanged = state != mPendingState;
- boolean backlightChanged =
- !BrightnessSynchronizer.floatEquals(brightnessState, mPendingBacklight)
- || !BrightnessSynchronizer.floatEquals(
- sdrBrightnessState, mPendingSdrBacklight);
+ boolean backlightChanged = brightnessState != mPendingBacklight
+ || sdrBrightnessState != mPendingSdrBacklight;
if (stateChanged || backlightChanged) {
if (DEBUG) {
Slog.d(TAG, "Requesting new screen state: state="
@@ -486,10 +484,8 @@
stateChanged = (state != mActualState);
brightnessState = mPendingBacklight;
sdrBrightnessState = mPendingSdrBacklight;
- backlightChanged =
- !BrightnessSynchronizer.floatEquals(brightnessState, mActualBacklight)
- || !BrightnessSynchronizer.floatEquals(
- sdrBrightnessState, mActualSdrBacklight);
+ backlightChanged = brightnessState != mActualBacklight
+ || sdrBrightnessState != mActualSdrBacklight;
if (!stateChanged) {
// State changed applied, notify outer class.
postScreenUpdateThreadSafe();
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 2f17481..f953cc8 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -648,12 +648,11 @@
public Runnable requestDisplayStateLocked(final int state, final float brightnessState,
final float sdrBrightnessState) {
// Assume that the brightness is off if the display is being turned off.
- assert state != Display.STATE_OFF || BrightnessSynchronizer.floatEquals(
- brightnessState, PowerManager.BRIGHTNESS_OFF_FLOAT);
+ assert state != Display.STATE_OFF
+ || brightnessState == PowerManager.BRIGHTNESS_OFF_FLOAT;
final boolean stateChanged = (mState != state);
- final boolean brightnessChanged =
- !(BrightnessSynchronizer.floatEquals(mBrightnessState, brightnessState)
- && BrightnessSynchronizer.floatEquals(mSdrBrightnessState, sdrBrightnessState));
+ final boolean brightnessChanged = mBrightnessState != brightnessState
+ || mSdrBrightnessState != sdrBrightnessState;
if (stateChanged || brightnessChanged) {
final long physicalDisplayId = mPhysicalDisplayId;
final IBinder token = getDisplayTokenLocked();
@@ -807,8 +806,7 @@
}
private float brightnessToBacklight(float brightness) {
- if (BrightnessSynchronizer.floatEquals(
- brightness, PowerManager.BRIGHTNESS_OFF_FLOAT)) {
+ if (brightness == PowerManager.BRIGHTNESS_OFF_FLOAT) {
return PowerManager.BRIGHTNESS_OFF_FLOAT;
} else {
return getDisplayDeviceConfig().getBacklightFromBrightness(brightness);
diff --git a/services/core/java/com/android/server/display/RampAnimator.java b/services/core/java/com/android/server/display/RampAnimator.java
index 20feafa..ed3b15f 100644
--- a/services/core/java/com/android/server/display/RampAnimator.java
+++ b/services/core/java/com/android/server/display/RampAnimator.java
@@ -20,8 +20,6 @@
import android.util.FloatProperty;
import android.view.Choreographer;
-import com.android.internal.display.BrightnessSynchronizer;
-
/**
* A custom animator that progressively updates a property value at
* a given variable rate until it reaches a particular target value.
@@ -157,10 +155,10 @@
}
final float oldCurrentValue = mCurrentValue;
mCurrentValue = mAnimatedValue;
- if (!BrightnessSynchronizer.floatEquals(oldCurrentValue, mCurrentValue)) {
+ if (oldCurrentValue != mCurrentValue) {
mProperty.setValue(mObject, mCurrentValue);
}
- if (!BrightnessSynchronizer.floatEquals(mTargetValue, mCurrentValue)) {
+ if (mTargetValue != mCurrentValue) {
postAnimationCallback();
} else {
mAnimating = false;
diff --git a/services/core/java/com/android/server/location/provider/LocationProviderManager.java b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
index 5c1ce64..8c9068d 100644
--- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java
+++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
@@ -155,7 +155,7 @@
private static final float FASTEST_INTERVAL_JITTER_PERCENTAGE = .10f;
// max absolute jitter allowed for min update interval evaluation
- private static final int MAX_FASTEST_INTERVAL_JITTER_MS = 5 * 1000;
+ private static final int MAX_FASTEST_INTERVAL_JITTER_MS = 30 * 1000;
// minimum amount of request delay in order to respect the delay, below this value the request
// will just be scheduled immediately
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index 73dc8dc..53bf7b8 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -1051,13 +1051,18 @@
final ParsedPackage parsedPackage2 = packageParser.parsePackage(
new File(apexInfo.modulePath), flags, /* useCaches= */ false);
final PackageInfo finalApexPkg = PackageInfoWithoutStateUtils.generate(
- parsedPackage, apexInfo, flags);
+ parsedPackage2, apexInfo, flags);
// Installation was successful, time to update mAllPackagesCache
synchronized (mLock) {
- for (int i = 0, size = mAllPackagesCache.size(); i < size; i++) {
- if (mAllPackagesCache.get(i).equals(existingApexPkg)) {
- mAllPackagesCache.set(i, finalApexPkg);
- break;
+ if (isFactory(existingApexPkg)) {
+ existingApexPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED;
+ mAllPackagesCache.add(finalApexPkg);
+ } else {
+ for (int i = 0, size = mAllPackagesCache.size(); i < size; i++) {
+ if (mAllPackagesCache.get(i).equals(existingApexPkg)) {
+ mAllPackagesCache.set(i, finalApexPkg);
+ break;
+ }
}
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index acc83cf..6adde9a 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -957,7 +957,7 @@
android.Manifest.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION, mInstallerUid)
== PackageManager.PERMISSION_GRANTED);
final int targetPackageUid = mPm.getPackageUid(packageName, 0, userId);
- final boolean isUpdate = targetPackageUid != -1;
+ final boolean isUpdate = targetPackageUid != -1 || isApexSession();
final InstallSourceInfo existingInstallSourceInfo = isUpdate
? mPm.getInstallSourceInfo(packageName)
: null;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 0a7053c..af3cb5b 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -17362,6 +17362,7 @@
} catch (PackageManagerException e) {
request.installResult.setError("APEX installation failed", e);
}
+ invalidatePackageInfoCache();
notifyInstallObserver(request.installResult, request.args.observer);
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index e6adeb3..fb4d96e 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -904,7 +904,9 @@
}
} else {
// handled by single key or another power key policy.
- mSingleKeyGestureDetector.reset();
+ if (!mSingleKeyGestureDetector.isKeyIntercepted(KEYCODE_POWER)) {
+ mSingleKeyGestureDetector.reset();
+ }
}
finishPowerKeyPress();
@@ -918,7 +920,6 @@
}
private void powerPress(long eventTime, int count, boolean beganFromNonInteractive) {
- mCameraGestureTriggered = false;
if (mDefaultDisplayPolicy.isScreenOnEarly() && !mDefaultDisplayPolicy.isScreenOnFully()) {
Slog.i(TAG, "Suppressed redundant power key press while "
+ "already in the process of turning the screen on.");
@@ -1068,24 +1069,18 @@
}
private int getMaxMultiPressPowerCount() {
- // GestureLauncherService could handle power multi tap gesture.
- if (mGestureLauncherService != null
- && mGestureLauncherService.isEmergencyGestureEnabled()) {
- return 5; // EMERGENCY_GESTURE_POWER_TAP_COUNT_THRESHOLD
- }
-
+ // The actual max power button press count is 5
+ // (EMERGENCY_GESTURE_POWER_TAP_COUNT_THRESHOLD), which is coming from
+ // GestureLauncherService.
+ // To speed up the handling of single-press of power button inside SingleKeyGestureDetector,
+ // however, we limit the max count to the number of button presses actually handled by the
+ // SingleKeyGestureDetector.
if (mTriplePressOnPowerBehavior != MULTI_PRESS_POWER_NOTHING) {
return 3;
}
if (mDoublePressOnPowerBehavior != MULTI_PRESS_POWER_NOTHING) {
return 2;
}
-
- if (mGestureLauncherService != null
- && mGestureLauncherService.isCameraDoubleTapPowerEnabled()) {
- return 2; // CAMERA_POWER_TAP_COUNT_THRESHOLD
- }
-
return 1;
}
@@ -1972,7 +1967,6 @@
void onPress(long downTime) {
powerPress(downTime, 1 /*count*/,
mSingleKeyGestureDetector.beganFromNonInteractive());
- finishPowerKeyPress();
}
@Override
@@ -1995,7 +1989,6 @@
@Override
void onMultiPress(long downTime, int count) {
powerPress(downTime, count, mSingleKeyGestureDetector.beganFromNonInteractive());
- finishPowerKeyPress();
}
}
@@ -3849,17 +3842,17 @@
if (mGestureLauncherService == null) {
return false;
}
-
+ mCameraGestureTriggered = false;
final MutableBoolean outLaunched = new MutableBoolean(false);
- final boolean gesturedServiceIntercepted = mGestureLauncherService.interceptPowerKeyDown(
- event, interactive, outLaunched);
- if (outLaunched.value) {
- mCameraGestureTriggered = true;
+ mGestureLauncherService.interceptPowerKeyDown(event, interactive, outLaunched);
+ if (!outLaunched.value) {
+ return false;
}
- if (outLaunched.value && mRequestedOrSleepingDefaultDisplay) {
+ mCameraGestureTriggered = true;
+ if (mRequestedOrSleepingDefaultDisplay) {
mCameraGestureTriggeredDuringGoingToSleep = true;
}
- return gesturedServiceIntercepted;
+ return true;
}
/**
@@ -4232,7 +4225,8 @@
mDefaultDisplayRotation.updateOrientationListener();
if (mKeyguardDelegate != null) {
- mKeyguardDelegate.onFinishedGoingToSleep(pmSleepReason, mCameraGestureTriggered);
+ mKeyguardDelegate.onFinishedGoingToSleep(pmSleepReason,
+ mCameraGestureTriggeredDuringGoingToSleep);
}
if (mDisplayFoldController != null) {
mDisplayFoldController.finishedGoingToSleep();
@@ -4428,6 +4422,8 @@
// Called on the DisplayManager's DisplayPowerController thread.
@Override
public void screenTurnedOn(int displayId) {
+ if (DEBUG_WAKEUP) Slog.i(TAG, "Display " + displayId + " turned on...");
+
if (displayId != DEFAULT_DISPLAY) {
return;
}
diff --git a/services/core/java/com/android/server/policy/SingleKeyGestureDetector.java b/services/core/java/com/android/server/policy/SingleKeyGestureDetector.java
index 3f4d920..1ef2bf9 100644
--- a/services/core/java/com/android/server/policy/SingleKeyGestureDetector.java
+++ b/services/core/java/com/android/server/policy/SingleKeyGestureDetector.java
@@ -272,8 +272,10 @@
if (DEBUG) {
Log.i(TAG, "press key " + KeyEvent.keyCodeToString(event.getKeyCode()));
}
- mActiveRule.onPress(downTime);
- reset();
+ Message msg = mHandler.obtainMessage(MSG_KEY_DELAYED_PRESS, mActiveRule.mKeyCode,
+ 1, downTime);
+ msg.setAsynchronous(true);
+ mHandler.sendMessage(msg);
return true;
}
@@ -316,10 +318,7 @@
}
boolean isKeyIntercepted(int keyCode) {
- if (mActiveRule != null && mActiveRule.shouldInterceptKey(keyCode)) {
- return mHandledByLongPress;
- }
- return false;
+ return mActiveRule != null && mActiveRule.shouldInterceptKey(keyCode);
}
boolean beganFromNonInteractive() {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 64b5fc7..f3dbed5 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -5029,6 +5029,10 @@
// Reset the last saved PiP snap fraction on app stop.
mDisplayContent.mPinnedTaskController.onActivityHidden(mActivityComponent);
mDisplayContent.mUnknownAppVisibilityController.appRemovedOrHidden(this);
+ if (isClientVisible()) {
+ // Though this is usually unlikely to happen, still make sure the client is invisible.
+ setClientVisible(false);
+ }
destroySurfaces();
// Remove any starting window that was added for this app if they are still around.
removeStartingWindow();
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index e2ef82b..a9a25fc 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -86,6 +86,7 @@
import android.app.PendingIntent;
import android.app.ProfilerInfo;
import android.app.WaitResult;
+import android.content.ComponentName;
import android.content.IIntentSender;
import android.content.Intent;
import android.content.IntentSender;
@@ -1221,6 +1222,20 @@
mController.onExecutionComplete(this);
}
+ private boolean isHomeApp(int uid, @Nullable String packageName) {
+ if (mService.mHomeProcess != null) {
+ // Fast check
+ return uid == mService.mHomeProcess.mUid;
+ }
+ if (packageName == null) {
+ return false;
+ }
+ ComponentName activity =
+ mService.getPackageManagerInternalLocked().getDefaultHomeActivity(
+ UserHandle.getUserId(uid));
+ return activity != null && packageName.equals(activity.getPackageName());
+ }
+
boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid,
final String callingPackage, int realCallingUid, int realCallingPid,
WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent,
@@ -1236,7 +1251,7 @@
}
// Always allow home application to start activities.
- if (mService.mHomeProcess != null && callingUid == mService.mHomeProcess.mUid) {
+ if (isHomeApp(callingUid, callingPackage)) {
if (DEBUG_ACTIVITY_STARTS) {
Slog.d(TAG, "Activity start allowed for home app callingUid (" + callingUid + ")");
}
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 737ef33..9e147b1 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -952,7 +952,8 @@
"cleanupAnimation(): Notify animation finished mPendingAnimations=%d "
+ "reorderMode=%d",
mPendingAnimations.size(), reorderMode);
- if (reorderMode != REORDER_MOVE_TO_ORIGINAL_POSITION) {
+ if (reorderMode != REORDER_MOVE_TO_ORIGINAL_POSITION
+ && mTargetActivityRecord != mDisplayContent.topRunningActivity()) {
// Notify the state at the beginning because the removeAnimation may notify the
// transition is finished. This is a signal that there will be a next transition.
mDisplayContent.mFixedRotationTransitionListener.notifyRecentsWillBeTop();
@@ -1029,7 +1030,13 @@
@Override
public void binderDied() {
- cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "binderDied");
+ if (!mCanceled) {
+ cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "binderDied");
+ } else {
+ // If we are already canceled but with a screenshot, and are waiting for the
+ // cleanupScreenshot() callback, then force-finish the animation now
+ continueDeferredCancelAnimation();
+ }
synchronized (mService.getWindowManagerLock()) {
// Clear associated input consumers on runner death
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index e553075..fd71d1b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -17557,9 +17557,7 @@
}
final boolean usbEnabled;
synchronized (getLockObject()) {
- final ActiveAdmin admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked(
- UserHandle.USER_SYSTEM);
- usbEnabled = admin != null && admin.mUsbDataSignalingEnabled;
+ usbEnabled = isUsbDataSignalingEnabledInternalLocked();
}
if (!mInjector.binderWithCleanCallingIdentity(
() -> mInjector.getUsbManager().enableUsbDataSignal(usbEnabled))) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index d487483..91d4f7e 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -552,6 +552,7 @@
if (maxFd > enableThreshold) {
// Do a manual GC to clean up fds that are hanging around as garbage.
System.gc();
+ System.runFinalization();
maxFd = getMaxFd();
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/appsearch/AppSearchConfigTest.java b/services/tests/mockingservicestests/src/com/android/server/appsearch/AppSearchConfigTest.java
index ffb1dd9..8336663 100644
--- a/services/tests/mockingservicestests/src/com/android/server/appsearch/AppSearchConfigTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/appsearch/AppSearchConfigTest.java
@@ -54,6 +54,12 @@
AppSearchConfig.DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES);
assertThat(appSearchConfig.getCachedLimitConfigMaxDocumentCount()).isEqualTo(
AppSearchConfig.DEFAULT_LIMIT_CONFIG_MAX_DOCUMENT_COUNT);
+ assertThat(appSearchConfig.getCachedBytesOptimizeThreshold()).isEqualTo(
+ AppSearchConfig.DEFAULT_BYTES_OPTIMIZE_THRESHOLD);
+ assertThat(appSearchConfig.getCachedTimeOptimizeThresholdMs()).isEqualTo(
+ AppSearchConfig.DEFAULT_TIME_OPTIMIZE_THRESHOLD_MILLIS);
+ assertThat(appSearchConfig.getCachedDocCountOptimizeThreshold()).isEqualTo(
+ AppSearchConfig.DEFAULT_DOC_COUNT_OPTIMIZE_THRESHOLD);
}
@Test
@@ -163,10 +169,8 @@
/**
* Tests if we fall back to {@link AppSearchConfig#DEFAULT_SAMPLING_INTERVAL} if both default
- * sampling
- * interval and custom value are not set in DeviceConfig, and there is some other sampling
- * interval
- * set.
+ * sampling interval and custom value are not set in DeviceConfig, and there is some other
+ * sampling interval set.
*/
@Test
public void testFallbackToDefaultSamplingValue_useHardCodedDefault() {
@@ -269,7 +273,7 @@
}
@Test
- public void testCustomizedValue() {
+ public void testCustomizedValue_maxDocument() {
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
AppSearchConfig.KEY_LIMIT_CONFIG_MAX_DOCUMENT_SIZE_BYTES,
Integer.toString(2001),
@@ -285,6 +289,64 @@
}
@Test
+ public void testCustomizedValue_optimizeThreshold() {
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
+ AppSearchConfig.KEY_BYTES_OPTIMIZE_THRESHOLD,
+ Integer.toString(147147),
+ false);
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
+ AppSearchConfig.KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS,
+ Integer.toString(258258),
+ false);
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
+ AppSearchConfig.KEY_DOC_COUNT_OPTIMIZE_THRESHOLD,
+ Integer.toString(369369),
+ false);
+
+ AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
+
+ assertThat(appSearchConfig.getCachedBytesOptimizeThreshold()).isEqualTo(147147);
+ assertThat(appSearchConfig.getCachedTimeOptimizeThresholdMs()).isEqualTo(258258);
+ assertThat(appSearchConfig.getCachedDocCountOptimizeThreshold()).isEqualTo(369369);
+ }
+
+ @Test
+ public void testCustomizedValueOverride_optimizeThreshold() {
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
+ AppSearchConfig.KEY_BYTES_OPTIMIZE_THRESHOLD,
+ Integer.toString(147147),
+ false);
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
+ AppSearchConfig.KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS,
+ Integer.toString(258258),
+ false);
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
+ AppSearchConfig.KEY_DOC_COUNT_OPTIMIZE_THRESHOLD,
+ Integer.toString(369369),
+ false);
+
+ AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
+
+ // Override
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
+ AppSearchConfig.KEY_BYTES_OPTIMIZE_THRESHOLD,
+ Integer.toString(741741),
+ false);
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
+ AppSearchConfig.KEY_TIME_OPTIMIZE_THRESHOLD_MILLIS,
+ Integer.toString(852852),
+ false);
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH,
+ AppSearchConfig.KEY_DOC_COUNT_OPTIMIZE_THRESHOLD,
+ Integer.toString(963963),
+ false);
+
+ assertThat(appSearchConfig.getCachedBytesOptimizeThreshold()).isEqualTo(741741);
+ assertThat(appSearchConfig.getCachedTimeOptimizeThresholdMs()).isEqualTo(852852);
+ assertThat(appSearchConfig.getCachedDocCountOptimizeThreshold()).isEqualTo(963963);
+ }
+
+ @Test
public void testNotUsable_afterClose() {
AppSearchConfig appSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
@@ -302,5 +364,14 @@
Assert.assertThrows("Trying to use a closed AppSearchConfig instance.",
IllegalStateException.class,
() -> appSearchConfig.getCachedSamplingIntervalForPutDocumentStats());
+ Assert.assertThrows("Trying to use a closed AppSearchConfig instance.",
+ IllegalStateException.class,
+ () -> appSearchConfig.getCachedBytesOptimizeThreshold());
+ Assert.assertThrows("Trying to use a closed AppSearchConfig instance.",
+ IllegalStateException.class,
+ () -> appSearchConfig.getCachedTimeOptimizeThresholdMs());
+ Assert.assertThrows("Trying to use a closed AppSearchConfig instance.",
+ IllegalStateException.class,
+ () -> appSearchConfig.getCachedDocCountOptimizeThreshold());
}
}
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/FrameworkOptimizeStrategyTest.java b/services/tests/servicestests/src/com/android/server/appsearch/FrameworkOptimizeStrategyTest.java
similarity index 74%
rename from services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/FrameworkOptimizeStrategyTest.java
rename to services/tests/servicestests/src/com/android/server/appsearch/FrameworkOptimizeStrategyTest.java
index de71d21..8389c85 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/FrameworkOptimizeStrategyTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/FrameworkOptimizeStrategyTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package com.android.server.appsearch;
-package com.android.server.appsearch.external.localstorage;
-
-import static com.android.server.appsearch.external.localstorage.FrameworkOptimizeStrategy.BYTES_OPTIMIZE_THRESHOLD;
-import static com.android.server.appsearch.external.localstorage.FrameworkOptimizeStrategy.DOC_COUNT_OPTIMIZE_THRESHOLD;
-import static com.android.server.appsearch.external.localstorage.FrameworkOptimizeStrategy.TIME_OPTIMIZE_THRESHOLD_MILLIS;
+import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
import static com.google.common.truth.Truth.assertThat;
@@ -28,26 +25,17 @@
import org.junit.Test;
public class FrameworkOptimizeStrategyTest {
- FrameworkOptimizeStrategy mFrameworkOptimizeStrategy = new FrameworkOptimizeStrategy();
-
- @Test
- public void testShouldOptimize_docCountThreshold() {
- GetOptimizeInfoResultProto optimizeInfo =
- GetOptimizeInfoResultProto.newBuilder()
- .setTimeSinceLastOptimizeMs(0)
- .setEstimatedOptimizableBytes(BYTES_OPTIMIZE_THRESHOLD)
- .setOptimizableDocs(0)
- .setStatus(StatusProto.newBuilder().setCode(StatusProto.Code.OK).build())
- .build();
- assertThat(mFrameworkOptimizeStrategy.shouldOptimize(optimizeInfo)).isTrue();
- }
+ AppSearchConfig mAppSearchConfig = AppSearchConfig.create(DIRECT_EXECUTOR);
+ FrameworkOptimizeStrategy mFrameworkOptimizeStrategy =
+ new FrameworkOptimizeStrategy(mAppSearchConfig);
@Test
public void testShouldOptimize_byteThreshold() {
GetOptimizeInfoResultProto optimizeInfo =
GetOptimizeInfoResultProto.newBuilder()
- .setTimeSinceLastOptimizeMs(TIME_OPTIMIZE_THRESHOLD_MILLIS)
- .setEstimatedOptimizableBytes(0)
+ .setTimeSinceLastOptimizeMs(0)
+ .setEstimatedOptimizableBytes(
+ mAppSearchConfig.getCachedBytesOptimizeThreshold())
.setOptimizableDocs(0)
.setStatus(StatusProto.newBuilder().setCode(StatusProto.Code.OK).build())
.build();
@@ -58,9 +46,23 @@
public void testShouldNotOptimize_timeThreshold() {
GetOptimizeInfoResultProto optimizeInfo =
GetOptimizeInfoResultProto.newBuilder()
+ .setTimeSinceLastOptimizeMs(
+ mAppSearchConfig.getCachedTimeOptimizeThresholdMs())
+ .setEstimatedOptimizableBytes(0)
+ .setOptimizableDocs(0)
+ .setStatus(StatusProto.newBuilder().setCode(StatusProto.Code.OK).build())
+ .build();
+ assertThat(mFrameworkOptimizeStrategy.shouldOptimize(optimizeInfo)).isTrue();
+ }
+
+ @Test
+ public void testShouldOptimize_docCountThreshold() {
+ GetOptimizeInfoResultProto optimizeInfo =
+ GetOptimizeInfoResultProto.newBuilder()
.setTimeSinceLastOptimizeMs(0)
.setEstimatedOptimizableBytes(0)
- .setOptimizableDocs(DOC_COUNT_OPTIMIZE_THRESHOLD)
+ .setOptimizableDocs(
+ mAppSearchConfig.getCachedDocCountOptimizeThreshold())
.setStatus(StatusProto.newBuilder().setCode(StatusProto.Code.OK).build())
.build();
assertThat(mFrameworkOptimizeStrategy.shouldOptimize(optimizeInfo)).isTrue();
diff --git a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
index fb768a8..8b8a7e6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
@@ -37,6 +37,7 @@
import android.apex.ApexSessionParams;
import android.apex.IApexService;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
@@ -349,9 +350,9 @@
}
@Test
- public void testInstallPackage() throws Exception {
+ public void testInstallPackage_activeOnSystem() throws Exception {
ApexInfo activeApexInfo = createApexInfo("test.apex_rebootless", 1, /* isActive= */ true,
- /* isFactory= */ false, extractResource("test.apex_rebootless_v1",
+ /* isFactory= */ true, extractResource("test.apex_rebootless_v1",
"test.rebootless_apex_v1.apex"));
when(mApexService.getAllPackages()).thenReturn(new ApexInfo[]{activeApexInfo});
mApexManager.scanApexPackagesTraced(mPackageParser2,
@@ -369,6 +370,55 @@
ApexManager.MATCH_ACTIVE_PACKAGE);
assertThat(newInfo.applicationInfo.sourceDir).isEqualTo(finalApex.getAbsolutePath());
assertThat(newInfo.applicationInfo.longVersionCode).isEqualTo(2);
+ assertThat(newInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM).isEqualTo(0);
+ assertThat(newInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
+ .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
+
+ PackageInfo factoryInfo = mApexManager.getPackageInfo("test.apex.rebootless",
+ ApexManager.MATCH_FACTORY_PACKAGE);
+ assertThat(factoryInfo.applicationInfo.sourceDir).isEqualTo(activeApexInfo.modulePath);
+ assertThat(factoryInfo.applicationInfo.longVersionCode).isEqualTo(1);
+ assertThat(factoryInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
+ .isEqualTo(ApplicationInfo.FLAG_SYSTEM);
+ assertThat(factoryInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED).isEqualTo(0);
+ }
+
+ @Test
+ public void testInstallPackage_activeOnData() throws Exception {
+ ApexInfo factoryApexInfo = createApexInfo("test.apex_rebootless", 1, /* isActive= */ false,
+ /* isFactory= */ true, extractResource("test.apex_rebootless_v1",
+ "test.rebootless_apex_v1.apex"));
+ ApexInfo activeApexInfo = createApexInfo("test.apex_rebootless", 1, /* isActive= */ true,
+ /* isFactory= */ false, extractResource("test.apex.rebootless@1",
+ "test.rebootless_apex_v1.apex"));
+ when(mApexService.getAllPackages())
+ .thenReturn(new ApexInfo[]{factoryApexInfo, activeApexInfo});
+ mApexManager.scanApexPackagesTraced(mPackageParser2,
+ ParallelPackageParser.makeExecutorService());
+
+ File finalApex = extractResource("test.rebootles_apex_v2", "test.rebootless_apex_v2.apex");
+ ApexInfo newApexInfo = createApexInfo("test.apex_rebootless", 2, /* isActive= */ true,
+ /* isFactory= */ false, finalApex);
+ when(mApexService.installAndActivatePackage(anyString())).thenReturn(newApexInfo);
+
+ File installedApex = extractResource("installed", "test.rebootless_apex_v2.apex");
+ mApexManager.installPackage(installedApex, mPackageParser2);
+
+ PackageInfo newInfo = mApexManager.getPackageInfo("test.apex.rebootless",
+ ApexManager.MATCH_ACTIVE_PACKAGE);
+ assertThat(newInfo.applicationInfo.sourceDir).isEqualTo(finalApex.getAbsolutePath());
+ assertThat(newInfo.applicationInfo.longVersionCode).isEqualTo(2);
+ assertThat(newInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM).isEqualTo(0);
+ assertThat(newInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
+ .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
+
+ PackageInfo factoryInfo = mApexManager.getPackageInfo("test.apex.rebootless",
+ ApexManager.MATCH_FACTORY_PACKAGE);
+ assertThat(factoryInfo.applicationInfo.sourceDir).isEqualTo(factoryApexInfo.modulePath);
+ assertThat(factoryInfo.applicationInfo.longVersionCode).isEqualTo(1);
+ assertThat(factoryInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
+ .isEqualTo(ApplicationInfo.FLAG_SYSTEM);
+ assertThat(factoryInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED).isEqualTo(0);
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 0a36af2..d0588a3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -348,6 +348,7 @@
invocation -> {
throw new RuntimeException("Not stubbed");
});
+ doReturn(null).when(mMockPackageManager).getDefaultHomeActivity(anyInt());
doReturn(mMockPackageManager).when(mAtm).getPackageManagerInternalLocked();
doReturn(false).when(mMockPackageManager).isInstantAppInstallerComponent(any());
doReturn(null).when(mMockPackageManager).resolveIntent(any(), any(), anyInt(), anyInt(),
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index a034ac2..d88fbee 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -307,6 +307,29 @@
}
@Test
+ public void testBinderDiedAfterCancelWithDeferredScreenshot() throws Exception {
+ mWm.setRecentsAnimationController(mController);
+ final ActivityRecord homeActivity = createHomeActivity();
+ final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
+ final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, activity, "win1");
+ activity.addWindow(win1);
+
+ initializeRecentsAnimationController(mController, homeActivity);
+ mController.setWillFinishToHome(true);
+
+ // Verify cancel is called with a snapshot and that we've created an overlay
+ spyOn(mWm.mTaskSnapshotController);
+ doReturn(mMockTaskSnapshot).when(mWm.mTaskSnapshotController).getSnapshot(anyInt(),
+ anyInt(), eq(false) /* restoreFromDisk */, eq(false) /* isLowResolution */);
+ mController.cancelAnimationWithScreenshot(true /* screenshot */);
+ verify(mMockRunner).onAnimationCanceled(any());
+
+ // Simulate process crashing and ensure the animation is still canceled
+ mController.binderDied();
+ verify(mAnimationCallbacks).onAnimationFinished(REORDER_KEEP_IN_PLACE, false);
+ }
+
+ @Test
public void testRecentViewInFixedPortraitWhenTopAppInLandscape() {
unblockDisplayRotation(mDefaultDisplay);
mWm.setRecentsAnimationController(mController);
@@ -701,6 +724,12 @@
// Continue the animation (simulating a call to cleanupScreenshot())
mController.continueDeferredCancelAnimation();
verify(mAnimationCallbacks).onAnimationFinished(REORDER_MOVE_TO_TOP, false);
+
+ // Assume home was moved to front so will-be-top callback should not be called.
+ homeActivity.moveFocusableActivityToTop("test");
+ spyOn(mDefaultDisplay.mFixedRotationTransitionListener);
+ mController.cleanupAnimation(REORDER_MOVE_TO_TOP);
+ verify(mDefaultDisplay.mFixedRotationTransitionListener, never()).notifyRecentsWillBeTop();
}
private ActivityRecord createHomeActivity() {
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index d6c0469..ec28040 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -385,29 +385,16 @@
* @param none
*/
private void updateUsbHalVersion() {
- android.hardware.usb.V1_3.IUsb usbProxy_V1_3 =
- android.hardware.usb.V1_3.IUsb.castFrom(mProxy);
- if (usbProxy_V1_3 != null) {
+ if (android.hardware.usb.V1_3.IUsb.castFrom(mProxy) != null) {
mCurrentUsbHalVersion = UsbManager.USB_HAL_V1_3;
- return;
- }
-
- android.hardware.usb.V1_2.IUsb usbProxy_V1_2 =
- android.hardware.usb.V1_2.IUsb.castFrom(mProxy);
- if (usbProxy_V1_2 != null) {
+ } else if (android.hardware.usb.V1_2.IUsb.castFrom(mProxy) != null) {
mCurrentUsbHalVersion = UsbManager.USB_HAL_V1_2;
- return;
- }
-
- android.hardware.usb.V1_1.IUsb usbProxy_V1_1 =
- android.hardware.usb.V1_1.IUsb.castFrom(mProxy);
- if (usbProxy_V1_1 != null) {
+ } else if (android.hardware.usb.V1_1.IUsb.castFrom(mProxy) != null) {
mCurrentUsbHalVersion = UsbManager.USB_HAL_V1_1;
- return;
+ } else {
+ mCurrentUsbHalVersion = UsbManager.USB_HAL_V1_0;
}
-
- mCurrentUsbHalVersion = UsbManager.USB_HAL_V1_0;
- return;
+ logAndPrint(Log.INFO, null, "USB HAL version: " + mCurrentUsbHalVersion);
}
public void setPortRoles(String portId, int newPowerRole, int newDataRole,
@@ -850,7 +837,7 @@
mProxy.linkToDeath(new DeathRecipient(pw), USB_HAL_DEATH_COOKIE);
mProxy.setCallback(mHALCallback);
mProxy.queryPortStatus();
- mCurrentUsbHalVersion = UsbManager.USB_HAL_V1_0;
+ updateUsbHalVersion();
} catch (NoSuchElementException e) {
logAndPrintException(pw, "connectToProxy: usb hal service not found."
+ " Did the service fail to start?", e);
@@ -1183,7 +1170,6 @@
case MSG_SYSTEM_READY: {
mNotificationManager = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
- updateUsbHalVersion();
break;
}
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 666265e..e408cfc 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -16,20 +16,28 @@
package com.android.server.voiceinteraction;
+import static android.Manifest.permission.CAPTURE_AUDIO_HOTWORD;
+import static android.Manifest.permission.RECORD_AUDIO;
import static android.service.voice.HotwordDetectionService.AUDIO_SOURCE_EXTERNAL;
import static android.service.voice.HotwordDetectionService.AUDIO_SOURCE_MICROPHONE;
import static android.service.voice.HotwordDetectionService.INITIALIZATION_STATUS_UNKNOWN;
import static android.service.voice.HotwordDetectionService.KEY_INITIALIZATION_STATUS;
+import static com.android.server.voiceinteraction.SoundTriggerSessionPermissionsDecorator.enforcePermissionForPreflight;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.AppOpsManager;
import android.content.ComponentName;
import android.content.ContentCaptureOptions;
import android.content.Context;
import android.content.Intent;
+import android.content.PermissionChecker;
import android.hardware.soundtrigger.IRecognitionStatusCallback;
import android.hardware.soundtrigger.SoundTrigger;
import android.media.AudioFormat;
+import android.media.permission.Identity;
+import android.media.permission.PermissionUtil;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
@@ -46,6 +54,7 @@
import android.service.voice.IHotwordDetectionService;
import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback;
import android.service.voice.VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity;
+import android.text.TextUtils;
import android.util.Pair;
import android.util.Slog;
import android.view.contentcapture.IContentCaptureManager;
@@ -107,6 +116,10 @@
private ScheduledFuture<?> mCancellationTaskFuture;
+ /** Identity used for attributing app ops when delivering data to the Interactor. */
+ @GuardedBy("mLock")
+ @Nullable
+ private final Identity mVoiceInteractorIdentity;
@GuardedBy("mLock")
private ParcelFileDescriptor mCurrentAudioSink;
@GuardedBy("mLock")
@@ -117,12 +130,13 @@
private IBinder mAudioFlinger;
HotwordDetectionConnection(Object lock, Context context, int voiceInteractionServiceUid,
- ComponentName serviceName, int userId, boolean bindInstantServiceAllowed,
- @Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory,
- IHotwordRecognitionStatusCallback callback) {
+ Identity voiceInteractorIdentity, ComponentName serviceName, int userId,
+ boolean bindInstantServiceAllowed, @Nullable PersistableBundle options,
+ @Nullable SharedMemory sharedMemory, IHotwordRecognitionStatusCallback callback) {
mLock = lock;
mContext = context;
mVoiceInteractionServiceUid = voiceInteractionServiceUid;
+ mVoiceInteractorIdentity = voiceInteractorIdentity;
mDetectionComponentName = serviceName;
mUser = userId;
final Intent intent = new Intent(HotwordDetectionService.SERVICE_INTERFACE);
@@ -310,6 +324,7 @@
}
synchronized (mLock) {
if (mPerformingSoftwareHotwordDetection) {
+ enforcePermissionsForDataDelivery();
mSoftwareCallback.onDetected(result, null, null);
mPerformingSoftwareHotwordDetection = false;
if (result != null) {
@@ -404,6 +419,7 @@
synchronized (mLock) {
if (mValidatingDspTrigger) {
mValidatingDspTrigger = false;
+ enforcePermissionsForDataDelivery();
externalCallback.onKeyphraseDetected(recognitionEvent, result);
if (result != null) {
Slog.i(TAG, "Egressed " + HotwordDetectedResult.getUsageSize(result)
@@ -461,6 +477,7 @@
return;
}
mValidatingDspTrigger = false;
+ enforcePermissionsForDataDelivery();
externalCallback.onKeyphraseDetected(recognitionEvent, result);
if (result != null) {
Slog.i(TAG, "Egressed " + HotwordDetectedResult.getUsageSize(result)
@@ -575,8 +592,7 @@
if (DEBUG) {
Slog.d(TAG, "onKeyphraseDetected recognitionEvent : " + recognitionEvent);
}
- final boolean useHotwordDetectionService = mHotwordDetectionConnection != null
- && mHotwordDetectionConnection.isBound();
+ final boolean useHotwordDetectionService = mHotwordDetectionConnection != null;
if (useHotwordDetectionService) {
mRecognitionEvent = recognitionEvent;
mHotwordDetectionConnection.detectFromDspSource(
@@ -692,7 +708,7 @@
throws RemoteException {
bestEffortClose(serviceAudioSink);
bestEffortClose(serviceAudioSource);
- // TODO: noteOp here.
+ enforcePermissionsForDataDelivery();
callback.onDetected(triggerResult, null /* audioFormat */,
null /* audioStream */);
if (triggerResult != null) {
@@ -872,4 +888,42 @@
}
}
}
+
+ // TODO: Share this code with SoundTriggerMiddlewarePermission.
+ private void enforcePermissionsForDataDelivery() {
+ Binder.withCleanCallingIdentity(() -> {
+ enforcePermissionForPreflight(mContext, mVoiceInteractorIdentity, RECORD_AUDIO);
+ int hotwordOp = AppOpsManager.strOpToOp(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD);
+ mContext.getSystemService(AppOpsManager.class).noteOpNoThrow(hotwordOp,
+ mVoiceInteractorIdentity.uid, mVoiceInteractorIdentity.packageName,
+ mVoiceInteractorIdentity.attributionTag, OP_MESSAGE);
+ enforcePermissionForDataDelivery(mContext, mVoiceInteractorIdentity,
+ CAPTURE_AUDIO_HOTWORD, OP_MESSAGE);
+ });
+ }
+
+ /**
+ * Throws a {@link SecurityException} iff the given identity has given permission to receive
+ * data.
+ *
+ * @param context A {@link Context}, used for permission checks.
+ * @param identity The identity to check.
+ * @param permission The identifier of the permission we want to check.
+ * @param reason The reason why we're requesting the permission, for auditing purposes.
+ */
+ private static void enforcePermissionForDataDelivery(@NonNull Context context,
+ @NonNull Identity identity,
+ @NonNull String permission, @NonNull String reason) {
+ final int status = PermissionUtil.checkPermissionForDataDelivery(context, identity,
+ permission, reason);
+ if (status != PermissionChecker.PERMISSION_GRANTED) {
+ throw new SecurityException(
+ TextUtils.formatSimple("Failed to obtain permission %s for identity %s",
+ permission,
+ SoundTriggerSessionPermissionsDecorator.toString(identity)));
+ }
+ }
+
+ private static final String OP_MESSAGE =
+ "Providing hotword detection result to VoiceInteractionService";
};
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java
index bb7ca16..b9e1fcd 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java
@@ -124,7 +124,7 @@
* @param identity The identity to check.
* @param permission The identifier of the permission we want to check.
*/
- private static void enforcePermissionForPreflight(@NonNull Context context,
+ static void enforcePermissionForPreflight(@NonNull Context context,
@NonNull Identity identity, @NonNull String permission) {
final int status = PermissionUtil.checkPermissionForPreflight(context, identity,
permission);
@@ -144,7 +144,7 @@
}
}
- private static String toString(Identity identity) {
+ static String toString(Identity identity) {
return "{uid=" + identity.uid
+ " pid=" + identity.pid
+ " packageName=" + identity.packageName
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 91d17f7..ccf4267 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -1101,8 +1101,11 @@
//----------------- Hotword Detection/Validation APIs --------------------------------//
@Override
- public void updateState(@Nullable PersistableBundle options,
- @Nullable SharedMemory sharedMemory, IHotwordRecognitionStatusCallback callback) {
+ public void updateState(
+ @NonNull Identity voiceInteractorIdentity,
+ @Nullable PersistableBundle options,
+ @Nullable SharedMemory sharedMemory,
+ IHotwordRecognitionStatusCallback callback) {
enforceCallingPermission(Manifest.permission.MANAGE_HOTWORD_DETECTION);
synchronized (this) {
enforceIsCurrentVoiceInteractionService();
@@ -1111,9 +1114,14 @@
Slog.w(TAG, "updateState without running voice interaction service");
return;
}
+
+ voiceInteractorIdentity.uid = Binder.getCallingUid();
+ voiceInteractorIdentity.pid = Binder.getCallingPid();
+
final long caller = Binder.clearCallingIdentity();
try {
- mImpl.updateStateLocked(options, sharedMemory, callback);
+ mImpl.updateStateLocked(
+ voiceInteractorIdentity, options, sharedMemory, callback);
} finally {
Binder.restoreCallingIdentity(caller);
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 89c5a72..6be47e1 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -42,6 +42,7 @@
import android.hardware.soundtrigger.IRecognitionStatusCallback;
import android.hardware.soundtrigger.SoundTrigger;
import android.media.AudioFormat;
+import android.media.permission.Identity;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -405,8 +406,11 @@
return mInfo.getSupportsLocalInteraction();
}
- public void updateStateLocked(@Nullable PersistableBundle options,
- @Nullable SharedMemory sharedMemory, IHotwordRecognitionStatusCallback callback) {
+ public void updateStateLocked(
+ @NonNull Identity voiceInteractorIdentity,
+ @Nullable PersistableBundle options,
+ @Nullable SharedMemory sharedMemory,
+ IHotwordRecognitionStatusCallback callback) {
if (DEBUG) {
Slog.d(TAG, "updateStateLocked");
}
@@ -447,8 +451,9 @@
if (mHotwordDetectionConnection == null) {
mHotwordDetectionConnection = new HotwordDetectionConnection(mServiceStub, mContext,
- mInfo.getServiceInfo().applicationInfo.uid, mHotwordDetectionComponentName,
- mUser, /* bindInstantServiceAllowed= */ false, options, sharedMemory, callback);
+ mInfo.getServiceInfo().applicationInfo.uid, voiceInteractorIdentity,
+ mHotwordDetectionComponentName, mUser, /* bindInstantServiceAllowed= */ false,
+ options, sharedMemory, callback);
} else {
mHotwordDetectionConnection.updateStateLocked(options, sharedMemory);
}
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index 7ba6f36..53922ed 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -37,6 +37,7 @@
import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.IIntegerConsumer;
@@ -447,8 +448,9 @@
executor.execute(() -> stateCallback.accept(result));
}
});
- } catch (RemoteException e) {
- throw e.rethrowAsRuntimeException();
+ } catch (ServiceSpecificException | RemoteException e) {
+ Log.w("ImsMmTelManager", "Error getting registration state: " + e);
+ executor.execute(() -> stateCallback.accept(REGISTRATION_STATE_NOT_REGISTERED));
}
}
@@ -488,8 +490,10 @@
executor.execute(() -> transportTypeCallback.accept(result));
}
});
- } catch (RemoteException e) {
- throw e.rethrowAsRuntimeException();
+ } catch (ServiceSpecificException | RemoteException e) {
+ Log.w("ImsMmTelManager", "Error getting transport type: " + e);
+ executor.execute(() -> transportTypeCallback.accept(
+ AccessNetworkConstants.TRANSPORT_TYPE_INVALID));
}
}
diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java
index 3700026..91c5324 100644
--- a/telephony/java/android/telephony/ims/ImsRcsManager.java
+++ b/telephony/java/android/telephony/ims/ImsRcsManager.java
@@ -302,8 +302,10 @@
executor.execute(() -> stateCallback.accept(result));
}
});
- } catch (RemoteException e) {
- throw e.rethrowAsRuntimeException();
+ } catch (ServiceSpecificException | RemoteException e) {
+ Log.w(TAG, "Get registration state error: " + e);
+ executor.execute(() -> stateCallback.accept(
+ RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED));
}
}
@@ -346,8 +348,10 @@
executor.execute(() -> transportTypeCallback.accept(result));
}
});
- } catch (RemoteException e) {
- throw e.rethrowAsRuntimeException();
+ } catch (ServiceSpecificException | RemoteException e) {
+ Log.w(TAG, "Get registration transport type error: " + e);
+ executor.execute(() -> transportTypeCallback.accept(
+ AccessNetworkConstants.TRANSPORT_TYPE_INVALID));
}
}
diff --git a/tests/StagedInstallTest/Android.bp b/tests/StagedInstallTest/Android.bp
index c563e06..1aa0499 100644
--- a/tests/StagedInstallTest/Android.bp
+++ b/tests/StagedInstallTest/Android.bp
@@ -33,6 +33,8 @@
java_resources: [
":com.android.apex.apkrollback.test_v2",
":StagedInstallTestApexV2_WrongSha",
+ ":test.rebootless_apex_v1",
+ ":test.rebootless_apex_v2",
],
}
@@ -54,6 +56,7 @@
":com.android.apex.cts.shim.v2_prebuilt",
":StagedInstallTestApexV2_WrongSha",
":TestAppAv1",
+ ":test.rebootless_apex_v1",
],
test_suites: ["general-tests"],
test_config: "StagedInstallInternalTest.xml",
diff --git a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
index 6a62304..9cdaef7 100644
--- a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
@@ -23,7 +23,10 @@
import static com.google.common.truth.Truth.assertWithMessage;
import android.Manifest;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
+import android.content.pm.PackageManager;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -192,6 +195,68 @@
assertSessionFailedWithMessage(sessionId, "has unexpected SHA512 hash");
}
+ @Test
+ public void testRebootlessUpdates() throws Exception {
+ InstallUtils.dropShellPermissionIdentity();
+ InstallUtils.adoptShellPermissionIdentity(Manifest.permission.INSTALL_PACKAGE_UPDATES);
+
+ final PackageManager pm =
+ InstrumentationRegistry.getInstrumentation().getContext().getPackageManager();
+ {
+ PackageInfo apex = pm.getPackageInfo("test.apex.rebootless", PackageManager.MATCH_APEX);
+ assertThat(apex.getLongVersionCode()).isEqualTo(1);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
+ .isEqualTo(ApplicationInfo.FLAG_SYSTEM);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
+ .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
+ assertThat(apex.applicationInfo.sourceDir).startsWith("/system/apex");
+ }
+
+ TestApp apex1 = new TestApp("TestRebootlessApexV1", "test.apex.rebootless", 1,
+ /* isApex= */ true, "test.rebootless_apex_v1.apex");
+ Install.single(apex1).commit();
+
+ {
+ PackageInfo apex = pm.getPackageInfo("test.apex.rebootless", PackageManager.MATCH_APEX);
+ assertThat(apex.getLongVersionCode()).isEqualTo(1);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM).isEqualTo(0);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
+ .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
+ assertThat(apex.applicationInfo.sourceDir).startsWith("/data/apex/active");
+ }
+ {
+ PackageInfo apex = pm.getPackageInfo("test.apex.rebootless",
+ PackageManager.MATCH_APEX | PackageManager.MATCH_FACTORY_ONLY);
+ assertThat(apex.getLongVersionCode()).isEqualTo(1);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
+ .isEqualTo(ApplicationInfo.FLAG_SYSTEM);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED).isEqualTo(0);
+ assertThat(apex.applicationInfo.sourceDir).startsWith("/system/apex");
+ }
+
+ TestApp apex2 = new TestApp("TestRebootlessApexV1", "test.apex.rebootless", 2,
+ /* isApex= */ true, "test.rebootless_apex_v2.apex");
+ Install.single(apex2).commit();
+
+ {
+ PackageInfo apex = pm.getPackageInfo("test.apex.rebootless", PackageManager.MATCH_APEX);
+ assertThat(apex.getLongVersionCode()).isEqualTo(2);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM).isEqualTo(0);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
+ .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
+ assertThat(apex.applicationInfo.sourceDir).startsWith("/data/apex/active");
+ }
+ {
+ PackageInfo apex = pm.getPackageInfo("test.apex.rebootless",
+ PackageManager.MATCH_APEX | PackageManager.MATCH_FACTORY_ONLY);
+ assertThat(apex.getLongVersionCode()).isEqualTo(1);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
+ .isEqualTo(ApplicationInfo.FLAG_SYSTEM);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED).isEqualTo(0);
+ assertThat(apex.applicationInfo.sourceDir).startsWith("/system/apex");
+ }
+ }
+
private static void assertSessionFailedWithMessage(int sessionId, String msg) {
assertSessionState(sessionId, (session) -> {
assertThat(session.isStagedSessionFailed()).isTrue();
diff --git a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
index 5d7fdd1..e19f97b 100644
--- a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
@@ -85,7 +85,9 @@
}
deleteFiles("/system/apex/" + APK_IN_APEX_TESTAPEX_NAME + "*.apex",
"/data/apex/active/" + APK_IN_APEX_TESTAPEX_NAME + "*.apex",
- "/data/apex/active/" + SHIM_APEX_PACKAGE_NAME + "*.apex");
+ "/data/apex/active/" + SHIM_APEX_PACKAGE_NAME + "*.apex",
+ "/system/apex/test.rebootless_apex_v1.apex",
+ "/data/apex/active/test.apex.rebootless*.apex");
}
@Before
@@ -124,9 +126,8 @@
}
}
- private void pushTestApex() throws Exception {
+ private void pushTestApex(String fileName) throws Exception {
CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
- final String fileName = APK_IN_APEX_TESTAPEX_NAME + "_v1.apex";
final File apex = buildHelper.getTestFile(fileName);
if (!getDevice().isAdbRoot()) {
getDevice().enableAdbRoot();
@@ -142,7 +143,7 @@
@Test
@LargeTest
public void testDuplicateApkInApexShouldFail() throws Exception {
- pushTestApex();
+ pushTestApex(APK_IN_APEX_TESTAPEX_NAME + "_v1.apex");
runPhase("testDuplicateApkInApexShouldFail_Commit");
getDevice().reboot();
runPhase("testDuplicateApkInApexShouldFail_Verify");
@@ -344,6 +345,12 @@
runPhase("testApexActivationFailureIsCapturedInSession_Verify");
}
+ @Test
+ public void testRebootlessUpdates() throws Exception {
+ pushTestApex("test.rebootless_apex_v1.apex");
+ runPhase("testRebootlessUpdates");
+ }
+
private List<String> getStagingDirectories() throws DeviceNotAvailableException {
String baseDir = "/data/app-staging";
try {