summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java6
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java96
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java33
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java2
-rw-r--r--core/java/android/app/ActivityManager.java11
-rw-r--r--core/java/android/app/TaskInfo.java15
-rw-r--r--core/java/android/content/AttributionSource.java7
-rw-r--r--core/java/android/hardware/ISensorPrivacyManager.aidl2
-rw-r--r--core/java/android/hardware/SensorPrivacyManager.java8
-rw-r--r--core/java/android/hardware/location/ContextHubClientCallback.java7
-rw-r--r--core/java/android/hardware/location/ContextHubManager.java3
-rwxr-xr-xcore/java/android/os/Build.java95
-rw-r--r--core/java/android/service/notification/ZenModeConfig.java12
-rw-r--r--core/java/android/service/voice/VoiceInteractionSession.java2
-rw-r--r--core/java/android/util/apk/ApkSignatureVerifier.java13
-rw-r--r--core/java/android/view/ViewRootImpl.java16
-rw-r--r--core/java/android/widget/AnalogClock.java20
-rw-r--r--core/java/android/widget/EdgeEffect.java8
-rw-r--r--core/java/com/android/internal/app/PlatLogoActivity.java476
-rw-r--r--core/java/com/android/internal/widget/ConversationHeaderLinearLayout.java179
-rw-r--r--core/res/AndroidManifest.xml4
-rw-r--r--core/res/res/drawable-hdpi/clock_dial.pngbin10519 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/clock_hand_hour.pngbin2196 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/clock_hand_minute.pngbin2518 -> 0 bytes
-rw-r--r--core/res/res/drawable-ldpi/clock_dial.pngbin3086 -> 0 bytes
-rw-r--r--core/res/res/drawable-ldpi/clock_hand_hour.pngbin820 -> 0 bytes
-rw-r--r--core/res/res/drawable-ldpi/clock_hand_minute.pngbin913 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/clock_dial.pngbin7384 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/clock_hand_hour.pngbin1412 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/clock_hand_minute.pngbin1550 -> 0 bytes
-rw-r--r--core/res/res/drawable-nodpi/clock_dial.xml10
-rw-r--r--core/res/res/drawable-nodpi/clock_hand_hour.xml10
-rw-r--r--core/res/res/drawable-nodpi/clock_hand_minute.xml10
-rw-r--r--core/res/res/drawable-nodpi/platlogo.xml82
-rw-r--r--core/res/res/drawable-xhdpi/clock_dial.pngbin12539 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/clock_hand_hour.pngbin2642 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/clock_hand_minute.pngbin3115 -> 0 bytes
-rw-r--r--core/res/res/drawable/ic_lock.xml23
-rw-r--r--core/res/res/drawable/ic_lock_open.xml23
-rw-r--r--core/res/res/layout/notification_template_conversation_header.xml5
-rw-r--r--core/res/res/values-as/strings.xml4
-rw-r--r--core/res/res/values-bn/strings.xml2
-rw-r--r--core/res/res/values-fa/strings.xml2
-rw-r--r--core/res/res/values-in/strings.xml2
-rw-r--r--core/res/res/values-is/strings.xml4
-rw-r--r--core/res/res/values-kn/strings.xml2
-rw-r--r--core/res/res/values-ky/strings.xml4
-rw-r--r--core/res/res/values-or/strings.xml4
-rw-r--r--core/res/res/values-sl/strings.xml6
-rw-r--r--core/res/res/values-zh-rCN/strings.xml6
-rw-r--r--core/res/res/values/config.xml2
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java29
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurface.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java76
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java55
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java3
-rw-r--r--libs/hwui/Readback.cpp6
-rw-r--r--libs/hwui/pipeline/skia/SkiaPipeline.cpp8
-rw-r--r--libs/hwui/renderthread/DrawFrameTask.cpp6
-rw-r--r--native/android/surface_control.cpp80
-rw-r--r--packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml2
-rw-r--r--packages/PrintSpooler/res/values-ta/strings.xml2
-rw-r--r--packages/Shell/res/values-ta/strings.xml2
-rw-r--r--packages/SystemUI/AndroidManifest.xml1
-rw-r--r--packages/SystemUI/animation/Android.bp1
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt71
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt21
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/DetailAdapter.java3
-rw-r--r--packages/SystemUI/res/anim/fp_to_unlock.xml171
-rw-r--r--packages/SystemUI/res/anim/lock_to_unlock.xml163
-rw-r--r--packages/SystemUI/res/drawable/fingerprint_bg.xml3
-rw-r--r--packages/SystemUI/res/layout/auth_biometric_contents.xml1
-rw-r--r--packages/SystemUI/res/layout/people_tile_medium_with_content.xml2
-rw-r--r--packages/SystemUI/res/layout/status_bar_expanded.xml19
-rw-r--r--packages/SystemUI/res/layout/udfps_keyguard_view.xml5
-rw-r--r--packages/SystemUI/res/raw/udfps_aod_fp.json3483
-rw-r--r--packages/SystemUI/res/raw/udfps_lockscreen_fp.json1018
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml3
-rw-r--r--packages/SystemUI/res/values-as/strings.xml5
-rw-r--r--packages/SystemUI/res/values-az/strings.xml3
-rw-r--r--packages/SystemUI/res/values-be/strings.xml3
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml2
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml2
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml4
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml4
-rw-r--r--packages/SystemUI/res/values-in/strings.xml7
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml3
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml3
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml3
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml7
-rw-r--r--packages/SystemUI/res/values-land-television/dimens.xml2
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml3
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml4
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml3
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml5
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml3
-rw-r--r--packages/SystemUI/res/values-my/strings.xml2
-rw-r--r--packages/SystemUI/res/values-or/strings.xml3
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml2
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml3
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml3
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml3
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml3
-rw-r--r--packages/SystemUI/res/values-te/strings.xml3
-rw-r--r--packages/SystemUI/res/values-television/dimens.xml4
-rw-r--r--packages/SystemUI/res/values-th/strings.xml3
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml3
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml3
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml10
-rw-r--r--packages/SystemUI/res/values/dimens.xml4
-rw-r--r--packages/SystemUI/res/values/dimens_tv.xml4
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskInfoCompat.java67
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java27
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java10
-rw-r--r--packages/SystemUI/src/com/android/keyguard/LockIconView.java96
-rw-r--r--packages/SystemUI/src/com/android/keyguard/LockIconViewController.java44
-rw-r--r--packages/SystemUI/src/com/android/keyguard/NumPadButton.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java77
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java84
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSDetail.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyControllerImpl.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt24
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/animation/GhostedViewLaunchAnimatorControllerTest.kt42
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java2
-rw-r--r--proto/src/system_messages.proto8
-rw-r--r--services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java33
-rw-r--r--services/core/java/com/android/server/SensorPrivacyService.java54
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java11
-rw-r--r--services/core/java/com/android/server/am/BatteryExternalStatsWorker.java6
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java14
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java23
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java22
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java23
-rw-r--r--services/core/java/com/android/server/notification/ZenModeHelper.java28
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java50
-rw-r--r--services/core/java/com/android/server/pm/PackageSetting.java44
-rw-r--r--services/core/java/com/android/server/pm/PackageSettingBase.java9
-rw-r--r--services/core/java/com/android/server/pm/SettingBase.java3
-rw-r--r--services/core/java/com/android/server/pm/SharedUserSetting.java53
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java108
-rw-r--r--services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java22
-rw-r--r--services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java8
-rw-r--r--services/core/java/com/android/server/vibrator/VibrationThread.java43
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java5
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java7
-rw-r--r--services/core/java/com/android/server/wm/ConfigurationContainer.java8
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java4
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java1
-rw-r--r--services/core/java/com/android/server/wm/Task.java15
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java25
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java157
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java444
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java1
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java75
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java28
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java128
188 files changed, 4997 insertions, 3819 deletions
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 b52a503a2166..666d49770a70 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -795,7 +795,7 @@ public class AppSearchManagerService extends SystemService {
AppSearchUserInstance instance =
mAppSearchUserInstanceManager.getUserInstance(callingUser);
SearchResultPage searchResultPage =
- instance.getAppSearchImpl().getNextPage(nextPageToken);
+ instance.getAppSearchImpl().getNextPage(packageName, nextPageToken);
invokeCallbackOnResult(
callback,
AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
@@ -821,7 +821,7 @@ public class AppSearchManagerService extends SystemService {
verifyNotInstantApp(userContext, packageName);
AppSearchUserInstance instance =
mAppSearchUserInstanceManager.getUserInstance(callingUser);
- instance.getAppSearchImpl().invalidateNextPageToken(nextPageToken);
+ instance.getAppSearchImpl().invalidateNextPageToken(packageName, nextPageToken);
} catch (Throwable t) {
Log.e(TAG, "Unable to invalidate the query page token", t);
}
@@ -871,7 +871,7 @@ public class AppSearchManagerService extends SystemService {
.getGenericDocument().getBundle());
}
searchResultPage = instance.getAppSearchImpl().getNextPage(
- searchResultPage.getNextPageToken());
+ packageName, searchResultPage.getNextPageToken());
}
}
invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
index a1b93ce12975..830e76c62279 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
@@ -173,6 +173,21 @@ public final class AppSearchImpl implements Closeable {
@GuardedBy("mReadWriteLock")
private final Map<String, Integer> mDocumentCountMapLocked = new ArrayMap<>();
+ // Maps packages to the set of valid nextPageTokens that the package can manipulate. A token
+ // is unique and constant per query (i.e. the same token '123' is used to iterate through
+ // pages of search results). The tokens themselves are generated and tracked by
+ // IcingSearchEngine. IcingSearchEngine considers a token valid and won't be reused
+ // until we call invalidateNextPageToken on the token.
+ //
+ // Note that we synchronize on itself because the nextPageToken cache is checked at
+ // query-time, and queries are done in parallel with a read lock. Ideally, this would be
+ // guarded by the normal mReadWriteLock.writeLock, but ReentrantReadWriteLocks can't upgrade
+ // read to write locks. This lock should be acquired at the smallest scope possible.
+ // mReadWriteLock is a higher-level lock, so calls shouldn't be made out
+ // to any functions that grab the lock.
+ @GuardedBy("mNextPageTokensLocked")
+ private final Map<String, Set<Long>> mNextPageTokensLocked = new ArrayMap<>();
+
/**
* The counter to check when to call {@link #checkForOptimize}. The interval is {@link
* #CHECK_OPTIMIZE_INTERVAL}.
@@ -837,12 +852,15 @@ public final class AppSearchImpl implements Closeable {
String prefix = createPrefix(packageName, databaseName);
Set<String> allowedPrefixedSchemas = getAllowedPrefixSchemasLocked(prefix, searchSpec);
- return doQueryLocked(
- Collections.singleton(createPrefix(packageName, databaseName)),
- allowedPrefixedSchemas,
- queryExpression,
- searchSpec,
- sStatsBuilder);
+ SearchResultPage searchResultPage =
+ doQueryLocked(
+ Collections.singleton(createPrefix(packageName, databaseName)),
+ allowedPrefixedSchemas,
+ queryExpression,
+ searchSpec,
+ sStatsBuilder);
+ addNextPageToken(packageName, searchResultPage.getNextPageToken());
+ return searchResultPage;
} finally {
mReadWriteLock.readLock().unlock();
if (logger != null) {
@@ -956,12 +974,15 @@ public final class AppSearchImpl implements Closeable {
}
}
- return doQueryLocked(
- prefixFilters,
- prefixedSchemaFilters,
- queryExpression,
- searchSpec,
- sStatsBuilder);
+ SearchResultPage searchResultPage =
+ doQueryLocked(
+ prefixFilters,
+ prefixedSchemaFilters,
+ queryExpression,
+ searchSpec,
+ sStatsBuilder);
+ addNextPageToken(callerPackageName, searchResultPage.getNextPageToken());
+ return searchResultPage;
} finally {
mReadWriteLock.readLock().unlock();
@@ -1093,17 +1114,20 @@ public final class AppSearchImpl implements Closeable {
*
* <p>This method belongs to query group.
*
+ * @param packageName Package name of the caller.
* @param nextPageToken The token of pre-loaded results of previously executed query.
* @return The next page of results of previously executed query.
- * @throws AppSearchException on IcingSearchEngine error.
+ * @throws AppSearchException on IcingSearchEngine error or if can't advance on nextPageToken.
*/
@NonNull
- public SearchResultPage getNextPage(long nextPageToken) throws AppSearchException {
+ public SearchResultPage getNextPage(@NonNull String packageName, long nextPageToken)
+ throws AppSearchException {
mReadWriteLock.readLock().lock();
try {
throwIfClosedLocked();
mLogUtil.piiTrace("getNextPage, request", nextPageToken);
+ checkNextPageToken(packageName, nextPageToken);
SearchResultProto searchResultProto =
mIcingSearchEngineLocked.getNextPage(nextPageToken);
mLogUtil.piiTrace(
@@ -1122,16 +1146,26 @@ public final class AppSearchImpl implements Closeable {
*
* <p>This method belongs to query group.
*
+ * @param packageName Package name of the caller.
* @param nextPageToken The token of pre-loaded results of previously executed query to be
* Invalidated.
+ * @throws AppSearchException if nextPageToken is unusable.
*/
- public void invalidateNextPageToken(long nextPageToken) {
+ public void invalidateNextPageToken(@NonNull String packageName, long nextPageToken)
+ throws AppSearchException {
mReadWriteLock.readLock().lock();
try {
throwIfClosedLocked();
mLogUtil.piiTrace("invalidateNextPageToken, request", nextPageToken);
+ checkNextPageToken(packageName, nextPageToken);
mIcingSearchEngineLocked.invalidateNextPageToken(nextPageToken);
+
+ synchronized (mNextPageTokensLocked) {
+ // At this point, we're guaranteed that this nextPageToken exists for this package,
+ // otherwise checkNextPageToken would've thrown an exception.
+ mNextPageTokensLocked.get(packageName).remove(nextPageToken);
+ }
} finally {
mReadWriteLock.readLock().unlock();
}
@@ -1568,6 +1602,9 @@ public final class AppSearchImpl implements Closeable {
Set<String> databaseNames = entry.getValue();
if (!installedPackages.contains(packageName) && databaseNames != null) {
mDocumentCountMapLocked.remove(packageName);
+ synchronized (mNextPageTokensLocked) {
+ mNextPageTokensLocked.remove(packageName);
+ }
for (String databaseName : databaseNames) {
String removedPrefix = createPrefix(packageName, databaseName);
mSchemaMapLocked.remove(removedPrefix);
@@ -1601,6 +1638,9 @@ public final class AppSearchImpl implements Closeable {
mSchemaMapLocked.clear();
mNamespaceMapLocked.clear();
mDocumentCountMapLocked.clear();
+ synchronized (mNextPageTokensLocked) {
+ mNextPageTokensLocked.clear();
+ }
if (initStatsBuilder != null) {
initStatsBuilder
.setHasReset(true)
@@ -2015,6 +2055,32 @@ public final class AppSearchImpl implements Closeable {
return schemaProto.getSchema();
}
+ private void addNextPageToken(String packageName, long nextPageToken) {
+ synchronized (mNextPageTokensLocked) {
+ Set<Long> tokens = mNextPageTokensLocked.get(packageName);
+ if (tokens == null) {
+ tokens = new ArraySet<>();
+ mNextPageTokensLocked.put(packageName, tokens);
+ }
+ tokens.add(nextPageToken);
+ }
+ }
+
+ private void checkNextPageToken(String packageName, long nextPageToken)
+ throws AppSearchException {
+ synchronized (mNextPageTokensLocked) {
+ Set<Long> nextPageTokens = mNextPageTokensLocked.get(packageName);
+ if (nextPageTokens == null || !nextPageTokens.contains(nextPageToken)) {
+ throw new AppSearchException(
+ AppSearchResult.RESULT_SECURITY_ERROR,
+ "Package \""
+ + packageName
+ + "\" cannot use nextPageToken: "
+ + nextPageToken);
+ }
+ }
+ }
+
private static void addToMap(
Map<String, Set<String>> map, String prefix, String prefixedValue) {
Set<String> values = map.get(prefix);
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index ed80ddbd2cd7..9f529548833d 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -256,6 +256,7 @@ public class AlarmManagerService extends SystemService {
AlarmHandler mHandler;
AppWakeupHistory mAppWakeupHistory;
AppWakeupHistory mAllowWhileIdleHistory;
+ AppWakeupHistory mAllowWhileIdleCompatHistory;
private final SparseLongArray mLastPriorityAlarmDispatch = new SparseLongArray();
private final SparseArray<RingBuffer<RemovedAlarm>> mRemovalHistory = new SparseArray<>();
ClockReceiver mClockReceiver;
@@ -1633,6 +1634,7 @@ public class AlarmManagerService extends SystemService {
mAppWakeupHistory = new AppWakeupHistory(Constants.DEFAULT_APP_STANDBY_WINDOW);
mAllowWhileIdleHistory = new AppWakeupHistory(INTERVAL_HOUR);
+ mAllowWhileIdleCompatHistory = new AppWakeupHistory(INTERVAL_HOUR);
mNextWakeup = mNextNonWakeup = 0;
@@ -2142,20 +2144,23 @@ public class AlarmManagerService extends SystemService {
final int userId = UserHandle.getUserId(alarm.creatorUid);
final int quota;
final long window;
+ final AppWakeupHistory history;
if ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0) {
quota = mConstants.ALLOW_WHILE_IDLE_QUOTA;
window = mConstants.ALLOW_WHILE_IDLE_WINDOW;
+ history = mAllowWhileIdleHistory;
} else {
quota = mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA;
window = mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW;
+ history = mAllowWhileIdleCompatHistory;
}
- final int dispatchesInWindow = mAllowWhileIdleHistory.getTotalWakeupsInWindow(
+ final int dispatchesInHistory = history.getTotalWakeupsInWindow(
alarm.sourcePackage, userId);
- if (dispatchesInWindow < quota) {
+ if (dispatchesInHistory < quota) {
// fine to go out immediately.
batterySaverPolicyElapsed = nowElapsed;
} else {
- batterySaverPolicyElapsed = mAllowWhileIdleHistory.getNthLastWakeupForPackage(
+ batterySaverPolicyElapsed = history.getNthLastWakeupForPackage(
alarm.sourcePackage, userId, quota) + window;
}
} else if ((alarm.flags & FLAG_PRIORITIZE) != 0) {
@@ -2201,20 +2206,23 @@ public class AlarmManagerService extends SystemService {
final int userId = UserHandle.getUserId(alarm.creatorUid);
final int quota;
final long window;
+ final AppWakeupHistory history;
if ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0) {
quota = mConstants.ALLOW_WHILE_IDLE_QUOTA;
window = mConstants.ALLOW_WHILE_IDLE_WINDOW;
+ history = mAllowWhileIdleHistory;
} else {
quota = mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA;
window = mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW;
+ history = mAllowWhileIdleCompatHistory;
}
- final int dispatchesInWindow = mAllowWhileIdleHistory.getTotalWakeupsInWindow(
+ final int dispatchesInHistory = history.getTotalWakeupsInWindow(
alarm.sourcePackage, userId);
- if (dispatchesInWindow < quota) {
+ if (dispatchesInHistory < quota) {
// fine to go out immediately.
deviceIdlePolicyTime = nowElapsed;
} else {
- final long whenInQuota = mAllowWhileIdleHistory.getNthLastWakeupForPackage(
+ final long whenInQuota = history.getNthLastWakeupForPackage(
alarm.sourcePackage, userId, quota) + window;
deviceIdlePolicyTime = Math.min(whenInQuota, mPendingIdleUntil.getWhenElapsed());
}
@@ -2502,6 +2510,7 @@ public class AlarmManagerService extends SystemService {
Binder.getCallingPid(), callingUid, "AlarmManager.setPrioritized");
// The API doesn't allow using both together.
flags &= ~FLAG_ALLOW_WHILE_IDLE;
+ // Prioritized alarms don't need any extra permission to be exact.
} else if (exact || allowWhileIdle) {
final boolean needsPermission;
boolean lowerQuota;
@@ -2992,6 +3001,10 @@ public class AlarmManagerService extends SystemService {
mAllowWhileIdleHistory.dump(pw, nowELAPSED);
pw.println();
+ pw.println("Allow while idle compat history:");
+ mAllowWhileIdleCompatHistory.dump(pw, nowELAPSED);
+ pw.println();
+
if (mLastPriorityAlarmDispatch.size() > 0) {
pw.println("Last priority alarm dispatches:");
pw.increaseIndent();
@@ -4553,6 +4566,7 @@ public class AlarmManagerService extends SystemService {
removeUserLocked(userHandle);
mAppWakeupHistory.removeForUser(userHandle);
mAllowWhileIdleHistory.removeForUser(userHandle);
+ mAllowWhileIdleCompatHistory.removeForUser(userHandle);
}
return;
case Intent.ACTION_UID_REMOVED:
@@ -4588,6 +4602,8 @@ public class AlarmManagerService extends SystemService {
// package-removed and package-restarted case
mAppWakeupHistory.removeForPackage(pkg, UserHandle.getUserId(uid));
mAllowWhileIdleHistory.removeForPackage(pkg, UserHandle.getUserId(uid));
+ mAllowWhileIdleCompatHistory.removeForPackage(pkg,
+ UserHandle.getUserId(uid));
removeLocked(uid, REMOVE_REASON_UNDEFINED);
} else {
// external-applications-unavailable case
@@ -4965,7 +4981,10 @@ public class AlarmManagerService extends SystemService {
if (isAllowedWhileIdleRestricted(alarm)) {
// Record the last time this uid handled an ALLOW_WHILE_IDLE alarm while the
// device was in doze or battery saver.
- mAllowWhileIdleHistory.recordAlarmForPackage(alarm.sourcePackage,
+ final AppWakeupHistory history = ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0)
+ ? mAllowWhileIdleHistory
+ : mAllowWhileIdleCompatHistory;
+ history.recordAlarmForPackage(alarm.sourcePackage,
UserHandle.getUserId(alarm.creatorUid), nowELAPSED);
mAlarmStore.updateAlarmDeliveries(a -> {
if (a.creatorUid != alarm.creatorUid || !isAllowedWhileIdleRestricted(a)) {
diff --git a/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java b/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java
index 3069db32c548..6d67ee37d8e6 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java
@@ -59,7 +59,7 @@ public class ThermalStatusRestriction extends JobRestriction {
@Override
public boolean isJobRestricted(JobStatus job) {
- return mIsThermalRestricted && job.hasConnectivityConstraint();
+ return mIsThermalRestricted;
}
@Override
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 91e2d88ad7cb..4376d225e676 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -406,6 +406,12 @@ public class ActivityManager {
public static final int BROADCAST_FAILED_USER_STOPPED = -2;
/**
+ * Type for IActivityManaqer.getIntentSender: this PendingIntent type is unknown.
+ * @hide
+ */
+ public static final int INTENT_SENDER_UNKNOWN = 0;
+
+ /**
* Type for IActivityManaqer.getIntentSender: this PendingIntent is
* for a sendBroadcast operation.
* @hide
@@ -4860,12 +4866,12 @@ public class ActivityManager {
*/
public static final class PendingIntentInfo implements Parcelable {
- private final String mCreatorPackage;
+ @Nullable private final String mCreatorPackage;
private final int mCreatorUid;
private final boolean mImmutable;
private final int mIntentSenderType;
- public PendingIntentInfo(String creatorPackage, int creatorUid, boolean immutable,
+ public PendingIntentInfo(@Nullable String creatorPackage, int creatorUid, boolean immutable,
int intentSenderType) {
mCreatorPackage = creatorPackage;
mCreatorUid = creatorUid;
@@ -4873,6 +4879,7 @@ public class ActivityManager {
mIntentSenderType = intentSenderType;
}
+ @Nullable
public String getCreatorPackage() {
return mCreatorPackage;
}
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index 444cc4eedcb1..85758a92fa98 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -28,11 +28,13 @@ import android.content.LocusId;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Point;
+import android.graphics.Rect;
import android.os.Build;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.Log;
+import android.view.DisplayCutout;
import android.window.TaskSnapshot;
import android.window.WindowContainerToken;
@@ -174,6 +176,15 @@ public class TaskInfo {
public PictureInPictureParams pictureInPictureParams;
/**
+ * The {@link Rect} copied from {@link DisplayCutout#getSafeInsets()} if the cutout is not of
+ * (LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES, LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS),
+ * {@code null} otherwise.
+ * @hide
+ */
+ @Nullable
+ public Rect displayCutoutInsets;
+
+ /**
* The activity type of the top activity in this task.
* @hide
*/
@@ -332,6 +343,7 @@ public class TaskInfo {
&& supportsMultiWindow == that.supportsMultiWindow
&& Objects.equals(positionInParent, that.positionInParent)
&& Objects.equals(pictureInPictureParams, that.pictureInPictureParams)
+ && Objects.equals(displayCutoutInsets, that.displayCutoutInsets)
&& getWindowingMode() == that.getWindowingMode()
&& Objects.equals(taskDescription, that.taskDescription)
&& isFocused == that.isFocused
@@ -382,6 +394,7 @@ public class TaskInfo {
token = WindowContainerToken.CREATOR.createFromParcel(source);
topActivityType = source.readInt();
pictureInPictureParams = source.readTypedObject(PictureInPictureParams.CREATOR);
+ displayCutoutInsets = source.readTypedObject(Rect.CREATOR);
topActivityInfo = source.readTypedObject(ActivityInfo.CREATOR);
isResizeable = source.readBoolean();
source.readBinderList(launchCookies);
@@ -419,6 +432,7 @@ public class TaskInfo {
token.writeToParcel(dest, flags);
dest.writeInt(topActivityType);
dest.writeTypedObject(pictureInPictureParams, flags);
+ dest.writeTypedObject(displayCutoutInsets, flags);
dest.writeTypedObject(topActivityInfo, flags);
dest.writeBoolean(isResizeable);
dest.writeBinderList(launchCookies);
@@ -447,6 +461,7 @@ public class TaskInfo {
+ " token=" + token
+ " topActivityType=" + topActivityType
+ " pictureInPictureParams=" + pictureInPictureParams
+ + " displayCutoutSafeInsets=" + displayCutoutInsets
+ " topActivityInfo=" + topActivityInfo
+ " launchCookies=" + launchCookies
+ " positionInParent=" + positionInParent
diff --git a/core/java/android/content/AttributionSource.java b/core/java/android/content/AttributionSource.java
index d63ce0f4a943..bdb7900b5bb9 100644
--- a/core/java/android/content/AttributionSource.java
+++ b/core/java/android/content/AttributionSource.java
@@ -152,6 +152,10 @@ public final class AttributionSource implements Parcelable {
AttributionSource(@NonNull Parcel in) {
this(AttributionSourceState.CREATOR.createFromParcel(in));
+
+ // Since we just unpacked this object as part of it transiting a Binder
+ // call, this is the perfect time to enforce that its UID can be trusted
+ enforceCallingUid();
}
/** @hide */
@@ -248,7 +252,8 @@ public final class AttributionSource implements Parcelable {
*/
public boolean checkCallingUid() {
final int callingUid = Binder.getCallingUid();
- if (callingUid != Process.SYSTEM_UID
+ if (callingUid != Process.ROOT_UID
+ && callingUid != Process.SYSTEM_UID
&& callingUid != mAttributionSourceState.uid) {
return false;
}
diff --git a/core/java/android/hardware/ISensorPrivacyManager.aidl b/core/java/android/hardware/ISensorPrivacyManager.aidl
index 6105c26dc651..debc074ea21a 100644
--- a/core/java/android/hardware/ISensorPrivacyManager.aidl
+++ b/core/java/android/hardware/ISensorPrivacyManager.aidl
@@ -46,6 +46,6 @@ interface ISensorPrivacyManager {
void setIndividualSensorPrivacyForProfileGroup(int userId, int source, int sensor, boolean enable);
// =============== End of transactions used on native side as well ============================
- void suppressIndividualSensorPrivacyReminders(int userId, String packageName, IBinder token,
+ void suppressIndividualSensorPrivacyReminders(int userId, int sensor, IBinder token,
boolean suppress);
} \ No newline at end of file
diff --git a/core/java/android/hardware/SensorPrivacyManager.java b/core/java/android/hardware/SensorPrivacyManager.java
index c392fbb52de0..b7d95e7dea74 100644
--- a/core/java/android/hardware/SensorPrivacyManager.java
+++ b/core/java/android/hardware/SensorPrivacyManager.java
@@ -461,9 +461,9 @@ public final class SensorPrivacyManager {
* @hide
*/
@RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY)
- public void suppressSensorPrivacyReminders(@NonNull String packageName,
+ public void suppressSensorPrivacyReminders(int sensor,
boolean suppress) {
- suppressSensorPrivacyReminders(packageName, suppress, mContext.getUserId());
+ suppressSensorPrivacyReminders(sensor, suppress, mContext.getUserId());
}
/**
@@ -476,10 +476,10 @@ public final class SensorPrivacyManager {
* @hide
*/
@RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY)
- public void suppressSensorPrivacyReminders(@NonNull String packageName,
+ public void suppressSensorPrivacyReminders(int sensor,
boolean suppress, @UserIdInt int userId) {
try {
- mService.suppressIndividualSensorPrivacyReminders(userId, packageName,
+ mService.suppressIndividualSensorPrivacyReminders(userId, sensor,
token, suppress);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
diff --git a/core/java/android/hardware/location/ContextHubClientCallback.java b/core/java/android/hardware/location/ContextHubClientCallback.java
index 35d00f03de67..9309c5b0d8e3 100644
--- a/core/java/android/hardware/location/ContextHubClientCallback.java
+++ b/core/java/android/hardware/location/ContextHubClientCallback.java
@@ -68,8 +68,11 @@ public class ContextHubClientCallback {
/**
* Callback invoked when a nanoapp is dynamically loaded at the attached Context Hub through
- * the {@link android.hardware.location.ContextHubManager}. This callback is not invoked for a
- * nanoapp that is loaded internally by CHRE (e.g. nanoapps that are preloaded by the system).
+ * the {@link android.hardware.location.ContextHubManager}.
+ *
+ * NOTE: This callback is <b>not</b> invoked for a nanoapp that is loaded internally by CHRE
+ * (e.g. nanoapps that are preloaded by the system). To check the availability of these
+ * nanoapps, use the {@link ContextHubManager#queryNanoApps(ContextHubInfo)} API.
*
* @param client the client that is associated with this callback
* @param nanoAppId the ID of the nanoapp that had been loaded
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java
index f69a7d7e5f16..9af0e09ee97a 100644
--- a/core/java/android/hardware/location/ContextHubManager.java
+++ b/core/java/android/hardware/location/ContextHubManager.java
@@ -128,7 +128,8 @@ public final class ContextHubManager {
public static final int AUTHORIZATION_GRANTED = 2;
/**
- * Constants describing the type of events from a Context Hub.
+ * Constants describing the type of events from a Context Hub, as defined in
+ * {@link ContextHubClientCallback}.
* {@hide}
*/
@Retention(RetentionPolicy.SOURCE)
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index a5b7e995293a..6bf394dc347b 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -441,23 +441,30 @@ public class Build {
public static final int CUR_DEVELOPMENT = 10000;
/**
- * October 2008: The original, first, version of Android. Yay!
+ * The original, first, version of Android. Yay!
+ *
+ * <p>Released publicly as Android 1.0 in September 2008.
*/
public static final int BASE = 1;
/**
- * February 2009: First Android update, officially called 1.1.
+ * First Android update.
+ *
+ * <p>Released publicly as Android 1.1 in February 2009.
*/
public static final int BASE_1_1 = 2;
/**
- * May 2009: Android 1.5.
+ * C.
+ *
+ * <p>Released publicly as Android 1.5 in April 2009.
*/
public static final int CUPCAKE = 3;
/**
- * September 2009: Android 1.6.
+ * D.
*
+ * <p>Released publicly as Android 1.6 in September 2009.
* <p>Applications targeting this or a later release will get these
* new changes in behavior:</p>
* <ul>
@@ -481,8 +488,9 @@ public class Build {
public static final int DONUT = 4;
/**
- * November 2009: Android 2.0
+ * E.
*
+ * <p>Released publicly as Android 2.0 in October 2009.
* <p>Applications targeting this or a later release will get these
* new changes in behavior:</p>
* <ul>
@@ -501,23 +509,30 @@ public class Build {
public static final int ECLAIR = 5;
/**
- * December 2009: Android 2.0.1
+ * E incremental update.
+ *
+ * <p>Released publicly as Android 2.0.1 in December 2009.
*/
public static final int ECLAIR_0_1 = 6;
/**
- * January 2010: Android 2.1
+ * E MR1.
+ *
+ * <p>Released publicly as Android 2.1 in January 2010.
*/
public static final int ECLAIR_MR1 = 7;
/**
- * June 2010: Android 2.2
+ * F.
+ *
+ * <p>Released publicly as Android 2.2 in May 2010.
*/
public static final int FROYO = 8;
/**
- * November 2010: Android 2.3
+ * G.
*
+ * <p>Released publicly as Android 2.3 in December 2010.
* <p>Applications targeting this or a later release will get these
* new changes in behavior:</p>
* <ul>
@@ -528,13 +543,16 @@ public class Build {
public static final int GINGERBREAD = 9;
/**
- * February 2011: Android 2.3.3.
+ * G MR1.
+ *
+ * <p>Released publicly as Android 2.3.3 in February 2011.
*/
public static final int GINGERBREAD_MR1 = 10;
/**
- * February 2011: Android 3.0.
+ * H.
*
+ * <p>Released publicly as Android 3.0 in February 2011.
* <p>Applications targeting this or a later release will get these
* new changes in behavior:</p>
* <ul>
@@ -573,13 +591,16 @@ public class Build {
public static final int HONEYCOMB = 11;
/**
- * May 2011: Android 3.1.
+ * H MR1.
+ *
+ * <p>Released publicly as Android 3.1 in May 2011.
*/
public static final int HONEYCOMB_MR1 = 12;
/**
- * June 2011: Android 3.2.
+ * H MR2.
*
+ * <p>Released publicly as Android 3.2 in July 2011.
* <p>Update to Honeycomb MR1 to support 7 inch tablets, improve
* screen compatibility mode, etc.</p>
*
@@ -626,8 +647,9 @@ public class Build {
public static final int HONEYCOMB_MR2 = 13;
/**
- * October 2011: Android 4.0.
+ * I.
*
+ * <p>Released publicly as Android 4.0 in October 2011.
* <p>Applications targeting this or a later release will get these
* new changes in behavior:</p>
* <ul>
@@ -672,13 +694,16 @@ public class Build {
public static final int ICE_CREAM_SANDWICH = 14;
/**
- * December 2011: Android 4.0.3.
+ * I MR1.
+ *
+ * <p>Released publicly as Android 4.03 in December 2011.
*/
public static final int ICE_CREAM_SANDWICH_MR1 = 15;
/**
- * June 2012: Android 4.1.
+ * J.
*
+ * <p>Released publicly as Android 4.1 in July 2012.
* <p>Applications targeting this or a later release will get these
* new changes in behavior:</p>
* <ul>
@@ -720,8 +745,9 @@ public class Build {
public static final int JELLY_BEAN = 16;
/**
- * November 2012: Android 4.2, Moar jelly beans!
+ * J MR1.
*
+ * <p>Released publicly as Android 4.2 in November 2012.
* <p>Applications targeting this or a later release will get these
* new changes in behavior:</p>
* <ul>
@@ -740,13 +766,16 @@ public class Build {
public static final int JELLY_BEAN_MR1 = 17;
/**
- * July 2013: Android 4.3, the revenge of the beans.
+ * J MR2.
+ *
+ * <p>Released publicly as Android 4.3 in July 2013.
*/
public static final int JELLY_BEAN_MR2 = 18;
/**
- * October 2013: Android 4.4, KitKat, another tasty treat.
+ * K.
*
+ * <p>Released publicly as Android 4.4 in October 2013.
* <p>Applications targeting this or a later release will get these
* new changes in behavior. For more information about this release, see the
* <a href="/about/versions/kitkat/">Android KitKat overview</a>.</p>
@@ -778,8 +807,9 @@ public class Build {
public static final int KITKAT = 19;
/**
- * June 2014: Android 4.4W. KitKat for watches, snacks on the run.
+ * K for watches.
*
+ * <p>Released publicly as Android 4.4W in June 2014.
* <p>Applications targeting this or a later release will get these
* new changes in behavior:</p>
* <ul>
@@ -796,8 +826,9 @@ public class Build {
public static final int L = 21;
/**
- * November 2014: Lollipop. A flat one with beautiful shadows. But still tasty.
+ * L.
*
+ * <p>Released publicly as Android 5.0 in November 2014.
* <p>Applications targeting this or a later release will get these
* new changes in behavior. For more information about this release, see the
* <a href="/about/versions/lollipop/">Android Lollipop overview</a>.</p>
@@ -828,15 +859,18 @@ public class Build {
public static final int LOLLIPOP = 21;
/**
- * March 2015: Lollipop with an extra sugar coating on the outside!
- * For more information about this release, see the
+ * L MR1.
+ *
+ * <p>Released publicly as Android 5.1 in March 2015.
+ * <p>For more information about this release, see the
* <a href="/about/versions/android-5.1">Android 5.1 APIs</a>.
*/
public static final int LOLLIPOP_MR1 = 22;
/**
- * M is for Marshmallow!
+ * M.
*
+ * <p>Released publicly as Android 6.0 in October 2015.
* <p>Applications targeting this or a later release will get these
* new changes in behavior. For more information about this release, see the
* <a href="/about/versions/marshmallow/">Android 6.0 Marshmallow overview</a>.</p>
@@ -867,8 +901,9 @@ public class Build {
public static final int M = 23;
/**
- * N is for Nougat.
+ * N.
*
+ * <p>Released publicly as Android 7.0 in August 2016.
* <p>Applications targeting this or a later release will get these
* new changes in behavior. For more information about this release, see
* the <a href="/about/versions/nougat/">Android Nougat overview</a>.</p>
@@ -921,7 +956,10 @@ public class Build {
public static final int N = 24;
/**
- * N MR1: Nougat++. For more information about this release, see
+ * N MR1.
+ *
+ * <p>Released publicly as Android 7.1 in October 2016.
+ * <p>For more information about this release, see
* <a href="/about/versions/nougat/android-7.1">Android 7.1 for
* Developers</a>.
*/
@@ -930,6 +968,7 @@ public class Build {
/**
* O.
*
+ * <p>Released publicly as Android 8.0 in August 2017.
* <p>Applications targeting this or a later release will get these
* new changes in behavior. For more information about this release, see
* the <a href="/about/versions/oreo/">Android Oreo overview</a>.</p>
@@ -1020,6 +1059,7 @@ public class Build {
/**
* O MR1.
*
+ * <p>Released publicly as Android 8.1 in December 2017.
* <p>Applications targeting this or a later release will get these
* new changes in behavior. For more information about this release, see
* <a href="/about/versions/oreo/android-8.1">Android 8.1 features and
@@ -1037,6 +1077,7 @@ public class Build {
/**
* P.
*
+ * <p>Released publicly as Android 9 in August 2018.
* <p>Applications targeting this or a later release will get these
* new changes in behavior. For more information about this release, see the
* <a href="/about/versions/pie/">Android 9 Pie overview</a>.</p>
@@ -1054,6 +1095,7 @@ public class Build {
/**
* Q.
*
+ * <p>Released publicly as Android 10 in September 2019.
* <p>Applications targeting this or a later release will get these new changes in behavior.
* For more information about this release, see the
* <a href="/about/versions/10">Android 10 overview</a>.</p>
@@ -1069,6 +1111,7 @@ public class Build {
/**
* R.
*
+ * <p>Released publicly as Android 11 in September 2020.
* <p>Applications targeting this or a later release will get these new changes in behavior.
* For more information about this release, see the
* <a href="/about/versions/11">Android 11 overview</a>.</p>
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index ff692818863a..ee8353a9f203 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -1969,7 +1969,17 @@ public class ZenModeConfig implements Parcelable {
}
public boolean isAutomaticActive() {
- return enabled && !snoozing && pkg != null && isTrueOrUnknown();
+ return enabled && !snoozing && getPkg() != null && isTrueOrUnknown();
+ }
+
+ public String getPkg() {
+ return !TextUtils.isEmpty(pkg)
+ ? pkg
+ : (component != null)
+ ? component.getPackageName()
+ : (configurationActivity != null)
+ ? configurationActivity.getPackageName()
+ : null;
}
public boolean isTrueOrUnknown() {
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index ad09a48cf4c3..725e20f2a74d 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -2014,7 +2014,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
return mIndex;
}
- /**s
+ /**
* @return the total number of activities for which the assist data is
* being returned.
*/
diff --git a/core/java/android/util/apk/ApkSignatureVerifier.java b/core/java/android/util/apk/ApkSignatureVerifier.java
index 696271c69717..73f7543ba819 100644
--- a/core/java/android/util/apk/ApkSignatureVerifier.java
+++ b/core/java/android/util/apk/ApkSignatureVerifier.java
@@ -198,6 +198,7 @@ public class ApkSignatureVerifier {
ApkSignatureSchemeV4Verifier.extractCertificates(apkPath);
Certificate[][] signerCerts = new Certificate[][]{vSigner.certs};
Signature[] signerSigs = convertToSignatures(signerCerts);
+ Signature[] pastSignerSigs = null;
if (verifyFull) {
Map<Integer, byte[]> nonstreamingDigests;
@@ -210,6 +211,15 @@ public class ApkSignatureVerifier {
ApkSignatureSchemeV3Verifier.unsafeGetCertsWithoutVerification(apkPath);
nonstreamingDigests = v3Signer.contentDigests;
nonstreamingCerts = new Certificate[][]{v3Signer.certs};
+ if (v3Signer.por != null) {
+ // populate proof-of-rotation information
+ pastSignerSigs = new Signature[v3Signer.por.certs.size()];
+ for (int i = 0; i < pastSignerSigs.length; i++) {
+ pastSignerSigs[i] = new Signature(
+ v3Signer.por.certs.get(i).getEncoded());
+ pastSignerSigs[i].setFlags(v3Signer.por.flagsList.get(i));
+ }
+ }
} catch (SignatureNotFoundException e) {
try {
ApkSignatureSchemeV2Verifier.VerifiedSigner v2Signer =
@@ -250,7 +260,8 @@ public class ApkSignatureVerifier {
}
return new SigningDetailsWithDigests(new PackageParser.SigningDetails(signerSigs,
- SignatureSchemeVersion.SIGNING_BLOCK_V4), vSigner.contentDigests);
+ SignatureSchemeVersion.SIGNING_BLOCK_V4, pastSignerSigs),
+ vSigner.contentDigests);
} catch (SignatureNotFoundException e) {
throw e;
} catch (Exception e) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 280685065aaf..3550a31f9038 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1955,22 +1955,23 @@ public final class ViewRootImpl implements ViewParent,
return mBoundsLayer;
}
- Surface getOrCreateBLASTSurface(int width, int height,
- @Nullable WindowManager.LayoutParams params) {
+ Surface getOrCreateBLASTSurface() {
if (!mSurfaceControl.isValid()) {
return null;
}
- int format = params == null ? PixelFormat.TRANSLUCENT : params.format;
Surface ret = null;
if (mBlastBufferQueue == null) {
- mBlastBufferQueue = new BLASTBufferQueue(mTag, mSurfaceControl, width, height,
- format);
+ mBlastBufferQueue = new BLASTBufferQueue(mTag, mSurfaceControl,
+ mSurfaceSize.x, mSurfaceSize.y,
+ mWindowAttributes.format);
// We only return the Surface the first time, as otherwise
// it hasn't changed and there is no need to update.
ret = mBlastBufferQueue.createSurface();
} else {
- mBlastBufferQueue.update(mSurfaceControl, width, height, format);
+ mBlastBufferQueue.update(mSurfaceControl,
+ mSurfaceSize.x, mSurfaceSize.y,
+ mWindowAttributes.format);
}
return ret;
@@ -7784,8 +7785,7 @@ public final class ViewRootImpl implements ViewParent,
if (!useBLAST()) {
mSurface.copyFrom(mSurfaceControl);
} else {
- final Surface blastSurface = getOrCreateBLASTSurface(mSurfaceSize.x, mSurfaceSize.y,
- params);
+ final Surface blastSurface = getOrCreateBLASTSurface();
// If blastSurface == null that means it hasn't changed since the last time we
// called. In this situation, avoid calling transferFrom as we would then
// inc the generation ID and cause EGL resources to be recreated.
diff --git a/core/java/android/widget/AnalogClock.java b/core/java/android/widget/AnalogClock.java
index 9c1285064afb..3df09c24ca30 100644
--- a/core/java/android/widget/AnalogClock.java
+++ b/core/java/android/widget/AnalogClock.java
@@ -740,8 +740,22 @@ public class AnalogClock extends View {
}
}
- private void onTimeChanged() {
- Instant now = mClock.instant();
+ /**
+ * Return the current Instant to be used for drawing the clockface. Protected to allow
+ * subclasses to override this to show a different time from the system clock.
+ *
+ * @return the Instant to be shown on the clockface
+ * @hide
+ */
+ protected Instant now() {
+ return mClock.instant();
+ }
+
+ /**
+ * @hide
+ */
+ protected void onTimeChanged() {
+ Instant now = now();
onTimeChanged(now.atZone(mClock.getZone()).toLocalTime(), now.toEpochMilli());
}
@@ -789,7 +803,7 @@ public class AnalogClock extends View {
return;
}
- Instant now = mClock.instant();
+ Instant now = now();
ZonedDateTime zonedDateTime = now.atZone(mClock.getZone());
LocalTime localTime = zonedDateTime.toLocalTime();
diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java
index 472e3e72ab2f..c110ab956030 100644
--- a/core/java/android/widget/EdgeEffect.java
+++ b/core/java/android/widget/EdgeEffect.java
@@ -365,6 +365,10 @@ public class EdgeEffect {
mDuration = PULL_TIME;
mPullDistance += deltaDistance;
+ if (edgeEffectBehavior == TYPE_STRETCH) {
+ // Don't allow stretch beyond 1
+ mPullDistance = Math.min(1f, mPullDistance);
+ }
mDistance = Math.max(0f, mPullDistance);
mVelocity = 0;
@@ -783,6 +787,10 @@ public class EdgeEffect {
+ mDampedFreq * sinCoeff * Math.cos(mDampedFreq * deltaT));
mDistance = (float) distance / mHeight;
mVelocity = (float) velocity;
+ if (mDistance > 1f) {
+ mDistance = 1f;
+ mVelocity = 0f;
+ }
if (isAtEquilibrium()) {
mDistance = 0;
mVelocity = 0;
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index 986bbc8628ec..b7f6a615a452 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -16,9 +16,9 @@
package com.android.internal.app;
+import static android.graphics.PixelFormat.TRANSLUCENT;
+
import android.animation.ObjectAnimator;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.app.ActionBar;
import android.app.Activity;
import android.content.ActivityNotFoundException;
@@ -26,22 +26,21 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
-import android.graphics.Color;
import android.graphics.ColorFilter;
-import android.graphics.LinearGradient;
import android.graphics.Paint;
-import android.graphics.PixelFormat;
import android.graphics.Rect;
-import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.provider.Settings;
-import android.util.AttributeSet;
+import android.util.DisplayMetrics;
import android.util.Log;
+import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View;
-import android.view.animation.PathInterpolator;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.OvershootInterpolator;
+import android.widget.AnalogClock;
import android.widget.FrameLayout;
import android.widget.ImageView;
@@ -49,17 +48,22 @@ import com.android.internal.R;
import org.json.JSONObject;
+import java.time.Clock;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+
/**
* @hide
*/
public class PlatLogoActivity extends Activity {
- private static final boolean WRITE_SETTINGS = true;
-
- private static final String R_EGG_UNLOCK_SETTING = "egg_mode_r";
+ private static final String TAG = "PlatLogoActivity";
- private static final int UNLOCK_TRIES = 3;
+ private static final String S_EGG_UNLOCK_SETTING = "egg_mode_s";
- BigDialView mDialView;
+ private SettableAnalogClock mClock;
+ private ImageView mLogo;
+ private BubblesDrawable mBg;
@Override
protected void onPause() {
@@ -69,42 +73,81 @@ public class PlatLogoActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- final float dp = getResources().getDisplayMetrics().density;
- getWindow().getDecorView().setSystemUiVisibility(
- View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
getWindow().setNavigationBarColor(0);
getWindow().setStatusBarColor(0);
final ActionBar ab = getActionBar();
if (ab != null) ab.hide();
- mDialView = new BigDialView(this, null);
- if (Settings.System.getLong(getContentResolver(),
- R_EGG_UNLOCK_SETTING, 0) == 0) {
- mDialView.setUnlockTries(UNLOCK_TRIES);
- } else {
- mDialView.setUnlockTries(0);
- }
-
final FrameLayout layout = new FrameLayout(this);
- layout.setBackgroundColor(0xFFFF0000);
- layout.addView(mDialView, FrameLayout.LayoutParams.MATCH_PARENT,
- FrameLayout.LayoutParams.MATCH_PARENT);
+
+ mClock = new SettableAnalogClock(this);
+
+ final DisplayMetrics dm = getResources().getDisplayMetrics();
+ final float dp = dm.density;
+ final int minSide = Math.min(dm.widthPixels, dm.heightPixels);
+ final int widgetSize = (int) (minSide * 0.75);
+ final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(widgetSize, widgetSize);
+ lp.gravity = Gravity.CENTER;
+ layout.addView(mClock, lp);
+
+ mLogo = new ImageView(this);
+ mLogo.setVisibility(View.GONE);
+ mLogo.setImageResource(R.drawable.platlogo);
+ layout.addView(mLogo, lp);
+
+ mBg = new BubblesDrawable();
+ mBg.setLevel(0);
+ mBg.avoid = widgetSize / 2;
+ mBg.padding = 0.5f * dp;
+ mBg.minR = 1 * dp;
+ layout.setBackground(mBg);
+
setContentView(layout);
}
+ private boolean shouldWriteSettings() {
+ return getPackageName().equals("android");
+ }
+
private void launchNextStage(boolean locked) {
+ mClock.animate()
+ .alpha(0f).scaleX(0.5f).scaleY(0.5f)
+ .withEndAction(() -> mClock.setVisibility(View.GONE))
+ .start();
+
+ mLogo.setAlpha(0f);
+ mLogo.setScaleX(0.5f);
+ mLogo.setScaleY(0.5f);
+ mLogo.setVisibility(View.VISIBLE);
+ mLogo.animate()
+ .alpha(1f)
+ .scaleX(1f)
+ .scaleY(1f)
+ .setInterpolator(new OvershootInterpolator())
+ .start();
+
+ mLogo.postDelayed(() -> {
+ final ObjectAnimator anim = ObjectAnimator.ofInt(mBg, "level", 0, 10000);
+ anim.setInterpolator(new DecelerateInterpolator(1f));
+ anim.start();
+ },
+ 500
+ );
+
final ContentResolver cr = getContentResolver();
try {
- if (WRITE_SETTINGS) {
+ if (shouldWriteSettings()) {
+ Log.v(TAG, "Saving egg unlock=" + locked);
+ syncTouchPressure();
Settings.System.putLong(cr,
- R_EGG_UNLOCK_SETTING,
+ S_EGG_UNLOCK_SETTING,
locked ? 0 : System.currentTimeMillis());
}
} catch (RuntimeException e) {
- Log.e("com.android.internal.app.PlatLogoActivity", "Can't write settings", e);
+ Log.e(TAG, "Can't write settings", e);
}
try {
@@ -151,7 +194,7 @@ public class PlatLogoActivity extends Activity {
if (mPressureMax >= 0) {
touchData.put("min", mPressureMin);
touchData.put("max", mPressureMax);
- if (WRITE_SETTINGS) {
+ if (shouldWriteSettings()) {
Settings.System.putString(getContentResolver(), TOUCH_STATS,
touchData.toString());
}
@@ -173,44 +216,35 @@ public class PlatLogoActivity extends Activity {
super.onStop();
}
- class BigDialView extends ImageView {
- private static final int COLOR_GREEN = 0xff3ddc84;
- private static final int COLOR_BLUE = 0xff4285f4;
- private static final int COLOR_NAVY = 0xff073042;
- private static final int COLOR_ORANGE = 0xfff86734;
- private static final int COLOR_CHARTREUSE = 0xffeff7cf;
- private static final int COLOR_LIGHTBLUE = 0xffd7effe;
-
- private static final int STEPS = 11;
- private static final float VALUE_CHANGE_MAX = 1f / STEPS;
-
- private BigDialDrawable mDialDrawable;
- private boolean mWasLocked;
-
- BigDialView(Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- init();
- }
-
- BigDialView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- init();
- }
-
- BigDialView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- init();
- }
+ /**
+ * Subclass of AnalogClock that allows the user to flip up the glass and adjust the hands.
+ */
+ public class SettableAnalogClock extends AnalogClock {
+ private int mOverrideHour = -1;
+ private int mOverrideMinute = -1;
+ private boolean mOverride = false;
- private void init() {
- mDialDrawable = new BigDialDrawable();
- setImageDrawable(mDialDrawable);
+ public SettableAnalogClock(Context context) {
+ super(context);
}
@Override
- public void onDraw(Canvas c) {
- super.onDraw(c);
+ protected Instant now() {
+ final Instant realNow = super.now();
+ final ZoneId tz = Clock.systemDefaultZone().getZone();
+ final ZonedDateTime zdTime = realNow.atZone(tz);
+ if (mOverride) {
+ if (mOverrideHour < 0) {
+ mOverrideHour = zdTime.getHour();
+ }
+ return Clock.fixed(zdTime
+ .withHour(mOverrideHour)
+ .withMinute(mOverrideMinute)
+ .withSecond(0)
+ .toInstant(), tz).instant();
+ } else {
+ return realNow;
+ }
}
double toPositiveDegrees(double rad) {
@@ -221,226 +255,174 @@ public class PlatLogoActivity extends Activity {
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
- mWasLocked = mDialDrawable.isLocked();
+ mOverride = true;
// pass through
case MotionEvent.ACTION_MOVE:
+ measureTouchPressure(ev);
+
float x = ev.getX();
float y = ev.getY();
- float cx = (getLeft() + getRight()) / 2f;
- float cy = (getTop() + getBottom()) / 2f;
+ float cx = getWidth() / 2f;
+ float cy = getHeight() / 2f;
float angle = (float) toPositiveDegrees(Math.atan2(x - cx, y - cy));
- final int oldLevel = mDialDrawable.getUserLevel();
- mDialDrawable.touchAngle(angle);
- final int newLevel = mDialDrawable.getUserLevel();
- if (oldLevel != newLevel) {
- performHapticFeedback(newLevel == STEPS
- ? HapticFeedbackConstants.CONFIRM
- : HapticFeedbackConstants.CLOCK_TICK);
+
+ int minutes = (75 - (int) (angle / 6)) % 60;
+ int minuteDelta = minutes - mOverrideMinute;
+ if (minuteDelta != 0) {
+ if (Math.abs(minuteDelta) > 45 && mOverrideHour >= 0) {
+ int hourDelta = (minuteDelta < 0) ? 1 : -1;
+ mOverrideHour = (mOverrideHour + 24 + hourDelta) % 24;
+ }
+ mOverrideMinute = minutes;
+ if (mOverrideMinute == 0) {
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ if (getScaleX() == 1f) {
+ setScaleX(1.05f);
+ setScaleY(1.05f);
+ animate().scaleX(1f).scaleY(1f).setDuration(150).start();
+ }
+ } else {
+ performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK);
+ }
+
+ onTimeChanged();
+ postInvalidate();
}
+
return true;
case MotionEvent.ACTION_UP:
- if (mWasLocked != mDialDrawable.isLocked()) {
- launchNextStage(mDialDrawable.isLocked());
+ if (mOverrideMinute == 0 && (mOverrideHour % 12) == 0) {
+ Log.v(TAG, "12:00 let's gooooo");
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ launchNextStage(false);
}
return true;
}
return false;
}
+ }
- @Override
- public boolean performClick() {
- if (mDialDrawable.getUserLevel() < STEPS - 1) {
- mDialDrawable.setUserLevel(mDialDrawable.getUserLevel() + 1);
- performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK);
- }
- return true;
- }
-
- void setUnlockTries(int tries) {
- mDialDrawable.setUnlockTries(tries);
- }
+ static class Bubble {
+ public float x, y, r;
+ public int color;
+ }
- private class BigDialDrawable extends Drawable {
- public final int STEPS = 10;
- private int mUnlockTries = 0;
- final Paint mPaint = new Paint();
- final Drawable mEleven;
- private boolean mNightMode;
- private float mValue = 0f;
- float mElevenAnim = 0f;
- ObjectAnimator mElevenShowAnimator = ObjectAnimator.ofFloat(this, "elevenAnim", 0f,
- 1f).setDuration(300);
- ObjectAnimator mElevenHideAnimator = ObjectAnimator.ofFloat(this, "elevenAnim", 1f,
- 0f).setDuration(500);
-
- BigDialDrawable() {
- mNightMode = getContext().getResources().getConfiguration().isNightModeActive();
- mEleven = getContext().getDrawable(R.drawable.ic_number11);
- mElevenShowAnimator.setInterpolator(new PathInterpolator(0.4f, 0f, 0.2f, 1f));
- mElevenHideAnimator.setInterpolator(new PathInterpolator(0.8f, 0.2f, 0.6f, 1f));
- }
+ class BubblesDrawable extends Drawable {
+ private static final int MAX_BUBBS = 2000;
- public void setUnlockTries(int count) {
- if (mUnlockTries != count) {
- mUnlockTries = count;
- setValue(getValue());
- invalidateSelf();
- }
- }
+ private final int[] mColorIds = {
+ android.R.color.system_accent1_400,
+ android.R.color.system_accent1_500,
+ android.R.color.system_accent1_600,
- boolean isLocked() {
- return mUnlockTries > 0;
- }
+ android.R.color.system_accent2_400,
+ android.R.color.system_accent2_500,
+ android.R.color.system_accent2_600,
+ };
- public void setValue(float v) {
- // until the dial is "unlocked", you can't turn it all the way to 11
- final float max = isLocked() ? 1f - 1f / STEPS : 1f;
- mValue = v < 0f ? 0f : v > max ? max : v;
- invalidateSelf();
- }
+ private int[] mColors = new int[mColorIds.length];
- public float getValue() {
- return mValue;
- }
+ private final Bubble[] mBubbs = new Bubble[MAX_BUBBS];
+ private int mNumBubbs;
- public int getUserLevel() {
- return Math.round(getValue() * STEPS - 0.25f);
- }
+ private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- public void setUserLevel(int i) {
- setValue(getValue() + ((float) i) / STEPS);
- }
+ public float avoid = 0f;
+ public float padding = 0f;
+ public float minR = 0f;
- public float getElevenAnim() {
- return mElevenAnim;
+ BubblesDrawable() {
+ for (int i = 0; i < mColorIds.length; i++) {
+ mColors[i] = getColor(mColorIds[i]);
}
-
- public void setElevenAnim(float f) {
- if (mElevenAnim != f) {
- mElevenAnim = f;
- invalidateSelf();
- }
+ for (int j = 0; j < mBubbs.length; j++) {
+ mBubbs[j] = new Bubble();
}
+ }
- @Override
- public void draw(@NonNull Canvas canvas) {
- final Rect bounds = getBounds();
- final int w = bounds.width();
- final int h = bounds.height();
- final float w2 = w / 2f;
- final float h2 = h / 2f;
- final float radius = w / 4f;
-
- canvas.drawColor(mNightMode ? COLOR_NAVY : COLOR_LIGHTBLUE);
-
- canvas.save();
- canvas.rotate(45, w2, h2);
- canvas.clipRect(w2, h2 - radius, Math.min(w, h), h2 + radius);
- final int gradientColor = mNightMode ? 0x60000020 : (0x10FFFFFF & COLOR_NAVY);
- mPaint.setShader(
- new LinearGradient(w2, h2, Math.min(w, h), h2, gradientColor,
- 0x00FFFFFF & gradientColor, Shader.TileMode.CLAMP));
- mPaint.setColor(Color.BLACK);
- canvas.drawPaint(mPaint);
- mPaint.setShader(null);
- canvas.restore();
-
- mPaint.setStyle(Paint.Style.FILL);
- mPaint.setColor(COLOR_GREEN);
-
- canvas.drawCircle(w2, h2, radius, mPaint);
-
- mPaint.setColor(mNightMode ? COLOR_LIGHTBLUE : COLOR_NAVY);
- final float cx = w * 0.85f;
- for (int i = 0; i < STEPS; i++) {
- final float f = (float) i / STEPS;
- canvas.save();
- final float angle = valueToAngle(f);
- canvas.rotate(-angle, w2, h2);
- canvas.drawCircle(cx, h2, (i <= getUserLevel()) ? 20 : 5, mPaint);
- canvas.restore();
- }
-
- if (mElevenAnim > 0f) {
- final int color = COLOR_ORANGE;
- final int size2 = (int) ((0.5 + 0.5f * mElevenAnim) * w / 14);
- final float cx11 = cx + size2 / 4f;
- mEleven.setBounds((int) cx11 - size2, (int) h2 - size2,
- (int) cx11 + size2, (int) h2 + size2);
- final int alpha = 0xFFFFFF | ((int) clamp(0xFF * 2 * mElevenAnim, 0, 0xFF)
- << 24);
- mEleven.setTint(alpha & color);
- mEleven.draw(canvas);
- }
-
- // don't want to use the rounded value here since the quantization will be visible
- final float angle = valueToAngle(mValue);
-
- // it's easier to draw at far-right and rotate backwards
- canvas.rotate(-angle, w2, h2);
- mPaint.setColor(Color.WHITE);
- final float dimple = w2 / 12f;
- canvas.drawCircle(w - radius - dimple * 2, h2, dimple, mPaint);
+ @Override
+ public void draw(Canvas canvas) {
+ final float f = getLevel() / 10000f;
+ mPaint.setStyle(Paint.Style.FILL);
+ int drawn = 0;
+ for (int j = 0; j < mNumBubbs; j++) {
+ if (mBubbs[j].color == 0 || mBubbs[j].r == 0) continue;
+ mPaint.setColor(mBubbs[j].color);
+ canvas.drawCircle(mBubbs[j].x, mBubbs[j].y, mBubbs[j].r * f, mPaint);
+ drawn++;
}
+ }
- float clamp(float x, float a, float b) {
- return x < a ? a : x > b ? b : x;
- }
+ @Override
+ protected boolean onLevelChange(int level) {
+ invalidateSelf();
+ return true;
+ }
- float angleToValue(float a) {
- return 1f - clamp(a / (360 - 45), 0f, 1f);
- }
+ @Override
+ protected void onBoundsChange(Rect bounds) {
+ super.onBoundsChange(bounds);
+ randomize();
+ }
- // rotation: min is at 4:30, max is at 3:00
- float valueToAngle(float v) {
- return (1f - v) * (360 - 45);
+ private void randomize() {
+ final float w = getBounds().width();
+ final float h = getBounds().height();
+ final float maxR = Math.min(w, h) / 3f;
+ mNumBubbs = 0;
+ if (avoid > 0f) {
+ mBubbs[mNumBubbs].x = w / 2f;
+ mBubbs[mNumBubbs].y = h / 2f;
+ mBubbs[mNumBubbs].r = avoid;
+ mBubbs[mNumBubbs].color = 0;
+ mNumBubbs++;
}
-
- public void touchAngle(float a) {
- final int oldUserLevel = getUserLevel();
- final float newValue = angleToValue(a);
- // this is how we prevent the knob from snapping from max back to min, or from
- // jumping around wherever the user presses. The new value must be pretty close
- // to the
- // previous one.
- if (Math.abs(newValue - getValue()) < VALUE_CHANGE_MAX) {
- setValue(newValue);
-
- if (isLocked() && oldUserLevel != STEPS - 1 && getUserLevel() == STEPS - 1) {
- mUnlockTries--;
- } else if (!isLocked() && getUserLevel() == 0) {
- mUnlockTries = UNLOCK_TRIES;
+ for (int j = 0; j < MAX_BUBBS; j++) {
+ // a simple but time-tested bubble-packing algorithm:
+ // 1. pick a spot
+ // 2. shrink the bubble until it is no longer overlapping any other bubble
+ // 3. if the bubble hasn't popped, keep it
+ int tries = 5;
+ while (tries-- > 0) {
+ float x = (float) Math.random() * w;
+ float y = (float) Math.random() * h;
+ float r = Math.min(Math.min(x, w - x), Math.min(y, h - y));
+
+ // shrink radius to fit other bubbs
+ for (int i = 0; i < mNumBubbs; i++) {
+ r = (float) Math.min(r,
+ Math.hypot(x - mBubbs[i].x, y - mBubbs[i].y) - mBubbs[i].r
+ - padding);
+ if (r < minR) break;
}
- if (!isLocked()) {
- if (getUserLevel() == STEPS && mElevenAnim != 1f
- && !mElevenShowAnimator.isRunning()) {
- mElevenHideAnimator.cancel();
- mElevenShowAnimator.start();
- } else if (getUserLevel() != STEPS && mElevenAnim == 1f
- && !mElevenHideAnimator.isRunning()) {
- mElevenShowAnimator.cancel();
- mElevenHideAnimator.start();
- }
+ if (r >= minR) {
+ // we have found a spot for this bubble to live, let's save it and move on
+ r = Math.min(maxR, r);
+
+ mBubbs[mNumBubbs].x = x;
+ mBubbs[mNumBubbs].y = y;
+ mBubbs[mNumBubbs].r = r;
+ mBubbs[mNumBubbs].color = mColors[(int) (Math.random() * mColors.length)];
+ mNumBubbs++;
+ break;
}
}
}
+ Log.v(TAG, String.format("successfully placed %d bubbles (%d%%)",
+ mNumBubbs, (int) (100f * mNumBubbs / MAX_BUBBS)));
+ }
- @Override
- public void setAlpha(int i) {
- }
+ @Override
+ public void setAlpha(int alpha) { }
- @Override
- public void setColorFilter(@Nullable ColorFilter colorFilter) {
- }
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) { }
- @Override
- public int getOpacity() {
- return PixelFormat.TRANSLUCENT;
- }
+ @Override
+ public int getOpacity() {
+ return TRANSLUCENT;
}
}
-}
-
-
+}
diff --git a/core/java/com/android/internal/widget/ConversationHeaderLinearLayout.java b/core/java/com/android/internal/widget/ConversationHeaderLinearLayout.java
new file mode 100644
index 000000000000..481183e700a2
--- /dev/null
+++ b/core/java/com/android/internal/widget/ConversationHeaderLinearLayout.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.RemoteViews;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * This is a subclass of LinearLayout meant to be used in the Conversation header, to fix a bug
+ * when multiple user-provided strings are shown in the same conversation header. b/189723284
+ *
+ * This works around a deficiency in LinearLayout when shrinking views that it can't fully reduce
+ * all contents if any of the oversized views reaches zero.
+ */
+@RemoteViews.RemoteView
+public class ConversationHeaderLinearLayout extends LinearLayout {
+
+ public ConversationHeaderLinearLayout(Context context) {
+ super(context);
+ }
+
+ public ConversationHeaderLinearLayout(Context context,
+ @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public ConversationHeaderLinearLayout(Context context, @Nullable AttributeSet attrs,
+ int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ private int calculateTotalChildLength() {
+ final int count = getChildCount();
+ int totalLength = 0;
+
+ for (int i = 0; i < count; ++i) {
+ final View child = getChildAt(i);
+ if (child == null || child.getVisibility() == GONE) {
+ continue;
+ }
+ final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)
+ child.getLayoutParams();
+ totalLength += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
+ }
+ return totalLength + getPaddingLeft() + getPaddingRight();
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+ final int containerWidth = getMeasuredWidth();
+ final int contentsWidth = calculateTotalChildLength();
+
+ int excessContents = contentsWidth - containerWidth;
+ if (excessContents <= 0) {
+ return;
+ }
+ final int count = getChildCount();
+
+ float remainingWeight = 0;
+ List<ViewInfo> visibleChildrenToShorten = null;
+
+ // Find children which need to be shortened in order to ensure the contents fit.
+ for (int i = 0; i < count; ++i) {
+ final View child = getChildAt(i);
+ if (child == null || child.getVisibility() == View.GONE) {
+ continue;
+ }
+ final float weight = ((LayoutParams) child.getLayoutParams()).weight;
+ if (weight == 0) {
+ continue;
+ }
+ if (child.getMeasuredWidth() == 0) {
+ continue;
+ }
+ if (visibleChildrenToShorten == null) {
+ visibleChildrenToShorten = new LinkedList<>();
+ }
+ visibleChildrenToShorten.add(new ViewInfo(child));
+ remainingWeight += Math.max(0, weight);
+ }
+ if (visibleChildrenToShorten == null || visibleChildrenToShorten.isEmpty()) {
+ return;
+ }
+ balanceViewWidths(visibleChildrenToShorten, remainingWeight, excessContents);
+ remeasureChangedChildren(visibleChildrenToShorten);
+ }
+
+ /**
+ * Measure any child with a width that has changed.
+ */
+ private void remeasureChangedChildren(List<ViewInfo> childrenInfo) {
+ for (ViewInfo info : childrenInfo) {
+ if (info.mWidth != info.mStartWidth) {
+ final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+ Math.max(0, info.mWidth), MeasureSpec.EXACTLY);
+ final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
+ info.mView.getMeasuredHeight(), MeasureSpec.EXACTLY);
+ info.mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+ }
+ }
+ }
+
+ /**
+ * Given a list of view, use the weights to remove width from each view proportionally to the
+ * weight (and ignoring the view's actual width), but do this iteratively whenever a view is
+ * reduced to zero width, because in that case other views need reduction.
+ */
+ void balanceViewWidths(List<ViewInfo> viewInfos, float weightSum, int excessContents) {
+ boolean performAnotherPass = true;
+ // Loops only when all of the following are true:
+ // * `performAnotherPass` -- a view clamped to 0 width (or the first iteration)
+ // * `excessContents > 0` -- there is still horizontal space to allocate
+ // * `weightSum > 0` -- at least 1 view with nonzero width AND nonzero weight left
+ while (performAnotherPass && excessContents > 0 && weightSum > 0) {
+ int excessRemovedDuringThisPass = 0;
+ float weightSumForNextPass = 0;
+ performAnotherPass = false;
+ for (ViewInfo info : viewInfos) {
+ if (info.mWeight <= 0) {
+ continue;
+ }
+ if (info.mWidth <= 0) {
+ continue;
+ }
+ int newWidth = (int) (info.mWidth - (excessContents * (info.mWeight / weightSum)));
+ if (newWidth < 0) {
+ newWidth = 0;
+ performAnotherPass = true;
+ }
+ excessRemovedDuringThisPass += info.mWidth - newWidth;
+ info.mWidth = newWidth;
+ if (info.mWidth > 0) {
+ weightSumForNextPass += info.mWeight;
+ }
+ }
+ excessContents -= excessRemovedDuringThisPass;
+ weightSum = weightSumForNextPass;
+ }
+ }
+
+ /**
+ * A helper class for measuring children.
+ */
+ static class ViewInfo {
+ final View mView;
+ final float mWeight;
+ final int mStartWidth;
+ int mWidth;
+
+ ViewInfo(View view) {
+ this.mView = view;
+ this.mWeight = ((LayoutParams) view.getLayoutParams()).weight;
+ this.mStartWidth = this.mWidth = view.getMeasuredWidth();
+ }
+ }
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 7b97902da0b1..4dec0ffccb5e 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -5902,8 +5902,8 @@
android:process=":ui">
</activity>
<activity android:name="com.android.internal.app.PlatLogoActivity"
- android:theme="@style/Theme.DeviceDefault.DayNight"
- android:configChanges="orientation|keyboardHidden"
+ android:theme="@style/Theme.DeviceDefault.Wallpaper.NoTitleBar"
+ android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
android:icon="@drawable/platlogo"
android:process=":ui">
</activity>
diff --git a/core/res/res/drawable-hdpi/clock_dial.png b/core/res/res/drawable-hdpi/clock_dial.png
deleted file mode 100644
index 9de29bc0e53e..000000000000
--- a/core/res/res/drawable-hdpi/clock_dial.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/clock_hand_hour.png b/core/res/res/drawable-hdpi/clock_hand_hour.png
deleted file mode 100644
index 9f7e5c02d49c..000000000000
--- a/core/res/res/drawable-hdpi/clock_hand_hour.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/clock_hand_minute.png b/core/res/res/drawable-hdpi/clock_hand_minute.png
deleted file mode 100644
index 2eec38060c45..000000000000
--- a/core/res/res/drawable-hdpi/clock_hand_minute.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/clock_dial.png b/core/res/res/drawable-ldpi/clock_dial.png
deleted file mode 100644
index cbc996185cc7..000000000000
--- a/core/res/res/drawable-ldpi/clock_dial.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/clock_hand_hour.png b/core/res/res/drawable-ldpi/clock_hand_hour.png
deleted file mode 100644
index 3362fd0775d5..000000000000
--- a/core/res/res/drawable-ldpi/clock_hand_hour.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/clock_hand_minute.png b/core/res/res/drawable-ldpi/clock_hand_minute.png
deleted file mode 100644
index 5c73d45ada5c..000000000000
--- a/core/res/res/drawable-ldpi/clock_hand_minute.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/clock_dial.png b/core/res/res/drawable-mdpi/clock_dial.png
deleted file mode 100644
index 82f73fec0423..000000000000
--- a/core/res/res/drawable-mdpi/clock_dial.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/clock_hand_hour.png b/core/res/res/drawable-mdpi/clock_hand_hour.png
deleted file mode 100644
index 1f0aec80ba14..000000000000
--- a/core/res/res/drawable-mdpi/clock_hand_hour.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/clock_hand_minute.png b/core/res/res/drawable-mdpi/clock_hand_minute.png
deleted file mode 100644
index 6cd8a4bfa48d..000000000000
--- a/core/res/res/drawable-mdpi/clock_hand_minute.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-nodpi/clock_dial.xml b/core/res/res/drawable-nodpi/clock_dial.xml
new file mode 100644
index 000000000000..5263218ef880
--- /dev/null
+++ b/core/res/res/drawable-nodpi/clock_dial.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="380dp"
+ android:height="380dp"
+ android:viewportWidth="380"
+ android:viewportHeight="380">
+ <path
+ android:pathData="M177.389,2.803C185.381,-0.934 194.619,-0.934 202.611,2.803L231.193,16.169C234.358,17.649 237.76,18.56 241.242,18.861L272.677,21.577C281.467,22.336 289.468,26.956 294.52,34.188L312.59,60.054C314.591,62.919 317.081,65.409 319.946,67.41L345.812,85.48C353.044,90.533 357.664,98.533 358.423,107.323L361.139,138.758C361.44,142.24 362.351,145.642 363.832,148.807L377.197,177.389C380.934,185.381 380.934,194.619 377.197,202.611L363.832,231.193C362.351,234.359 361.44,237.76 361.139,241.242L358.423,272.677C357.664,281.467 353.044,289.468 345.812,294.52L319.946,312.59C317.081,314.591 314.591,317.081 312.59,319.946L294.52,345.812C289.468,353.044 281.467,357.664 272.677,358.423L241.242,361.139C237.76,361.44 234.359,362.351 231.193,363.832L202.611,377.197C194.619,380.934 185.381,380.934 177.389,377.197L148.807,363.832C145.642,362.351 142.24,361.44 138.758,361.139L107.323,358.423C98.533,357.664 90.533,353.044 85.48,345.812L67.41,319.946C65.409,317.081 62.919,314.591 60.054,312.59L34.188,294.52C26.956,289.468 22.336,281.467 21.577,272.677L18.861,241.242C18.56,237.76 17.649,234.359 16.169,231.193L2.803,202.611C-0.934,194.619 -0.934,185.381 2.803,177.389L16.169,148.807C17.649,145.642 18.56,142.24 18.861,138.758L21.577,107.323C22.336,98.533 26.956,90.533 34.188,85.48L60.054,67.41C62.919,65.409 65.409,62.919 67.41,60.054L85.48,34.188C90.533,26.956 98.533,22.336 107.323,21.577L138.758,18.861C142.24,18.56 145.642,17.649 148.807,16.169L177.389,2.803Z"
+ android:fillColor="@color/system_neutral1_200"/>
+</vector>
diff --git a/core/res/res/drawable-nodpi/clock_hand_hour.xml b/core/res/res/drawable-nodpi/clock_hand_hour.xml
new file mode 100644
index 000000000000..de165a429a57
--- /dev/null
+++ b/core/res/res/drawable-nodpi/clock_hand_hour.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="380dp"
+ android:height="380dp"
+ android:viewportWidth="380"
+ android:viewportHeight="380">
+ <path
+ android:pathData="M190,96L190,96A16,16 0,0 1,206 112L206,190A16,16 0,0 1,190 206L190,206A16,16 0,0 1,174 190L174,112A16,16 0,0 1,190 96z"
+ android:fillColor="@color/system_accent1_700"/>
+</vector>
diff --git a/core/res/res/drawable-nodpi/clock_hand_minute.xml b/core/res/res/drawable-nodpi/clock_hand_minute.xml
new file mode 100644
index 000000000000..72cac6e88597
--- /dev/null
+++ b/core/res/res/drawable-nodpi/clock_hand_minute.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="380dp"
+ android:height="380dp"
+ android:viewportWidth="380"
+ android:viewportHeight="380">
+ <path
+ android:pathData="M190,60L190,60A16,16 0,0 1,206 76L206,190A16,16 0,0 1,190 206L190,206A16,16 0,0 1,174 190L174,76A16,16 0,0 1,190 60z"
+ android:fillColor="@color/system_accent2_500"/>
+</vector>
diff --git a/core/res/res/drawable-nodpi/platlogo.xml b/core/res/res/drawable-nodpi/platlogo.xml
index b01eb3944b50..1d67570cf485 100644
--- a/core/res/res/drawable-nodpi/platlogo.xml
+++ b/core/res/res/drawable-nodpi/platlogo.xml
@@ -1,50 +1,36 @@
+<!--
+Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="512dp"
- android:height="512dp"
- android:viewportWidth="512"
- android:viewportHeight="512">
- <path
- android:fillColor="#F86734"
- android:pathData="M416.23 236.62h-10.67c-1.46 0-2.65-1.19-2.65-2.65v-9.85c0-1.47 1.19-2.65 2.65-2.65h23.37c1.47 0 2.66 1.19 2.66 2.65v66.9c0 1.46-1.2 2.65-2.66 2.65H418.9c-1.47 0-2.66-1.19-2.66-2.65v-54.4z"/>
- <path
- android:fillColor="#F86734"
- android:pathData="M455.51 236.62h-10.67c-1.47 0-2.65-1.19-2.65-2.65v-9.85c0-1.47 1.18-2.65 2.65-2.65h23.37c1.47 0 2.66 1.19 2.66 2.65v66.9c0 1.46-1.2 2.65-2.66 2.65h-10.05c-1.46 0-2.65-1.19-2.65-2.65v-54.4z"/>
- <path
- android:fillColor="#D6F0FF"
- android:pathData="M364.12 400.25a4.34 4.34 0 1 0 0 8.68a4.34 4.34 0 1 0 0-8.68z"/>
- <path
- android:fillColor="#D6F0FF"
- android:pathData="M275.46 433.53a4.84 4.84 0 1 0 0 9.68a4.84 4.84 0 1 0 0-9.68z"/>
- <path
- android:fillColor="#D6F0FF"
- android:pathData="M184.52 418.83a5.36 5.36 0 1 0 0 10.72a5.36 5.36 0 1 0 0-10.72z"/>
- <path
- android:fillColor="#D6F0FF"
- android:pathData="M110.42 359.19a5.89 5.89 0 1 0 0 11.78a5.89 5.89 0 1 0 0-11.78z"/>
- <path
- android:fillColor="#D6F0FF"
- android:pathData="M75.94 270.17a6.43 6.43 0 1 0 0 12.86a6.43 6.43 0 1 0 0-12.86z"/>
- <path
- android:fillColor="#D6F0FF"
- android:pathData="M89.48 178.57a6.98 6.98 0 1 0 0 13.96a6.98 6.98 0 1 0 0-13.96z"/>
- <path
- android:fillColor="#D6F0FF"
- android:pathData="M147.97 103.54a7.54 7.54 0 1 0 0 15.08a7.54 7.54 0 1 0 0-15.08z"/>
- <path
- android:fillColor="#D6F0FF"
- android:pathData="M236.63 66.7a8.1 8.1 0 1 0 0 16.2a8.1 8.1 0 1 0 0-16.2z"/>
- <path
- android:fillColor="#D6F0FF"
- android:pathData="M327.09 78.3a8.66 8.66 0 1 0 0 17.32a8.66 8.66 0 1 0 0-17.32z"/>
- <path
- android:fillColor="#D6F0FF"
- android:pathData="M401.05 136.97a9.22 9.22 0 1 0 0 18.44a9.22 9.22 0 1 0 0-18.44z"/>
- <group>
- <path
- android:fillColor="#3DDB85"
- android:pathData="M255.45 129.46a128.11 128.11 0 1 0 0 256.22a128.11 128.11 0 1 0 0-256.22z"/>
- <path
- android:fillColor="#FFF"
- android:pathData="M339.23 236.09a21.48 21.48 0 1 0 0 42.96a21.48 21.48 0 1 0 0-42.96z"/>
- </group>
+ android:width="128dp"
+ android:height="128dp"
+ android:viewportWidth="128"
+ android:viewportHeight="128">
+ <path
+ android:pathData="M64,64m-64,0a64,64 0,1 1,128 0a64,64 0,1 1,-128 0"
+ android:fillColor="@android:color/system_accent3_500"/>
+ <path
+ android:pathData="M32.5,34.15a10,10 0,0 1,9.94 10V93.85"
+ android:strokeWidth="4"
+ android:fillColor="#00000000"
+ android:strokeColor="#fff"
+ android:strokeLineCap="round"/>
+ <path
+ android:pathData="M95.5,93.85H55.71V83.9A19.9,19.9 0,0 1,75.61 64h10a9.94,9.94 0,0 0,9.94 -10,19.9 19.9,0 0,0 -38.69,-6.56A20.77,20.77 0,0 0,56 50.73"
+ android:strokeWidth="4"
+ android:fillColor="#00000000"
+ android:strokeColor="#fff"
+ android:strokeLineCap="round"/>
</vector>
diff --git a/core/res/res/drawable-xhdpi/clock_dial.png b/core/res/res/drawable-xhdpi/clock_dial.png
deleted file mode 100644
index 6cb60a296ed8..000000000000
--- a/core/res/res/drawable-xhdpi/clock_dial.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/clock_hand_hour.png b/core/res/res/drawable-xhdpi/clock_hand_hour.png
deleted file mode 100644
index bc0c5bd4d59f..000000000000
--- a/core/res/res/drawable-xhdpi/clock_hand_hour.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/clock_hand_minute.png b/core/res/res/drawable-xhdpi/clock_hand_minute.png
deleted file mode 100644
index 01d611fbbdcd..000000000000
--- a/core/res/res/drawable-xhdpi/clock_hand_minute.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/ic_lock.xml b/core/res/res/drawable/ic_lock.xml
index 7582d5f82c1d..c30f96330378 100644
--- a/core/res/res/drawable/ic_lock.xml
+++ b/core/res/res/drawable/ic_lock.xml
@@ -14,14 +14,23 @@ Copyright (C) 2019 The Android Open Source Project
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32dp"
- android:height="32dp"
- android:viewportWidth="32.0"
- android:viewportHeight="32.0">
+ android:width="26dp"
+ android:height="36dp"
+ android:viewportWidth="26"
+ android:viewportHeight="36">
<path
android:fillColor="#FF000000"
- android:pathData="M16,20m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"/>
+ android:pathData="M13.75 27.5 C15.13,27.5 16.25,26.38 16.25,25 C16.25,23.62 15.13,22.5 13.75,22.5 C12.37,22.5 11.25,23.62 11.25,25 C11.25,26.38 12.37,27.5 13.75,27.5c " />
<path
- android:fillColor="#FF000000"
- android:pathData="M24,11h-2.3V7.3c0,-3.1 -2.5,-5.7 -5.7,-5.7c-3.1,0 -5.7,2.5 -5.7,5.7V11H8c-1.3,0 -2.3,1 -2.3,2.3v13.3c0,1.3 1,2.3 2.3,2.3h16c1.3,0 2.3,-1 2.3,-2.3V13.3C26.3,12 25.3,11 24,11zM12.3,7.3c0,-2 1.6,-3.7 3.7,-3.7c2,0 3.7,1.6 3.7,3.7V11h-7.3V7.3zM24.3,26.7c0,0.2 -0.1,0.3 -0.3,0.3H8c-0.2,0 -0.3,-0.1 -0.3,-0.3V13.3C7.7,13.1 7.8,13 8,13h16c0.2,0 0.3,0.1 0.3,0.3V26.7z"/>
+ android:strokeColor="#FF000000"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="2.5"
+ android:pathData="M4.5 15 C4.5,15 23,15 23,15 C24.1,15 25,15.9 25,17 C25,17 25,33 25,33 C25,34.1 24.1,35 23,35 C23,35 4.5,35 4.5,35 C3.4,35 2.5,34.1 2.5,33 C2.5,33 2.5,17 2.5,17 C2.5,15.9 3.4,15 4.5,15c " />
+ <path
+ android:strokeColor="#FF000000"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="2.5"
+ android:pathData="M7.5 15 C7.5,15 7.5,8.61 7.5,8.61 C7.5,5.24 10.3,2.5 13.75,2.5 C17.2,2.5 20,5.24 20,8.61 C20,8.61 20,15 20,15 " />
</vector> \ No newline at end of file
diff --git a/core/res/res/drawable/ic_lock_open.xml b/core/res/res/drawable/ic_lock_open.xml
index e0deb598b1b1..abe6ddebb845 100644
--- a/core/res/res/drawable/ic_lock_open.xml
+++ b/core/res/res/drawable/ic_lock_open.xml
@@ -14,14 +14,23 @@ Copyright (C) 2019 The Android Open Source Project
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32dp"
- android:height="32dp"
- android:viewportWidth="32.0"
- android:viewportHeight="32.0">
+ android:height="36dp"
+ android:width="34dp"
+ android:viewportHeight="36"
+ android:viewportWidth="34">
<path
android:fillColor="#FF000000"
- android:pathData="M16,20m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"/>
+ android:pathData="M13.75 27.5 C15.13,27.5 16.25,26.38 16.25,25 C16.25,23.62 15.13,22.5 13.75,22.5 C12.37,22.5 11.25,23.62 11.25,25 C11.25,26.38 12.37,27.5 13.75,27.5c " />
<path
- android:fillColor="#FF000000"
- android:pathData="M25.3,1.7c-3.1,0 -5.7,2.5 -5.7,5.7V11H8c-1.3,0 -2.3,1 -2.3,2.3v13.3c0,1.3 1,2.3 2.3,2.3h16c1.3,0 2.3,-1 2.3,-2.3V13.3c0,-1.3 -1,-2.3 -2.3,-2.3h-2.3V7.3c0,-2 1.6,-3.7 3.7,-3.7c2,0 3.7,1.6 3.7,3.7V8h2V7.3C31,4.2 28.5,1.7 25.3,1.7zM24.3,13.3v13.3c0,0.2 -0.1,0.3 -0.3,0.3H8c-0.2,0 -0.3,-0.1 -0.3,-0.3V13.3C7.7,13.1 7.8,13 8,13h16C24.2,13 24.3,13.1 24.3,13.3z"/>
+ android:strokeColor="#FF000000"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="2.5"
+ android:pathData=" M4.5 15 C4.5,15 23,15 23,15 C24.1,15 25,15.9 25,17 C25,17 25,33 25,33 C25,34.1 24.1,35 23,35 C23,35 4.5,35 4.5,35 C3.4,35 2.5,34.1 2.5,33 C2.5,33 2.5,17 2.5,17 C2.5,15.9 3.4,15 4.5,15c " />
+ <path
+ android:strokeColor="#FF000000"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="2.5"
+ android:pathData="M20 15 C20,15 20,8.61 20,8.61 C20,5.24 22.8,2.5 26.25,2.5 C29.7,2.5 32.5,5.24 32.5,8.61 C32.5,8.61 32.5,15 32.5,15 " />
</vector> \ No newline at end of file
diff --git a/core/res/res/layout/notification_template_conversation_header.xml b/core/res/res/layout/notification_template_conversation_header.xml
index 389637eb2517..2faff412565e 100644
--- a/core/res/res/layout/notification_template_conversation_header.xml
+++ b/core/res/res/layout/notification_template_conversation_header.xml
@@ -14,7 +14,7 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-<LinearLayout
+<com.android.internal.widget.ConversationHeaderLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/conversation_header"
android:layout_width="wrap_content"
@@ -119,6 +119,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/notification_conversation_header_separating_margin"
+ android:layout_weight="100"
android:showRelative="true"
android:singleLine="true"
android:visibility="gone"
@@ -171,4 +172,4 @@
android:src="@drawable/ic_notifications_alerted"
android:visibility="gone"
/>
-</LinearLayout>
+</com.android.internal.widget.ConversationHeaderLinearLayout>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index f05e18fa2ce3..65e4664589f3 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -2288,8 +2288,8 @@
<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">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; আৰু আটাইবোৰ এপ আৰু সেৱাৰ বাবে"</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">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; আৰু আটাইবোৰ এপ্‌ আৰু সেৱাৰ বাবে"</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-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 47bcbe189570..7ea226b2b261 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -815,7 +815,7 @@
<string name="phoneTypeTtyTdd" msgid="532038552105328779">"TTY TDD"</string>
<string name="phoneTypeWorkMobile" msgid="7522314392003565121">"অফিসের মোবাইল"</string>
<string name="phoneTypeWorkPager" msgid="3748332310638505234">"কার্যক্ষেত্রের পেজার"</string>
- <string name="phoneTypeAssistant" msgid="757550783842231039">"Assistant"</string>
+ <string name="phoneTypeAssistant" msgid="757550783842231039">"অ্যাসিস্ট্যান্ট"</string>
<string name="phoneTypeMms" msgid="1799747455131365989">"MMS"</string>
<string name="eventTypeCustom" msgid="3257367158986466481">"কাস্টম"</string>
<string name="eventTypeBirthday" msgid="7770026752793912283">"জন্মদিন"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 1b5e4b979fff..f388427acab6 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1023,7 +1023,7 @@
<string name="text_copied" msgid="2531420577879738860">"متن در بریده‌دان کپی شد."</string>
<string name="copied" msgid="4675902854553014676">"کپی شد"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> از <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> جای‌گذاری کرد"</string>
- <string name="pasted_from_clipboard" msgid="7355790625710831847">"‫<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> از بریده‌دان جای‌گذاری کرد"</string>
+ <string name="pasted_from_clipboard" msgid="7355790625710831847">"‫<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> محتوا را از بریده‌دان جای‌گذاری کرد"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> نوشتاری را که کپی کردید جای‌گذاری کرد"</string>
<string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> تصویری را که کپی کردید جای‌گذاری کرد"</string>
<string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> محتوایی را که کپی کردید جای‌گذاری کرد"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index c86b8cddb342..17382c453f7f 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1960,7 +1960,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dipilih</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dipilih</item>
</plurals>
- <string name="default_notification_channel_label" msgid="3697928973567217330">"Belum dikategorikan"</string>
+ <string name="default_notification_channel_label" msgid="3697928973567217330">"Tidak dikategorikan"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Anda menyetel nilai penting notifikasi ini."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Ini penting karena orang-orang yang terlibat."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notifikasi aplikasi kustom"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 667dd9c46055..93e25a6b014e 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -2287,10 +2287,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Nú geturðu stækkað hluta skjásins"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Kveikja á í stillingum"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Hunsa"</string>
- <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Opna á hljóðnema tækisins"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Opna fyrir hljóðnema tækisins"</string>
<string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Opna fyrir myndavél tækisins"</string>
<string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Fyrir &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; og öll forrit og þjónustur"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Opna á"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Opna fyrir"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Persónuvernd skynjara"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Forritstákn"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Mynd af merki forrits"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index a7d6ae0d1fbe..0a121539c5a9 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -2287,7 +2287,7 @@
<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_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">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ಮತ್ತು ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳು ಹಾಗೂ ಸೇವೆಗಳಿಗಾಗಿ"</string>
<string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"ನಿರ್ಬಂಧವನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 174d7324dda9..421608687033 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -2287,8 +2287,8 @@
<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_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">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; жана башка бардык колдонмолор менен кызматтар үчүн"</string>
<string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Бөгөттөн чыгаруу"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Сенсордун купуялыгы"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index a76852f84895..85464afadf56 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -1323,7 +1323,7 @@
</string-array>
<string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ଏକ ଅଜଣା ନେଟ୍‌ୱର୍କ ପ୍ରକାର"</string>
<string name="accept" msgid="5447154347815825107">"ଗ୍ରହଣ କରନ୍ତୁ"</string>
- <string name="decline" msgid="6490507610282145874">"ପ୍ରତ୍ୟାଖ୍ୟାନ"</string>
+ <string name="decline" msgid="6490507610282145874">"ଅଗ୍ରାହ୍ୟ କରନ୍ତୁ"</string>
<string name="select_character" msgid="3352797107930786979">"ବର୍ଣ୍ଣ ଲେଖନ୍ତୁ"</string>
<string name="sms_control_title" msgid="4748684259903148341">"SMS ମେସେଜ୍‌ଗୁଡ଼ିକୁ ପଠାଯାଉଛି"</string>
<string name="sms_control_message" msgid="6574313876316388239">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ବହୁତ ସଂଖ୍ୟାର SMS ମେସେଜ୍‍ ପଠାଉଛି। ଏହି ଆପ୍‍ ମେସେଜ୍‍ ପଠାଇବା ଜାରି ରଖିବାକୁ ଆପଣ ଅନୁମତି ଦେବେ କି?"</string>
@@ -1389,7 +1389,7 @@
<string name="sharing_remote_bugreport_notification_title" msgid="3077385149217638550">"ବଗ୍‍ ରିପୋର୍ଟ ସେୟାର୍‌ କରାଯାଉଛି…"</string>
<string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"ଏହି ଡିଭାଇସ୍‌ର ସମସ୍ୟା ସମାଧାନ କରିବା ପାଇଁ ଆପଣଙ୍କର ଆଡମିନ୍‌ ଏକ ବଗ୍‍ ରିପୋର୍ଟ ମାଗିଛନ୍ତି। ଆପ୍‍ ଓ ଡାଟା ଶେୟର୍‌ କରାଯାଇପାରେ।"</string>
<string name="share_remote_bugreport_action" msgid="7630880678785123682">"ସେୟାର୍‌ କରନ୍ତୁ"</string>
- <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ପ୍ରତ୍ୟାଖ୍ୟାନ କରନ୍ତୁ"</string>
+ <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ଅଗ୍ରାହ୍ୟ କରନ୍ତୁ"</string>
<string name="select_input_method" msgid="3971267998568587025">"ଇନପୁଟ୍ ପଦ୍ଧତି ବାଛନ୍ତୁ"</string>
<string name="show_ime" msgid="6406112007347443383">"ଫିଜିକାଲ୍‌ କୀବୋର୍ଡ ସକ୍ରିୟ ଥିବାବେଳେ ଏହାକୁ ସ୍କ୍ରିନ୍‌ ଉପରେ ରଖନ୍ତୁ"</string>
<string name="hardware" msgid="1800597768237606953">"ଭର୍ଚୁଆଲ୍ କୀ’ବୋର୍ଡ ଦେଖାନ୍ତୁ"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index bebdf7a71828..93f2d7420124 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -2355,9 +2355,9 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Zdaj lahko povečate samo del zaslona."</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Vklopite v nastavitvah"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Opusti"</string>
- <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Odblokiranje mikrofona v napravi"</string>
- <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Odblokiranje fotoaparata v napravi"</string>
- <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Za aplikacijo &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ter vse aplikacije in storitve"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Odblokirajte mikrofon v napravi"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Odblokirajte fotoaparat v napravi"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Za aplikacijo &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ter vse aplikacije in storitve."</string>
<string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Odblokiraj"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Zasebnost pri uporabi tipal"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona aplikacije"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 51395222e24c..68a5ce7ee349 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -142,7 +142,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"WLAN"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"WLAN 通话"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
- <string name="wifi_calling_off_summary" msgid="5626710010766902560">"关闭"</string>
+ <string name="wifi_calling_off_summary" msgid="5626710010766902560">"已关闭"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"通过 WLAN 进行通话"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"通过移动网络进行通话"</string>
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"仅限 WLAN"</string>
@@ -1696,8 +1696,8 @@
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"同时按住两个音量键几秒钟,即可开启<xliff:g id="SERVICE">%1$s</xliff:g>无障碍功能。这样做可能会改变您设备的工作方式。\n\n您可以在“设置”&gt;“无障碍”中将此快捷方式更改为开启另一项功能。"</string>
<string name="accessibility_shortcut_on" msgid="5463618449556111344">"开启"</string>
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"不开启"</string>
- <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"开启"</string>
- <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"关闭"</string>
+ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"已开启"</string>
+ <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"已关闭"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"要允许<xliff:g id="SERVICE">%1$s</xliff:g>完全控制您的设备吗?"</string>
<string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"如果您开启<xliff:g id="SERVICE">%1$s</xliff:g>,您的设备将无法使用屏幕锁定功能来增强数据加密效果。"</string>
<string name="accessibility_service_warning_description" msgid="291674995220940133">"对于能满足您的无障碍功能需求的应用,可授予其完全控制权限;但对大部分应用来说,都不适合授予此权限。"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 029ed5b23d84..6d40216adb43 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4804,7 +4804,7 @@
<!-- Blur radius for the Option 3 in R.integer.config_letterboxBackgroundType. Values < 0 are
ignored and 0 is used. -->
- <dimen name="config_letterboxBackgroundWallpaperBlurRadius">100dp</dimen>
+ <dimen name="config_letterboxBackgroundWallpaperBlurRadius">31dp</dimen>
<!-- Alpha of a black translucent scrim showed over wallpaper letterbox background when
the Option 3 is selected for R.integer.config_letterboxBackgroundType.
diff --git a/core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java b/core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java
index 4ef45e2b126b..b59b84bb15ba 100644
--- a/core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java
@@ -580,11 +580,11 @@ public class BstatsCpuTimesValidationTest {
final long[] cpuTimesMs4 = getAllCpuFreqTimes(sTestPkgUid, PROCESS_STATE_TOP);
assertCpuTimesValid(cpuTimesMs4);
actualCpuTimeMs = 0;
- for (int i = 0; i < cpuTimesMs.length / 2; ++i) {
- actualCpuTimeMs += cpuTimesMs[i];
+ for (int i = 0; i < cpuTimesMs4.length / 2; ++i) {
+ actualCpuTimeMs += cpuTimesMs4[i];
}
assertApproximateValue("Incorrect total cpu time, " + msgCpuTimes,
- WORK_DURATION_MS, actualCpuTimeMs);
+ 2 * WORK_DURATION_MS, actualCpuTimeMs);
batteryOffScreenOn();
} finally {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
index 75dd561ffc61..107a3f880354 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
@@ -127,11 +127,13 @@ public class SplashscreenContentDrawer {
* parallel.
*
* @param suggestType Suggest type to create the splash screen view.
- * @param consumer Receiving the SplashScreenView object, which will also be executed
- * on splash screen thread. Note that the view can be null if failed.
+ * @param splashScreenViewConsumer Receiving the SplashScreenView object, which will also be
+ * executed on splash screen thread. Note that the view can be
+ * null if failed.
+ * @param bgColorConsumer Receiving the background color once it's estimated complete.
*/
void createContentView(Context context, @StartingWindowType int suggestType, ActivityInfo info,
- int taskId, Consumer<SplashScreenView> consumer) {
+ int taskId, Consumer<SplashScreenView> splashScreenViewConsumer) {
mSplashscreenWorkerHandler.post(() -> {
SplashScreenView contentView;
try {
@@ -143,7 +145,7 @@ public class SplashscreenContentDrawer {
+ taskId, e);
contentView = null;
}
- consumer.accept(contentView);
+ splashScreenViewConsumer.accept(contentView);
});
}
@@ -160,7 +162,10 @@ public class SplashscreenContentDrawer {
com.android.wm.shell.R.dimen.starting_surface_exit_animation_window_shift_length);
}
- private static int getSystemBGColor() {
+ /**
+ * @return Current system background color.
+ */
+ public static int getSystemBGColor() {
final Context systemContext = ActivityThread.currentApplication();
if (systemContext == null) {
Slog.e(TAG, "System context does not exist!");
@@ -170,12 +175,22 @@ public class SplashscreenContentDrawer {
return res.getColor(com.android.wm.shell.R.color.splash_window_background_default);
}
+ /**
+ * Estimate the background color of the app splash screen, this may take a while so use it only
+ * if there is no starting window exists for that context.
+ **/
+ int estimateTaskBackgroundColor(Context context) {
+ final SplashScreenWindowAttrs windowAttrs = new SplashScreenWindowAttrs();
+ getWindowAttrs(context, windowAttrs);
+ return peekWindowBGColor(context, windowAttrs);
+ }
+
private static Drawable createDefaultBackgroundDrawable() {
return new ColorDrawable(getSystemBGColor());
}
/** Extract the window background color from {@code attrs}. */
- public static int peekWindowBGColor(Context context, SplashScreenWindowAttrs attrs) {
+ private static int peekWindowBGColor(Context context, SplashScreenWindowAttrs attrs) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "peekWindowBGColor");
final Drawable themeBGDrawable;
if (attrs.mWindowBgColor != 0) {
@@ -255,7 +270,7 @@ public class SplashscreenContentDrawer {
* Get the {@link SplashScreenWindowAttrs} from {@code context} and fill them into
* {@code attrs}.
*/
- public static void getWindowAttrs(Context context, SplashScreenWindowAttrs attrs) {
+ private static void getWindowAttrs(Context context, SplashScreenWindowAttrs attrs) {
final TypedArray typedArray = context.obtainStyledAttributes(
com.android.internal.R.styleable.Window);
attrs.mWindowBgResId = typedArray.getResourceId(R.styleable.Window_windowBackground, 0);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurface.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurface.java
index 079d68973852..01c9b6630fa6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurface.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurface.java
@@ -16,6 +16,8 @@
package com.android.wm.shell.startingsurface;
+import android.app.TaskInfo;
+import android.graphics.Color;
/**
* Interface to engage starting window feature.
*/
@@ -27,4 +29,11 @@ public interface StartingSurface {
default IStartingWindow createExternalInterface() {
return null;
}
+
+ /**
+ * Returns the background color for a starting window if existing.
+ */
+ default int getBackgroundColor(TaskInfo taskInfo) {
+ return Color.BLACK;
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index 4dc5447cbe65..243751fe13e8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -26,17 +26,22 @@ import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SNAPSHOT;
import android.annotation.Nullable;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityTaskManager;
+import android.app.ActivityThread;
+import android.app.TaskInfo;
import android.content.Context;
import android.content.pm.ActivityInfo;
+import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
+import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.os.IBinder;
import android.os.RemoteCallback;
+import android.os.RemoteException;
import android.os.Trace;
import android.os.UserHandle;
import android.util.Slog;
@@ -149,6 +154,12 @@ public class StartingSurfaceDrawer {
return context.createDisplayContext(targetDisplay);
}
+ private int getSplashScreenTheme(int splashScreenThemeResId, ActivityInfo activityInfo) {
+ return splashScreenThemeResId != 0
+ ? splashScreenThemeResId
+ : activityInfo.getThemeResource() != 0 ? activityInfo.getThemeResource()
+ : com.android.internal.R.style.Theme_DeviceDefault_DayNight;
+ }
/**
* Called when a task need a splash screen starting window.
*
@@ -170,10 +181,7 @@ public class StartingSurfaceDrawer {
final int taskId = taskInfo.taskId;
Context context = mContext;
// replace with the default theme if the application didn't set
- final int theme = windowInfo.splashScreenThemeResId != 0
- ? windowInfo.splashScreenThemeResId
- : activityInfo.getThemeResource() != 0 ? activityInfo.getThemeResource()
- : com.android.internal.R.style.Theme_DeviceDefault_DayNight;
+ final int theme = getSplashScreenTheme(windowInfo.splashScreenThemeResId, activityInfo);
if (DEBUG_SPLASH_SCREEN) {
Slog.d(TAG, "addSplashScreen " + activityInfo.packageName
+ " theme=" + Integer.toHexString(theme) + " task=" + taskInfo.taskId
@@ -336,6 +344,10 @@ public class StartingSurfaceDrawer {
// the window before first round relayoutWindow, which will happen after insets
// animation.
mChoreographer.postCallback(CALLBACK_INSETS_ANIMATION, setViewSynchronized, null);
+ // Block until we get the background color.
+ final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
+ final SplashScreenView contentView = viewSupplier.get();
+ record.mBGColor = contentView.getInitBackgroundColor();
}
} catch (RuntimeException e) {
// don't crash if something else bad happens, for example a
@@ -346,11 +358,11 @@ public class StartingSurfaceDrawer {
}
int getStartingWindowBackgroundColorForTask(int taskId) {
- StartingWindowRecord startingWindowRecord = mStartingWindowRecords.get(taskId);
- if (startingWindowRecord == null || startingWindowRecord.mContentView == null) {
- return 0;
+ final StartingWindowRecord startingWindowRecord = mStartingWindowRecords.get(taskId);
+ if (startingWindowRecord == null) {
+ return Color.TRANSPARENT;
}
- return startingWindowRecord.mContentView.getInitBackgroundColor();
+ return startingWindowRecord.mBGColor;
}
private static class SplashScreenViewSupplier implements Supplier<SplashScreenView> {
@@ -378,6 +390,43 @@ public class StartingSurfaceDrawer {
}
}
+ int estimateTaskBackgroundColor(TaskInfo taskInfo) {
+ if (taskInfo.topActivityInfo == null) {
+ return Color.TRANSPARENT;
+ }
+ final ActivityInfo activityInfo = taskInfo.topActivityInfo;
+ final String packageName = activityInfo.packageName;
+ final int userId = taskInfo.userId;
+ final Context windowContext;
+ try {
+ windowContext = mContext.createPackageContextAsUser(
+ packageName, Context.CONTEXT_RESTRICTED, UserHandle.of(userId));
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.w(TAG, "Failed creating package context with package name "
+ + packageName + " for user " + taskInfo.userId, e);
+ return Color.TRANSPARENT;
+ }
+ try {
+ final IPackageManager packageManager = ActivityThread.getPackageManager();
+ final String splashScreenThemeName = packageManager.getSplashScreenTheme(packageName,
+ userId);
+ final int splashScreenThemeId = splashScreenThemeName != null
+ ? windowContext.getResources().getIdentifier(splashScreenThemeName, null, null)
+ : 0;
+
+ final int theme = getSplashScreenTheme(splashScreenThemeId, activityInfo);
+
+ if (theme != windowContext.getThemeResId()) {
+ windowContext.setTheme(theme);
+ }
+ return mSplashscreenContentDrawer.estimateTaskBackgroundColor(windowContext);
+ } catch (RuntimeException | RemoteException e) {
+ Slog.w(TAG, "failed get starting window background color at taskId: "
+ + taskInfo.taskId, e);
+ }
+ return Color.TRANSPARENT;
+ }
+
/**
* Called when a task need a snapshot starting window.
*/
@@ -556,19 +605,16 @@ public class StartingSurfaceDrawer {
private SplashScreenView mContentView;
private boolean mSetSplashScreen;
private @StartingWindowType int mSuggestType;
-
- StartingWindowRecord(IBinder appToken, View decorView,
- TaskSnapshotWindow taskSnapshotWindow) {
- mAppToken = appToken;
- mDecorView = decorView;
- mTaskSnapshotWindow = taskSnapshotWindow;
- }
+ private int mBGColor;
StartingWindowRecord(IBinder appToken, View decorView,
TaskSnapshotWindow taskSnapshotWindow, @StartingWindowType int suggestType) {
mAppToken = appToken;
mDecorView = decorView;
mTaskSnapshotWindow = taskSnapshotWindow;
+ if (mTaskSnapshotWindow != null) {
+ mBGColor = mTaskSnapshotWindow.getBackgroundColor();
+ }
mSuggestType = suggestType;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
index eaa89d8e3ab5..e84d498a9258 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
@@ -18,18 +18,23 @@ package com.android.wm.shell.startingsurface;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN;
+import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_NONE;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SNAPSHOT;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
import android.app.ActivityManager.RunningTaskInfo;
+import android.app.TaskInfo;
import android.content.Context;
+import android.graphics.Color;
import android.graphics.Rect;
+import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.Trace;
import android.util.Slog;
+import android.util.SparseIntArray;
import android.view.SurfaceControl;
import android.window.StartingWindowInfo;
import android.window.StartingWindowInfo.StartingWindowType;
@@ -38,6 +43,7 @@ import android.window.TaskSnapshot;
import androidx.annotation.BinderThread;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.function.TriConsumer;
import com.android.wm.shell.common.RemoteCallable;
import com.android.wm.shell.common.ShellExecutor;
@@ -62,10 +68,11 @@ import com.android.wm.shell.common.TransactionPool;
public class StartingWindowController implements RemoteCallable<StartingWindowController> {
private static final String TAG = StartingWindowController.class.getSimpleName();
- // TODO b/183150443 Keep this flag open for a while, several things might need to adjust.
- public static final boolean DEBUG_SPLASH_SCREEN = true;
+ public static final boolean DEBUG_SPLASH_SCREEN = Build.isDebuggable();
public static final boolean DEBUG_TASK_SNAPSHOT = false;
+ private static final long TASK_BG_COLOR_RETAIN_TIME_MS = 5000;
+
private final StartingSurfaceDrawer mStartingSurfaceDrawer;
private final StartingWindowTypeAlgorithm mStartingWindowTypeAlgorithm;
@@ -73,6 +80,11 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
private final StartingSurfaceImpl mImpl = new StartingSurfaceImpl();
private final Context mContext;
private final ShellExecutor mSplashScreenExecutor;
+ /**
+ * Need guarded because it has exposed to StartingSurface
+ */
+ @GuardedBy("mTaskBackgroundColors")
+ private final SparseIntArray mTaskBackgroundColors = new SparseIntArray();
public StartingWindowController(Context context, ShellExecutor splashScreenExecutor,
StartingWindowTypeAlgorithm startingWindowTypeAlgorithm, TransactionPool pool) {
@@ -125,13 +137,19 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
final TaskSnapshot snapshot = windowInfo.mTaskSnapshot;
mStartingSurfaceDrawer.makeTaskSnapshotWindow(windowInfo, appToken,
snapshot);
- } else /* suggestionType == STARTING_WINDOW_TYPE_NONE */ {
- // Don't add a staring window.
}
- if (mTaskLaunchingCallback != null && isSplashScreenType(suggestionType)) {
+ if (suggestionType != STARTING_WINDOW_TYPE_NONE) {
int taskId = runningTaskInfo.taskId;
- int color = mStartingSurfaceDrawer.getStartingWindowBackgroundColorForTask(taskId);
- mTaskLaunchingCallback.accept(taskId, suggestionType, color);
+ int color = mStartingSurfaceDrawer
+ .getStartingWindowBackgroundColorForTask(taskId);
+ if (color != Color.TRANSPARENT) {
+ synchronized (mTaskBackgroundColors) {
+ mTaskBackgroundColors.append(taskId, color);
+ }
+ }
+ if (mTaskLaunchingCallback != null && isSplashScreenType(suggestionType)) {
+ mTaskLaunchingCallback.accept(taskId, suggestionType, color);
+ }
}
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
@@ -163,9 +181,13 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
*/
public void removeStartingWindow(int taskId, SurfaceControl leash, Rect frame,
boolean playRevealAnimation) {
- mSplashScreenExecutor.execute(() -> {
- mStartingSurfaceDrawer.removeStartingWindow(taskId, leash, frame, playRevealAnimation);
- });
+ mSplashScreenExecutor.execute(() -> mStartingSurfaceDrawer.removeStartingWindow(
+ taskId, leash, frame, playRevealAnimation));
+ mSplashScreenExecutor.executeDelayed(() -> {
+ synchronized (mTaskBackgroundColors) {
+ mTaskBackgroundColors.delete(taskId);
+ }
+ }, TASK_BG_COLOR_RETAIN_TIME_MS);
}
/**
@@ -182,6 +204,19 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
mIStartingWindow = new IStartingWindowImpl(StartingWindowController.this);
return mIStartingWindow;
}
+
+ @Override
+ public int getBackgroundColor(TaskInfo taskInfo) {
+ synchronized (mTaskBackgroundColors) {
+ final int index = mTaskBackgroundColors.indexOfKey(taskInfo.taskId);
+ if (index >= 0) {
+ return mTaskBackgroundColors.valueAt(index);
+ }
+ }
+ final int color = mStartingSurfaceDrawer.estimateTaskBackgroundColor(taskInfo);
+ return color != Color.TRANSPARENT
+ ? color : SplashscreenContentDrawer.getSystemBGColor();
+ }
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
index 382d5806e3c2..6052d3dee891 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
@@ -283,6 +283,10 @@ public class TaskSnapshotWindow {
mClearWindowHandler = clearWindowHandler;
}
+ int getBackgroundColor() {
+ return mBackgroundPaint.getColor();
+ }
+
/**
* Ask system bar background painter to draw status bar background.
* @hide
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
index 5061b2369bb2..284f384a3d26 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
@@ -97,7 +97,8 @@ public class StartingSurfaceDrawerTests {
// listen for addView
mAddWindowForTask = taskId;
mViewThemeResId = view.getContext().getThemeResId();
- return true;
+ // Do not wait for background color
+ return false;
}
@Override
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index d8735ce57b65..a743d30939d0 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/Readback.cpp
@@ -183,8 +183,10 @@ CopyResult Readback::copySurfaceInto(ANativeWindow* window, const Rect& inSrcRec
SkPaint paint;
paint.setAlpha(255);
paint.setBlendMode(SkBlendMode::kSrc);
- canvas->drawImageRect(image, imageSrcRect, imageDstRect, sampling, &paint,
- SkCanvas::kFast_SrcRectConstraint);
+ const bool hasBufferCrop = cropRect.left < cropRect.right && cropRect.top < cropRect.bottom;
+ auto constraint =
+ hasBufferCrop ? SkCanvas::kStrict_SrcRectConstraint : SkCanvas::kFast_SrcRectConstraint;
+ canvas->drawImageRect(image, imageSrcRect, imageDstRect, sampling, &paint, constraint);
canvas->restore();
if (!tmpSurface->readPixels(*bitmap, 0, 0)) {
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 44a6e4354608..4e7471d5d888 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -207,12 +207,16 @@ bool SkiaPipeline::createOrUpdateLayer(RenderNode* node, const DamageAccumulator
void SkiaPipeline::prepareToDraw(const RenderThread& thread, Bitmap* bitmap) {
GrDirectContext* context = thread.getGrContext();
- if (context) {
+ if (context && !bitmap->isHardware()) {
ATRACE_FORMAT("Bitmap#prepareToDraw %dx%d", bitmap->width(), bitmap->height());
auto image = bitmap->makeImage();
- if (image.get() && !bitmap->isHardware()) {
+ if (image.get()) {
SkImage_pinAsTexture(image.get(), context);
SkImage_unpinAsTexture(image.get(), context);
+ // A submit is necessary as there may not be a frame coming soon, so without a call
+ // to submit these texture uploads can just sit in the queue building up until
+ // we run out of RAM
+ context->flushAndSubmit();
}
}
}
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 5c4b9019b0ad..db29e342855b 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -130,6 +130,12 @@ void DrawFrameTask::run() {
if (CC_LIKELY(canDrawThisFrame)) {
dequeueBufferDuration = context->draw();
} else {
+ // Do a flush in case syncFrameState performed any texture uploads. Since we skipped
+ // the draw() call, those uploads (or deletes) will end up sitting in the queue.
+ // Do them now
+ if (GrDirectContext* grContext = mRenderThread->getGrContext()) {
+ grContext->flushAndSubmit();
+ }
// wait on fences so tasks don't overlap next frame
context->waitOnFences();
}
diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp
index 93a54445a033..693a027bd0e2 100644
--- a/native/android/surface_control.cpp
+++ b/native/android/surface_control.cpp
@@ -44,70 +44,14 @@ using Transaction = SurfaceComposerClient::Transaction;
LOG_ALWAYS_FATAL_IF(!static_cast<const Rect&>(name).isValid(), \
"invalid arg passed as " #name " argument");
-static bool getWideColorSupport(const sp<SurfaceControl>& surfaceControl) {
- sp<SurfaceComposerClient> client = surfaceControl->getClient();
-
- const sp<IBinder> display = client->getInternalDisplayToken();
- if (display == nullptr) {
- ALOGE("unable to get wide color support for disconnected internal display");
- return false;
- }
-
- bool isWideColorDisplay = false;
- status_t err = client->isWideColorDisplay(display, &isWideColorDisplay);
- if (err) {
- ALOGE("unable to get wide color support");
- return false;
- }
- return isWideColorDisplay;
-}
-
-static bool getHdrSupport(const sp<SurfaceControl>& surfaceControl) {
- sp<SurfaceComposerClient> client = surfaceControl->getClient();
-
- const sp<IBinder> display = client->getInternalDisplayToken();
- if (display == nullptr) {
- ALOGE("unable to get hdr capabilities for disconnected internal display");
- return false;
- }
-
- ui::DynamicDisplayInfo info;
- if (status_t err = client->getDynamicDisplayInfo(display, &info); err != NO_ERROR) {
- ALOGE("unable to get hdr capabilities");
- return err;
- }
-
- return !info.hdrCapabilities.getSupportedHdrTypes().empty();
-}
-
-static bool isDataSpaceValid(const sp<SurfaceControl>& surfaceControl, ADataSpace dataSpace) {
- static_assert(static_cast<int>(ADATASPACE_UNKNOWN) == static_cast<int>(HAL_DATASPACE_UNKNOWN));
- static_assert(static_cast<int>(ADATASPACE_SCRGB_LINEAR) == static_cast<int>(HAL_DATASPACE_V0_SCRGB_LINEAR));
- static_assert(static_cast<int>(ADATASPACE_SRGB) == static_cast<int>(HAL_DATASPACE_V0_SRGB));
- static_assert(static_cast<int>(ADATASPACE_SCRGB) == static_cast<int>(HAL_DATASPACE_V0_SCRGB));
- static_assert(static_cast<int>(ADATASPACE_DISPLAY_P3) == static_cast<int>(HAL_DATASPACE_DISPLAY_P3));
- static_assert(static_cast<int>(ADATASPACE_BT2020_PQ) == static_cast<int>(HAL_DATASPACE_BT2020_PQ));
-
- switch (static_cast<android_dataspace_t>(dataSpace)) {
- case HAL_DATASPACE_UNKNOWN:
- case HAL_DATASPACE_V0_SRGB:
- return true;
- // These data space need wide gamut support.
- case HAL_DATASPACE_V0_SCRGB_LINEAR:
- case HAL_DATASPACE_V0_SCRGB:
- case HAL_DATASPACE_DISPLAY_P3:
- return getWideColorSupport(surfaceControl);
- // These data space need HDR support.
- case HAL_DATASPACE_BT2020_PQ:
- if (!getHdrSupport(surfaceControl)) {
- ALOGE("Invalid dataspace - device does not support hdr");
- return false;
- }
- return true;
- default:
- return false;
- }
-}
+static_assert(static_cast<int>(ADATASPACE_UNKNOWN) == static_cast<int>(HAL_DATASPACE_UNKNOWN));
+static_assert(static_cast<int>(ADATASPACE_SCRGB_LINEAR) ==
+ static_cast<int>(HAL_DATASPACE_V0_SCRGB_LINEAR));
+static_assert(static_cast<int>(ADATASPACE_SRGB) == static_cast<int>(HAL_DATASPACE_V0_SRGB));
+static_assert(static_cast<int>(ADATASPACE_SCRGB) == static_cast<int>(HAL_DATASPACE_V0_SCRGB));
+static_assert(static_cast<int>(ADATASPACE_DISPLAY_P3) ==
+ static_cast<int>(HAL_DATASPACE_DISPLAY_P3));
+static_assert(static_cast<int>(ADATASPACE_BT2020_PQ) == static_cast<int>(HAL_DATASPACE_BT2020_PQ));
Transaction* ASurfaceTransaction_to_Transaction(ASurfaceTransaction* aSurfaceTransaction) {
return reinterpret_cast<Transaction*>(aSurfaceTransaction);
@@ -580,10 +524,6 @@ void ASurfaceTransaction_setBufferDataSpace(ASurfaceTransaction* aSurfaceTransac
CHECK_NOT_NULL(aSurfaceControl);
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
- if (!isDataSpaceValid(surfaceControl, aDataSpace)) {
- ALOGE("Failed to set buffer dataspace - invalid dataspace");
- return;
- }
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
transaction->setDataspace(surfaceControl, static_cast<ui::Dataspace>(aDataSpace));
}
@@ -650,10 +590,6 @@ void ASurfaceTransaction_setColor(ASurfaceTransaction* aSurfaceTransaction,
CHECK_NOT_NULL(aSurfaceControl);
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
- if (!isDataSpaceValid(surfaceControl, dataspace)) {
- ALOGE("Failed to set buffer dataspace - invalid dataspace");
- return;
- }
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
half3 color;
diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
index 2cf872cc7c71..1dcd3375c1cf 100644
--- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
@@ -20,7 +20,7 @@
<string name="chooser_title" msgid="2262294130493605839">"Choisissez un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> qui sera géré par &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
<string name="profile_name_watch" msgid="576290739483672360">"montre"</string>
- <string name="confirmation_title" msgid="8455544820286920304">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pour gérer votre &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="confirmation_title" msgid="8455544820286920304">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à gérer votre &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_summary" msgid="2059360676631420073">"Cette application est nécessaire pour gérer votre <xliff:g id="PROFILE_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
<string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
<string name="consent_no" msgid="2640796915611404382">"Ne pas autoriser"</string>
diff --git a/packages/PrintSpooler/res/values-ta/strings.xml b/packages/PrintSpooler/res/values-ta/strings.xml
index 4bb167a07010..eaf05b104046 100644
--- a/packages/PrintSpooler/res/values-ta/strings.xml
+++ b/packages/PrintSpooler/res/values-ta/strings.xml
@@ -102,7 +102,7 @@
<item msgid="4061931020926489228">"உறுவப்படம்"</item>
<item msgid="3199660090246166812">"நிலத்தோற்றம்"</item>
</string-array>
- <string name="print_write_error_message" msgid="5787642615179572543">"கோப்பில் எழுத முடியவில்லை"</string>
+ <string name="print_write_error_message" msgid="5787642615179572543">"ஃபைலில் எழுத முடியவில்லை"</string>
<string name="print_error_default_message" msgid="8602678405502922346">"செயல்படவில்லை. மீண்டும் முயலவும்."</string>
<string name="print_error_retry" msgid="1426421728784259538">"மீண்டும் முயலவும்"</string>
<string name="print_error_printer_unavailable" msgid="8985614415253203381">"இப்போது பிரிண்டர் இல்லை."</string>
diff --git a/packages/Shell/res/values-ta/strings.xml b/packages/Shell/res/values-ta/strings.xml
index a906abede3fd..30d087368d40 100644
--- a/packages/Shell/res/values-ta/strings.xml
+++ b/packages/Shell/res/values-ta/strings.xml
@@ -32,7 +32,7 @@
<string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"மீண்டும் காட்டாதே"</string>
<string name="bugreport_storage_title" msgid="5332488144740527109">"பிழை அறிக்கைகள்"</string>
<string name="bugreport_unreadable_text" msgid="586517851044535486">"பிழை அறிக்கையைப் படிக்க முடியவில்லை"</string>
- <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"பிழை அறிக்கை விவரங்களை ஜிப் கோப்பில் சேர்க்க முடியவில்லை"</string>
+ <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"பிழை அறிக்கை விவரங்களை ஜிப் ஃபைலில் சேர்க்க முடியவில்லை"</string>
<string name="bugreport_unnamed" msgid="2800582406842092709">"பெயரிடப்படாதது"</string>
<string name="bugreport_info_action" msgid="2158204228510576227">"விவரங்கள்"</string>
<string name="bugreport_screenshot_action" msgid="8677781721940614995">"ஸ்கிரீன்ஷாட்"</string>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 8963ddaece35..1b2aefcd6ff0 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -451,6 +451,7 @@
<!-- started from SensoryPrivacyService -->
<activity android:name=".sensorprivacy.SensorUseStartedActivity"
android:exported="true"
+ android:launchMode="singleTop"
android:permission="android.permission.MANAGE_SENSOR_PRIVACY"
android:theme="@style/Theme.SystemUI.Dialog.Alert"
android:finishOnCloseSystemDialogs="true">
diff --git a/packages/SystemUI/animation/Android.bp b/packages/SystemUI/animation/Android.bp
index 761b1f460bb5..1b15d20d2c52 100644
--- a/packages/SystemUI/animation/Android.bp
+++ b/packages/SystemUI/animation/Android.bp
@@ -36,7 +36,6 @@ android_library {
static_libs: [
"PluginCoreLib",
- "WindowManager-Shell",
],
manifest: "AndroidManifest.xml",
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
index ac9298dc9e89..a50efd731cf6 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
@@ -7,6 +7,7 @@ import android.app.ActivityManager
import android.app.ActivityTaskManager
import android.app.AppGlobals
import android.app.PendingIntent
+import android.app.TaskInfo
import android.content.Context
import android.graphics.Matrix
import android.graphics.PorterDuff
@@ -16,7 +17,6 @@ import android.graphics.RectF
import android.graphics.drawable.GradientDrawable
import android.os.Looper
import android.os.RemoteException
-import android.os.UserHandle
import android.util.Log
import android.util.MathUtils
import android.view.IRemoteAnimationFinishedCallback
@@ -31,20 +31,18 @@ import android.view.animation.AnimationUtils
import android.view.animation.PathInterpolator
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.policy.ScreenDecorationsUtils
-import com.android.wm.shell.startingsurface.SplashscreenContentDrawer
-import com.android.wm.shell.startingsurface.SplashscreenContentDrawer.SplashScreenWindowAttrs
import kotlin.math.roundToInt
+private const val TAG = "ActivityLaunchAnimator"
+
/**
* A class that allows activities to be started in a seamless way from a view that is transforming
* nicely into the starting window.
*/
class ActivityLaunchAnimator(
- private val keyguardHandler: KeyguardHandler,
+ private val callback: Callback,
context: Context
) {
- private val TAG = this::class.java.simpleName
-
companion object {
const val ANIMATION_DURATION = 500L
private const val ANIMATION_DURATION_FADE_OUT_CONTENT = 150L
@@ -120,7 +118,7 @@ class ActivityLaunchAnimator(
Log.d(TAG, "Starting intent with a launch animation")
val runner = Runner(controller)
- val isOnKeyguard = keyguardHandler.isOnKeyguard()
+ val isOnKeyguard = callback.isOnKeyguard()
// Pass the RemoteAnimationAdapter to the intent starter only if we are not on the keyguard.
val animationAdapter = if (!isOnKeyguard) {
@@ -163,7 +161,7 @@ class ActivityLaunchAnimator(
// Hide the keyguard using the launch animation instead of the default unlock animation.
if (isOnKeyguard) {
- keyguardHandler.hideKeyguardWithAnimation(runner)
+ callback.hideKeyguardWithAnimation(runner)
}
}
}
@@ -212,7 +210,7 @@ class ActivityLaunchAnimator(
fun startPendingIntent(animationAdapter: RemoteAnimationAdapter?): Int
}
- interface KeyguardHandler {
+ interface Callback {
/** Whether we are currently on the keyguard or not. */
fun isOnKeyguard(): Boolean
@@ -221,6 +219,9 @@ class ActivityLaunchAnimator(
/** Enable/disable window blur so they don't overlap with the window launch animation **/
fun setBlursDisabledForAppLaunch(disabled: Boolean)
+
+ /* Get the background color of [task]. */
+ fun getBackgroundColor(task: TaskInfo): Int
}
/**
@@ -233,11 +234,21 @@ class ActivityLaunchAnimator(
/**
* Return a [Controller] that will animate and expand [view] into the opening window.
*
- * Important: The view must be attached to the window when calling this function and
- * during the animation.
+ * Important: The view must be attached to a [ViewGroup] when calling this function and
+ * during the animation. For safety, this method will return null when it is not.
*/
@JvmStatic
- fun fromView(view: View, cujType: Int? = null): Controller {
+ fun fromView(view: View, cujType: Int? = null): Controller? {
+ if (view.parent !is ViewGroup) {
+ // TODO(b/192194319): Throw instead of just logging.
+ Log.wtf(
+ TAG,
+ "Skipping animation as view $view is not attached to a ViewGroup",
+ Exception()
+ )
+ return null
+ }
+
return GhostedViewLaunchAnimatorController(view, cujType)
}
}
@@ -474,7 +485,7 @@ class ActivityLaunchAnimator(
// which is usually the same color of the app background. We first fade in this layer
// to hide the expanding view, then we fade it out with SRC mode to draw a hole in the
// launch container and reveal the opening window.
- val windowBackgroundColor = extractSplashScreenBackgroundColor(window)
+ val windowBackgroundColor = callback.getBackgroundColor(window.taskInfo)
val windowBackgroundLayer = GradientDrawable().apply {
setColor(windowBackgroundColor)
alpha = 0
@@ -490,7 +501,7 @@ class ActivityLaunchAnimator(
animator.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator?, isReverse: Boolean) {
Log.d(TAG, "Animation started")
- keyguardHandler.setBlursDisabledForAppLaunch(true)
+ callback.setBlursDisabledForAppLaunch(true)
controller.onLaunchAnimationStart(isExpandingFullyAbove)
// Add the drawable to the launch container overlay. Overlays always draw
@@ -501,7 +512,7 @@ class ActivityLaunchAnimator(
override fun onAnimationEnd(animation: Animator?) {
Log.d(TAG, "Animation ended")
- keyguardHandler.setBlursDisabledForAppLaunch(false)
+ callback.setBlursDisabledForAppLaunch(false)
iCallback?.invoke()
controller.onLaunchAnimationEnd(isExpandingFullyAbove)
launchContainerOverlay.remove(windowBackgroundLayer)
@@ -553,36 +564,6 @@ class ActivityLaunchAnimator(
animator.start()
}
- /** Extract the background color of the app splash screen. */
- private fun extractSplashScreenBackgroundColor(window: RemoteAnimationTarget): Int {
- val taskInfo = window.taskInfo
- val windowPackage = taskInfo.topActivity.packageName
- val userId = taskInfo.userId
- val windowContext = context.createPackageContextAsUser(
- windowPackage, Context.CONTEXT_RESTRICTED, UserHandle.of(userId))
- val activityInfo = taskInfo.topActivityInfo
- val splashScreenThemeName = packageManager.getSplashScreenTheme(windowPackage, userId)
- val splashScreenThemeId = if (splashScreenThemeName != null) {
- windowContext.resources.getIdentifier(splashScreenThemeName, null, null)
- } else {
- 0
- }
-
- val themeResId = when {
- splashScreenThemeId != 0 -> splashScreenThemeId
- activityInfo.themeResource != 0 -> activityInfo.themeResource
- else -> com.android.internal.R.style.Theme_DeviceDefault_DayNight
- }
-
- if (themeResId != windowContext.themeResId) {
- windowContext.setTheme(themeResId)
- }
-
- val windowAttrs = SplashScreenWindowAttrs()
- SplashscreenContentDrawer.getWindowAttrs(windowContext, windowAttrs)
- return SplashscreenContentDrawer.peekWindowBGColor(windowContext, windowAttrs)
- }
-
private fun applyStateToWindow(window: RemoteAnimationTarget, state: State) {
val screenBounds = window.screenSpaceBounds
val centerX = (screenBounds.left + screenBounds.right) / 2f
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
index ffb7ab4eff7c..b4ffb3f6cf4e 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
@@ -9,6 +9,7 @@ import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.InsetDrawable
import android.graphics.drawable.LayerDrawable
+import android.util.Log
import android.view.GhostView
import android.view.View
import android.view.ViewGroup
@@ -17,13 +18,15 @@ import android.widget.FrameLayout
import com.android.internal.jank.InteractionJankMonitor
import kotlin.math.min
+private const val TAG = "GhostedViewLaunchAnimatorController"
+
/**
* A base implementation of [ActivityLaunchAnimator.Controller] which creates a [ghost][GhostView]
* of [ghostedView] as well as an expandable background view, which are drawn and animated instead
* of the ghosted view.
*
- * Important: [ghostedView] must be attached to the window when calling this function and during the
- * animation.
+ * Important: [ghostedView] must be attached to a [ViewGroup] when calling this function and during
+ * the animation.
*
* Note: Avoid instantiating this directly and call [ActivityLaunchAnimator.Controller.fromView]
* whenever possible instead.
@@ -113,6 +116,13 @@ open class GhostedViewLaunchAnimatorController(
}
override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
+ if (ghostedView.parent !is ViewGroup) {
+ // This should usually not happen, but let's make sure we don't crash if the view was
+ // detached right before we started the animation.
+ Log.w(TAG, "Skipping animation as ghostedView is not attached to a ViewGroup")
+ return
+ }
+
backgroundView = FrameLayout(launchContainer.context)
launchContainerOverlay.add(backgroundView)
@@ -138,7 +148,7 @@ open class GhostedViewLaunchAnimatorController(
progress: Float,
linearProgress: Float
) {
- val ghostView = this.ghostView!!
+ val ghostView = this.ghostView ?: return
val backgroundView = this.backgroundView!!
if (!state.visible) {
@@ -173,6 +183,11 @@ open class GhostedViewLaunchAnimatorController(
}
override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
+ if (ghostView == null) {
+ // We didn't actually run the animation.
+ return
+ }
+
cujType?.let { InteractionJankMonitor.getInstance().end(it) }
backgroundDrawable?.wrapped?.alpha = startBackgroundAlpha
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/DetailAdapter.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/DetailAdapter.java
index 95c2d2efcd89..6d1408d5d212 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/DetailAdapter.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/DetailAdapter.java
@@ -72,7 +72,8 @@ public interface DetailAdapter {
}
/**
- * @return if detail panel should animate when shown or closed
+ * Indicates whether the detail view wants to animate when shown. This has no affect over the
+ * closing animation. Detail panels will always animate when closed.
*/
default boolean shouldAnimate() {
return true;
diff --git a/packages/SystemUI/res/anim/fp_to_unlock.xml b/packages/SystemUI/res/anim/fp_to_unlock.xml
new file mode 100644
index 000000000000..a348208f48c7
--- /dev/null
+++ b/packages/SystemUI/res/anim/fp_to_unlock.xml
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android">
+ <aapt:attr name="android:drawable">
+ <vector android:height="65dp" android:width="46dp" android:viewportHeight="65" android:viewportWidth="46">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_1_G_N_7_T_0" android:translateX="-27" android:translateY="-17.5">
+ <group android:name="_R_G_L_1_G" android:translateX="30.75" android:translateY="25.75">
+ <path android:name="_R_G_L_1_G_D_0_P_0" android:strokeColor="#b7f29f" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2.5" android:strokeAlpha="1" android:pathData=" M27.52 38.98 C26.49,39.95 25.29,40.73 23.98,41.29 C23.17,41.65 22.31,41.91 21.41,42.07 C20.74,42.19 20.05,42.25 19.34,42.25 C18.44,42.25 17.56,42.15 16.72,41.96 C15.93,41.77 15.16,41.51 14.43,41.18 C13.23,40.63 12.13,39.88 11.16,38.98 " />
+ <path android:name="_R_G_L_1_G_D_1_P_0" android:strokeColor="#b7f29f" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2.5" android:strokeAlpha="1" android:pathData=" M8.64 34.07 C7.89,31.97 7.89,29.85 7.89,29.85 C7.89,24.05 12.81,19.34 19.34,19.34 C25.87,19.34 30.8,24.05 30.8,29.85 C30.8,29.85 30.8,30.16 30.8,30.16 C30.8,32.32 29.04,34.07 26.89,34.07 C25.28,34.07 23.86,33.1 23.27,31.61 C23.27,31.61 21.96,28.34 21.96,28.34 C21.37,26.85 19.93,25.89 18.34,25.89 C16.18,25.89 14.43,27.64 14.43,29.8 C14.43,31.42 14.87,32.99 15.68,34.36 C16.22,35.26 16.93,36.08 17.77,36.75 C17.77,36.75 18.52,37.34 18.52,37.34 " />
+ <path android:name="_R_G_L_1_G_D_2_P_0" android:strokeColor="#b7f29f" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2.5" android:strokeAlpha="1" android:pathData=" M6.25 19.34 C7.48,17.3 9.46,15.58 11.9,14.42 C12.93,13.94 14.03,13.55 15.2,13.27 C16.51,12.96 17.9,12.8 19.34,12.8 C20.77,12.8 22.14,12.96 23.45,13.26 C24.9,13.6 26.26,14.12 27.48,14.78 C29.6,15.92 31.32,17.5 32.43,19.34 " />
+ <path android:name="_R_G_L_1_G_D_3_P_0" android:strokeColor="#b7f29f" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2.5" android:strokeAlpha="1" android:pathData=" M9.52 8.7 C10.98,7.91 12.58,7.28 14.28,6.86 C15.89,6.46 17.58,6.25 19.34,6.25 C21.06,6.25 22.72,6.45 24.3,6.83 C26.04,7.25 27.67,7.89 29.16,8.7 " />
+ </group>
+ </group>
+ <group android:name="_R_G_L_0_G_N_7_T_0" android:translateX="-27" android:translateY="-17.5">
+ <group android:name="_R_G_L_0_G" android:translateX="47.357" android:translateY="53.25" android:pivotX="2.75" android:pivotY="2.75" android:scaleX="1.41866" android:scaleY="1.41866">
+ <path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#b7f29f" android:fillAlpha="0" android:fillType="nonZero" android:pathData=" M2.75 5.25 C4.13,5.25 5.25,4.13 5.25,2.75 C5.25,1.37 4.13,0.25 2.75,0.25 C1.37,0.25 0.25,1.37 0.25,2.75 C0.25,4.13 1.37,5.25 2.75,5.25c " />
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_1_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData" android:duration="107" android:startOffset="0" android:valueFrom="M27.52 38.98 C26.49,39.95 25.29,40.73 23.98,41.29 C23.17,41.65 22.31,41.91 21.41,42.07 C20.74,42.19 20.05,42.25 19.34,42.25 C18.44,42.25 17.56,42.15 16.72,41.96 C15.93,41.77 15.16,41.51 14.43,41.18 C13.23,40.63 12.13,39.88 11.16,38.98 " android:valueTo="M30.81 32.26 C30.56,32.49 30.27,38.76 29.96,38.9 C29.77,39.46 29.13,39.94 28.57,40.26 C28.15,40.51 26.93,40.65 26.4,40.65 C26.18,40.65 11.91,40.62 11.71,40.58 C10.68,40.53 9.06,39.79 8.89,38.88 C8.6,38.74 8.34,32.48 8.1,32.27 " android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.541,0 0.833,0.767 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="143" android:startOffset="107" android:valueFrom="M30.81 32.26 C30.56,32.49 30.27,38.76 29.96,38.9 C29.77,39.46 29.13,39.94 28.57,40.26 C28.15,40.51 26.93,40.65 26.4,40.65 C26.18,40.65 11.91,40.62 11.71,40.58 C10.68,40.53 9.06,39.79 8.89,38.88 C8.6,38.74 8.34,32.48 8.1,32.27 " android:valueTo="M30.64 30.14 C30.64,30.14 30.64,38.14 30.64,38.14 C30.64,38.77 30.36,39.32 29.91,39.69 C29.57,39.97 29.12,40.14 28.64,40.14 C28.64,40.14 10.14,40.14 10.14,40.14 C9.04,40.14 8.14,39.25 8.14,38.14 C8.14,38.14 8.14,30.14 8.14,30.14 " android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.233 0.331,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_D_1_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="strokeAlpha" android:duration="140" android:startOffset="0" android:valueFrom="1" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="strokeAlpha" android:duration="50" android:startOffset="140" android:valueFrom="1" android:valueTo="0" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_D_1_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData" android:duration="107" android:startOffset="0" android:valueFrom="M8.64 34.07 C7.89,31.97 7.89,29.85 7.89,29.85 C7.89,24.05 12.81,19.34 19.34,19.34 C25.87,19.34 30.8,24.05 30.8,29.85 C30.8,29.85 30.8,30.16 30.8,30.16 C30.8,32.32 29.04,34.07 26.89,34.07 C25.28,34.07 23.86,33.1 23.27,31.61 C23.27,31.61 21.96,28.34 21.96,28.34 C21.37,26.85 19.93,25.89 18.34,25.89 C16.18,25.89 14.43,27.64 14.43,29.8 C14.43,31.42 14.87,32.99 15.68,34.36 C16.22,35.26 16.93,36.08 17.77,36.75 C17.77,36.75 18.52,37.34 18.52,37.34 " android:valueTo="M18.93 32.18 C17.11,32.68 16.62,30.26 16.62,30.26 C16.62,28.78 17.81,27.59 19.39,27.59 C20.96,27.59 22.15,28.78 22.15,30.26 C22.15,30.26 22.15,30.34 22.15,30.34 C22.15,30.89 21.11,32.54 19.57,32.19 C19.19,32.1 20.48,31.09 20.34,30.71 C20.34,30.71 20.02,29.88 20.02,29.88 C19.88,29.5 19.53,29.25 19.15,29.25 C18.63,29.25 18,29.67 18,30.22 C18,30.57 18.06,31.08 18.32,31.51 C18.49,31.8 19.02,32.25 19.79,32.04 C20.41,31.7 20.38,31.36 20.38,31.36 " android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.541,0 0.833,0.767 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="107" android:startOffset="107" android:valueFrom="M18.93 32.18 C17.11,32.68 16.62,30.26 16.62,30.26 C16.62,28.78 17.81,27.59 19.39,27.59 C20.96,27.59 22.15,28.78 22.15,30.26 C22.15,30.26 22.15,30.34 22.15,30.34 C22.15,30.89 21.11,32.54 19.57,32.19 C19.19,32.1 20.48,31.09 20.34,30.71 C20.34,30.71 20.02,29.88 20.02,29.88 C19.88,29.5 19.53,29.25 19.15,29.25 C18.63,29.25 18,29.67 18,30.22 C18,30.57 18.06,31.08 18.32,31.51 C18.49,31.8 19.02,32.25 19.79,32.04 C20.41,31.7 20.38,31.36 20.38,31.36 " android:valueTo="M19.42 31.53 C18.15,31.52 18.11,30.33 18.11,30.33 C18.11,29.59 18.66,28.98 19.4,28.98 C20.13,28.98 20.69,29.59 20.69,30.33 C20.69,30.33 20.69,30.37 20.69,30.37 C20.69,30.64 20.49,30.87 20.25,30.87 C20.07,30.87 19.91,30.74 19.84,30.55 C19.84,30.55 19.69,30.14 19.69,30.14 C19.63,29.94 19.46,29.82 19.28,29.82 C19.04,29.82 18.61,30.02 18.61,30.29 C18.61,30.43 18.6,30.75 18.76,31.03 C18.87,31.21 19.21,31.77 19.96,31.41 C20.69,31.01 20.69,30.34 20.69,30.34 " android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.233 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_D_2_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData" android:duration="250" android:startOffset="0" android:valueFrom="M6.25 19.34 C7.48,17.3 9.46,15.58 11.9,14.42 C12.93,13.94 14.03,13.55 15.2,13.27 C16.51,12.96 17.9,12.8 19.34,12.8 C20.77,12.8 22.14,12.96 23.45,13.26 C24.9,13.6 26.26,14.12 27.48,14.78 C29.6,15.92 31.32,17.5 32.43,19.34 " android:valueTo="M8.14 30.22 C8.14,30.22 8.14,22.22 8.14,22.22 C8.14,21.71 8.33,21.25 8.64,20.9 C9,20.48 9.54,20.22 10.14,20.22 C10.14,20.22 28.64,20.22 28.64,20.22 C29.75,20.22 30.64,21.11 30.64,22.22 C30.64,22.22 30.64,30.14 30.64,30.14 " android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.541,0 0.189,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_D_3_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData" android:duration="95" android:startOffset="0" android:valueFrom="M9.52 8.7 C10.98,7.91 12.58,7.28 14.28,6.86 C15.89,6.46 17.58,6.25 19.34,6.25 C21.06,6.25 22.72,6.45 24.3,6.83 C26.04,7.25 27.67,7.89 29.16,8.7 " android:valueTo="M11.47 14.84 C11.47,14.84 12.21,11.43 13.54,9.84 C14.84,8.28 16.68,7.22 19.35,7.22 C22.01,7.22 23.98,8.4 25.19,10.18 C26.39,11.96 27.25,14.84 27.25,14.84 " android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.541,0 0.833,0.767 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="24" android:startOffset="95" android:valueFrom="M11.47 14.84 C11.47,14.84 12.21,11.43 13.54,9.84 C14.84,8.28 16.68,7.22 19.35,7.22 C22.01,7.22 23.98,8.4 25.19,10.18 C26.39,11.96 27.25,14.84 27.25,14.84 " android:valueTo="M12.11 16.85 C12.11,16.85 12.82,12.71 13.37,11.5 C14.17,9.24 16.38,7.53 19.35,7.53 C22.32,7.53 24.61,9.32 25.35,11.72 C25.61,12.64 26.62,16.85 26.62,16.85 " android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.233 0.833,0.767 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="81" android:startOffset="119" android:valueFrom="M12.11 16.85 C12.11,16.85 12.82,12.71 13.37,11.5 C14.17,9.24 16.38,7.53 19.35,7.53 C22.32,7.53 24.61,9.32 25.35,11.72 C25.61,12.64 26.62,16.85 26.62,16.85 " android:valueTo="M13.12 20.04 C13.12,20.04 13.11,14.15 13.11,14.15 C13.11,10.77 15.91,8.04 19.36,8.04 C22.81,8.04 25.61,10.77 25.61,14.15 C25.61,14.15 25.62,20.04 25.62,20.04 " android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.233 0.261,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="233" android:startOffset="200" android:valueFrom="M13.12 20.04 C13.12,20.04 13.11,14.15 13.11,14.15 C13.11,10.77 15.91,8.04 19.36,8.04 C22.81,8.04 25.61,10.77 25.61,14.15 C25.61,14.15 25.62,20.04 25.62,20.04 " android:valueTo="M37.91 20.05 C37.91,20.05 37.89,14.16 37.89,14.16 C37.89,10.79 35.15,8.05 31.86,8.03 C28.46,8.01 25.61,10.77 25.61,14.15 C25.61,14.15 25.62,20.04 25.62,20.04 " android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.123,0 0.23,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="fillAlpha" android:duration="120" android:startOffset="0" android:valueFrom="0" android:valueTo="0" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="20" android:startOffset="120" android:valueFrom="0" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleX" android:duration="120" android:startOffset="0" android:valueFrom="1.4186600000000003" android:valueTo="1.4186600000000003" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0.43,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="120" android:startOffset="0" android:valueFrom="1.4186600000000003" android:valueTo="1.4186600000000003" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0.43,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="130" android:startOffset="120" android:valueFrom="1.4186600000000003" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0.43,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="130" android:startOffset="120" android:valueFrom="1.4186600000000003" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0.43,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateX" android:duration="517" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/anim/lock_to_unlock.xml b/packages/SystemUI/res/anim/lock_to_unlock.xml
new file mode 100644
index 000000000000..ec51c0171709
--- /dev/null
+++ b/packages/SystemUI/res/anim/lock_to_unlock.xml
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android">
+ <aapt:attr name="android:drawable">
+ <vector android:height="65dp" android:width="46dp" android:viewportHeight="65" android:viewportWidth="46">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_2_G_N_10_N_11_T_0" android:translateX="-27.5" android:translateY="-17.5">
+ <group android:name="_R_G_L_2_G_N_10_T_1" android:translateX="50.25" android:translateY="61">
+ <group android:name="_R_G_L_2_G_N_10_T_0" android:translateX="-13.75" android:translateY="-7.5">
+ <group android:name="_R_G_L_2_G" android:translateX="-0.375" android:translateY="-22.375">
+ <path android:name="_R_G_L_2_G_D_0_P_0" android:strokeColor="#b7f29f" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2.5" android:strokeAlpha="1" android:pathData=" M4.75 15 C4.75,15 23.25,15 23.25,15 C24.35,15 25.25,15.9 25.25,17 C25.25,17 25.25,33 25.25,33 C25.25,34.1 24.35,35 23.25,35 C23.25,35 4.75,35 4.75,35 C3.65,35 2.75,34.1 2.75,33 C2.75,33 2.75,17 2.75,17 C2.75,15.9 3.65,15 4.75,15c " />
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="_R_G_L_1_G_N_10_N_11_T_0" android:translateX="-27.5" android:translateY="-17.5">
+ <group android:name="_R_G_L_1_G_N_10_T_1" android:translateX="50.25" android:translateY="61">
+ <group android:name="_R_G_L_1_G_N_10_T_0" android:translateX="-13.75" android:translateY="-7.5">
+ <group android:name="_R_G_L_1_G" android:translateX="5" android:translateY="-22.5">
+ <path android:name="_R_G_L_1_G_D_0_P_0" android:strokeColor="#b7f29f" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2.5" android:strokeAlpha="1" android:pathData=" M2.5 15 C2.5,15 2.5,8.61 2.5,8.61 C2.5,5.24 5.3,2.5 8.75,2.5 C12.2,2.5 15,5.24 15,8.61 C15,8.61 15,15 15,15 " />
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="_R_G_L_0_G_N_10_N_11_T_0" android:translateX="-27.5" android:translateY="-17.5">
+ <group android:name="_R_G_L_0_G_N_10_T_1" android:translateX="50.25" android:translateY="61">
+ <group android:name="_R_G_L_0_G_N_10_T_0" android:translateX="-13.75" android:translateY="-7.5">
+ <group android:name="_R_G_L_0_G" android:translateX="11" android:translateY="-0.25" android:pivotX="2.75" android:pivotY="2.75" android:scaleX="1" android:scaleY="1">
+ <path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#b7f29f" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M2.75 5.25 C4.13,5.25 5.25,4.13 5.25,2.75 C5.25,1.37 4.13,0.25 2.75,0.25 C1.37,0.25 0.25,1.37 0.25,2.75 C0.25,4.13 1.37,5.25 2.75,5.25c " />
+ </group>
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_2_G_N_10_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateY" android:duration="133" android:startOffset="0" android:valueFrom="61" android:valueTo="57" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.369,0 0.6,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="133" android:startOffset="133" android:valueFrom="57" android:valueTo="62.125" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.436,0 0.58,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="100" android:startOffset="267" android:valueFrom="62.125" android:valueTo="61" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.449,0 0.469,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData" android:duration="67" android:startOffset="0" android:valueFrom="M2.5 15 C2.5,15 2.5,8.61 2.5,8.61 C2.5,5.24 5.3,2.5 8.75,2.5 C12.2,2.5 15,5.24 15,8.61 C15,8.61 15,15 15,15 " android:valueTo="M2.5 9.94 C2.5,9.94 2.5,3.55 2.5,3.55 C2.5,0.17 5.3,-2.56 8.75,-2.56 C12.2,-2.56 15,0.17 15,3.55 C15,3.55 15,15 15,15 " android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.552,0 0.453,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="333" android:startOffset="67" android:valueFrom="M2.5 9.94 C2.5,9.94 2.5,3.55 2.5,3.55 C2.5,0.17 5.3,-2.56 8.75,-2.56 C12.2,-2.56 15,0.17 15,3.55 C15,3.55 15,15 15,15 " android:valueTo="M27.19 14.81 C27.19,14.81 27.19,8.3 27.19,8.3 C27.19,4.92 24.44,2.88 21.19,2.75 C17.74,2.62 15,4.74 15,8.11 C15,8.11 15,15 15,15 " android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.476,0 0.396,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_10_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateY" android:duration="133" android:startOffset="0" android:valueFrom="61" android:valueTo="57" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.369,0 0.6,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="133" android:startOffset="133" android:valueFrom="57" android:valueTo="62.125" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.436,0 0.58,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="100" android:startOffset="267" android:valueFrom="62.125" android:valueTo="61" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.449,0 0.469,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleX" android:duration="100" android:startOffset="0" android:valueFrom="1" android:valueTo="0.8200000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.415,0 0.338,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="100" android:startOffset="0" android:valueFrom="1" android:valueTo="0.8200000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.415,0 0.338,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="283" android:startOffset="100" android:valueFrom="0.8200000000000001" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.249,0 0.529,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="283" android:startOffset="100" android:valueFrom="0.8200000000000001" android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.249,0 0.529,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_N_10_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateY" android:duration="133" android:startOffset="0" android:valueFrom="61" android:valueTo="57" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.369,0 0.6,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="133" android:startOffset="133" android:valueFrom="57" android:valueTo="62.125" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.436,0 0.58,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="100" android:startOffset="267" android:valueFrom="62.125" android:valueTo="61" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.449,0 0.469,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateX" android:duration="517" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/fingerprint_bg.xml b/packages/SystemUI/res/drawable/fingerprint_bg.xml
index 2b0ab6f9a8d2..558ec08b2ceb 100644
--- a/packages/SystemUI/res/drawable/fingerprint_bg.xml
+++ b/packages/SystemUI/res/drawable/fingerprint_bg.xml
@@ -14,10 +14,11 @@
-->
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="oval">
<solid
- android:color="?android:attr/colorBackground"/>
+ android:color="?androidprv:attr/colorSurface"/>
<size
android:width="64dp"
diff --git a/packages/SystemUI/res/layout/auth_biometric_contents.xml b/packages/SystemUI/res/layout/auth_biometric_contents.xml
index 99e8116cb681..3c9e44e2dba9 100644
--- a/packages/SystemUI/res/layout/auth_biometric_contents.xml
+++ b/packages/SystemUI/res/layout/auth_biometric_contents.xml
@@ -52,6 +52,7 @@
android:layout_width="@dimen/biometric_dialog_biometric_icon_size"
android:layout_height="@dimen/biometric_dialog_biometric_icon_size"
android:layout_gravity="center"
+ android:contentDescription="@null"
android:scaleType="fitXY" />
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/people_tile_medium_with_content.xml b/packages/SystemUI/res/layout/people_tile_medium_with_content.xml
index 892f64b3123b..404365629aba 100644
--- a/packages/SystemUI/res/layout/people_tile_medium_with_content.xml
+++ b/packages/SystemUI/res/layout/people_tile_medium_with_content.xml
@@ -131,6 +131,7 @@
<TextView
android:id="@+id/messages_count"
android:gravity="end"
+ android:layout_marginStart="-32dp"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
@@ -147,6 +148,7 @@
android:id="@+id/predefined_icon"
android:tint="?android:attr/textColorSecondary"
android:gravity="end|center_vertical"
+ android:layout_marginStart="-24dp"
android:layout_width="@dimen/regular_predefined_icon"
android:layout_height="@dimen/regular_predefined_icon" />
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index dbbf641e4bf7..b0f1f487b260 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -52,9 +52,26 @@
<include layout="@layout/dock_info_bottom_area_overlay" />
<com.android.keyguard.LockIconView
+ android:id="@+id/lock_icon_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:id="@+id/lock_icon_view" />
+ android:layout_gravity="center">
+ <!-- Background protection -->
+ <ImageView
+ android:id="@+id/lock_icon_bg"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/fingerprint_bg"
+ android:visibility="invisible"/>
+
+ <ImageView
+ android:id="@+id/lock_icon"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="48px"
+ android:layout_gravity="center"
+ android:scaleType="centerCrop"/>
+ </com.android.keyguard.LockIconView>
<com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/udfps_keyguard_view.xml b/packages/SystemUI/res/layout/udfps_keyguard_view.xml
index 33baa4e07dc7..8834ac040b54 100644
--- a/packages/SystemUI/res/layout/udfps_keyguard_view.xml
+++ b/packages/SystemUI/res/layout/udfps_keyguard_view.xml
@@ -30,16 +30,15 @@
android:visibility="gone"/>
<!-- Fingerprint -->
-
<!-- AOD dashed fingerprint icon with moving dashes -->
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/udfps_aod_fp"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:padding="48px"
android:layout_gravity="center"
android:scaleType="centerCrop"
app:lottie_autoPlay="false"
- android:padding="16dp"
app:lottie_loop="true"
app:lottie_rawRes="@raw/udfps_aod_fp"/>
@@ -48,10 +47,10 @@
android:id="@+id/udfps_lockscreen_fp"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:padding="48px"
android:layout_gravity="center"
android:scaleType="centerCrop"
app:lottie_autoPlay="false"
app:lottie_loop="false"
- android:padding="16dp"
app:lottie_rawRes="@raw/udfps_lockscreen_fp"/>
</com.android.systemui.biometrics.UdfpsKeyguardView>
diff --git a/packages/SystemUI/res/raw/udfps_aod_fp.json b/packages/SystemUI/res/raw/udfps_aod_fp.json
index cdac33244345..3247fe74fcfe 100644
--- a/packages/SystemUI/res/raw/udfps_aod_fp.json
+++ b/packages/SystemUI/res/raw/udfps_aod_fp.json
@@ -1,1095 +1,1324 @@
{
- "v": "5.7.8",
- "fr": 60,
- "ip": 0,
- "op": 361,
- "w": 180,
- "h": 185,
- "nm": "fingerprint_burn_in_Loop",
- "ddd": 0,
- "assets": [],
- "layers": [
+ "v":"5.7.8",
+ "fr":60,
+ "ip":0,
+ "op":361,
+ "w":46,
+ "h":65,
+ "nm":"fingerprint_burn_in_Loop_02",
+ "ddd":0,
+ "assets":[
+
+ ],
+ "layers":[
{
- "ddd": 0,
- "ind": 1,
- "ty": 4,
- "nm": "Layer 1 Outlines 10",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
+ "ddd":0,
+ "ind":2,
+ "ty":4,
+ "nm":"Fingerprint_20210701 Outlines 9",
+ "sr":1,
+ "ks":{
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":11
},
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
+ "r":{
+ "a":0,
+ "k":0,
+ "ix":10
},
- "p": {
- "a": 0,
- "k": [
- 91.456,
- 92.206,
+ "p":{
+ "a":0,
+ "k":[
+ 23.091,
+ 32.5,
0
],
- "ix": 2,
- "l": 2
+ "ix":2,
+ "l":2
},
- "a": {
- "a": 0,
- "k": [
- 20,
- 25,
+ "a":{
+ "a":0,
+ "k":[
+ 19.341,
+ 24.25,
0
],
- "ix": 1,
- "l": 2
+ "ix":1,
+ "l":2
},
- "s": {
- "a": 0,
- "k": [
- 350,
- 350,
+ "s":{
+ "a":0,
+ "k":[
+ 100,
+ 100,
100
],
- "ix": 6,
- "l": 2
+ "ix":6,
+ "l":2
}
},
- "ao": 0,
- "shapes": [
+ "ao":0,
+ "shapes":[
{
- "ty": "gr",
- "it": [
+ "ty":"gr",
+ "it":[
{
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
+ "ind":0,
+ "ty":"sh",
+ "ix":1,
+ "ks":{
+ "a":0,
+ "k":{
+ "i":[
[
0,
0
],
[
- -3.684,
+ -1.701,
+ 0.42
+ ],
+ [
+ -1.757,
0
],
[
- -2.883,
- -1.583
+ -1.577,
+ -0.381
+ ],
+ [
+ -1.485,
+ -0.816
]
],
- "o": [
+ "o":[
+ [
+ 1.455,
+ -0.799
+ ],
[
- 2.883,
- -1.583
+ 1.608,
+ -0.397
],
[
- 3.683,
+ 1.719,
0
],
[
+ 1.739,
+ 0.42
+ ],
+ [
0,
0
]
],
- "v": [
+ "v":[
[
- -10.417,
- 1.25
+ -9.818,
+ 1.227
],
[
- 0.001,
- -1.25
+ -5.064,
+ -0.618
+ ],
+ [
+ 0,
+ -1.227
+ ],
+ [
+ 4.96,
+ -0.643
],
[
- 10.417,
- 1.25
+ 9.818,
+ 1.227
]
],
- "c": false
+ "c":false
},
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 17,
- "ix": 2
- },
- "o": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 0,
- "s": [
- 246
- ]
- },
- {
- "t": 360,
- "s": [
- 1326
- ]
- }
- ],
- "ix": 3
+ "ix":2
},
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
+ "nm":"Path 1",
+ "mn":"ADBE Vector Shape - Group",
+ "hd":false
},
{
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
+ "ty":"st",
+ "c":{
+ "a":0,
+ "k":[
1,
1,
1,
1
],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 1,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
+ "ix":3
+ },
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":4
+ },
+ "w":{
+ "a":0,
+ "k":1,
+ "ix":5
+ },
+ "lc":2,
+ "lj":1,
+ "ml":10,
+ "bm":0,
+ "nm":"Stroke 1",
+ "mn":"ADBE Vector Graphic - Stroke",
+ "hd":false
+ },
+ {
+ "ty":"tr",
+ "p":{
+ "a":0,
+ "k":[
+ 19.341,
+ 7.477
+ ],
+ "ix":2
+ },
+ "a":{
+ "a":0,
+ "k":[
+ 0,
+ 0
+ ],
+ "ix":1
+ },
+ "s":{
+ "a":0,
+ "k":[
+ 100,
+ 100
+ ],
+ "ix":3
+ },
+ "r":{
+ "a":0,
+ "k":0,
+ "ix":6
+ },
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":7
+ },
+ "sk":{
+ "a":0,
+ "k":0,
+ "ix":4
+ },
+ "sa":{
+ "a":0,
+ "k":0,
+ "ix":5
+ },
+ "nm":"Transform"
+ }
+ ],
+ "nm":"Top",
+ "np":2,
+ "cix":2,
+ "bm":0,
+ "ix":1,
+ "mn":"ADBE Vector Group",
+ "hd":false
+ },
+ {
+ "ty":"tm",
+ "s":{
+ "a":0,
+ "k":0,
+ "ix":1
+ },
+ "e":{
+ "a":0,
+ "k":17,
+ "ix":2
+ },
+ "o":{
+ "a":1,
+ "k":[
+ {
+ "i":{
+ "x":[
+ 0.833
+ ],
+ "y":[
+ 0.833
+ ]
+ },
+ "o":{
+ "x":[
+ 0.167
+ ],
+ "y":[
+ 0.167
+ ]
+ },
+ "t":0,
+ "s":[
+ 246
+ ]
+ },
+ {
+ "t":360,
+ "s":[
+ 1326
+ ]
+ }
+ ],
+ "ix":3
+ },
+ "m":1,
+ "ix":2,
+ "nm":"Trim Paths 1",
+ "mn":"ADBE Vector Filter - Trim",
+ "hd":false
+ },
+ {
+ "ty":"gr",
+ "it":[
+ {
+ "ty":"tm",
+ "s":{
+ "a":0,
+ "k":0,
+ "ix":1
+ },
+ "e":{
+ "a":0,
+ "k":17,
+ "ix":2
+ },
+ "o":{
+ "a":0,
+ "k":0,
+ "ix":3
+ },
+ "m":1,
+ "ix":1,
+ "nm":"Trim Paths 1",
+ "mn":"ADBE Vector Filter - Trim",
+ "hd":false
},
{
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 19.999,
- 7.5
+ "ty":"tr",
+ "p":{
+ "a":0,
+ "k":[
+ 0,
+ 0
],
- "ix": 2
+ "ix":2
},
- "a": {
- "a": 0,
- "k": [
+ "a":{
+ "a":0,
+ "k":[
0,
0
],
- "ix": 1
+ "ix":1
},
- "s": {
- "a": 0,
- "k": [
+ "s":{
+ "a":0,
+ "k":[
100,
100
],
- "ix": 3
+ "ix":3
},
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
+ "r":{
+ "a":0,
+ "k":0,
+ "ix":6
},
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":7
},
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
+ "sk":{
+ "a":0,
+ "k":0,
+ "ix":4
},
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
+ "sa":{
+ "a":0,
+ "k":0,
+ "ix":5
},
- "nm": "Transform"
+ "nm":"Transform"
}
],
- "nm": "Group 3",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
+ "nm":"Group 1",
+ "np":1,
+ "cix":2,
+ "bm":0,
+ "ix":3,
+ "mn":"ADBE Vector Group",
+ "hd":false
}
],
- "ip": 0,
- "op": 600,
- "st": 0,
- "bm": 0
+ "ip":0,
+ "op":600,
+ "st":0,
+ "bm":0
},
{
- "ddd": 0,
- "ind": 2,
- "ty": 4,
- "nm": "Layer 1 Outlines 5",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
+ "ddd":0,
+ "ind":3,
+ "ty":4,
+ "nm":"Fingerprint_20210701 Outlines 8",
+ "sr":1,
+ "ks":{
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":11
},
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
+ "r":{
+ "a":0,
+ "k":0,
+ "ix":10
},
- "p": {
- "a": 0,
- "k": [
- 91.456,
- 92.206,
+ "p":{
+ "a":0,
+ "k":[
+ 23.091,
+ 32.5,
0
],
- "ix": 2,
- "l": 2
+ "ix":2,
+ "l":2
},
- "a": {
- "a": 0,
- "k": [
- 20,
- 25,
+ "a":{
+ "a":0,
+ "k":[
+ 19.341,
+ 24.25,
0
],
- "ix": 1,
- "l": 2
+ "ix":1,
+ "l":2
},
- "s": {
- "a": 0,
- "k": [
- 350,
- 350,
+ "s":{
+ "a":0,
+ "k":[
+ 100,
+ 100,
100
],
- "ix": 6,
- "l": 2
+ "ix":6,
+ "l":2
}
},
- "ao": 0,
- "shapes": [
+ "ao":0,
+ "shapes":[
{
- "ty": "gr",
- "it": [
+ "ty":"gr",
+ "it":[
{
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
+ "ind":0,
+ "ty":"sh",
+ "ix":1,
+ "ks":{
+ "a":0,
+ "k":{
+ "i":[
[
0,
0
],
[
- -3.684,
+ -1.701,
+ 0.42
+ ],
+ [
+ -1.757,
0
],
[
- -2.883,
- -1.583
+ -1.577,
+ -0.381
+ ],
+ [
+ -1.485,
+ -0.816
]
],
- "o": [
+ "o":[
+ [
+ 1.455,
+ -0.799
+ ],
[
- 2.883,
- -1.583
+ 1.608,
+ -0.397
],
[
- 3.683,
+ 1.719,
0
],
[
+ 1.739,
+ 0.42
+ ],
+ [
0,
0
]
],
- "v": [
+ "v":[
[
- -10.417,
- 1.25
+ -9.818,
+ 1.227
],
[
- 0.001,
- -1.25
+ -5.064,
+ -0.618
+ ],
+ [
+ 0,
+ -1.227
+ ],
+ [
+ 4.96,
+ -0.643
],
[
- 10.417,
- 1.25
+ 9.818,
+ 1.227
]
],
- "c": false
+ "c":false
},
- "ix": 2
+ "ix":2
},
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
+ "nm":"Path 1",
+ "mn":"ADBE Vector Shape - Group",
+ "hd":false
},
{
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 54,
- "ix": 2
- },
- "o": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 0,
- "s": [
- 0
- ]
- },
- {
- "t": 360,
- "s": [
- 1080
- ]
- }
- ],
- "ix": 3
- },
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
+ "ty":"st",
+ "c":{
+ "a":0,
+ "k":[
1,
1,
1,
1
],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 1,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
+ "ix":3
+ },
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":4
+ },
+ "w":{
+ "a":0,
+ "k":1,
+ "ix":5
+ },
+ "lc":2,
+ "lj":1,
+ "ml":10,
+ "bm":0,
+ "nm":"Stroke 1",
+ "mn":"ADBE Vector Graphic - Stroke",
+ "hd":false
},
{
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 19.999,
- 7.5
+ "ty":"tr",
+ "p":{
+ "a":0,
+ "k":[
+ 19.341,
+ 7.477
],
- "ix": 2
+ "ix":2
},
- "a": {
- "a": 0,
- "k": [
+ "a":{
+ "a":0,
+ "k":[
0,
0
],
- "ix": 1
+ "ix":1
},
- "s": {
- "a": 0,
- "k": [
+ "s":{
+ "a":0,
+ "k":[
100,
100
],
- "ix": 3
+ "ix":3
},
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
+ "r":{
+ "a":0,
+ "k":0,
+ "ix":6
},
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":7
},
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
+ "sk":{
+ "a":0,
+ "k":0,
+ "ix":4
},
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
+ "sa":{
+ "a":0,
+ "k":0,
+ "ix":5
},
- "nm": "Transform"
+ "nm":"Transform"
}
],
- "nm": "Group 3",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
+ "nm":"Top",
+ "np":2,
+ "cix":2,
+ "bm":0,
+ "ix":1,
+ "mn":"ADBE Vector Group",
+ "hd":false
+ },
+ {
+ "ty":"tm",
+ "s":{
+ "a":0,
+ "k":0,
+ "ix":1
+ },
+ "e":{
+ "a":0,
+ "k":54,
+ "ix":2
+ },
+ "o":{
+ "a":1,
+ "k":[
+ {
+ "i":{
+ "x":[
+ 0.833
+ ],
+ "y":[
+ 0.833
+ ]
+ },
+ "o":{
+ "x":[
+ 0.167
+ ],
+ "y":[
+ 0.167
+ ]
+ },
+ "t":0,
+ "s":[
+ 0
+ ]
+ },
+ {
+ "t":360,
+ "s":[
+ 1080
+ ]
+ }
+ ],
+ "ix":3
+ },
+ "m":1,
+ "ix":2,
+ "nm":"Trim Paths 1",
+ "mn":"ADBE Vector Filter - Trim",
+ "hd":false
}
],
- "ip": 0,
- "op": 600,
- "st": 0,
- "bm": 0
+ "ip":0,
+ "op":600,
+ "st":0,
+ "bm":0
},
{
- "ddd": 0,
- "ind": 3,
- "ty": 4,
- "nm": "Layer 1 Outlines 8",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
+ "ddd":0,
+ "ind":4,
+ "ty":4,
+ "nm":"Fingerprint_20210701 Outlines 7",
+ "sr":1,
+ "ks":{
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":11
},
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
+ "r":{
+ "a":0,
+ "k":0,
+ "ix":10
},
- "p": {
- "a": 0,
- "k": [
- 91.456,
- 92.206,
+ "p":{
+ "a":0,
+ "k":[
+ 23.091,
+ 32.5,
0
],
- "ix": 2,
- "l": 2
+ "ix":2,
+ "l":2
},
- "a": {
- "a": 0,
- "k": [
- 20,
- 25,
+ "a":{
+ "a":0,
+ "k":[
+ 19.341,
+ 24.25,
0
],
- "ix": 1,
- "l": 2
+ "ix":1,
+ "l":2
},
- "s": {
- "a": 0,
- "k": [
- 350,
- 350,
+ "s":{
+ "a":0,
+ "k":[
+ 100,
+ 100,
100
],
- "ix": 6,
- "l": 2
+ "ix":6,
+ "l":2
}
},
- "ao": 0,
- "shapes": [
+ "ao":0,
+ "shapes":[
{
- "ty": "gr",
- "it": [
+ "ty":"gr",
+ "it":[
{
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
+ "ind":0,
+ "ty":"sh",
+ "ix":1,
+ "ks":{
+ "a":0,
+ "k":{
+ "i":[
[
0,
0
],
[
- -5.883,
+ -2.446,
+ 1.161
+ ],
+ [
+ -1.168,
+ 0.275
+ ],
+ [
+ -1.439,
0
],
[
- -2.367,
- -3.933
+ -1.301,
+ -0.304
+ ],
+ [
+ -1.225,
+ -0.66
+ ],
+ [
+ -1.11,
+ -1.844
]
],
- "o": [
+ "o":[
+ [
+ 1.23,
+ -2.044
+ ],
[
- 2.367,
- -3.933
+ 1.024,
+ -0.486
],
[
- 5.883,
+ 1.312,
+ -0.31
+ ],
+ [
+ 1.425,
0
],
[
+ 1.454,
+ 0.34
+ ],
+ [
+ 2.122,
+ 1.143
+ ],
+ [
0,
0
]
],
- "v": [
+ "v":[
+ [
+ -13.091,
+ 3.273
+ ],
[
- -13.75,
- 3.333
+ -7.438,
+ -1.646
+ ],
+ [
+ -4.14,
+ -2.797
],
[
0,
- -3.333
+ -3.273
+ ],
+ [
+ 4.104,
+ -2.805
],
[
- 13.75,
- 3.333
+ 8.141,
+ -1.29
+ ],
+ [
+ 13.091,
+ 3.273
]
],
- "c": false
+ "c":false
},
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 38.235,
- "ix": 2
- },
- "o": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 0,
- "s": [
- 170
- ]
- },
- {
- "t": 360,
- "s": [
- 890
- ]
- }
- ],
- "ix": 3
+ "ix":2
},
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
+ "nm":"Path 1",
+ "mn":"ADBE Vector Shape - Group",
+ "hd":false
},
{
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
+ "ty":"st",
+ "c":{
+ "a":0,
+ "k":[
1,
1,
1,
1
],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 1,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
+ "ix":3
+ },
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":4
+ },
+ "w":{
+ "a":0,
+ "k":1,
+ "ix":5
+ },
+ "lc":2,
+ "lj":1,
+ "ml":10,
+ "bm":0,
+ "nm":"Stroke 1",
+ "mn":"ADBE Vector Graphic - Stroke",
+ "hd":false
},
{
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 20,
- 16.25
+ "ty":"tr",
+ "p":{
+ "a":0,
+ "k":[
+ 19.341,
+ 16.069
],
- "ix": 2
+ "ix":2
},
- "a": {
- "a": 0,
- "k": [
+ "a":{
+ "a":0,
+ "k":[
0,
0
],
- "ix": 1
+ "ix":1
},
- "s": {
- "a": 0,
- "k": [
+ "s":{
+ "a":0,
+ "k":[
100,
100
],
- "ix": 3
+ "ix":3
},
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
+ "r":{
+ "a":0,
+ "k":0,
+ "ix":6
},
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":7
},
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
+ "sk":{
+ "a":0,
+ "k":0,
+ "ix":4
},
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
+ "sa":{
+ "a":0,
+ "k":0,
+ "ix":5
},
- "nm": "Transform"
+ "nm":"Transform"
}
],
- "nm": "Group 2",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
+ "nm":"Mid Top",
+ "np":2,
+ "cix":2,
+ "bm":0,
+ "ix":1,
+ "mn":"ADBE Vector Group",
+ "hd":false
+ },
+ {
+ "ty":"tm",
+ "s":{
+ "a":0,
+ "k":0,
+ "ix":1
+ },
+ "e":{
+ "a":0,
+ "k":38.2,
+ "ix":2
+ },
+ "o":{
+ "a":1,
+ "k":[
+ {
+ "i":{
+ "x":[
+ 0.833
+ ],
+ "y":[
+ 0.833
+ ]
+ },
+ "o":{
+ "x":[
+ 0.167
+ ],
+ "y":[
+ 0.167
+ ]
+ },
+ "t":0,
+ "s":[
+ 170
+ ]
+ },
+ {
+ "t":360,
+ "s":[
+ 890
+ ]
+ }
+ ],
+ "ix":3
+ },
+ "m":1,
+ "ix":2,
+ "nm":"Trim Paths 1",
+ "mn":"ADBE Vector Filter - Trim",
+ "hd":false
}
],
- "ip": 0,
- "op": 600,
- "st": 0,
- "bm": 0
+ "ip":0,
+ "op":600,
+ "st":0,
+ "bm":0
},
{
- "ddd": 0,
- "ind": 4,
- "ty": 4,
- "nm": "Layer 1 Outlines 4",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
+ "ddd":0,
+ "ind":5,
+ "ty":4,
+ "nm":"Fingerprint_20210701 Outlines 6",
+ "sr":1,
+ "ks":{
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":11
},
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
+ "r":{
+ "a":0,
+ "k":0,
+ "ix":10
},
- "p": {
- "a": 0,
- "k": [
- 91.456,
- 92.206,
+ "p":{
+ "a":0,
+ "k":[
+ 23.091,
+ 32.5,
0
],
- "ix": 2,
- "l": 2
+ "ix":2,
+ "l":2
},
- "a": {
- "a": 0,
- "k": [
- 20,
- 25,
+ "a":{
+ "a":0,
+ "k":[
+ 19.341,
+ 24.25,
0
],
- "ix": 1,
- "l": 2
+ "ix":1,
+ "l":2
},
- "s": {
- "a": 0,
- "k": [
- 350,
- 350,
+ "s":{
+ "a":0,
+ "k":[
+ 100,
+ 100,
100
],
- "ix": 6,
- "l": 2
+ "ix":6,
+ "l":2
}
},
- "ao": 0,
- "shapes": [
+ "ao":0,
+ "shapes":[
{
- "ty": "gr",
- "it": [
+ "ty":"gr",
+ "it":[
{
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
+ "ind":0,
+ "ty":"sh",
+ "ix":1,
+ "ks":{
+ "a":0,
+ "k":{
+ "i":[
[
0,
0
],
[
- -5.883,
+ -2.446,
+ 1.161
+ ],
+ [
+ -1.168,
+ 0.275
+ ],
+ [
+ -1.439,
0
],
[
- -2.367,
- -3.933
+ -1.301,
+ -0.304
+ ],
+ [
+ -1.225,
+ -0.66
+ ],
+ [
+ -1.11,
+ -1.844
]
],
- "o": [
+ "o":[
+ [
+ 1.23,
+ -2.044
+ ],
[
- 2.367,
- -3.933
+ 1.024,
+ -0.486
],
[
- 5.883,
+ 1.312,
+ -0.31
+ ],
+ [
+ 1.425,
0
],
[
+ 1.454,
+ 0.34
+ ],
+ [
+ 2.122,
+ 1.143
+ ],
+ [
0,
0
]
],
- "v": [
+ "v":[
+ [
+ -13.091,
+ 3.273
+ ],
+ [
+ -7.438,
+ -1.646
+ ],
[
- -13.75,
- 3.333
+ -4.14,
+ -2.797
],
[
0,
- -3.333
+ -3.273
+ ],
+ [
+ 4.104,
+ -2.805
+ ],
+ [
+ 8.141,
+ -1.29
],
[
- 13.75,
- 3.333
+ 13.091,
+ 3.273
]
],
- "c": false
+ "c":false
},
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 34.235,
- "ix": 2
- },
- "o": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 0,
- "s": [
- 0
- ]
- },
- {
- "t": 360,
- "s": [
- 720
- ]
- }
- ],
- "ix": 3
+ "ix":2
},
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
+ "nm":"Path 1",
+ "mn":"ADBE Vector Shape - Group",
+ "hd":false
},
{
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
+ "ty":"st",
+ "c":{
+ "a":0,
+ "k":[
1,
1,
1,
1
],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 1,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
+ "ix":3
+ },
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":4
+ },
+ "w":{
+ "a":0,
+ "k":1,
+ "ix":5
+ },
+ "lc":2,
+ "lj":1,
+ "ml":10,
+ "bm":0,
+ "nm":"Stroke 1",
+ "mn":"ADBE Vector Graphic - Stroke",
+ "hd":false
},
{
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 20,
- 16.25
+ "ty":"tr",
+ "p":{
+ "a":0,
+ "k":[
+ 19.341,
+ 16.069
],
- "ix": 2
+ "ix":2
},
- "a": {
- "a": 0,
- "k": [
+ "a":{
+ "a":0,
+ "k":[
0,
0
],
- "ix": 1
+ "ix":1
},
- "s": {
- "a": 0,
- "k": [
+ "s":{
+ "a":0,
+ "k":[
100,
100
],
- "ix": 3
+ "ix":3
},
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
+ "r":{
+ "a":0,
+ "k":0,
+ "ix":6
},
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":7
},
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
+ "sk":{
+ "a":0,
+ "k":0,
+ "ix":4
},
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
+ "sa":{
+ "a":0,
+ "k":0,
+ "ix":5
},
- "nm": "Transform"
+ "nm":"Transform"
}
],
- "nm": "Group 2",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
+ "nm":"Mid Top",
+ "np":2,
+ "cix":2,
+ "bm":0,
+ "ix":1,
+ "mn":"ADBE Vector Group",
+ "hd":false
+ },
+ {
+ "ty":"tm",
+ "s":{
+ "a":0,
+ "k":0,
+ "ix":1
+ },
+ "e":{
+ "a":0,
+ "k":34.2,
+ "ix":2
+ },
+ "o":{
+ "a":1,
+ "k":[
+ {
+ "i":{
+ "x":[
+ 0.833
+ ],
+ "y":[
+ 0.833
+ ]
+ },
+ "o":{
+ "x":[
+ 0.167
+ ],
+ "y":[
+ 0.167
+ ]
+ },
+ "t":0,
+ "s":[
+ 0
+ ]
+ },
+ {
+ "t":360,
+ "s":[
+ 720
+ ]
+ }
+ ],
+ "ix":3
+ },
+ "m":1,
+ "ix":2,
+ "nm":"Trim Paths 1",
+ "mn":"ADBE Vector Filter - Trim",
+ "hd":false
}
],
- "ip": 0,
- "op": 600,
- "st": 0,
- "bm": 0
+ "ip":0,
+ "op":600,
+ "st":0,
+ "bm":0
},
{
- "ddd": 0,
- "ind": 5,
- "ty": 4,
- "nm": "Layer 1 Outlines 7",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
+ "ddd":0,
+ "ind":6,
+ "ty":4,
+ "nm":"Fingerprint_20210701 Outlines 5",
+ "sr":1,
+ "ks":{
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":11
},
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
+ "r":{
+ "a":0,
+ "k":0,
+ "ix":10
},
- "p": {
- "a": 0,
- "k": [
- 91.456,
- 92.206,
+ "p":{
+ "a":0,
+ "k":[
+ 23.091,
+ 32.5,
0
],
- "ix": 2,
- "l": 2
+ "ix":2,
+ "l":2
},
- "a": {
- "a": 0,
- "k": [
- 20,
- 25,
+ "a":{
+ "a":0,
+ "k":[
+ 19.341,
+ 24.25,
0
],
- "ix": 1,
- "l": 2
+ "ix":1,
+ "l":2
},
- "s": {
- "a": 0,
- "k": [
- 350,
- 350,
+ "s":{
+ "a":0,
+ "k":[
+ 100,
+ 100,
100
],
- "ix": 6,
- "l": 2
+ "ix":6,
+ "l":2
}
},
- "ao": 0,
- "shapes": [
+ "ao":0,
+ "shapes":[
{
- "ty": "gr",
- "it": [
+ "ty":"gr",
+ "it":[
{
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
+ "ind":0,
+ "ty":"sh",
+ "ix":1,
+ "ks":{
+ "a":0,
+ "k":{
+ "i":[
[
0,
0
@@ -1099,61 +1328,61 @@
0
],
[
- -6.65,
+ -6.53,
0
],
[
0,
- -5.9
+ -5.793
],
[
0,
0
],
[
- 2.333,
+ 2.159,
0
],
[
- 0.633,
- 1.601
+ 0.59,
+ 1.489
],
[
0,
0
],
[
- 1.717,
+ 1.587,
0
],
[
0,
- 0
+ -2.16
],
[
- 0,
- -2.2
+ -0.81,
+ -1.363
],
[
- -2.15,
- -1.716
+ -0.844,
+ -0.674
],
[
0,
0
]
],
- "o": [
+ "o":[
[
- -0.767,
- -2.134
+ -0.753,
+ -2.095
],
[
0,
- -5.917
+ -5.793
],
[
- 6.65,
+ 6.529,
0
],
[
@@ -1162,10 +1391,10 @@
],
[
0,
- 2.333
+ 2.16
],
[
- -1.734,
+ -1.604,
0
],
[
@@ -1173,20 +1402,20 @@
0
],
[
- -0.634,
- -1.599
+ -0.589,
+ -1.489
],
[
- 0,
+ -2.161,
0
],
[
- -2.2,
- 0
+ 0,
+ 1.62
],
[
- 0,
- 2.75
+ 0.54,
+ 0.909
],
[
0,
@@ -1197,274 +1426,274 @@
0
]
],
- "v": [
+ "v":[
[
- -11.108,
- 5.825
+ -10.702,
+ 5.728
],
[
- -11.875,
- 1.525
+ -11.454,
+ 1.506
],
[
- -0.208,
- -9.175
+ 0.001,
+ -9
],
[
- 11.875,
- 1.525
+ 11.454,
+ 1.506
],
[
- 11.875,
- 1.592
+ 11.454,
+ 1.817
],
[
- 7.659,
- 5.808
+ 7.544,
+ 5.728
],
[
- 3.742,
- 3.158
+ 3.926,
+ 3.273
],
[
- 2.526,
- 0.141
+ 2.618,
+ 0
],
[
- -1.391,
- -2.508
+ -0.997,
+ -2.454
],
[
- -1.641,
- -2.508
+ -4.91,
+ 1.457
],
[
- -5.625,
- 1.475
+ -3.657,
+ 6.014
],
[
- -2.225,
- 8.558
+ -1.57,
+ 8.412
],
[
- -1.458,
- 9.175
+ -0.818,
+ 9
]
],
- "c": false
+ "c":false
},
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 35,
- "ix": 2
- },
- "o": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 0,
- "s": [
- -159
- ]
- },
- {
- "t": 360,
- "s": [
- 201
- ]
- }
- ],
- "ix": 3
+ "ix":2
},
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
+ "nm":"Path 1",
+ "mn":"ADBE Vector Shape - Group",
+ "hd":false
},
{
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
+ "ty":"st",
+ "c":{
+ "a":0,
+ "k":[
1,
1,
1,
1
],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 1,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 4,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
+ "ix":3
+ },
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":4
+ },
+ "w":{
+ "a":0,
+ "k":1,
+ "ix":5
+ },
+ "lc":2,
+ "lj":1,
+ "ml":10,
+ "bm":0,
+ "nm":"Stroke 1",
+ "mn":"ADBE Vector Graphic - Stroke",
+ "hd":false
},
{
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 19.992,
- 28.758
+ "ty":"tr",
+ "p":{
+ "a":0,
+ "k":[
+ 19.341,
+ 28.341
],
- "ix": 2
+ "ix":2
},
- "a": {
- "a": 0,
- "k": [
+ "a":{
+ "a":0,
+ "k":[
0,
0
],
- "ix": 1
+ "ix":1
},
- "s": {
- "a": 0,
- "k": [
+ "s":{
+ "a":0,
+ "k":[
100,
100
],
- "ix": 3
+ "ix":3
},
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
+ "r":{
+ "a":0,
+ "k":0,
+ "ix":6
},
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":7
},
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
+ "sk":{
+ "a":0,
+ "k":0,
+ "ix":4
},
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
+ "sa":{
+ "a":0,
+ "k":0,
+ "ix":5
},
- "nm": "Transform"
+ "nm":"Transform"
}
],
- "nm": "Group 4",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
+ "nm":"Inside to dot ",
+ "np":2,
+ "cix":2,
+ "bm":0,
+ "ix":1,
+ "mn":"ADBE Vector Group",
+ "hd":false
+ },
+ {
+ "ty":"tm",
+ "s":{
+ "a":0,
+ "k":0,
+ "ix":1
+ },
+ "e":{
+ "a":0,
+ "k":35,
+ "ix":2
+ },
+ "o":{
+ "a":1,
+ "k":[
+ {
+ "i":{
+ "x":[
+ 0.833
+ ],
+ "y":[
+ 0.833
+ ]
+ },
+ "o":{
+ "x":[
+ 0.167
+ ],
+ "y":[
+ 0.167
+ ]
+ },
+ "t":0,
+ "s":[
+ -159
+ ]
+ },
+ {
+ "t":360,
+ "s":[
+ 201
+ ]
+ }
+ ],
+ "ix":3
+ },
+ "m":1,
+ "ix":2,
+ "nm":"Trim Paths 1",
+ "mn":"ADBE Vector Filter - Trim",
+ "hd":false
}
],
- "ip": 0,
- "op": 600,
- "st": 0,
- "bm": 0
+ "ip":0,
+ "op":600,
+ "st":0,
+ "bm":0
},
{
- "ddd": 0,
- "ind": 6,
- "ty": 4,
- "nm": "Layer 1 Outlines 6",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
+ "ddd":0,
+ "ind":7,
+ "ty":4,
+ "nm":"Fingerprint_20210701 Outlines 4",
+ "sr":1,
+ "ks":{
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":11
},
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
+ "r":{
+ "a":0,
+ "k":0,
+ "ix":10
},
- "p": {
- "a": 0,
- "k": [
- 91.456,
- 92.206,
+ "p":{
+ "a":0,
+ "k":[
+ 23.091,
+ 32.5,
0
],
- "ix": 2,
- "l": 2
+ "ix":2,
+ "l":2
},
- "a": {
- "a": 0,
- "k": [
- 20,
- 25,
+ "a":{
+ "a":0,
+ "k":[
+ 19.341,
+ 24.25,
0
],
- "ix": 1,
- "l": 2
+ "ix":1,
+ "l":2
},
- "s": {
- "a": 0,
- "k": [
- 350,
- 350,
+ "s":{
+ "a":0,
+ "k":[
+ 100,
+ 100,
100
],
- "ix": 6,
- "l": 2
+ "ix":6,
+ "l":2
}
},
- "ao": 0,
- "shapes": [
+ "ao":0,
+ "shapes":[
{
- "ty": "gr",
- "it": [
+ "ty":"gr",
+ "it":[
{
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
+ "ind":0,
+ "ty":"sh",
+ "ix":1,
+ "ks":{
+ "a":0,
+ "k":{
+ "i":[
[
0,
0
@@ -1474,61 +1703,61 @@
0
],
[
- -6.65,
+ -6.53,
0
],
[
0,
- -5.9
+ -5.793
],
[
0,
0
],
[
- 2.333,
+ 2.159,
0
],
[
- 0.633,
- 1.601
+ 0.59,
+ 1.489
],
[
0,
0
],
[
- 1.717,
+ 1.587,
0
],
[
0,
- 0
+ -2.16
],
[
- 0,
- -2.2
+ -0.81,
+ -1.363
],
[
- -2.15,
- -1.716
+ -0.844,
+ -0.674
],
[
0,
0
]
],
- "o": [
+ "o":[
[
- -0.767,
- -2.134
+ -0.753,
+ -2.095
],
[
0,
- -5.917
+ -5.793
],
[
- 6.65,
+ 6.529,
0
],
[
@@ -1537,10 +1766,10 @@
],
[
0,
- 2.333
+ 2.16
],
[
- -1.734,
+ -1.604,
0
],
[
@@ -1548,20 +1777,20 @@
0
],
[
- -0.634,
- -1.599
+ -0.589,
+ -1.489
],
[
- 0,
+ -2.161,
0
],
[
- -2.2,
- 0
+ 0,
+ 1.62
],
[
- 0,
- 2.75
+ 0.54,
+ 0.909
],
[
0,
@@ -1572,274 +1801,274 @@
0
]
],
- "v": [
+ "v":[
[
- -11.108,
- 5.825
+ -10.702,
+ 5.728
],
[
- -11.875,
- 1.525
+ -11.454,
+ 1.506
],
[
- -0.208,
- -9.175
+ 0.001,
+ -9
],
[
- 11.875,
- 1.525
+ 11.454,
+ 1.506
],
[
- 11.875,
- 1.592
+ 11.454,
+ 1.817
],
[
- 7.659,
- 5.808
+ 7.544,
+ 5.728
],
[
- 3.742,
- 3.158
+ 3.926,
+ 3.273
],
[
- 2.526,
- 0.141
+ 2.618,
+ 0
],
[
- -1.391,
- -2.508
+ -0.997,
+ -2.454
],
[
- -1.641,
- -2.508
+ -4.91,
+ 1.457
],
[
- -5.625,
- 1.475
+ -3.657,
+ 6.014
],
[
- -2.225,
- 8.558
+ -1.57,
+ 8.412
],
[
- -1.458,
- 9.175
+ -0.818,
+ 9
]
],
- "c": false
+ "c":false
},
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 9,
- "ix": 2
- },
- "o": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 0,
- "s": [
- 135
- ]
- },
- {
- "t": 360,
- "s": [
- 495
- ]
- }
- ],
- "ix": 3
+ "ix":2
},
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
+ "nm":"Path 1",
+ "mn":"ADBE Vector Shape - Group",
+ "hd":false
},
{
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
+ "ty":"st",
+ "c":{
+ "a":0,
+ "k":[
1,
1,
1,
1
],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 1,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 4,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
+ "ix":3
+ },
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":4
+ },
+ "w":{
+ "a":0,
+ "k":1,
+ "ix":5
+ },
+ "lc":2,
+ "lj":1,
+ "ml":10,
+ "bm":0,
+ "nm":"Stroke 1",
+ "mn":"ADBE Vector Graphic - Stroke",
+ "hd":false
},
{
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 19.992,
- 28.758
+ "ty":"tr",
+ "p":{
+ "a":0,
+ "k":[
+ 19.341,
+ 28.341
],
- "ix": 2
+ "ix":2
},
- "a": {
- "a": 0,
- "k": [
+ "a":{
+ "a":0,
+ "k":[
0,
0
],
- "ix": 1
+ "ix":1
},
- "s": {
- "a": 0,
- "k": [
+ "s":{
+ "a":0,
+ "k":[
100,
100
],
- "ix": 3
+ "ix":3
},
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
+ "r":{
+ "a":0,
+ "k":0,
+ "ix":6
},
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":7
},
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
+ "sk":{
+ "a":0,
+ "k":0,
+ "ix":4
},
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
+ "sa":{
+ "a":0,
+ "k":0,
+ "ix":5
},
- "nm": "Transform"
+ "nm":"Transform"
}
],
- "nm": "Group 4",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
+ "nm":"Inside to dot ",
+ "np":2,
+ "cix":2,
+ "bm":0,
+ "ix":1,
+ "mn":"ADBE Vector Group",
+ "hd":false
+ },
+ {
+ "ty":"tm",
+ "s":{
+ "a":0,
+ "k":0,
+ "ix":1
+ },
+ "e":{
+ "a":0,
+ "k":9,
+ "ix":2
+ },
+ "o":{
+ "a":1,
+ "k":[
+ {
+ "i":{
+ "x":[
+ 0.833
+ ],
+ "y":[
+ 0.833
+ ]
+ },
+ "o":{
+ "x":[
+ 0.167
+ ],
+ "y":[
+ 0.167
+ ]
+ },
+ "t":0,
+ "s":[
+ 135
+ ]
+ },
+ {
+ "t":360,
+ "s":[
+ 495
+ ]
+ }
+ ],
+ "ix":3
+ },
+ "m":1,
+ "ix":2,
+ "nm":"Trim Paths 1",
+ "mn":"ADBE Vector Filter - Trim",
+ "hd":false
}
],
- "ip": 0,
- "op": 600,
- "st": 0,
- "bm": 0
+ "ip":0,
+ "op":600,
+ "st":0,
+ "bm":0
},
{
- "ddd": 0,
- "ind": 7,
- "ty": 4,
- "nm": "Layer 1 Outlines 3",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
+ "ddd":0,
+ "ind":8,
+ "ty":4,
+ "nm":"Fingerprint_20210701 Outlines 3",
+ "sr":1,
+ "ks":{
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":11
},
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
+ "r":{
+ "a":0,
+ "k":0,
+ "ix":10
},
- "p": {
- "a": 0,
- "k": [
- 91.456,
- 92.206,
+ "p":{
+ "a":0,
+ "k":[
+ 23.091,
+ 32.5,
0
],
- "ix": 2,
- "l": 2
+ "ix":2,
+ "l":2
},
- "a": {
- "a": 0,
- "k": [
- 20,
- 25,
+ "a":{
+ "a":0,
+ "k":[
+ 19.341,
+ 24.25,
0
],
- "ix": 1,
- "l": 2
+ "ix":1,
+ "l":2
},
- "s": {
- "a": 0,
- "k": [
- 350,
- 350,
+ "s":{
+ "a":0,
+ "k":[
+ 100,
+ 100,
100
],
- "ix": 6,
- "l": 2
+ "ix":6,
+ "l":2
}
},
- "ao": 0,
- "shapes": [
+ "ao":0,
+ "shapes":[
{
- "ty": "gr",
- "it": [
+ "ty":"gr",
+ "it":[
{
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
+ "ind":0,
+ "ty":"sh",
+ "ix":1,
+ "ks":{
+ "a":0,
+ "k":{
+ "i":[
[
0,
0
@@ -1849,61 +2078,61 @@
0
],
[
- -6.65,
+ -6.53,
0
],
[
0,
- -5.9
+ -5.793
],
[
0,
0
],
[
- 2.333,
+ 2.159,
0
],
[
- 0.633,
- 1.601
+ 0.59,
+ 1.489
],
[
0,
0
],
[
- 1.717,
+ 1.587,
0
],
[
0,
- 0
+ -2.16
],
[
- 0,
- -2.2
+ -0.81,
+ -1.363
],
[
- -2.15,
- -1.716
+ -0.844,
+ -0.674
],
[
0,
0
]
],
- "o": [
+ "o":[
[
- -0.767,
- -2.134
+ -0.753,
+ -2.095
],
[
0,
- -5.917
+ -5.793
],
[
- 6.65,
+ 6.529,
0
],
[
@@ -1912,10 +2141,10 @@
],
[
0,
- 2.333
+ 2.16
],
[
- -1.734,
+ -1.604,
0
],
[
@@ -1923,20 +2152,20 @@
0
],
[
- -0.634,
- -1.599
+ -0.589,
+ -1.489
],
[
- 0,
+ -2.161,
0
],
[
- -2.2,
- 0
+ 0,
+ 1.62
],
[
- 0,
- 2.75
+ 0.54,
+ 0.909
],
[
0,
@@ -1947,499 +2176,527 @@
0
]
],
- "v": [
+ "v":[
[
- -11.108,
- 5.825
+ -10.702,
+ 5.728
],
[
- -11.875,
- 1.525
+ -11.454,
+ 1.506
],
[
- -0.208,
- -9.175
+ 0.001,
+ -9
],
[
- 11.875,
- 1.525
+ 11.454,
+ 1.506
],
[
- 11.875,
- 1.592
+ 11.454,
+ 1.817
],
[
- 7.659,
- 5.808
+ 7.544,
+ 5.728
],
[
- 3.742,
- 3.158
+ 3.926,
+ 3.273
],
[
- 2.526,
- 0.141
+ 2.618,
+ 0
],
[
- -1.391,
- -2.508
+ -0.997,
+ -2.454
],
[
- -1.641,
- -2.508
+ -4.91,
+ 1.457
],
[
- -5.625,
- 1.475
+ -3.657,
+ 6.014
],
[
- -2.225,
- 8.558
+ -1.57,
+ 8.412
],
[
- -1.458,
- 9.175
+ -0.818,
+ 9
]
],
- "c": false
+ "c":false
},
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 30,
- "ix": 2
- },
- "o": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 0,
- "s": [
- 0
- ]
- },
- {
- "t": 360,
- "s": [
- 360
- ]
- }
- ],
- "ix": 3
+ "ix":2
},
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
+ "nm":"Path 1",
+ "mn":"ADBE Vector Shape - Group",
+ "hd":false
},
{
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
+ "ty":"st",
+ "c":{
+ "a":0,
+ "k":[
1,
1,
1,
1
],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 1,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 4,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
+ "ix":3
+ },
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":4
+ },
+ "w":{
+ "a":0,
+ "k":1,
+ "ix":5
+ },
+ "lc":2,
+ "lj":1,
+ "ml":10,
+ "bm":0,
+ "nm":"Stroke 1",
+ "mn":"ADBE Vector Graphic - Stroke",
+ "hd":false
},
{
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 19.992,
- 28.758
+ "ty":"tr",
+ "p":{
+ "a":0,
+ "k":[
+ 19.341,
+ 28.341
],
- "ix": 2
+ "ix":2
},
- "a": {
- "a": 0,
- "k": [
+ "a":{
+ "a":0,
+ "k":[
0,
0
],
- "ix": 1
+ "ix":1
},
- "s": {
- "a": 0,
- "k": [
+ "s":{
+ "a":0,
+ "k":[
100,
100
],
- "ix": 3
+ "ix":3
},
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
+ "r":{
+ "a":0,
+ "k":0,
+ "ix":6
},
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":7
},
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
+ "sk":{
+ "a":0,
+ "k":0,
+ "ix":4
},
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
+ "sa":{
+ "a":0,
+ "k":0,
+ "ix":5
},
- "nm": "Transform"
+ "nm":"Transform"
}
],
- "nm": "Group 4",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
+ "nm":"Inside to dot ",
+ "np":2,
+ "cix":2,
+ "bm":0,
+ "ix":1,
+ "mn":"ADBE Vector Group",
+ "hd":false
+ },
+ {
+ "ty":"tm",
+ "s":{
+ "a":0,
+ "k":0,
+ "ix":1
+ },
+ "e":{
+ "a":0,
+ "k":30,
+ "ix":2
+ },
+ "o":{
+ "a":1,
+ "k":[
+ {
+ "i":{
+ "x":[
+ 0.833
+ ],
+ "y":[
+ 0.833
+ ]
+ },
+ "o":{
+ "x":[
+ 0.167
+ ],
+ "y":[
+ 0.167
+ ]
+ },
+ "t":0,
+ "s":[
+ 0
+ ]
+ },
+ {
+ "t":360,
+ "s":[
+ 360
+ ]
+ }
+ ],
+ "ix":3
+ },
+ "m":1,
+ "ix":2,
+ "nm":"Trim Paths 1",
+ "mn":"ADBE Vector Filter - Trim",
+ "hd":false
}
],
- "ip": 0,
- "op": 600,
- "st": 0,
- "bm": 0
+ "ip":0,
+ "op":600,
+ "st":0,
+ "bm":0
},
{
- "ddd": 0,
- "ind": 8,
- "ty": 4,
- "nm": "Layer 1 Outlines 2",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
+ "ddd":0,
+ "ind":9,
+ "ty":4,
+ "nm":"Fingerprint_20210701 Outlines",
+ "sr":1,
+ "ks":{
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":11
},
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
+ "r":{
+ "a":0,
+ "k":0,
+ "ix":10
},
- "p": {
- "a": 0,
- "k": [
- 91.456,
- 92.206,
+ "p":{
+ "a":0,
+ "k":[
+ 23.091,
+ 32.5,
0
],
- "ix": 2,
- "l": 2
+ "ix":2,
+ "l":2
},
- "a": {
- "a": 0,
- "k": [
- 20,
- 25,
+ "a":{
+ "a":0,
+ "k":[
+ 19.341,
+ 24.25,
0
],
- "ix": 1,
- "l": 2
+ "ix":1,
+ "l":2
},
- "s": {
- "a": 0,
- "k": [
- 350,
- 350,
+ "s":{
+ "a":0,
+ "k":[
+ 100,
+ 100,
100
],
- "ix": 6,
- "l": 2
+ "ix":6,
+ "l":2
}
},
- "ao": 0,
- "shapes": [
+ "ao":0,
+ "shapes":[
{
- "ty": "gr",
- "it": [
+ "ty":"gr",
+ "it":[
{
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
+ "ind":0,
+ "ty":"sh",
+ "ix":1,
+ "ks":{
+ "a":0,
+ "k":{
+ "i":[
[
0,
0
],
[
- 3.2,
+ 1.307,
+ -0.561
+ ],
+ [
+ 0.894,
+ -0.16
+ ],
+ [
+ 0.706,
0
],
[
- 2.217,
- 2.066
+ 0.844,
+ 0.193
+ ],
+ [
+ 0.728,
+ 0.334
+ ],
+ [
+ 0.967,
+ 0.901
]
],
- "o": [
+ "o":[
[
- -2.217,
- 2.066
+ -1.038,
+ 0.967
],
[
- -3.2,
+ -0.817,
+ 0.351
+ ],
+ [
+ -0.673,
+ 0.12
+ ],
+ [
+ -0.9,
0
],
[
+ -0.794,
+ -0.182
+ ],
+ [
+ -1.203,
+ -0.551
+ ],
+ [
0,
0
]
],
- "v": [
+ "v":[
[
- 8.75,
- -1.667
+ 8.182,
+ -1.636
],
[
- 0,
- 1.667
+ 4.642,
+ 0.681
+ ],
+ [
+ 2.07,
+ 1.453
+ ],
+ [
+ -0.001,
+ 1.636
+ ],
+ [
+ -2.621,
+ 1.341
+ ],
+ [
+ -4.909,
+ 0.563
],
[
- -8.75,
- -1.667
+ -8.182,
+ -1.636
]
],
- "c": false
+ "c":false
},
- "ix": 2
+ "ix":2
},
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
+ "nm":"Path 1",
+ "mn":"ADBE Vector Shape - Group",
+ "hd":false
},
{
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 69,
- "ix": 2
- },
- "o": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0.833
- ],
- "y": [
- 0.833
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 0,
- "s": [
- 0
- ]
- },
- {
- "t": 360,
- "s": [
- 720
- ]
- }
- ],
- "ix": 3
- },
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
+ "ty":"st",
+ "c":{
+ "a":0,
+ "k":[
1,
1,
1,
1
],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 0,
- "k": 1,
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "d": [
- {
- "n": "d",
- "nm": "dash",
- "v": {
- "a": 0,
- "k": 0,
- "ix": 1
- }
- },
- {
- "n": "o",
- "nm": "offset",
- "v": {
- "a": 0,
- "k": 25,
- "ix": 7
- }
- }
- ],
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
+ "ix":3
+ },
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":4
+ },
+ "w":{
+ "a":0,
+ "k":1,
+ "ix":5
+ },
+ "lc":2,
+ "lj":1,
+ "ml":10,
+ "bm":0,
+ "nm":"Stroke 1",
+ "mn":"ADBE Vector Graphic - Stroke",
+ "hd":false
},
{
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 20,
- 42.083
+ "ty":"tr",
+ "p":{
+ "a":0,
+ "k":[
+ 19.341,
+ 40.614
],
- "ix": 2
+ "ix":2
},
- "a": {
- "a": 0,
- "k": [
+ "a":{
+ "a":0,
+ "k":[
0,
0
],
- "ix": 1
+ "ix":1
},
- "s": {
- "a": 0,
- "k": [
+ "s":{
+ "a":0,
+ "k":[
100,
100
],
- "ix": 3
+ "ix":3
},
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
+ "r":{
+ "a":0,
+ "k":0,
+ "ix":6
},
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
+ "o":{
+ "a":0,
+ "k":100,
+ "ix":7
},
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
+ "sk":{
+ "a":0,
+ "k":0,
+ "ix":4
},
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
+ "sa":{
+ "a":0,
+ "k":0,
+ "ix":5
},
- "nm": "Transform"
+ "nm":"Transform"
}
],
- "nm": "Group 1",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
+ "nm":"Bottom",
+ "np":2,
+ "cix":2,
+ "bm":0,
+ "ix":1,
+ "mn":"ADBE Vector Group",
+ "hd":false
+ },
+ {
+ "ty":"tm",
+ "s":{
+ "a":0,
+ "k":0,
+ "ix":1
+ },
+ "e":{
+ "a":0,
+ "k":69,
+ "ix":2
+ },
+ "o":{
+ "a":1,
+ "k":[
+ {
+ "i":{
+ "x":[
+ 0.833
+ ],
+ "y":[
+ 0.833
+ ]
+ },
+ "o":{
+ "x":[
+ 0.167
+ ],
+ "y":[
+ 0.167
+ ]
+ },
+ "t":0,
+ "s":[
+ 0
+ ]
+ },
+ {
+ "t":360,
+ "s":[
+ 720
+ ]
+ }
+ ],
+ "ix":3
+ },
+ "m":1,
+ "ix":2,
+ "nm":"Trim Paths 1",
+ "mn":"ADBE Vector Filter - Trim",
+ "hd":false
}
],
- "ip": 0,
- "op": 600,
- "st": 0,
- "bm": 0
+ "ip":0,
+ "op":600,
+ "st":0,
+ "bm":0
}
],
- "markers": [
+ "markers":[
{
- "tm": 210,
- "cm": "2",
- "dr": 0
+ "tm":210,
+ "cm":"2",
+ "dr":0
},
{
- "tm": 255,
- "cm": "1",
- "dr": 0
+ "tm":255,
+ "cm":"1",
+ "dr":0
}
]
} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/udfps_lockscreen_fp.json b/packages/SystemUI/res/raw/udfps_lockscreen_fp.json
index cef433ef95d2..a25a47595fe7 100644
--- a/packages/SystemUI/res/raw/udfps_lockscreen_fp.json
+++ b/packages/SystemUI/res/raw/udfps_lockscreen_fp.json
@@ -1,1017 +1 @@
-{
- "v": "5.7.8",
- "fr": 60,
- "ip": 0,
- "op": 46,
- "w": 180,
- "h": 185,
- "nm": "fingerprint_build_on",
- "ddd": 0,
- "assets": [],
- "layers": [
- {
- "ddd": 0,
- "ind": 1,
- "ty": 4,
- "nm": "fingerprint_build_on",
- "sr": 1,
- "ks": {
- "o": {
- "a": 0,
- "k": 100,
- "ix": 11
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 10
- },
- "p": {
- "a": 0,
- "k": [
- 91.456,
- 92.206,
- 0
- ],
- "ix": 2,
- "l": 2
- },
- "a": {
- "a": 0,
- "k": [
- 20,
- 25,
- 0
- ],
- "ix": 1,
- "l": 2
- },
- "s": {
- "a": 0,
- "k": [
- 350,
- 350,
- 100
- ],
- "ix": 6,
- "l": 2
- }
- },
- "ao": 0,
- "shapes": [
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 3.2,
- 0
- ],
- [
- 2.217,
- 2.066
- ]
- ],
- "o": [
- [
- -2.217,
- 2.066
- ],
- [
- -3.2,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- 8.75,
- -1.667
- ],
- [
- 0,
- 1.667
- ],
- [
- -8.75,
- -1.667
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 100,
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 0,
- "ix": 3
- },
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 1,
- 1,
- 1,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 0,
- "s": [
- 0
- ]
- },
- {
- "t": 24,
- "s": [
- 2.5
- ]
- }
- ],
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "d": [
- {
- "n": "d",
- "nm": "dash",
- "v": {
- "a": 0,
- "k": 0,
- "ix": 1
- }
- },
- {
- "n": "o",
- "nm": "offset",
- "v": {
- "a": 0,
- "k": 0,
- "ix": 7
- }
- }
- ],
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 20,
- 42.083
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 1",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 1,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- -5.883,
- 0
- ],
- [
- -2.367,
- -3.933
- ]
- ],
- "o": [
- [
- 2.367,
- -3.933
- ],
- [
- 5.883,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -13.75,
- 3.333
- ],
- [
- 0,
- -3.333
- ],
- [
- 13.75,
- 3.333
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 100,
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 0,
- "ix": 3
- },
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 1,
- 1,
- 1,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 0,
- "s": [
- 0
- ]
- },
- {
- "t": 24,
- "s": [
- 2.5
- ]
- }
- ],
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 20,
- 16.25
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 2",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 2,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- -3.684,
- 0
- ],
- [
- -2.883,
- -1.583
- ]
- ],
- "o": [
- [
- 2.883,
- -1.583
- ],
- [
- 3.683,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -10.417,
- 1.25
- ],
- [
- 0.001,
- -1.25
- ],
- [
- 10.417,
- 1.25
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 100,
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 0,
- "ix": 3
- },
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 1,
- 1,
- 1,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 0,
- "s": [
- 0
- ]
- },
- {
- "t": 24,
- "s": [
- 2.5
- ]
- }
- ],
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 19.999,
- 7.5
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 3",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 3,
- "mn": "ADBE Vector Group",
- "hd": false
- },
- {
- "ty": "gr",
- "it": [
- {
- "ind": 0,
- "ty": "sh",
- "ix": 1,
- "ks": {
- "a": 0,
- "k": {
- "i": [
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- -6.65,
- 0
- ],
- [
- 0,
- -5.9
- ],
- [
- 0,
- 0
- ],
- [
- 2.333,
- 0
- ],
- [
- 0.633,
- 1.601
- ],
- [
- 0,
- 0
- ],
- [
- 1.717,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 0,
- -2.2
- ],
- [
- -2.15,
- -1.716
- ],
- [
- 0,
- 0
- ]
- ],
- "o": [
- [
- -0.767,
- -2.134
- ],
- [
- 0,
- -5.917
- ],
- [
- 6.65,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- 0,
- 2.333
- ],
- [
- -1.734,
- 0
- ],
- [
- 0,
- 0
- ],
- [
- -0.634,
- -1.599
- ],
- [
- 0,
- 0
- ],
- [
- -2.2,
- 0
- ],
- [
- 0,
- 2.75
- ],
- [
- 0,
- 0
- ],
- [
- 0,
- 0
- ]
- ],
- "v": [
- [
- -11.108,
- 5.825
- ],
- [
- -11.875,
- 1.525
- ],
- [
- -0.208,
- -9.175
- ],
- [
- 11.875,
- 1.525
- ],
- [
- 11.875,
- 1.592
- ],
- [
- 7.659,
- 5.808
- ],
- [
- 3.742,
- 3.158
- ],
- [
- 2.526,
- 0.141
- ],
- [
- -1.391,
- -2.508
- ],
- [
- -1.641,
- -2.508
- ],
- [
- -5.625,
- 1.475
- ],
- [
- -2.225,
- 8.558
- ],
- [
- -1.458,
- 9.175
- ]
- ],
- "c": false
- },
- "ix": 2
- },
- "nm": "Path 1",
- "mn": "ADBE Vector Shape - Group",
- "hd": false
- },
- {
- "ty": "tm",
- "s": {
- "a": 0,
- "k": 0,
- "ix": 1
- },
- "e": {
- "a": 0,
- "k": 100,
- "ix": 2
- },
- "o": {
- "a": 0,
- "k": 0,
- "ix": 3
- },
- "m": 1,
- "ix": 2,
- "nm": "Trim Paths 1",
- "mn": "ADBE Vector Filter - Trim",
- "hd": false
- },
- {
- "ty": "st",
- "c": {
- "a": 0,
- "k": [
- 1,
- 1,
- 1,
- 1
- ],
- "ix": 3
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 4
- },
- "w": {
- "a": 1,
- "k": [
- {
- "i": {
- "x": [
- 0
- ],
- "y": [
- 1
- ]
- },
- "o": {
- "x": [
- 0.167
- ],
- "y": [
- 0.167
- ]
- },
- "t": 0,
- "s": [
- 0
- ]
- },
- {
- "t": 24,
- "s": [
- 2.5
- ]
- }
- ],
- "ix": 5
- },
- "lc": 2,
- "lj": 1,
- "ml": 10,
- "bm": 0,
- "nm": "Stroke 1",
- "mn": "ADBE Vector Graphic - Stroke",
- "hd": false
- },
- {
- "ty": "tr",
- "p": {
- "a": 0,
- "k": [
- 19.992,
- 28.758
- ],
- "ix": 2
- },
- "a": {
- "a": 0,
- "k": [
- 0,
- 0
- ],
- "ix": 1
- },
- "s": {
- "a": 0,
- "k": [
- 100,
- 100
- ],
- "ix": 3
- },
- "r": {
- "a": 0,
- "k": 0,
- "ix": 6
- },
- "o": {
- "a": 0,
- "k": 100,
- "ix": 7
- },
- "sk": {
- "a": 0,
- "k": 0,
- "ix": 4
- },
- "sa": {
- "a": 0,
- "k": 0,
- "ix": 5
- },
- "nm": "Transform"
- }
- ],
- "nm": "Group 4",
- "np": 3,
- "cix": 2,
- "bm": 0,
- "ix": 4,
- "mn": "ADBE Vector Group",
- "hd": false
- }
- ],
- "ip": 0,
- "op": 600,
- "st": 0,
- "bm": 0
- }
- ],
- "markers": [
- {
- "tm": 210,
- "cm": "2",
- "dr": 0
- },
- {
- "tm": 255,
- "cm": "1",
- "dr": 0
- }
- ]
-} \ No newline at end of file
+{"v":"5.7.8","fr":60,"ip":0,"op":46,"w":46,"h":65,"nm":"fingerprint_build_on","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Fingerprint_20210701 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[23.091,32.5,0],"ix":2,"l":2},"a":{"a":0,"k":[19.341,24.25,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.701,0.42],[-1.757,0],[-1.577,-0.381],[-1.485,-0.816]],"o":[[1.455,-0.799],[1.608,-0.397],[1.719,0],[1.739,0.42],[0,0]],"v":[[-9.818,1.227],[-5.064,-0.618],[0,-1.227],[4.96,-0.643],[9.818,1.227]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.717999985639,0.948999980852,0.62400004069,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":24,"s":[2.5]}],"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[19.341,7.477],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Top","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-2.446,1.161],[-1.168,0.275],[-1.439,0],[-1.301,-0.304],[-1.225,-0.66],[-1.11,-1.844]],"o":[[1.23,-2.044],[1.024,-0.486],[1.312,-0.31],[1.425,0],[1.454,0.34],[2.122,1.143],[0,0]],"v":[[-13.091,3.273],[-7.438,-1.646],[-4.14,-2.797],[0,-3.273],[4.104,-2.805],[8.141,-1.29],[13.091,3.273]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.717999985639,0.948999980852,0.62400004069,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":24,"s":[2.5]}],"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[19.341,16.069],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Mid Top","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-6.53,0],[0,-5.793],[0,0],[2.159,0],[0.59,1.489],[0,0],[1.587,0],[0,-2.16],[-0.81,-1.363],[-0.844,-0.674],[0,0]],"o":[[-0.753,-2.095],[0,-5.793],[6.529,0],[0,0],[0,2.16],[-1.604,0],[0,0],[-0.589,-1.489],[-2.161,0],[0,1.62],[0.54,0.909],[0,0],[0,0]],"v":[[-10.702,5.728],[-11.454,1.506],[0.001,-9],[11.454,1.506],[11.454,1.817],[7.544,5.728],[3.926,3.273],[2.618,0],[-0.997,-2.454],[-4.91,1.457],[-3.657,6.014],[-1.57,8.412],[-0.818,9]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.717999994755,0.949000000954,0.624000012875,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":24,"s":[2.5]}],"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[19.341,28.341],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Inside to dot ","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[1.307,-0.561],[0.894,-0.16],[0.706,0],[0.844,0.193],[0.728,0.334],[0.967,0.901]],"o":[[-1.038,0.967],[-0.817,0.351],[-0.673,0.12],[-0.9,0],[-0.794,-0.182],[-1.203,-0.551],[0,0]],"v":[[8.182,-1.636],[4.642,0.681],[2.07,1.453],[-0.001,1.636],[-2.621,1.341],[-4.909,0.563],[-8.182,-1.636]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.717999985639,0.948999980852,0.62400004069,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":24,"s":[2.5]}],"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[19.341,40.614],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Bottom","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0}],"markers":[{"tm":210,"cm":"2","dr":0},{"tm":255,"cm":"1","dr":0}]} \ No newline at end of file
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index bfcfd9bd41d5..6195e5fdb062 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -1173,8 +1173,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>
- <!-- no translation found for person_available (2318599327472755472) -->
- <skip />
+ <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-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 316c87b18df0..bc5a91a6b859 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -427,7 +427,7 @@
<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_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>
@@ -1149,8 +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>
- <!-- no translation found for person_available (2318599327472755472) -->
- <skip />
+ <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-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 452164f2e42a..54790897af76 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -1149,8 +1149,7 @@
<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="person_available" msgid="2318599327472755472">"Əlçatan"</string>
<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-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 8cbc8bd31e41..491cdcd6917d 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -1161,8 +1161,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>
- <!-- no translation found for person_available (2318599327472755472) -->
- <skip />
+ <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-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 540be62d0f78..a431258e742d 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -431,7 +431,7 @@
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"¿Quieres desbloquear la cámara y el micrófono del dispositivo?"</string>
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Esta acción desbloquea el acceso para todos los servicios y las apps que tengan permitido usar el micrófono."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Esta acción desbloquea el acceso para todos los servicios y las apps que tengan permitido usar la cámara."</string>
- <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Esta acción desbloquea el acceso para todos los servicios y las apps que tengan permitido usar la cámara o el micrófono."</string>
+ <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Esta acción permite que todas las aplicaciones y servicios que tengan permiso puedan usar la cámara o el 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 app"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Arrastra a la derecha para cambiar aplicaciones rápidamente"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 4a5941e38828..e9638538170c 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -431,7 +431,7 @@
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Kumotaanko laitteen kameran ja mikrofonin esto?"</string>
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Tämä kumoaa kaikkien sellaisten sovellusten ja palveluiden eston, joilla on lupa käyttää mikrofoniasi."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Tämä kumoaa kaikkien sellaisten sovellusten ja palveluiden eston, joilla on lupa käyttää kameraasi."</string>
- <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Tämä kumoaa kaikkien sellaisten sovellusten ja palveluiden eston, joilla on lupa käyttää kameraasi tai mikrofoniasi."</string>
+ <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Tämä kumoaa eston kaikkien sellaisten sovellusten ja palveluiden osalta, joilla on lupa käyttää kameraasi tai mikrofoniasi."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Laite"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Vaihda sovellusta pyyhkäisemällä ylös"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Vaihda sovellusta nopeasti vetämällä oikealle"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 6e032efb2083..a1c50d8c85a2 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -431,7 +431,7 @@
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Débloquer l\'appareil photo et le micro de l\'appareil ?"</string>
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Cette action débloque l\'accès à tous les services et applis autorisés à utiliser votre micro."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Cette action débloque l\'accès à tous les services et applis autorisés à utiliser votre appareil photo."</string>
- <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Cette action débloque l\'accès à tous les services et applis autorisés à utiliser votre appareil photo ou votre micro."</string>
+ <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Cette action débloque l\'accès pour tous les services et applis autorisés à utiliser votre appareil photo ou votre micro."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Appareil"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Balayer l\'écran vers le haut pour changer d\'application"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Déplacer vers la droite pour changer rapidement d\'application"</string>
@@ -1139,7 +1139,7 @@
<string name="audio_status" msgid="4237055636967709208">"Écoute du contenu"</string>
<string name="game_status" msgid="1340694320630973259">"Joue"</string>
<string name="empty_user_name" msgid="3389155775773578300">"Amis"</string>
- <string name="empty_status" msgid="5938893404951307749">"Chattez ce soir !"</string>
+ <string name="empty_status" msgid="5938893404951307749">"Bavardons ce soir !"</string>
<string name="status_before_loading" msgid="1500477307859631381">"Le contenu s\'affichera bientôt"</string>
<string name="missed_call" msgid="4228016077700161689">"Appel manqué"</string>
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"+ de <xliff:g id="NUMBER">%d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 9ae4721d8aa0..abbb46a5e451 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -428,10 +428,10 @@
<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_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>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 227bf4d22d3e..ef20347a2576 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -431,7 +431,7 @@
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Berhenti memblokir kamera dan mikrofon perangkat?"</string>
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Ini akan berhenti memblokir akses untuk semua aplikasi dan layanan yang diizinkan menggunakan mikrofon."</string>
<string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Ini akan berhenti memblokir akses untuk semua aplikasi dan layanan yang diizinkan menggunakan kamera."</string>
- <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Ini akan berhenti memblokir akses untuk semua aplikasi dan layanan yang diizinkan menggunakan kamera atau mikrofon."</string>
+ <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Langkah ini akan berhenti memblokir akses untuk semua aplikasi dan layanan yang diizinkan menggunakan kamera atau mikrofon."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Perangkat"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Geser ke atas untuk beralih aplikasi"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Tarik ke kanan untuk beralih aplikasi dengan cepat"</string>
@@ -1127,7 +1127,7 @@
<string name="over_two_weeks_timestamp" msgid="6300507859007874050">"Lebih dari 2 minggu lalu"</string>
<string name="birthday_status" msgid="2596961629465396761">"Ulang Tahun"</string>
<string name="birthday_status_content_description" msgid="682836371128282925">"Hari ini ulang tahun <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="upcoming_birthday_status" msgid="2005452239256870351">"Ulang tahun segera"</string>
+ <string name="upcoming_birthday_status" msgid="2005452239256870351">"Segera ulang tahun"</string>
<string name="upcoming_birthday_status_content_description" msgid="2165036816803797148">"Ulang tahun <xliff:g id="NAME">%1$s</xliff:g> sebentar lagi"</string>
<string name="anniversary_status" msgid="1790034157507590838">"Hari Peringatan"</string>
<string name="anniversary_status_content_description" msgid="8212171790843327442">"Hari ini hari jadi <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -1149,8 +1149,7 @@
<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="person_available" msgid="2318599327472755472">"Online"</string>
<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-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 65c23d47e043..731d36ca36c1 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -1161,8 +1161,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>
- <!-- no translation found for person_available (2318599327472755472) -->
- <skip />
+ <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 5ce3fe571bdd..aff2521a7bad 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -1149,8 +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>
- <!-- no translation found for person_available (2318599327472755472) -->
- <skip />
+ <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-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index cba176d5953b..674f6a04393c 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -1149,8 +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>
- <!-- no translation found for person_available (2318599327472755472) -->
- <skip />
+ <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 94df302a007b..264f24834b04 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -428,7 +428,7 @@
<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_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>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 34d799c2a25b..42d684ea34f0 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -426,8 +426,8 @@
<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_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>
@@ -1149,8 +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>
- <!-- no translation found for person_available (2318599327472755472) -->
- <skip />
+ <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-land-television/dimens.xml b/packages/SystemUI/res/values-land-television/dimens.xml
index a9bc9e5cd638..8fc46125b477 100644
--- a/packages/SystemUI/res/values-land-television/dimens.xml
+++ b/packages/SystemUI/res/values-land-television/dimens.xml
@@ -22,7 +22,7 @@
<dimen name="volume_dialog_panel_transparent_padding">24dp</dimen>
<dimen name="volume_dialog_slider_width">4dp</dimen>
<dimen name="volume_dialog_slider_corner_radius">@dimen/volume_dialog_slider_width</dimen>
- <dimen name="volume_dialog_background_blur_radius">100dp</dimen>
+ <dimen name="volume_dialog_background_blur_radius">31dp</dimen>
<dimen name="volume_tool_tip_right_margin">136dp</dimen>
<dimen name="tv_volume_dialog_bubble_size">36dp</dimen>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 11d363ed59ef..19e8fbfd623c 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -1161,8 +1161,7 @@
<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="person_available" msgid="2318599327472755472">"Pasiekiama"</string>
<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 6b68297dea71..f0d26c837c48 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -432,8 +432,8 @@
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vai vēlaties atbloķēt ierīces kameru?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vai atbloķēt ierīces kameru un mikrofonu?"</string>
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Visas lietotnes un pakalpojumi, kurām ir atļauts izmantot mikrofonu, varēs tam piekļūt."</string>
- <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Visas lietotnes un pakalpojumi, kurām ir atļauts izmantot kameru, varēs tai piekļūt."</string>
- <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Visas lietotnes un pakalpojumi, kurām ir atļauts izmantot kameru vai mikrofonu, varēs tiem piekļūt."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Visas lietotnes un pakalpojumi, kuriem ir atļauts izmantot kameru, varēs tai piekļūt."</string>
+ <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Visas lietotnes un pakalpojumi, kuriem ir atļauts izmantot kameru vai mikrofonu, varēs tiem piekļūt."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Ierīce"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Velciet augšup, lai pārslēgtu lietotnes"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Lai ātri pārslēgtu lietotnes, velciet pa labi"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 5392d52526f3..719f519f3405 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -1149,8 +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>
- <!-- no translation found for person_available (2318599327472755472) -->
- <skip />
+ <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 bf27df9c63f9..cd3966d46276 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -275,7 +275,7 @@
<string name="accessibility_quick_settings_location_off" msgid="6122523378294740598">"स्थान अहवाल बंद."</string>
<string name="accessibility_quick_settings_location_on" msgid="6869947200325467243">"स्थान अहवाल सुरू."</string>
<string name="accessibility_quick_settings_location_changed_off" msgid="5132776369388699133">"स्थान अहवाल बंद केला."</string>
- <string name="accessibility_quick_settings_location_changed_on" msgid="7159115433070112154">"स्थान अहवाल सुरू केला."</string>
+ <string name="accessibility_quick_settings_location_changed_on" msgid="7159115433070112154">"स्थान अहवाल देणे सुरू केले."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g> साठी अलार्म सेट केला."</string>
<string name="accessibility_quick_settings_close" msgid="2974895537860082341">"पॅनल बंद करा."</string>
<string name="accessibility_quick_settings_more_time" msgid="7646479831704665284">"अधिक वेळ."</string>
@@ -1149,8 +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>
- <!-- no translation found for person_available (2318599327472755472) -->
- <skip />
+ <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-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 1d16edcdc49c..684d71850351 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -1149,8 +1149,7 @@
<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="person_available" msgid="2318599327472755472">"Tersedia"</string>
<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 c92a45e8dbcc..d588d271fb6f 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -376,7 +376,7 @@
<string name="quick_settings_cast_title" msgid="2279220930629235211">"မျက်နှာပြင် ကာ့စ်လုပ်ခြင်း"</string>
<string name="quick_settings_casting" msgid="1435880708719268055">"ကာစ်တင်"</string>
<string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"အမည်မတပ် ကိရိယာ"</string>
- <string name="quick_settings_cast_device_default_description" msgid="2580520859212250265">"ကာစ်တ် လုပ်ရန် အသင့် ရှိနေပြီ"</string>
+ <string name="quick_settings_cast_device_default_description" msgid="2580520859212250265">"ကာစ် လုပ်ရန် အသင့် ရှိနေပြီ"</string>
<string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"ကိရိယာများ မရှိ"</string>
<string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"Wi-Fi ချိတ်ဆက်ထားခြင်းမရှိပါ"</string>
<string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"အလင်းတောက်ပမှု"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 2ad54f7fd75a..b8a104fc5a04 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -1149,8 +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>
- <!-- no translation found for person_available (2318599327472755472) -->
- <skip />
+ <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-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 3f2e4810dbd2..708462f94553 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/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>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 990b461fe0f9..b8da6bbedc53 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -748,10 +748,10 @@
<string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;Stan:&lt;/b&gt; zmieniono na Ciche"</string>
<string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;Stan:&lt;/b&gt; podniesiono ważność"</string>
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Stan:&lt;/b&gt; obniżono ważność"</string>
- <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekran blokady"</string>
- <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekran blokady, jako dymek"</string>
- <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekran blokady, przerywa działanie trybu Nie przeszkadzać"</string>
- <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekran blokady, jako dymek, przerywa działanie trybu Nie przeszkadzać"</string>
+ <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekranie blokady"</string>
+ <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekranie blokady, jako dymek"</string>
+ <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekranie blokady, przerywa działanie trybu Nie przeszkadzać"</string>
+ <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekranie blokady, jako dymek, przerywa działanie trybu Nie przeszkadzać"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Ustawienia"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Priorytetowe"</string>
<string name="no_shortcut" msgid="8257177117568230126">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> nie obsługuje funkcji rozmów"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 346323685e83..cf957a45dbdd 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -1155,8 +1155,7 @@
<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="person_available" msgid="2318599327472755472">"Disponibil"</string>
<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 53500b5d8b1e..9fd91f191837 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -1161,8 +1161,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>
- <!-- no translation found for person_available (2318599327472755472) -->
- <skip />
+ <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 4967718196ef..14aa0a7bc303 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -1161,8 +1161,7 @@
<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="person_available" msgid="2318599327472755472">"K dispozícii"</string>
<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-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index ad8e2659b612..5ce3cd43eef9 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -1149,8 +1149,7 @@
<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="person_available" msgid="2318599327472755472">"I disponueshëm"</string>
<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-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 409eced5a67d..2bc29234f5b3 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -1149,8 +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>
- <!-- no translation found for person_available (2318599327472755472) -->
- <skip />
+ <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-television/dimens.xml b/packages/SystemUI/res/values-television/dimens.xml
index c258fcc4273a..76c620d53ccf 100644
--- a/packages/SystemUI/res/values-television/dimens.xml
+++ b/packages/SystemUI/res/values-television/dimens.xml
@@ -38,7 +38,7 @@
<dimen name="bottom_sheet_min_height">208dp</dimen>
<dimen name="bottom_sheet_margin">24dp</dimen>
- <dimen name="bottom_sheet_background_blur_radius">120dp</dimen>
+ <dimen name="bottom_sheet_background_blur_radius">37dp</dimen>
<dimen name="privacy_chip_margin">12dp</dimen>
<dimen name="privacy_chip_icon_margin_in_between">9dp</dimen>
@@ -56,4 +56,4 @@
<dimen name="privacy_chip_dot_bg_height">18dp</dimen>
<dimen name="privacy_chip_dot_bg_radius">9dp</dimen>
-</resources> \ No newline at end of file
+</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 6e0662693d4a..69b499985632 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -1149,8 +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>
- <!-- no translation found for person_available (2318599327472755472) -->
- <skip />
+ <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-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 9a83c227bf32..d65f16dba762 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -1149,8 +1149,7 @@
<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="person_available" msgid="2318599327472755472">"Available"</string>
<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-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 2d1500965136..d4d18162e07f 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -433,9 +433,9 @@
<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_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="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>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index ffcd9a750abf..e8cb65725514 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -1149,8 +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>
- <!-- no translation found for person_available (2318599327472755472) -->
- <skip />
+ <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-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index ea79e3c94840..e432c620c3ab 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -211,8 +211,8 @@
<string name="accessibility_two_bars" msgid="1335676987274417121">"信号强度为两格。"</string>
<string name="accessibility_three_bars" msgid="819417766606501295">"信号强度为三格。"</string>
<string name="accessibility_signal_full" msgid="5920148525598637311">"信号满格。"</string>
- <string name="accessibility_desc_on" msgid="2899626845061427845">"开启。"</string>
- <string name="accessibility_desc_off" msgid="8055389500285421408">"关闭。"</string>
+ <string name="accessibility_desc_on" msgid="2899626845061427845">"已开启。"</string>
+ <string name="accessibility_desc_off" msgid="8055389500285421408">"已关闭。"</string>
<string name="accessibility_desc_connected" msgid="3082590384032624233">"已连接。"</string>
<string name="accessibility_desc_connecting" msgid="8011433412112903614">"正在连接。"</string>
<string name="data_connection_hspa" msgid="6096234094857660873">"HSPA"</string>
@@ -221,7 +221,7 @@
<string name="accessibility_no_sim" msgid="1140839832913084973">"无 SIM 卡。"</string>
<string name="accessibility_cell_data" msgid="172950885786007392">"移动数据"</string>
<string name="accessibility_cell_data_on" msgid="691666434519443162">"移动数据已开启"</string>
- <string name="cell_data_off" msgid="4886198950247099526">"关闭"</string>
+ <string name="cell_data_off" msgid="4886198950247099526">"已关闭"</string>
<string name="accessibility_bluetooth_tether" msgid="6327291292208790599">"蓝牙网络共享。"</string>
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"飞行模式。"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN 已开启。"</string>
@@ -706,8 +706,8 @@
<string name="do_not_silence" msgid="4982217934250511227">"不静音"</string>
<string name="do_not_silence_block" msgid="4361847809775811849">"不静音也不屏蔽"</string>
<string name="tuner_full_importance_settings" msgid="1388025816553459059">"高级通知设置"</string>
- <string name="tuner_full_importance_settings_on" msgid="917981436602311547">"开启"</string>
- <string name="tuner_full_importance_settings_off" msgid="5580102038749680829">"关闭"</string>
+ <string name="tuner_full_importance_settings_on" msgid="917981436602311547">"已开启"</string>
+ <string name="tuner_full_importance_settings_off" msgid="5580102038749680829">"已关闭"</string>
<string name="power_notification_controls_description" msgid="1334963837572708952">"利用高级通知设置,您可以为应用通知设置从 0 级到 5 级的重要程度等级。\n\n"<b>"5 级"</b>" \n- 在通知列表顶部显示 \n- 允许全屏打扰 \n- 一律短暂显示通知 \n\n"<b>"4 级"</b>" \n- 禁止全屏打扰 \n- 一律短暂显示通知 \n\n"<b>"3 级"</b>" \n- 禁止全屏打扰 \n- 一律不短暂显示通知 \n\n"<b>"2 级"</b>" \n- 禁止全屏打扰 \n- 一律不短暂显示通知 \n- 一律不发出声音或振动 \n\n"<b>"1 级"</b>" \n- 禁止全屏打扰 \n- 一律不短暂显示通知 \n- 一律不发出声音或振动 \n- 不在锁定屏幕和状态栏中显示 \n- 在通知列表底部显示 \n\n"<b>"0 级"</b>" \n- 屏蔽应用的所有通知"</string>
<string name="notification_header_default_channel" msgid="225454696914642444">"通知"</string>
<string name="notification_channel_disabled" msgid="928065923928416337">"您将不会再看到这些通知"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 0a3e0c8c351e..7485ef858620 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1246,7 +1246,7 @@
<!-- Blur radius on status bar window and power menu -->
<dimen name="min_window_blur_radius">1px</dimen>
- <dimen name="max_window_blur_radius">72px</dimen>
+ <dimen name="max_window_blur_radius">23px</dimen>
<!-- How much into a DisplayCutout's bounds we can go, on each side -->
<dimen name="display_cutout_margin_consumption">0px</dimen>
@@ -1480,6 +1480,8 @@
<dimen name="content_text_size_for_large">14sp</dimen>
<dimen name="below_name_text_padding">16dp</dimen>
<dimen name="above_notification_text_padding">22dp</dimen>
+ <dimen name="before_messages_count_padding">40dp</dimen>
+ <dimen name="before_predefined_icon_padding">30dp</dimen>
<dimen name="regular_predefined_icon">18dp</dimen>
<dimen name="larger_predefined_icon">24dp</dimen>
<dimen name="largest_predefined_icon">32dp</dimen>
diff --git a/packages/SystemUI/res/values/dimens_tv.xml b/packages/SystemUI/res/values/dimens_tv.xml
index 5bd95ebc1c41..3dbd9903b62e 100644
--- a/packages/SystemUI/res/values/dimens_tv.xml
+++ b/packages/SystemUI/res/values/dimens_tv.xml
@@ -16,5 +16,5 @@
-->
<resources>
<dimen name="tv_notification_panel_width">360dp</dimen>
- <dimen name="tv_notification_blur_radius">100dp</dimen>
-</resources> \ No newline at end of file
+ <dimen name="tv_notification_blur_radius">31dp</dimen>
+</resources>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskInfoCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskInfoCompat.java
deleted file mode 100644
index 7b9ebc0d4656..000000000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskInfoCompat.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.shared.system;
-
-import android.app.ActivityManager;
-import android.app.PictureInPictureParams;
-import android.app.TaskInfo;
-import android.content.ComponentName;
-import android.content.pm.ActivityInfo;
-import android.graphics.Rect;
-
-public class TaskInfoCompat {
-
- public static int getUserId(TaskInfo info) {
- return info.userId;
- }
-
- public static int getActivityType(TaskInfo info) {
- return info.configuration.windowConfiguration.getActivityType();
- }
-
- public static int getWindowingMode(TaskInfo info) {
- return info.configuration.windowConfiguration.getWindowingMode();
- }
-
- public static Rect getWindowConfigurationBounds(TaskInfo info) {
- return info.configuration.windowConfiguration.getBounds();
- }
-
- public static boolean supportsSplitScreenMultiWindow(TaskInfo info) {
- return info.supportsSplitScreenMultiWindow;
- }
-
- public static ComponentName getTopActivity(TaskInfo info) {
- return info.topActivity;
- }
-
- public static ActivityManager.TaskDescription getTaskDescription(TaskInfo info) {
- return info.taskDescription;
- }
-
- public static ActivityInfo getTopActivityInfo(TaskInfo info) {
- return info.topActivityInfo;
- }
-
- public static boolean isAutoEnterPipEnabled(PictureInPictureParams params) {
- return params.isAutoEnterEnabled();
- }
-
- public static Rect getPipSourceRectHint(PictureInPictureParams params) {
- return params.getSourceRectHint();
- }
-}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index 2096c310744d..72e502816534 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -79,18 +79,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
dozeParameters, unlockedScreenOffAnimationController, /* animateYPos= */ true);
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
mSmartspaceTransitionController = smartspaceTransitionController;
-
- mKeyguardStateController.addCallback(new KeyguardStateController.Callback() {
- @Override
- public void onKeyguardShowingChanged() {
- // If we explicitly re-show the keyguard, make sure that all the child views are
- // visible. They might have been animating out as part of the SmartSpace shared
- // element transition.
- if (keyguardStateController.isShowing()) {
- mView.setChildrenAlphaExcludingClockView(1f);
- }
- }
- });
}
@Override
@@ -102,12 +90,14 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
protected void onViewAttached() {
mKeyguardUpdateMonitor.registerCallback(mInfoCallback);
mConfigurationController.addCallback(mConfigurationListener);
+ mKeyguardStateController.addCallback(mKeyguardStateControllerCallback);
}
@Override
protected void onViewDetached() {
mKeyguardUpdateMonitor.removeCallback(mInfoCallback);
mConfigurationController.removeCallback(mConfigurationListener);
+ mKeyguardStateController.removeCallback(mKeyguardStateControllerCallback);
}
/**
@@ -276,6 +266,19 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
}
};
+ private KeyguardStateController.Callback mKeyguardStateControllerCallback =
+ new KeyguardStateController.Callback() {
+ @Override
+ public void onKeyguardShowingChanged() {
+ // If we explicitly re-show the keyguard, make sure that all the child views are
+ // visible. They might have been animating out as part of the SmartSpace shared
+ // element transition.
+ if (mKeyguardStateController.isShowing()) {
+ mView.setChildrenAlphaExcludingClockView(1f);
+ }
+ }
+ };
+
/**
* Rect that specifies how KSV should be clipped, on its parent's coordinates.
*/
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index bd000b2effa3..e6e2ac980889 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -285,7 +285,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
@VisibleForTesting
protected boolean mTelephonyCapable;
- private final boolean mAcquiredHapticEnabled;
+ private final boolean mAcquiredHapticEnabled = false;
@Nullable private final Vibrator mVibrator;
// Device provisioning state
@@ -1413,11 +1413,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
@VisibleForTesting
public void playAcquiredHaptic() {
if (mAcquiredHapticEnabled && mVibrator != null) {
- String effect = Settings.Global.getString(
- mContext.getContentResolver(),
- "udfps_acquired_type");
- mVibrator.vibrate(UdfpsController.getVibration(effect,
- UdfpsController.EFFECT_TICK),
+ mVibrator.vibrate(UdfpsController.EFFECT_CLICK,
UdfpsController.VIBRATION_SONIFICATION_ATTRIBUTES);
}
}
@@ -1730,8 +1726,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
mLockPatternUtils = lockPatternUtils;
mAuthController = authController;
dumpManager.registerDumpable(getClass().getName(), this);
- mAcquiredHapticEnabled = Settings.Global.getInt(mContext.getContentResolver(),
- "udfps_acquired", 0) == 1;
mVibrator = vibrator;
mHandler = new Handler(mainLooper) {
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconView.java b/packages/SystemUI/src/com/android/keyguard/LockIconView.java
index c1d448db1e63..867e3ae6ae8c 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconView.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconView.java
@@ -16,16 +16,29 @@
package com.android.keyguard;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ArgbEvaluator;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.graphics.PointF;
import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.Interpolator;
+import android.view.animation.PathInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import androidx.annotation.NonNull;
+import com.android.settingslib.Utils;
import com.android.systemui.Dumpable;
+import com.android.systemui.R;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -33,16 +46,96 @@ import java.io.PrintWriter;
/**
* A view positioned under the notification shade.
*/
-public class LockIconView extends ImageView implements Dumpable {
+public class LockIconView extends FrameLayout implements Dumpable {
@NonNull private final RectF mSensorRect;
@NonNull private PointF mLockIconCenter = new PointF(0f, 0f);
private int mRadius;
+ private ImageView mLockIcon;
+ private ImageView mUnlockBgView;
+
+ private AnimatorSet mBgAnimator;
+ private int mLockIconColor;
+ private int mUnlockStartColor;
+ private int mUnlockEndColor;
+
public LockIconView(Context context, AttributeSet attrs) {
super(context, attrs);
mSensorRect = new RectF();
}
+ @Override
+ public void onFinishInflate() {
+ super.onFinishInflate();
+ mLockIcon = findViewById(R.id.lock_icon);
+ mUnlockBgView = findViewById(R.id.lock_icon_bg);
+ }
+
+ void updateColor() {
+ mLockIconColor = Utils.getColorAttrDefaultColor(getContext(),
+ R.attr.wallpaperTextColorAccent);
+ mUnlockStartColor = mLockIconColor;
+ mUnlockEndColor = Utils.getColorAttrDefaultColor(getContext(),
+ android.R.attr.textColorPrimary);
+ mUnlockBgView.setBackground(getContext().getDrawable(R.drawable.fingerprint_bg));
+ }
+
+ void setImageDrawable(Drawable drawable) {
+ mLockIcon.setImageDrawable(drawable);
+ }
+
+ void hideBg() {
+ mUnlockBgView.setVisibility(View.INVISIBLE);
+ mLockIcon.setImageTintList(ColorStateList.valueOf(mLockIconColor));
+ }
+
+ void animateBg() {
+ ValueAnimator bgAlphaAnimator = ObjectAnimator.ofFloat(mUnlockBgView, View.ALPHA, 0f, 1f);
+ bgAlphaAnimator.setDuration(133);
+
+ Interpolator interpolator = new PathInterpolator(0f, 0f, 0f, 1f);
+ Animator scaleXAnimator = ObjectAnimator.ofFloat(mUnlockBgView, View.SCALE_X, .9f, 1f);
+ scaleXAnimator.setInterpolator(interpolator);
+ scaleXAnimator.setDuration(300);
+ Animator scaleYAnimator = ObjectAnimator.ofFloat(mUnlockBgView, View.SCALE_Y, .9f, 1f);
+ scaleYAnimator.setDuration(300);
+ scaleYAnimator.setInterpolator(interpolator);
+
+ ValueAnimator lockIconColorAnimator =
+ ValueAnimator.ofObject(new ArgbEvaluator(), mUnlockStartColor, mUnlockEndColor);
+ lockIconColorAnimator.addUpdateListener(
+ animation -> mLockIcon.setImageTintList(
+ ColorStateList.valueOf((int) animation.getAnimatedValue())));
+ lockIconColorAnimator.setDuration(150);
+
+ if (mBgAnimator != null) {
+ if (mBgAnimator.isRunning()) {
+ return;
+ }
+ mBgAnimator.cancel();
+ }
+ mBgAnimator = new AnimatorSet();
+ mBgAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ mBgAnimator = null;
+ }
+ });
+ mBgAnimator.playTogether(
+ bgAlphaAnimator,
+ scaleYAnimator,
+ scaleXAnimator,
+ lockIconColorAnimator);
+ mBgAnimator.setStartDelay(167);
+ mUnlockBgView.setAlpha(0f);
+ mUnlockBgView.setScaleX(0);
+ mUnlockBgView.setScaleY(0);
+ mUnlockBgView.setVisibility(View.VISIBLE);
+
+ mBgAnimator.start();
+ }
+
void setCenterLocation(@NonNull PointF center, int radius) {
mLockIconCenter = center;
mRadius = radius;
@@ -70,7 +163,6 @@ public class LockIconView extends ImageView implements Dumpable {
return mLockIconCenter.y - mRadius;
}
-
@Override
public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
pw.println("Center in px (x, y)= (" + mLockIconCenter.x + ", " + mLockIconCenter.y + ")");
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index 7bbb63f02f14..a7bd4c8e3d27 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -24,8 +24,8 @@ import android.content.Context;
import android.content.res.Configuration;
import android.graphics.PointF;
import android.graphics.Rect;
+import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable;
-import android.graphics.drawable.InsetDrawable;
import android.hardware.biometrics.BiometricSourceType;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.util.DisplayMetrics;
@@ -40,7 +40,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
-import com.android.settingslib.Utils;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.biometrics.AuthController;
@@ -79,7 +78,8 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
@NonNull private final DelayableExecutor mExecutor;
private boolean mUdfpsEnrolled;
- @NonNull private final Drawable mUnlockIcon;
+ @NonNull private final AnimatedVectorDrawable mFpToUnlockIcon;
+ @NonNull private final AnimatedVectorDrawable mLockToUnlockIcon;
@NonNull private final Drawable mLockIcon;
@NonNull private final CharSequence mUnlockedLabel;
@NonNull private final CharSequence mLockedLabel;
@@ -133,17 +133,18 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
mExecutor = executor;
final Context context = view.getContext();
- mUnlockIcon = new InsetDrawable(context.getResources().getDrawable(
- com.android.internal.R.drawable.ic_lock_open, context.getTheme()),
- context.getResources().getDimensionPixelSize(
- com.android.systemui.R.dimen.udfps_unlock_icon_inset));
- mLockIcon = new InsetDrawable(context.getResources().getDrawable(
- com.android.internal.R.drawable.ic_lock, context.getTheme()),
- context.getResources().getDimensionPixelSize(
- com.android.systemui.R.dimen.udfps_unlock_icon_inset));
+ mLockIcon = mView.getContext().getResources().getDrawable(
+ R.anim.lock_to_unlock,
+ mView.getContext().getTheme());
+ mFpToUnlockIcon = (AnimatedVectorDrawable) mView.getContext().getResources().getDrawable(
+ R.anim.fp_to_unlock, mView.getContext().getTheme());
+ mLockToUnlockIcon = (AnimatedVectorDrawable) mView.getContext().getResources().getDrawable(
+ R.anim.lock_to_unlock,
+ mView.getContext().getTheme());
mUnlockedLabel = context.getResources().getString(R.string.accessibility_unlock_button);
mLockedLabel = context.getResources().getString(R.string.accessibility_lock_icon);
dumpManager.registerDumpable("LockIconViewController", this);
+
}
@Override
@@ -212,6 +213,8 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
return;
}
+ boolean wasShowingFpIcon = mHasUdfps && !mShowUnlockIcon && !mShowLockIcon;
+ boolean wasShowingLockIcon = mShowLockIcon;
mShowLockIcon = !mCanDismissLockScreen && !mUserUnlockedWithBiometric && isLockScreen()
&& (!mUdfpsEnrolled || !mRunningFPS);
mShowUnlockIcon = mCanDismissLockScreen && isLockScreen();
@@ -221,11 +224,22 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
mView.setImageDrawable(mLockIcon);
mView.setVisibility(View.VISIBLE);
mView.setContentDescription(mLockedLabel);
+ mView.hideBg();
} else if (mShowUnlockIcon) {
- mView.setImageDrawable(mUnlockIcon);
+ if (wasShowingFpIcon) {
+ mView.setImageDrawable(mFpToUnlockIcon);
+ mFpToUnlockIcon.forceAnimationOnUI();
+ mFpToUnlockIcon.start();
+ } else if (wasShowingLockIcon) {
+ mView.setImageDrawable(mLockToUnlockIcon);
+ mLockToUnlockIcon.forceAnimationOnUI();
+ mLockToUnlockIcon.start();
+ }
+ mView.animateBg();
mView.setVisibility(View.VISIBLE);
mView.setContentDescription(mUnlockedLabel);
} else {
+ mView.hideBg();
mView.setVisibility(View.INVISIBLE);
mView.setContentDescription(null);
}
@@ -270,10 +284,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
}
private void updateColors() {
- final int color = Utils.getColorAttrDefaultColor(mView.getContext(),
- R.attr.wallpaperTextColorAccent);
- mUnlockIcon.setTint(color);
- mLockIcon.setTint(color);
+ mView.updateColor();
}
private void updateConfiguration() {
@@ -433,6 +444,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
@Override
public void onConfigChanged(Configuration newConfig) {
updateConfiguration();
+ updateColors();
}
};
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
index 099e6f4b5341..57407f1f34c0 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
@@ -88,13 +88,10 @@ public class NumPadButton extends AlphaOptimizedImageButton {
* Reload colors from resources.
**/
public void reloadColors() {
- if (mAnimator != null) {
- mAnimator.reloadColors(getContext());
- } else {
- // Needed for old style pin
- int textColor = Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary)
- .getDefaultColor();
- ((VectorDrawable) getDrawable()).setTintList(ColorStateList.valueOf(textColor));
- }
+ if (mAnimator != null) mAnimator.reloadColors(getContext());
+
+ int textColor = Utils.getColorAttrDefaultColor(getContext(),
+ android.R.attr.colorBackground);
+ ((VectorDrawable) getDrawable()).setTintList(ColorStateList.valueOf(textColor));
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.java
index 45ee4ad9ae50..ee602bc9cb78 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.java
@@ -23,6 +23,8 @@ import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
+import androidx.annotation.Nullable;
+
import com.android.systemui.R;
public class AuthBiometricFingerprintView extends AuthBiometricView {
@@ -94,12 +96,37 @@ public class AuthBiometricFingerprintView extends AuthBiometricView {
mIconView.setImageDrawable(icon);
+ final CharSequence iconContentDescription = getIconContentDescription(newState);
+ if (iconContentDescription != null) {
+ mIconView.setContentDescription(iconContentDescription);
+ }
+
if (animation != null && shouldAnimateForTransition(lastState, newState)) {
animation.forceAnimationOnUI();
animation.start();
}
}
+ @Nullable
+ private CharSequence getIconContentDescription(int newState) {
+ switch (newState) {
+ case STATE_IDLE:
+ case STATE_AUTHENTICATING_ANIMATING_IN:
+ case STATE_AUTHENTICATING:
+ case STATE_PENDING_CONFIRMATION:
+ case STATE_AUTHENTICATED:
+ return mContext.getString(
+ R.string.accessibility_fingerprint_dialog_fingerprint_icon);
+
+ case STATE_ERROR:
+ case STATE_HELP:
+ return mContext.getString(R.string.biometric_dialog_try_again);
+
+ default:
+ return null;
+ }
+ }
+
private boolean shouldAnimateForTransition(int oldState, int newState) {
switch (newState) {
case STATE_HELP:
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
index bebf813e1833..60b06378a61a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
@@ -636,7 +636,6 @@ public abstract class AuthBiometricView extends LinearLayout {
mIndicatorView.setText(message);
mIndicatorView.setTextColor(mTextColorError);
mIndicatorView.setVisibility(View.VISIBLE);
- mIndicatorView.setSelected(true);
mHandler.postDelayed(resetMessageRunnable, mInjector.getDelayAfterError());
Utils.notifyAccessibilityContentChanged(mAccessibilityManager, this);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 068640622294..ab3e042e9da7 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -17,7 +17,6 @@
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;
import static com.android.internal.util.Preconditions.checkNotNull;
@@ -27,7 +26,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -47,8 +45,6 @@ import android.os.SystemClock;
import android.os.Trace;
import android.os.VibrationEffect;
import android.os.Vibrator;
-import android.provider.Settings;
-import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -160,16 +156,8 @@ public class UdfpsController implements DozeReceiver {
.setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
.build();
- public static final VibrationEffect EFFECT_TICK =
- VibrationEffect.get(VibrationEffect.EFFECT_TICK);
- private static final VibrationEffect EFFECT_TEXTURE_TICK =
- VibrationEffect.get(VibrationEffect.EFFECT_TEXTURE_TICK);
- @VisibleForTesting
- static final VibrationEffect EFFECT_CLICK = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
- private static final VibrationEffect EFFECT_HEAVY =
- VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK);
- private static final VibrationEffect EFFECT_DOUBLE_CLICK =
- VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
+ public static final VibrationEffect EFFECT_CLICK =
+ VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
private final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
@Override
@@ -437,7 +425,6 @@ public class UdfpsController implements DozeReceiver {
mTouchLogTime = SystemClock.elapsedRealtime();
mPowerManager.userActivity(SystemClock.uptimeMillis(),
PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
- playStartHaptic();
handled = true;
} else if (sinceLastLog >= MIN_TOUCH_LOG_INTERVAL) {
Log.v(TAG, "onTouch | finger move: " + touchInfo);
@@ -552,18 +539,7 @@ public class UdfpsController implements DozeReceiver {
@VisibleForTesting
public void playStartHaptic() {
if (mVibrator != null) {
- final ContentResolver contentResolver =
- mContext.getContentResolver();
- // TODO: these settings checks should eventually be removed after ux testing
- // (b/185124905)
- int startEnabled = Settings.Global.getInt(contentResolver,
- "udfps_start", 1);
- if (startEnabled > 0) {
- String startEffectSetting = Settings.Global.getString(
- contentResolver, "udfps_start_type");
- mVibrator.vibrate(getVibration(startEffectSetting,
- EFFECT_CLICK), VIBRATION_SONIFICATION_ATTRIBUTES);
- }
+ mVibrator.vibrate(EFFECT_CLICK, VIBRATION_SONIFICATION_ATTRIBUTES);
}
}
@@ -636,9 +612,12 @@ public class UdfpsController implements DozeReceiver {
// Gets the size based on the current rotation of the display.
mContext.getDisplay().getRealSize(p);
- // Transform dimensions if the device is in landscape mode.
+ // Transform dimensions if the device is in landscape mode
switch (mContext.getDisplay().getRotation()) {
case Surface.ROTATION_90:
+ if (animation instanceof UdfpsKeyguardViewController) {
+ break;
+ }
mCoreLayoutParams.x = mSensorProps.sensorLocationY - mSensorProps.sensorRadius
- paddingX;
mCoreLayoutParams.y = p.y - mSensorProps.sensorLocationX - mSensorProps.sensorRadius
@@ -646,6 +625,9 @@ public class UdfpsController implements DozeReceiver {
break;
case Surface.ROTATION_270:
+ if (animation instanceof UdfpsKeyguardViewController) {
+ break;
+ }
mCoreLayoutParams.x = p.x - mSensorProps.sensorLocationY - mSensorProps.sensorRadius
- paddingX;
mCoreLayoutParams.y = mSensorProps.sensorLocationX - mSensorProps.sensorRadius
@@ -654,6 +636,7 @@ public class UdfpsController implements DozeReceiver {
default:
// Do nothing to stay in portrait mode.
+ // Keyguard is always in portrait mode.
}
// avoid announcing window title
mCoreLayoutParams.accessibilityTitle = " ";
@@ -691,7 +674,8 @@ public class UdfpsController implements DozeReceiver {
// This view overlaps the sensor area, so prevent it from being selectable
// during a11y.
if (reason == IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR
- || reason == IUdfpsOverlayController.REASON_ENROLL_ENROLLING) {
+ || reason == IUdfpsOverlayController.REASON_ENROLL_ENROLLING
+ || reason == IUdfpsOverlayController.REASON_AUTH_BP) {
mView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
}
@@ -846,6 +830,9 @@ public class UdfpsController implements DozeReceiver {
Log.w(TAG, "Null view in onFingerDown");
return;
}
+ if (!mOnFingerDown) {
+ playStartHaptic();
+ }
mOnFingerDown = true;
mFingerprintManager.onPointerDown(mSensorProps.sensorId, x, y, minor, major);
Trace.endAsyncSection("UdfpsController.e2e.onPointerDown", 0);
@@ -873,38 +860,6 @@ public class UdfpsController implements DozeReceiver {
}
}
- /**
- * get vibration to play given string
- * used for testing purposes (b/185124905)
- */
- public static VibrationEffect getVibration(String effect, VibrationEffect defaultEffect) {
- if (TextUtils.isEmpty(effect)) {
- return defaultEffect;
- }
-
- switch (effect.toLowerCase()) {
- case "click":
- return EFFECT_CLICK;
- case "heavy":
- return EFFECT_HEAVY;
- case "texture_tick":
- return EFFECT_TEXTURE_TICK;
- case "tick":
- return EFFECT_TICK;
- case "double_tap":
- return EFFECT_DOUBLE_CLICK;
- default:
- try {
- int primitive = Integer.parseInt(effect);
- if (primitive <= PRIMITIVE_LOW_TICK && primitive > -1) {
- return VibrationEffect.startComposition().addPrimitive(primitive).compose();
- }
- } catch (NumberFormatException e) {
- }
- return defaultEffect;
- }
- }
-
private void updateTouchListener() {
if (mView == null) {
return;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
index e82f648503b9..eb02aa0d9cdf 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
@@ -43,6 +43,7 @@ import com.android.systemui.statusbar.StatusBarState;
import com.airbnb.lottie.LottieAnimationView;
import com.airbnb.lottie.LottieProperty;
import com.airbnb.lottie.model.KeyPath;
+
/**
* View corresponding with udfps_keyguard_view.xml
*/
@@ -138,9 +139,12 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
mAodFp.setTranslationX(mBurnInOffsetX);
mAodFp.setTranslationY(mBurnInOffsetY);
mAodFp.setProgress(mBurnInProgress);
+ mAodFp.setAlpha(255 * mInterpolatedDarkAmount);
mLockScreenFp.setTranslationX(mBurnInOffsetX);
mLockScreenFp.setTranslationY(mBurnInOffsetY);
+ mLockScreenFp.setProgress(1f - mInterpolatedDarkAmount);
+ mLockScreenFp.setAlpha((1f - mInterpolatedDarkAmount) * 255);
}
void requestUdfps(boolean request, int color) {
@@ -158,7 +162,12 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
}
void updateColor() {
+ mWallpaperTextColor = Utils.getColorAttrDefaultColor(mContext,
+ R.attr.wallpaperTextColorAccent);
+ mTextColorPrimary = Utils.getColorAttrDefaultColor(mContext,
+ android.R.attr.textColorPrimary);
mLockScreenFp.invalidate();
+ mBgProtection.setBackground(getContext().getDrawable(R.drawable.fingerprint_bg));
}
private boolean showingUdfpsBouncer() {
@@ -207,14 +216,6 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
mHintAnimator.cancel();
mInterpolatedDarkAmount = eased;
updateBurnInOffsets();
- mLockScreenFp.setProgress(1f - mInterpolatedDarkAmount);
- mAodFp.setAlpha(mInterpolatedDarkAmount);
-
- if (linear == 1f) {
- mLockScreenFp.setVisibility(View.INVISIBLE);
- } else {
- mLockScreenFp.setVisibility(View.VISIBLE);
- }
}
void animateHint() {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index c33f4fa8dee4..c7c25903923a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -2311,7 +2311,6 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
// only play "unlock" noises if not on a call (since the incall UI
// disables the keyguard)
if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) {
- Log.i("TEST", "playSounds: false");
playSounds(false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 902e8c28a85d..15a70831b2f9 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -475,6 +475,13 @@ public class MediaControlPanel {
@Nullable
private ActivityLaunchAnimator.Controller buildLaunchAnimatorController(
TransitionLayout player) {
+ if (!(player.getParent() instanceof ViewGroup)) {
+ // TODO(b/192194319): Throw instead of just logging.
+ Log.wtf(TAG, "Skipping player animation as it is not attached to a ViewGroup",
+ new Exception());
+ return null;
+ }
+
// TODO(b/174236650): Make sure that the carousel indicator also fades out.
// TODO(b/174236650): Instrument the animation to measure jank.
return new GhostedViewLaunchAnimatorController(player,
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
index 335ebca37bf0..a16b92f494a4 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
@@ -47,6 +47,7 @@ import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
+import android.graphics.ImageDecoder;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.graphics.text.LineBreaker;
@@ -59,6 +60,7 @@ import android.text.TextUtils;
import android.util.IconDrawableFactory;
import android.util.Log;
import android.util.Pair;
+import android.util.Size;
import android.util.SizeF;
import android.util.TypedValue;
import android.view.Gravity;
@@ -79,6 +81,7 @@ import com.android.systemui.people.widget.LaunchConversationActivity;
import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
import com.android.systemui.people.widget.PeopleTileKey;
+import java.io.IOException;
import java.text.NumberFormat;
import java.time.Duration;
import java.util.ArrayList;
@@ -178,6 +181,7 @@ public class PeopleTileViewHelper {
private int mWidth;
private int mHeight;
private int mLayoutSize;
+ private boolean mIsLeftToRight;
private Locale mLocale;
private NumberFormat mIntegerFormat;
@@ -192,6 +196,8 @@ public class PeopleTileViewHelper {
mWidth = width;
mHeight = height;
mLayoutSize = getLayoutSize();
+ mIsLeftToRight = TextUtils.getLayoutDirectionFromLocale(Locale.getDefault())
+ == View.LAYOUT_DIRECTION_LTR;
}
/**
@@ -656,7 +662,7 @@ public class PeopleTileViewHelper {
private RemoteViews createMissedCallRemoteViews() {
RemoteViews views = setViewForContentLayout(new RemoteViews(mContext.getPackageName(),
getLayoutForContent()));
- views.setViewVisibility(R.id.predefined_icon, View.VISIBLE);
+ setPredefinedIconVisible(views);
views.setViewVisibility(R.id.text_content, View.VISIBLE);
views.setViewVisibility(R.id.messages_count, View.GONE);
setMaxLines(views, false);
@@ -675,19 +681,39 @@ public class PeopleTileViewHelper {
return views;
}
+ private void setPredefinedIconVisible(RemoteViews views) {
+ views.setViewVisibility(R.id.predefined_icon, View.VISIBLE);
+ if (mLayoutSize == LAYOUT_MEDIUM) {
+ int endPadding = mContext.getResources().getDimensionPixelSize(
+ R.dimen.before_predefined_icon_padding);
+ views.setViewPadding(R.id.name, mIsLeftToRight ? 0 : endPadding, 0,
+ mIsLeftToRight ? endPadding : 0,
+ 0);
+ }
+ }
+
private RemoteViews createNotificationRemoteViews() {
RemoteViews views = setViewForContentLayout(new RemoteViews(mContext.getPackageName(),
getLayoutForNotificationContent()));
CharSequence sender = mTile.getNotificationSender();
- Uri image = mTile.getNotificationDataUri();
- if (image != null) {
- // TODO: Use NotificationInlineImageCache
- views.setImageViewUri(R.id.image, image);
+ Uri imageUri = mTile.getNotificationDataUri();
+ if (imageUri != null) {
String newImageDescription = mContext.getString(
R.string.new_notification_image_content_description, mTile.getUserName());
views.setContentDescription(R.id.image, newImageDescription);
views.setViewVisibility(R.id.image, View.VISIBLE);
views.setViewVisibility(R.id.text_content, View.GONE);
+ try {
+ Drawable drawable = resolveImage(imageUri, mContext);
+ Bitmap bitmap = convertDrawableToBitmap(drawable);
+ views.setImageViewBitmap(R.id.image, bitmap);
+ } catch (IOException e) {
+ Log.e(TAG, "Could not decode image: " + e);
+ // If we couldn't load the image, show text that we have a new image.
+ views.setTextViewText(R.id.text_content, newImageDescription);
+ views.setViewVisibility(R.id.text_content, View.VISIBLE);
+ views.setViewVisibility(R.id.image, View.GONE);
+ }
} else {
setMaxLines(views, !TextUtils.isEmpty(sender));
CharSequence content = mTile.getNotificationContent();
@@ -705,6 +731,13 @@ public class PeopleTileViewHelper {
views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_message);
}
if (mTile.getMessagesCount() > 1) {
+ if (mLayoutSize == LAYOUT_MEDIUM) {
+ int endPadding = mContext.getResources().getDimensionPixelSize(
+ R.dimen.before_messages_count_padding);
+ views.setViewPadding(R.id.name, mIsLeftToRight ? 0 : endPadding, 0,
+ mIsLeftToRight ? endPadding : 0,
+ 0);
+ }
views.setViewVisibility(R.id.messages_count, View.VISIBLE);
views.setTextViewText(R.id.messages_count,
getMessagesCountText(mTile.getMessagesCount()));
@@ -722,6 +755,40 @@ public class PeopleTileViewHelper {
return views;
}
+ private Drawable resolveImage(Uri uri, Context context) throws IOException {
+ final ImageDecoder.Source source =
+ ImageDecoder.createSource(context.getContentResolver(), uri);
+ final Drawable drawable =
+ ImageDecoder.decodeDrawable(source, (decoder, info, s) -> {
+ onHeaderDecoded(decoder, info, s);
+ });
+ return drawable;
+ }
+
+ private static int getPowerOfTwoForSampleRatio(double ratio) {
+ final int k = Integer.highestOneBit((int) Math.floor(ratio));
+ return Math.max(1, k);
+ }
+
+ private void onHeaderDecoded(ImageDecoder decoder, ImageDecoder.ImageInfo info,
+ ImageDecoder.Source source) {
+ int widthInPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mWidth,
+ mContext.getResources().getDisplayMetrics());
+ int heightInPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mHeight,
+ mContext.getResources().getDisplayMetrics());
+ int maxIconSizeInPx = Math.max(widthInPx, heightInPx);
+ int minDimen = (int) (1.5 * Math.min(widthInPx, heightInPx));
+ if (minDimen < maxIconSizeInPx) {
+ maxIconSizeInPx = minDimen;
+ }
+ final Size size = info.getSize();
+ final int originalSize = Math.max(size.getHeight(), size.getWidth());
+ final double ratio = (originalSize > maxIconSizeInPx)
+ ? originalSize * 1f / maxIconSizeInPx
+ : 1.0;
+ decoder.setTargetSampleSize(getPowerOfTwoForSampleRatio(ratio));
+ }
+
private void setContentDescriptionForNotificationTextContent(RemoteViews views,
CharSequence content, CharSequence sender) {
String newTextDescriptionWithNotificationContent = mContext.getString(
@@ -757,7 +824,7 @@ public class PeopleTileViewHelper {
if (TextUtils.isEmpty(statusText)) {
statusText = getStatusTextByType(status.getActivity());
}
- views.setViewVisibility(R.id.predefined_icon, View.VISIBLE);
+ setPredefinedIconVisible(views);
views.setTextViewText(R.id.text_content, statusText);
if (status.getActivity() == ACTIVITY_BIRTHDAY
@@ -867,13 +934,11 @@ public class PeopleTileViewHelper {
* on the status layouts compared to all other layouts.
*/
private void setAvailabilityDotPadding(RemoteViews views, int resId) {
- boolean isLeftToRight = TextUtils.getLayoutDirectionFromLocale(Locale.getDefault())
- == View.LAYOUT_DIRECTION_LTR;
int startPadding = mContext.getResources().getDimensionPixelSize(resId);
int bottomPadding = mContext.getResources().getDimensionPixelSize(
R.dimen.medium_content_padding_above_name);
views.setViewPadding(R.id.medium_content,
- isLeftToRight ? startPadding : 0, 0, isLeftToRight ? 0 : startPadding,
+ mIsLeftToRight ? startPadding : 0, 0, mIsLeftToRight ? 0 : startPadding,
bottomPadding);
}
@@ -1071,6 +1136,7 @@ public class PeopleTileViewHelper {
views.setViewPadding(R.id.content, horizontalPadding, verticalPadding,
horizontalPadding,
verticalPadding);
+ views.setViewPadding(R.id.name, 0, 0, 0, 0);
// Expand the name font on medium if there's space.
int heightRequiredForMaxContentText = (int) (mContext.getResources().getDimension(
R.dimen.medium_height_for_max_name_text_size) / mDensity);
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
index 3320fbda6fe5..985903435b9a 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
@@ -375,7 +375,7 @@ public class PeopleSpaceWidgetManager {
widgetSp.getInt(USER_ID, INVALID_USER_ID),
widgetSp.getString(PACKAGE_NAME, EMPTY_STRING));
- return getTileFromPersistentStorage(key, appWidgetId);
+ return getTileFromPersistentStorage(key, appWidgetId, /* supplementFromStorage= */ true);
}
/**
@@ -383,7 +383,8 @@ public class PeopleSpaceWidgetManager {
* If a {@link PeopleTileKey} is not provided, fetch one from {@link SharedPreferences}.
*/
@Nullable
- public PeopleSpaceTile getTileFromPersistentStorage(PeopleTileKey key, int appWidgetId) throws
+ public PeopleSpaceTile getTileFromPersistentStorage(PeopleTileKey key, int appWidgetId,
+ boolean supplementFromStorage) throws
PackageManager.NameNotFoundException {
if (!PeopleTileKey.isValid(key)) {
Log.e(TAG, "PeopleTileKey invalid: " + key.toString());
@@ -412,7 +413,8 @@ public class PeopleSpaceWidgetManager {
// Supplement with our storage.
String contactUri = mSharedPrefs.getString(String.valueOf(appWidgetId), null);
- if (contactUri != null && storedTile.build().getContactUri() == null) {
+ if (supplementFromStorage && contactUri != null
+ && storedTile.build().getContactUri() == null) {
if (DEBUG) Log.d(TAG, "Restore contact uri from storage: " + contactUri);
storedTile.setContactUri(Uri.parse(contactUri));
}
@@ -811,7 +813,8 @@ public class PeopleSpaceWidgetManager {
if (DEBUG) Log.d(TAG, "addNewWidget called with key for appWidgetId: " + appWidgetId);
PeopleSpaceTile tile = null;
try {
- tile = getTileFromPersistentStorage(key, appWidgetId);
+ tile = getTileFromPersistentStorage(key, appWidgetId, /* supplementFromStorage= */
+ false);
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Cannot add widget since app was uninstalled");
return;
@@ -850,7 +853,9 @@ public class PeopleSpaceWidgetManager {
} catch (Exception e) {
Log.w(TAG, "Exception caching shortcut:" + e);
}
- updateAppWidgetOptionsAndView(appWidgetId, tile);
+ PeopleSpaceTile finalTile = tile;
+ mBgExecutor.execute(
+ () -> updateAppWidgetOptionsAndView(appWidgetId, finalTile));
}
/** Registers a conversation listener for {@code appWidgetId} if not already registered. */
@@ -1071,7 +1076,7 @@ public class PeopleSpaceWidgetManager {
return;
}
for (int appWidgetId : appWidgetIds) {
- if (DEBUG) Log.d(TAG, "Updating widget from broadcast, widget id: " + appWidgetId);
+ if (DEBUG) Log.d(TAG, "Updating widget from broadcast, widget id: " + appWidgetId);
PeopleSpaceTile existingTile = null;
PeopleSpaceTile updatedTile = null;
try {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
index 1d6c7c94dcc3..929927e5d4e4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
@@ -212,6 +212,11 @@ public class QSDetail extends LinearLayout {
Dependency.get(CommandQueue.class).animateCollapsePanels();
mTriggeredExpand = false;
}
+ // Always animate on close, even if the last opened detail adapter had shouldAnimate()
+ // return false. This is necessary to avoid a race condition which could leave the
+ // keyguard in a bad state where QS remains visible underneath the notifications, clock,
+ // and status area.
+ mShouldAnimate = true;
}
boolean visibleDiff = wasShowingDetail != showingDetail;
@@ -245,10 +250,15 @@ public class QSDetail extends LinearLayout {
mClosingDetail = true;
mDetailAdapter = null;
listener = mTeardownDetailWhenDone;
- mHeader.setVisibility(View.VISIBLE);
- mFooter.setVisibility(View.VISIBLE);
- mQsPanelController.setGridContentVisibility(true);
- mQsPanelCallback.onScanStateChanged(false);
+ // Only update visibility if already expanded. Otherwise, a race condition can cause the
+ // keyguard to enter a bad state where the QS tiles are displayed underneath the
+ // notifications, clock, and status area.
+ if (mQsPanelController.isExpanded()) {
+ mHeader.setVisibility(View.VISIBLE);
+ mFooter.setVisibility(View.VISIBLE);
+ mQsPanelController.setGridContentVisibility(true);
+ mQsPanelCallback.onScanStateChanged(false);
+ }
}
sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
animateDetailVisibleDiff(x, y, visibleDiff, listener);
diff --git a/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt b/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt
index ef18df5706ad..f0fb5ebf9e1d 100644
--- a/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt
@@ -17,6 +17,7 @@
package com.android.systemui.sensorprivacy
import android.content.DialogInterface
+import android.content.Intent
import android.content.Intent.EXTRA_PACKAGE_NAME
import android.content.pm.PackageManager
import android.content.res.Resources
@@ -178,7 +179,7 @@ class SensorUseStartedActivity @Inject constructor(
override fun onStart() {
super.onStart()
- sensorPrivacyController.suppressSensorPrivacyReminders(sensorUsePackageName, true)
+ setSuppressed(true)
unsuppressImmediately = false
}
@@ -218,12 +219,10 @@ class SensorUseStartedActivity @Inject constructor(
super.onStop()
if (unsuppressImmediately) {
- sensorPrivacyController
- .suppressSensorPrivacyReminders(sensorUsePackageName, false)
+ setSuppressed(false)
} else {
bgHandler.postDelayed({
- sensorPrivacyController
- .suppressSensorPrivacyReminders(sensorUsePackageName, false)
+ setSuppressed(false)
}, SUPPRESS_REMINDERS_REMOVAL_DELAY_MILLIS)
}
}
@@ -237,6 +236,11 @@ class SensorUseStartedActivity @Inject constructor(
// do not allow backing out
}
+ override fun onNewIntent(intent: Intent?) {
+ setIntent(intent)
+ recreate()
+ }
+
private fun disableSensorPrivacy() {
if (sensor == ALL_SENSORS) {
sensorPrivacyController.setSensorBlocked(DIALOG, MICROPHONE, false)
@@ -247,4 +251,16 @@ class SensorUseStartedActivity @Inject constructor(
unsuppressImmediately = true
setResult(RESULT_OK)
}
+
+ private fun setSuppressed(suppressed: Boolean) {
+ if (sensor == ALL_SENSORS) {
+ sensorPrivacyController
+ .suppressSensorPrivacyReminders(MICROPHONE, suppressed)
+ sensorPrivacyController
+ .suppressSensorPrivacyReminders(CAMERA, suppressed)
+ } else {
+ sensorPrivacyController
+ .suppressSensorPrivacyReminders(sensor, suppressed)
+ }
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java
index b6aed23e64ee..180f81c22a9d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java
@@ -131,7 +131,7 @@ public class RemoteInputController {
*/
public void removeRemoteInput(NotificationEntry entry, Object token) {
Objects.requireNonNull(entry);
- if (entry.mRemoteEditImeVisible) return;
+ if (entry.mRemoteEditImeVisible && entry.mRemoteEditImeAnimatingAway) return;
// If the view is being removed, this may be called even though we're not active
if (!isRemoteInputActive(entry)) return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index 96b0e7819c7a..94ee868ceebc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -183,6 +183,7 @@ public final class NotificationEntry extends ListEntry {
private boolean mIsMarkedForUserTriggeredMovement;
private boolean mIsAlerting;
+ public boolean mRemoteEditImeAnimatingAway;
public boolean mRemoteEditImeVisible;
private boolean mExpandAnimationRunning;
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 e65038b32bf0..f460a132d65c 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
@@ -148,8 +148,22 @@ public class StackScrollAlgorithm {
AmbientState ambientState) {
NotificationShelf shelf = ambientState.getShelf();
- if (shelf != null) {
- shelf.updateState(algorithmState, ambientState);
+ if (shelf == null) {
+ return;
+ }
+
+ shelf.updateState(algorithmState, ambientState);
+
+ // After the shelf has updated its yTranslation,
+ // explicitly hide views below the shelf to skip rendering them in the hardware layer.
+ final float shelfTop = shelf.getViewState().yTranslation;
+
+ for (ExpandableView view : algorithmState.visibleChildren) {
+ final float viewTop = view.getViewState().yTranslation;
+
+ if (viewTop >= shelfTop) {
+ view.getViewState().hidden = true;
+ }
}
}
@@ -411,8 +425,7 @@ public class StackScrollAlgorithm {
} else {
if (view != ambientState.getTrackedHeadsUpRow()) {
if (ambientState.isExpansionChanging()) {
- // Show all views. Views below the shelf will later be clipped (essentially
- // hidden) in NotificationShelf.
+ // We later update shelf state, then hide views below the shelf.
viewState.hidden = false;
viewState.inShelf = algorithmState.firstViewInShelf != null
&& i >= algorithmState.visibleChildren.indexOf(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 16f8319928bb..91d503bac4fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -74,6 +74,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.settingslib.Utils;
import com.android.systemui.ActivityIntentHelper;
import com.android.systemui.Dependency;
import com.android.systemui.R;
@@ -459,6 +460,10 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
if (tileIcon != null) {
mWalletButton.setImageDrawable(tileIcon);
}
+ mWalletButton.getDrawable().setTint(
+ Utils.getColorAttr(
+ mContext,
+ com.android.internal.R.attr.textColorPrimary).getDefaultColor());
mWalletButton.setVisibility(VISIBLE);
mWalletButton.setOnClickListener(this::onWalletClick);
mIndicationArea.setPadding(mIndicationPadding, 0, mIndicationPadding, 0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index d6ea4a828395..8c0dfc5f7ab4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -87,7 +87,7 @@ public class KeyguardBouncer {
private final Runnable mResetRunnable = ()-> {
if (mKeyguardViewController != null) {
mKeyguardViewController.resetSecurityContainer();
- for (KeyguardResetCallback callback : mResetCallbacks) {
+ for (KeyguardResetCallback callback : new ArrayList<>(mResetCallbacks)) {
callback.onKeyguardReset();
}
}
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 f52aad96ce69..3c1892d4b7ea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -113,6 +113,7 @@ import com.android.systemui.plugins.qs.QS;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.qs.QSDetailDisplayer;
+import com.android.systemui.screenrecord.RecordingController;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags;
@@ -327,6 +328,7 @@ public class NotificationPanelViewController extends PanelViewController {
private final int mMaxKeyguardNotifications;
private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
private final TapAgainViewController mTapAgainViewController;
+ private final RecordingController mRecordingController;
private boolean mShouldUseSplitNotificationShade;
// Current max allowed keyguard notifications determined by measuring the panel
private int mMaxAllowedKeyguardNotifications;
@@ -711,6 +713,7 @@ public class NotificationPanelViewController extends PanelViewController {
FragmentService fragmentService,
ContentResolver contentResolver,
QuickAccessWalletController quickAccessWalletController,
+ RecordingController recordingController,
@Main Executor uiExecutor,
SecureSettings secureSettings,
UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
@@ -755,6 +758,7 @@ public class NotificationPanelViewController extends PanelViewController {
mView.setAccessibilityPaneTitle(determineAccessibilityPaneTitle());
setPanelAlpha(255, false /* animate */);
mCommandQueue = commandQueue;
+ mRecordingController = recordingController;
mDisplayId = displayId;
mPulseExpansionHandler = pulseExpansionHandler;
mDozeParameters = dozeParameters;
@@ -1571,7 +1575,10 @@ public class NotificationPanelViewController extends PanelViewController {
public void expandWithQsDetail(DetailAdapter qsDetailAdapter) {
traceQsJank(true /* startTracing */, false /* wasCancelled */);
flingSettings(0 /* velocity */, FLING_EXPAND);
- mQSDetailDisplayer.showDetailAdapter(qsDetailAdapter, 0, 0);
+ // When expanding with a panel, there's no meaningful touch point to correspond to. Set the
+ // origin to somewhere above the screen. This is used for animations.
+ int x = mQsFrame.getWidth() / 2;
+ mQSDetailDisplayer.showDetailAdapter(qsDetailAdapter, x, -getHeight());
if (mAccessibilityManager.isEnabled()) {
mView.setAccessibilityPaneTitle(determineAccessibilityPaneTitle());
}
@@ -2359,7 +2366,8 @@ public class NotificationPanelViewController extends PanelViewController {
// The padding on this area is large enough that we can use a cheaper clipping strategy
mKeyguardStatusAreaClipBounds.set(left, top, right, bottom);
clipStatusView = qsVisible;
- radius = (int) MathUtils.lerp(mScreenCornerRadius, mScrimCornerRadius,
+ float screenCornerRadius = mRecordingController.isRecording() ? 0 : mScreenCornerRadius;
+ radius = (int) MathUtils.lerp(screenCornerRadius, mScrimCornerRadius,
Math.min(top / (float) mScrimCornerRadius, 1f));
statusBarClipTop = top - mKeyguardStatusBar.getTop();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
index 022faf78b946..5e105bb64350 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
@@ -55,16 +55,18 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.google.android.collect.Lists;
-
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;
+import java.util.stream.Collectors;
import javax.inject.Inject;
@@ -100,7 +102,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
private ForcePluginOpenListener mForcePluginOpenListener;
private Consumer<Integer> mScrimsVisibilityListener;
private final ArrayList<WeakReference<StatusBarWindowCallback>>
- mCallbacks = Lists.newArrayList();
+ mCallbacks = new ArrayList<>();
private final SysuiColorExtractor mColorExtractor;
private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
@@ -464,13 +466,15 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
@Override
public void notifyStateChangedCallbacks() {
- for (int i = 0; i < mCallbacks.size(); i++) {
- StatusBarWindowCallback cb = mCallbacks.get(i).get();
- if (cb != null) {
- cb.onStateChanged(mCurrentState.mKeyguardShowing,
- mCurrentState.mKeyguardOccluded,
- mCurrentState.mBouncerShowing);
- }
+ // Copy callbacks to separate ArrayList to avoid concurrent modification
+ List<StatusBarWindowCallback> activeCallbacks = mCallbacks.stream()
+ .map(Reference::get)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+ for (StatusBarWindowCallback cb : activeCallbacks) {
+ cb.onStateChanged(mCurrentState.mKeyguardShowing,
+ mCurrentState.mKeyguardOccluded,
+ mCurrentState.mBouncerShowing);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 89711fa6b11e..db7ead7c1531 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -55,6 +55,7 @@ import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.StatusBarManager;
+import android.app.TaskInfo;
import android.app.UiModeManager;
import android.app.WallpaperInfo;
import android.app.WallpaperManager;
@@ -247,6 +248,8 @@ import com.android.systemui.volume.VolumeComponent;
import com.android.systemui.wmshell.BubblesManager;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
+import com.android.wm.shell.startingsurface.SplashscreenContentDrawer;
+import com.android.wm.shell.startingsurface.StartingSurface;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -268,7 +271,7 @@ public class StatusBar extends SystemUI implements DemoMode,
ColorExtractor.OnColorsChangedListener, ConfigurationListener,
StatusBarStateController.StateListener,
LifecycleOwner, BatteryController.BatteryStateChangeCallback,
- ActivityLaunchAnimator.KeyguardHandler {
+ ActivityLaunchAnimator.Callback {
public static final boolean MULTIUSER_DEBUG = false;
protected static final int MSG_HIDE_RECENT_APPS = 1020;
@@ -685,9 +688,7 @@ public class StatusBar extends SystemUI implements DemoMode,
new FalsingManager.FalsingBeliefListener() {
@Override
public void onFalse() {
- // Hides quick settings.
- mNotificationPanelViewController.resetViews(true);
- // Hides bouncer and quick-quick settings.
+ // Hides quick settings, bouncer, and quick-quick settings.
mStatusBarKeyguardViewManager.reset(true);
}
};
@@ -705,6 +706,7 @@ public class StatusBar extends SystemUI implements DemoMode,
private final Optional<BubblesManager> mBubblesManagerOptional;
private final Optional<Bubbles> mBubblesOptional;
private final Bubbles.BubbleExpandListener mBubbleExpandListener;
+ private final Optional<StartingSurface> mStartingSurfaceOptional;
private ActivityIntentHelper mActivityIntentHelper;
private NotificationStackScrollLayoutController mStackScrollerController;
@@ -804,7 +806,8 @@ public class StatusBar extends SystemUI implements DemoMode,
LockscreenShadeTransitionController lockscreenShadeTransitionController,
FeatureFlags featureFlags,
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
- UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
+ Optional<StartingSurface> startingSurfaceOptional) {
super(context);
mNotificationsController = notificationsController;
mLightBarController = lightBarController;
@@ -891,6 +894,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
+ mStartingSurfaceOptional = startingSurfaceOptional;
lockscreenShadeTransitionController.setStatusbar(this);
mExpansionChangedListeners = new ArrayList<>();
@@ -2119,6 +2123,16 @@ public class StatusBar extends SystemUI implements DemoMode,
mKeyguardViewMediator.setBlursDisabledForAppLaunch(disabled);
}
+ @Override
+ public int getBackgroundColor(TaskInfo task) {
+ if (!mStartingSurfaceOptional.isPresent()) {
+ Log.w(TAG, "No starting surface, defaulting to SystemBGColor");
+ return SplashscreenContentDrawer.getSystemBGColor();
+ }
+
+ return mStartingSurfaceOptional.get().getBackgroundColor(task);
+ }
+
public boolean isDeviceInVrMode() {
return mPresenter.isDeviceInVrMode();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 6f63b1780d68..8a7708aaa8c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -521,7 +521,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
@Override
public void reset(boolean hideBouncerWhenShowing) {
if (mShowing) {
- mNotificationPanelViewController.closeQs();
+ // Hide quick settings.
+ mNotificationPanelViewController.resetViews(/* animate= */ true);
+ // Hide bouncer and quick-quick settings.
if (mOccluded && !mDozing) {
mStatusBar.hideKeyguard();
if (hideBouncerWhenShowing || mBouncer.needsFullscreenBouncer()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index 98b9cc9bc716..9a6dd38ffca5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -514,7 +514,8 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
InteractionJankMonitor.CUJ_SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON
);
ActivityLaunchAnimator.Controller animationController =
- new StatusBarLaunchAnimatorController(viewController, mStatusBar,
+ viewController == null ? null
+ : new StatusBarLaunchAnimatorController(viewController, mStatusBar,
true /* isActivityIntent */);
mActivityLaunchAnimator.startIntentWithAnimation(animationController, animate,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index 2611ab5f7016..716d1dbc6462 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -109,6 +109,7 @@ import com.android.systemui.volume.VolumeComponent;
import com.android.systemui.wmshell.BubblesManager;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
+import com.android.wm.shell.startingsurface.StartingSurface;
import java.util.Optional;
import java.util.concurrent.Executor;
@@ -218,7 +219,8 @@ public interface StatusBarPhoneModule {
LockscreenShadeTransitionController transitionController,
FeatureFlags featureFlags,
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
- UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
+ Optional<StartingSurface> startingSurfaceOptional) {
return new StatusBar(
context,
notificationsController,
@@ -306,6 +308,7 @@ public interface StatusBarPhoneModule {
transitionController,
featureFlags,
keyguardUnlockAnimationController,
- unlockedScreenOffAnimationController);
+ unlockedScreenOffAnimationController,
+ startingSurfaceOptional);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index 081fe5a47626..a8097c4d74b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -41,6 +41,7 @@ import com.android.systemui.statusbar.notification.row.NotificationRowContentBin
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.ArrayList;
import java.util.HashSet;
/**
@@ -157,7 +158,7 @@ public abstract class HeadsUpManager extends AlertingNotificationManager {
NotificationPeekEvent.NOTIFICATION_PEEK, entry.getSbn().getUid(),
entry.getSbn().getPackageName(), entry.getSbn().getInstanceId());
}
- for (OnHeadsUpChangedListener listener : mListeners) {
+ for (OnHeadsUpChangedListener listener : new ArrayList<>(mListeners)) {
if (isPinned) {
listener.onHeadsUpPinned(entry);
} else {
@@ -177,7 +178,7 @@ public abstract class HeadsUpManager extends AlertingNotificationManager {
entry.setHeadsUp(true);
setEntryPinned((HeadsUpEntry) alertEntry, shouldHeadsUpBecomePinned(entry));
EventLogTags.writeSysuiHeadsUpStatus(entry.getKey(), 1 /* visible */);
- for (OnHeadsUpChangedListener listener : mListeners) {
+ for (OnHeadsUpChangedListener listener : new ArrayList<>(mListeners)) {
listener.onHeadsUpStateChanged(entry, true);
}
}
@@ -188,7 +189,7 @@ public abstract class HeadsUpManager extends AlertingNotificationManager {
entry.setHeadsUp(false);
setEntryPinned((HeadsUpEntry) alertEntry, false /* isPinned */);
EventLogTags.writeSysuiHeadsUpStatus(entry.getKey(), 0 /* visible */);
- for (OnHeadsUpChangedListener listener : mListeners) {
+ for (OnHeadsUpChangedListener listener : new ArrayList<>(mListeners)) {
listener.onHeadsUpStateChanged(entry, false);
}
}
@@ -206,7 +207,7 @@ public abstract class HeadsUpManager extends AlertingNotificationManager {
if (mHasPinnedNotification) {
MetricsLogger.count(mContext, "note_peek", 1);
}
- for (OnHeadsUpChangedListener listener : mListeners) {
+ for (OnHeadsUpChangedListener listener : new ArrayList<>(mListeners)) {
listener.onHeadsUpPinnedModeChanged(hasPinnedNotification);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyController.java
index acfdda4cea49..e01b95e81da8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyController.java
@@ -29,7 +29,7 @@ public interface IndividualSensorPrivacyController extends
void setSensorBlocked(@Source int source, @Sensor int sensor, boolean blocked);
- void suppressSensorPrivacyReminders(String packageName, boolean suppress);
+ void suppressSensorPrivacyReminders(int sensor, boolean suppress);
interface Callback {
void onSensorBlockedChanged(@Sensor int sensor, boolean blocked);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyControllerImpl.java
index 9807165f69d0..1d71301c7454 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyControllerImpl.java
@@ -68,8 +68,8 @@ public class IndividualSensorPrivacyControllerImpl implements IndividualSensorPr
}
@Override
- public void suppressSensorPrivacyReminders(String packageName, boolean suppress) {
- mSensorPrivacyManager.suppressSensorPrivacyReminders(packageName, suppress);
+ public void suppressSensorPrivacyReminders(int sensor, boolean suppress) {
+ mSensorPrivacyManager.suppressSensorPrivacyReminders(sensor, suppress);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index b18dfd2866c4..84d7c05ddc14 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -272,6 +272,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
public void onEnd(@NonNull WindowInsetsAnimation animation) {
super.onEnd(animation);
if (animation.getTypeMask() == WindowInsets.Type.ime()) {
+ mEntry.mRemoteEditImeAnimatingAway = false;
mEntry.mRemoteEditImeVisible =
mEditText.getRootWindowInsets().isVisible(WindowInsets.Type.ime());
if (!mEntry.mRemoteEditImeVisible && !mEditText.mShowImeOnInputConnection) {
@@ -392,6 +393,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
mSendButton.setVisibility(INVISIBLE);
mProgressBar.setVisibility(VISIBLE);
mEntry.lastRemoteInputSent = SystemClock.elapsedRealtime();
+ mEntry.mRemoteEditImeAnimatingAway = true;
mController.addSpinning(mEntry.getKey(), mToken);
mController.removeRemoteInput(mEntry, mToken);
mEditText.mShowImeOnInputConnection = false;
@@ -807,7 +809,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
}
private void onEditTextFocusChanged(RemoteEditText remoteEditText, boolean focused) {
- for (View.OnFocusChangeListener listener : mEditTextFocusChangeListeners) {
+ for (View.OnFocusChangeListener listener : new ArrayList<>(mEditTextFocusChangeListeners)) {
listener.onFocusChange(remoteEditText, focused);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java b/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java
index 361604c461b4..a40cf4f37cc3 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java
@@ -101,7 +101,12 @@ abstract public class SafetyWarningDialog extends SystemUIDialog
@Override
public void onDismiss(DialogInterface unused) {
- mContext.unregisterReceiver(mReceiver);
+ try {
+ mContext.unregisterReceiver(mReceiver);
+ } catch (IllegalArgumentException e) {
+ // Don't crash if the receiver has already been unregistered.
+ e.printStackTrace();
+ }
cleanUp();
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 5de7846a820e..3320852ca1f4 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -1743,7 +1743,7 @@ public class VolumeDialogImpl implements VolumeDialog,
mContext, android.R.attr.colorBackgroundFloating);
final ColorStateList inverseTextTint = Utils.getColorAttr(
- mContext, com.android.internal.R.attr.textColorPrimaryInverse);
+ mContext, com.android.internal.R.attr.textColorOnAccent);
row.sliderProgressSolid.setTintList(colorTint);
if (row.sliderBgIcon != null) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
index d01cdd45181f..14f112b8b071 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
@@ -10,10 +10,12 @@ import android.graphics.Rect
import android.os.Looper
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
+import android.util.Log
import android.view.IRemoteAnimationFinishedCallback
import android.view.RemoteAnimationAdapter
import android.view.RemoteAnimationTarget
import android.view.SurfaceControl
+import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.test.filters.SmallTest
@@ -25,6 +27,7 @@ import junit.framework.Assert.assertNotNull
import junit.framework.Assert.assertNull
import junit.framework.Assert.assertTrue
import junit.framework.AssertionFailedError
+import kotlin.concurrent.thread
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -37,23 +40,23 @@ import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.Spy
import org.mockito.junit.MockitoJUnit
-import kotlin.concurrent.thread
@SmallTest
@RunWith(AndroidTestingRunner::class)
@RunWithLooper
class ActivityLaunchAnimatorTest : SysuiTestCase() {
private val launchContainer = LinearLayout(mContext)
- @Mock lateinit var keyguardHandler: ActivityLaunchAnimator.KeyguardHandler
+ @Mock lateinit var callback: ActivityLaunchAnimator.Callback
@Spy private val controller = TestLaunchAnimatorController(launchContainer)
@Mock lateinit var iCallback: IRemoteAnimationFinishedCallback
+ @Mock lateinit var failHandler: Log.TerribleFailureHandler
private lateinit var activityLaunchAnimator: ActivityLaunchAnimator
@get:Rule val rule = MockitoJUnit.rule()
@Before
fun setup() {
- activityLaunchAnimator = ActivityLaunchAnimator(keyguardHandler, mContext)
+ activityLaunchAnimator = ActivityLaunchAnimator(callback, mContext)
}
private fun startIntentWithAnimation(
@@ -116,8 +119,8 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() {
@Test
fun animatesIfActivityIsAlreadyOpenAndIsOnKeyguard() {
- `when`(keyguardHandler.isOnKeyguard()).thenReturn(true)
- val animator = ActivityLaunchAnimator(keyguardHandler, context)
+ `when`(callback.isOnKeyguard()).thenReturn(true)
+ val animator = ActivityLaunchAnimator(callback, context)
val willAnimateCaptor = ArgumentCaptor.forClass(Boolean::class.java)
var animationAdapter: RemoteAnimationAdapter? = null
@@ -129,7 +132,7 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() {
waitForIdleSync()
verify(controller).onIntentStarted(willAnimateCaptor.capture())
- verify(keyguardHandler).hideKeyguardWithAnimation(any())
+ verify(callback).hideKeyguardWithAnimation(any())
assertTrue(willAnimateCaptor.value)
assertNull(animationAdapter)
@@ -171,10 +174,17 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() {
val runner = activityLaunchAnimator.createRunner(controller)
runner.onAnimationStart(0, arrayOf(fakeWindow()), emptyArray(), emptyArray(), iCallback)
waitForIdleSync()
- verify(keyguardHandler).setBlursDisabledForAppLaunch(eq(true))
+ verify(callback).setBlursDisabledForAppLaunch(eq(true))
verify(controller).onLaunchAnimationStart(anyBoolean())
}
+ @Test
+ fun controllerFromOrphanViewReturnsNullAndIsATerribleFailure() {
+ Log.setWtfHandler(failHandler)
+ assertNull(ActivityLaunchAnimator.Controller.fromView(View(mContext)))
+ verify(failHandler).onTerribleFailure(any(), any(), anyBoolean())
+ }
+
private fun fakeWindow(): RemoteAnimationTarget {
val bounds = Rect(10 /* left */, 20 /* top */, 30 /* right */, 40 /* bottom */)
val taskInfo = ActivityManager.RunningTaskInfo()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/GhostedViewLaunchAnimatorControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/GhostedViewLaunchAnimatorControllerTest.kt
new file mode 100644
index 000000000000..8cba25dc1b92
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/GhostedViewLaunchAnimatorControllerTest.kt
@@ -0,0 +1,42 @@
+/*
+ * 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.animation
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.widget.LinearLayout
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class GhostedViewLaunchAnimatorControllerTest : SysuiTestCase() {
+ @Test
+ fun animatingOrphanViewDoesNotCrash() {
+ val ghostedView = LinearLayout(mContext)
+ val controller = GhostedViewLaunchAnimatorController(ghostedView)
+ val state = ActivityLaunchAnimator.State(top = 0, bottom = 0, left = 0, right = 0)
+
+ controller.onIntentStarted(willAnimate = true)
+ controller.onLaunchAnimationStart(isExpandingFullyAbove = true)
+ controller.onLaunchAnimationProgress(state, progress = 0f, linearProgress = 0f)
+ controller.onLaunchAnimationEnd(isExpandingFullyAbove = true)
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
index 05bef4c2aeb7..24c189a85327 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
@@ -1125,7 +1125,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A));
when(mIPeopleManager.getConversation(TEST_PACKAGE_A, 0, SHORTCUT_ID)).thenReturn(channel);
PeopleTileKey key = new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A);
- PeopleSpaceTile tile = mManager.getTileFromPersistentStorage(key, WIDGET_ID_WITH_SHORTCUT);
+ PeopleSpaceTile tile = mManager
+ .getTileFromPersistentStorage(key, WIDGET_ID_WITH_SHORTCUT, true);
assertThat(tile.getId()).isEqualTo(key.getShortcutId());
}
@@ -1133,7 +1134,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
public void testGetPeopleTileFromPersistentStorageNoConversation() throws Exception {
when(mIPeopleManager.getConversation(TEST_PACKAGE_A, 0, SHORTCUT_ID)).thenReturn(null);
PeopleTileKey key = new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A);
- PeopleSpaceTile tile = mManager.getTileFromPersistentStorage(key, WIDGET_ID_WITH_SHORTCUT);
+ PeopleSpaceTile tile = mManager
+ .getTileFromPersistentStorage(key, WIDGET_ID_WITH_SHORTCUT, false);
assertThat(tile).isNull();
}
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 c2bd024f0375..84776c7eb18f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
@@ -148,8 +148,10 @@ public class QSDetailTest extends SysuiTestCase {
eq(true) /* in */, any());
clearInvocations(mQsDetail.mClipper);
+ // Detail adapters should always animate on close. shouldAnimate() should only affect the
+ // open transition
mQsDetail.handleShowingDetail(null, 0, 0, false);
- verify(mQsDetail.mClipper).updateCircularClip(eq(false) /* animate */, anyInt(), anyInt(),
+ verify(mQsDetail.mClipper).updateCircularClip(eq(true) /* animate */, anyInt(), anyInt(),
eq(false) /* in */, any());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index a6fc02d7dafc..f8fc22495d8d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -94,6 +94,7 @@ import com.android.systemui.media.MediaHierarchyManager;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.qs.QSDetailDisplayer;
+import com.android.systemui.screenrecord.RecordingController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.KeyguardAffordanceView;
@@ -295,6 +296,8 @@ public class NotificationPanelViewTest extends SysuiTestCase {
private NotificationRemoteInputManager mNotificationRemoteInputManager;
@Mock
private RemoteInputController mRemoteInputController;
+ @Mock
+ private RecordingController mRecordingController;
private SysuiStatusBarStateController mStatusBarStateController;
private NotificationPanelViewController mNotificationPanelViewController;
@@ -433,6 +436,7 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mFragmentService,
mContentResolver,
mQuickAccessWalletController,
+ mRecordingController,
new FakeExecutor(new FakeSystemClock()),
mSecureSettings,
mUnlockedScreenOffAnimationController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index cbc7c6dd0447..f126ed0c7555 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -152,6 +152,7 @@ import com.android.systemui.volume.VolumeComponent;
import com.android.systemui.wmshell.BubblesManager;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
+import com.android.wm.shell.startingsurface.StartingSurface;
import org.junit.Before;
import org.junit.Test;
@@ -273,6 +274,7 @@ public class StatusBarTest extends SysuiTestCase {
@Mock private IWallpaperManager mWallpaperManager;
@Mock private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
@Mock private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
+ @Mock private StartingSurface mStartingSurface;
private ShadeController mShadeController;
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
private InitController mInitController = new InitController();
@@ -443,7 +445,8 @@ public class StatusBarTest extends SysuiTestCase {
mLockscreenTransitionController,
mFeatureFlags,
mKeyguardUnlockAnimationController,
- mUnlockedScreenOffAnimationController);
+ mUnlockedScreenOffAnimationController,
+ Optional.of(mStartingSurface));
when(mKeyguardViewMediator.registerStatusBar(any(StatusBar.class), any(ViewGroup.class),
any(NotificationPanelViewController.class), any(BiometricUnlockController.class),
any(ViewGroup.class), any(KeyguardBypassController.class)))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index 3cea17567173..dd4830e893af 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -99,6 +99,8 @@ public class VolumeDialogImplTest extends SysuiTestCase {
Prefs.putInt(mContext,
Prefs.Key.SEEN_RINGER_GUIDANCE_COUNT,
VolumePrefs.SHOW_RINGER_TOAST_COUNT + 1);
+
+ Prefs.putBoolean(mContext, Prefs.Key.HAS_SEEN_ODI_CAPTIONS_TOOLTIP, false);
}
private State createShellState() {
diff --git a/proto/src/system_messages.proto b/proto/src/system_messages.proto
index a48f76ea1ca3..3047c9042848 100644
--- a/proto/src/system_messages.proto
+++ b/proto/src/system_messages.proto
@@ -268,6 +268,14 @@ message SystemMessage {
// Package: android
NOTE_NAS_UPGRADE = 64;
+ // Notify the user to unblock the microphone global toggle
+ // Package: android
+ NOTE_UNBLOCK_MIC_TOGGLE = 65;
+
+ // Notify the user to unblock the camera global toggle
+ // Package: android
+ NOTE_UNBLOCK_CAM_TOGGLE = 66;
+
// ADD_NEW_IDS_ABOVE_THIS_LINE
// Legacy IDs with arbitrary values appear below
// Legacy IDs existed as stable non-conflicting constants prior to the O release
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
index e1af2c48789f..d7bc04091181 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
@@ -258,7 +258,12 @@ public class TouchExplorer extends BaseEventStreamTransformation
super.onMotionEvent(event, rawEvent, policyFlags);
return;
}
-
+ try {
+ checkForMalformedEvent(event);
+ } catch (IllegalArgumentException e) {
+ Slog.e(LOG_TAG, "Ignoring malformed event: " + event.toString(), e);
+ return;
+ }
if (DEBUG) {
Slog.d(LOG_TAG, "Received event: " + event + ", policyFlags=0x"
+ Integer.toHexString(policyFlags));
@@ -1223,6 +1228,32 @@ public class TouchExplorer extends BaseEventStreamTransformation
}
/**
+ * Checks to see whether an event is consistent with itself.
+ *
+ * @throws IllegalArgumentException in the case of a malformed event.
+ */
+ private static void checkForMalformedEvent(MotionEvent event) {
+ if (event.getPointerCount() < 0) {
+ throw new IllegalArgumentException("Invalid pointer count: " + event.getPointerCount());
+ }
+ for (int i = 0; i < event.getPointerCount(); ++i) {
+ try {
+ int pointerId = event.getPointerId(i);
+ float x = event.getX(i);
+ float y = event.getY(i);
+ if (Float.isNaN(x) || Float.isNaN(y) || x < 0.0f || y < 0.0f) {
+ throw new IllegalArgumentException(
+ "Invalid coordinates: (" + x + ", " + y + ")");
+ }
+ } catch (Exception e) {
+ throw new IllegalArgumentException(
+ "Encountered exception getting details of pointer " + i + " / "
+ + event.getPointerCount(), e);
+ }
+ }
+ }
+
+ /**
* Class for delayed sending of hover enter and move events.
*/
class SendHoverEnterAndMoveDelayed implements Runnable {
diff --git a/services/core/java/com/android/server/SensorPrivacyService.java b/services/core/java/com/android/server/SensorPrivacyService.java
index 53ff8ff768de..ac43fbd4f976 100644
--- a/services/core/java/com/android/server/SensorPrivacyService.java
+++ b/services/core/java/com/android/server/SensorPrivacyService.java
@@ -122,6 +122,7 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FunctionalUtils;
@@ -260,7 +261,7 @@ public final class SensorPrivacyService extends SystemService {
* <Package, User> -> list of suppressor tokens
*/
@GuardedBy("mLock")
- private ArrayMap<Pair<String, UserHandle>, ArrayList<IBinder>> mSuppressReminders =
+ private ArrayMap<Pair<Integer, UserHandle>, ArrayList<IBinder>> mSuppressReminders =
new ArrayMap<>();
private final ArrayMap<SensorUseReminderDialogInfo, ArraySet<Integer>>
@@ -423,7 +424,7 @@ public final class SensorPrivacyService extends SystemService {
}
synchronized (mLock) {
- if (mSuppressReminders.containsKey(new Pair<>(packageName, user))) {
+ if (mSuppressReminders.containsKey(new Pair<>(sensor, user))) {
Log.d(TAG,
"Suppressed sensor privacy reminder for " + packageName + "/" + user);
return;
@@ -450,14 +451,22 @@ public final class SensorPrivacyService extends SystemService {
for (int taskNum = 0; taskNum < numTasks; taskNum++) {
RunningTaskInfo task = tasks.get(taskNum);
- if (task.isVisible && task.topActivity.getPackageName().equals(packageName)) {
- if (task.isFocused) {
- // There is the one focused activity
- enqueueSensorUseReminderDialogAsync(task.taskId, user, packageName, sensor);
- return;
- }
+ if (task.isVisible) {
+ if (task.topActivity.getPackageName().equals(packageName)) {
+ if (task.isFocused) {
+ // There is the one focused activity
+ enqueueSensorUseReminderDialogAsync(task.taskId, user, packageName,
+ sensor);
+ return;
+ }
- tasksOfPackageUsingSensor.add(task);
+ tasksOfPackageUsingSensor.add(task);
+ } else if (task.topActivity.flattenToString().equals(mContext.getResources()
+ .getString(R.string.config_sensorUseStartedActivity))
+ && task.isFocused) {
+ enqueueSensorUseReminderDialogAsync(task.taskId, user, packageName,
+ sensor);
+ }
}
}
@@ -550,8 +559,15 @@ public final class SensorPrivacyService extends SystemService {
SensorUseReminderDialogInfo info =
new SensorUseReminderDialogInfo(taskId, user, packageName);
if (!mQueuedSensorUseReminderDialogs.containsKey(info)) {
- ArraySet<Integer> sensors = new ArraySet<Integer>();
- sensors.add(sensor);
+ ArraySet<Integer> sensors = new ArraySet<>();
+ if (sensor == MICROPHONE && mSuppressReminders.containsKey(new Pair<>(CAMERA, user))
+ || sensor == CAMERA && mSuppressReminders
+ .containsKey(new Pair<>(MICROPHONE, user))) {
+ sensors.add(MICROPHONE);
+ sensors.add(CAMERA);
+ } else {
+ sensors.add(sensor);
+ }
mQueuedSensorUseReminderDialogs.put(info, sensors);
mHandler.sendMessageDelayed(
PooledLambda.obtainMessage(this::showSensorUserReminderDialog, info),
@@ -608,6 +624,7 @@ public final class SensorPrivacyService extends SystemService {
@NonNull String packageName, int sensor) {
int iconRes;
int messageRes;
+ int notificationId;
CharSequence packageLabel;
try {
@@ -622,9 +639,11 @@ public final class SensorPrivacyService extends SystemService {
if (sensor == MICROPHONE) {
iconRes = R.drawable.ic_mic_blocked;
messageRes = R.string.sensor_privacy_start_use_mic_notification_content_title;
+ notificationId = SystemMessage.NOTE_UNBLOCK_MIC_TOGGLE;
} else {
iconRes = R.drawable.ic_camera_blocked;
messageRes = R.string.sensor_privacy_start_use_camera_notification_content_title;
+ notificationId = SystemMessage.NOTE_UNBLOCK_CAM_TOGGLE;
}
NotificationManager notificationManager =
@@ -641,7 +660,7 @@ public final class SensorPrivacyService extends SystemService {
notificationManager.createNotificationChannel(channel);
Icon icon = Icon.createWithResource(getUiContext().getResources(), iconRes);
- notificationManager.notify(sensor,
+ notificationManager.notify(notificationId,
new Notification.Builder(mContext, SENSOR_PRIVACY_CHANNEL_ID)
.setContentTitle(getUiContext().getString(messageRes))
.setContentText(Html.fromHtml(getUiContext().getString(
@@ -1161,13 +1180,12 @@ public final class SensorPrivacyService extends SystemService {
}
@Override
- public void suppressIndividualSensorPrivacyReminders(int userId, String packageName,
+ public void suppressIndividualSensorPrivacyReminders(int userId, int sensor,
IBinder token, boolean suppress) {
enforceManageSensorPrivacyPermission();
- Objects.requireNonNull(packageName);
Objects.requireNonNull(token);
- Pair<String, UserHandle> key = new Pair<>(packageName, UserHandle.of(userId));
+ Pair<Integer, UserHandle> key = new Pair<>(sensor, UserHandle.of(userId));
synchronized (mLock) {
if (suppress) {
@@ -1197,7 +1215,7 @@ public final class SensorPrivacyService extends SystemService {
* @param key Key the token is in
* @param token The token to remove
*/
- private void removeSuppressPackageReminderToken(@NonNull Pair<String, UserHandle> key,
+ private void removeSuppressPackageReminderToken(@NonNull Pair<Integer, UserHandle> key,
@NonNull IBinder token) {
synchronized (mLock) {
ArrayList<IBinder> suppressPackageReminderTokens =
@@ -1229,7 +1247,7 @@ public final class SensorPrivacyService extends SystemService {
@Override
public void binderDied(@NonNull IBinder token) {
synchronized (mLock) {
- for (Pair<String, UserHandle> key : mSuppressReminders.keySet()) {
+ for (Pair<Integer, UserHandle> key : mSuppressReminders.keySet()) {
removeSuppressPackageReminderToken(key, token);
}
}
@@ -1557,7 +1575,7 @@ public final class SensorPrivacyService extends SystemService {
listeners.finishBroadcast();
}
- public void removeSuppressPackageReminderToken(Pair<String, UserHandle> key,
+ public void removeSuppressPackageReminderToken(Pair<Integer, UserHandle> key,
IBinder token) {
sendMessage(PooledLambda.obtainMessage(
SensorPrivacyServiceImpl::removeSuppressPackageReminderToken,
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 4ec5559a061d..2057a7e4264a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5003,7 +5003,7 @@ public class ActivityManagerService extends IActivityManager.Stub
(res.key.flags & PendingIntent.FLAG_IMMUTABLE) != 0,
res.key.type);
} else {
- throw new IllegalArgumentException();
+ return new PendingIntentInfo(null, -1, false, ActivityManager.INTENT_SENDER_UNKNOWN);
}
}
@@ -12425,6 +12425,15 @@ public class ActivityManagerService extends IActivityManager.Stub
return sticky;
}
+ // SafetyNet logging for b/177931370. If any process other than system_server tries to
+ // listen to this broadcast action, then log it.
+ if (callingPid != Process.myPid()) {
+ if (filter.hasAction("com.android.server.net.action.SNOOZE_WARNING")
+ || filter.hasAction("com.android.server.net.action.SNOOZE_RAPID")) {
+ EventLog.writeEvent(0x534e4554, "177931370", callingUid, "");
+ }
+ }
+
synchronized (this) {
IApplicationThread thread;
if (callerApp != null && ((thread = callerApp.getThread()) == null
diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
index 67dfb8051f93..0c633cacda92 100644
--- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
+++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
@@ -579,8 +579,10 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
}
}
- // Collect the latest low power stats without holding the mStats lock.
- mStats.fillLowPowerStats();
+ if ((updateFlags & BatteryStatsImpl.ExternalStatsSync.UPDATE_RPM) != 0) {
+ // Collect the latest low power stats without holding the mStats lock.
+ mStats.fillLowPowerStats();
+ }
final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver);
final BluetoothActivityEnergyInfo bluetoothInfo = awaitControllerInfo(bluetoothReceiver);
diff --git a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
index ca357b4c2cec..f11fe8aee64f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
@@ -188,18 +188,7 @@ public abstract class AcquisitionClient<T> extends HalClientMonitor<T> implement
mPowerManager.userActivity(now, PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
}
- protected boolean successHapticsEnabled() {
- return true;
- }
-
- protected boolean errorHapticsEnabled() {
- return true;
- }
-
protected final void vibrateSuccess() {
- if (!successHapticsEnabled()) {
- return;
- }
Vibrator vibrator = getContext().getSystemService(Vibrator.class);
if (vibrator != null) {
vibrator.vibrate(SUCCESS_VIBRATION_EFFECT, VIBRATION_SONIFICATION_ATTRIBUTES);
@@ -207,9 +196,6 @@ public abstract class AcquisitionClient<T> extends HalClientMonitor<T> implement
}
protected final void vibrateError() {
- if (!errorHapticsEnabled()) {
- return;
- }
Vibrator vibrator = getContext().getSystemService(Vibrator.class);
if (vibrator != null) {
vibrator.vibrate(ERROR_VIBRATION_EFFECT, VIBRATION_SONIFICATION_ATTRIBUTES);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
index db927b227d9a..3757404d226d 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
@@ -19,7 +19,6 @@ package com.android.server.biometrics.sensors.face.aidl;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.NotificationManager;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.hardware.biometrics.BiometricAuthenticator;
@@ -33,7 +32,6 @@ import android.hardware.face.FaceAuthenticationFrame;
import android.hardware.face.FaceManager;
import android.os.IBinder;
import android.os.RemoteException;
-import android.provider.Settings;
import android.util.Slog;
import com.android.internal.R;
@@ -59,9 +57,6 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
@Nullable private final NotificationManager mNotificationManager;
@Nullable private ICancellationSignal mCancellationSignal;
- @NonNull private final ContentResolver mContentResolver;
- private final boolean mCustomHaptics;
-
private final int[] mBiometricPromptIgnoreList;
private final int[] mBiometricPromptIgnoreListVendor;
private final int[] mKeyguardIgnoreList;
@@ -92,10 +87,6 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
R.array.config_face_acquire_keyguard_ignorelist);
mKeyguardIgnoreListVendor = resources.getIntArray(
R.array.config_face_acquire_vendor_keyguard_ignorelist);
-
- mContentResolver = context.getContentResolver();
- mCustomHaptics = Settings.Global.getInt(mContentResolver,
- "face_custom_success_error", 0) == 1;
}
@NonNull
@@ -261,18 +252,4 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
Slog.e(TAG, "Remote exception", e);
}
}
-
- @Override
- protected boolean successHapticsEnabled() {
- return mCustomHaptics
- ? Settings.Global.getInt(mContentResolver, "face_success_enabled", 1) == 0
- : super.successHapticsEnabled();
- }
-
- @Override
- protected boolean errorHapticsEnabled() {
- return mCustomHaptics
- ? Settings.Global.getInt(mContentResolver, "face_error_enabled", 1) == 0
- : super.errorHapticsEnabled();
- }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
index 6c0adafcf2ee..c3de7aa74d15 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
@@ -17,7 +17,6 @@
package com.android.server.biometrics.sensors.face.hidl;
import android.annotation.NonNull;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.hardware.biometrics.BiometricAuthenticator;
@@ -28,7 +27,6 @@ import android.hardware.biometrics.face.V1_0.IBiometricsFace;
import android.hardware.face.FaceManager;
import android.os.IBinder;
import android.os.RemoteException;
-import android.provider.Settings;
import android.util.Slog;
import com.android.internal.R;
@@ -49,8 +47,6 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
private static final String TAG = "FaceAuthenticationClient";
- @NonNull private final ContentResolver mContentResolver;
- private final boolean mCustomHaptics;
private final UsageStats mUsageStats;
private final int[] mBiometricPromptIgnoreList;
@@ -81,10 +77,6 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
R.array.config_face_acquire_keyguard_ignorelist);
mKeyguardIgnoreListVendor = resources.getIntArray(
R.array.config_face_acquire_vendor_keyguard_ignorelist);
-
- mContentResolver = context.getContentResolver();
- mCustomHaptics = Settings.Global.getInt(mContentResolver,
- "face_custom_success_error", 0) == 1;
}
@NonNull
@@ -200,18 +192,4 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
final boolean shouldSend = shouldSend(acquireInfo, vendorCode);
onAcquiredInternal(acquireInfo, vendorCode, shouldSend);
}
-
- @Override
- protected boolean successHapticsEnabled() {
- return mCustomHaptics
- ? Settings.Global.getInt(mContentResolver, "face_success_enabled", 1) == 0
- : super.successHapticsEnabled();
- }
-
- @Override
- protected boolean errorHapticsEnabled() {
- return mCustomHaptics
- ? Settings.Global.getInt(mContentResolver, "face_error_enabled", 1) == 0
- : super.errorHapticsEnabled();
- }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
index 6a05ed470123..19134e46f08f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
@@ -19,7 +19,6 @@ package com.android.server.biometrics.sensors.fingerprint.aidl;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.TaskStackListener;
-import android.content.ContentResolver;
import android.content.Context;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricFingerprintConstants;
@@ -30,7 +29,6 @@ import android.hardware.biometrics.fingerprint.ISession;
import android.hardware.fingerprint.IUdfpsOverlayController;
import android.os.IBinder;
import android.os.RemoteException;
-import android.provider.Settings;
import android.util.Slog;
import com.android.server.biometrics.Utils;
@@ -57,9 +55,6 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
@Nullable private ICancellationSignal mCancellationSignal;
- @NonNull private final ContentResolver mContentResolver;
- private final boolean mCustomHaptics;
-
FingerprintAuthenticationClient(@NonNull Context context,
@NonNull LazyDaemon<ISession> lazyDaemon, @NonNull IBinder token,
@NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId,
@@ -74,10 +69,6 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
lockoutCache, allowBackgroundAuthentication);
mLockoutCache = lockoutCache;
mUdfpsOverlayController = udfpsOverlayController;
-
- mContentResolver = context.getContentResolver();
- mCustomHaptics = Settings.Global.getInt(mContentResolver,
- "fp_custom_success_error", 0) == 1;
}
@NonNull
@@ -213,18 +204,4 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
mCallback.onClientFinished(this, false /* success */);
}
-
- @Override
- protected boolean successHapticsEnabled() {
- return mCustomHaptics
- ? Settings.Global.getInt(mContentResolver, "fp_success_enabled", 1) == 0
- : super.successHapticsEnabled();
- }
-
- @Override
- protected boolean errorHapticsEnabled() {
- return mCustomHaptics
- ? Settings.Global.getInt(mContentResolver, "fp_error_enabled", 1) == 0
- : super.errorHapticsEnabled();
- }
}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index b144ff27c993..16a0b7e39a07 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -372,7 +372,7 @@ public class ZenModeHelper {
}
}
if (rule.enabled != automaticZenRule.isEnabled()) {
- dispatchOnAutomaticRuleStatusChanged(mConfig.user, rule.pkg, ruleId,
+ dispatchOnAutomaticRuleStatusChanged(mConfig.user, rule.getPkg(), ruleId,
automaticZenRule.isEnabled()
? AUTOMATIC_RULE_STATUS_ENABLED : AUTOMATIC_RULE_STATUS_DISABLED);
}
@@ -391,13 +391,14 @@ public class ZenModeHelper {
if (ruleToRemove == null) return false;
if (canManageAutomaticZenRule(ruleToRemove)) {
newConfig.automaticRules.remove(id);
- if (ruleToRemove.pkg != null && !"android".equals(ruleToRemove.pkg)) {
+ if (ruleToRemove.getPkg() != null && !"android".equals(ruleToRemove.getPkg())) {
for (ZenRule currRule : newConfig.automaticRules.values()) {
- if (currRule.pkg != null && currRule.pkg.equals(ruleToRemove.pkg)) {
+ if (currRule.getPkg() != null
+ && currRule.getPkg().equals(ruleToRemove.getPkg())) {
break; // no need to remove from cache
}
}
- mRulesUidCache.remove(getPackageUserKey(ruleToRemove.pkg, newConfig.user));
+ mRulesUidCache.remove(getPackageUserKey(ruleToRemove.getPkg(), newConfig.user));
}
if (DEBUG) Log.d(TAG, "removeZenRule zenRule=" + id + " reason=" + reason);
} else {
@@ -405,7 +406,7 @@ public class ZenModeHelper {
"Cannot delete rules not owned by your condition provider");
}
dispatchOnAutomaticRuleStatusChanged(
- mConfig.user, ruleToRemove.pkg, id, AUTOMATIC_RULE_STATUS_REMOVED);
+ mConfig.user, ruleToRemove.getPkg(), id, AUTOMATIC_RULE_STATUS_REMOVED);
return setConfigLocked(newConfig, reason, null, true);
}
}
@@ -417,14 +418,7 @@ public class ZenModeHelper {
newConfig = mConfig.copy();
for (int i = newConfig.automaticRules.size() - 1; i >= 0; i--) {
ZenRule rule = newConfig.automaticRules.get(newConfig.automaticRules.keyAt(i));
- String pkg = rule.pkg != null
- ? rule.pkg
- : (rule.component != null)
- ? rule.component.getPackageName()
- : (rule.configurationActivity != null)
- ? rule.configurationActivity.getPackageName()
- : null;
- if (Objects.equals(pkg, packageName) && canManageAutomaticZenRule(rule)) {
+ if (Objects.equals(rule.getPkg(), packageName) && canManageAutomaticZenRule(rule)) {
newConfig.automaticRules.removeAt(i);
}
}
@@ -524,7 +518,7 @@ public class ZenModeHelper {
if (packages != null) {
final int packageCount = packages.length;
for (int i = 0; i < packageCount; i++) {
- if (packages[i].equals(rule.pkg)) {
+ if (packages[i].equals(rule.getPkg())) {
return true;
}
}
@@ -834,8 +828,8 @@ public class ZenModeHelper {
ZenRule rule = newConfig.automaticRules.get(newConfig.automaticRules.keyAt(i));
if (RULE_INSTANCE_GRACE_PERIOD < (currentTime - rule.creationTime)) {
try {
- if (rule.pkg != null) {
- mPm.getPackageInfo(rule.pkg, PackageManager.MATCH_ANY_USER);
+ if (rule.getPkg() != null) {
+ mPm.getPackageInfo(rule.getPkg(), PackageManager.MATCH_ANY_USER);
}
} catch (PackageManager.NameNotFoundException e) {
newConfig.automaticRules.removeAt(i);
@@ -1246,7 +1240,7 @@ public class ZenModeHelper {
}
// Look for packages and enablers, enablers get priority.
- String pkg = rule.pkg == null ? "" : rule.pkg;
+ String pkg = rule.getPkg() == null ? "" : rule.getPkg();
if (rule.enabler != null) {
pkg = rule.enabler;
id = ZenModeConfig.MANUAL_RULE_ID;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index af3cb5bbe0cb..ee44c10edbf3 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -112,8 +112,6 @@ import static com.android.internal.annotations.VisibleForTesting.Visibility;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
-import static com.android.internal.util.ArrayUtils.emptyIfNull;
-import static com.android.internal.util.ArrayUtils.filter;
import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_DATA_APP_AVG_SCAN_TIME;
import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_INIT_TIME;
import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_SYSTEM_APP_AVG_SCAN_TIME;
@@ -7957,12 +7955,9 @@ public class PackageManagerService extends IPackageManager.Stub
} catch (PackageManagerException e) {
Slog.w(TAG, "updateAllSharedLibrariesLPw failed: ", e);
}
- final int[] userIds = mUserManager.getUserIds();
- for (final int userId : userIds) {
- mPermissionManager.onPackageInstalled(pkg,
- PermissionManagerServiceInternal.PackageInstalledParams.DEFAULT,
- userId);
- }
+ mPermissionManager.onPackageInstalled(pkg,
+ PermissionManagerServiceInternal.PackageInstalledParams.DEFAULT,
+ UserHandle.USER_ALL);
writeSettingsLPrTEMP();
}
} catch (PackageManagerException e) {
@@ -19215,12 +19210,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
final int autoRevokePermissionsMode = installArgs.autoRevokePermissionsMode;
permissionParamsBuilder.setAutoRevokePermissionsMode(autoRevokePermissionsMode);
- for (int currentUserId : allUsersList) {
- if (ps.getInstalled(currentUserId)) {
- mPermissionManager.onPackageInstalled(pkg, permissionParamsBuilder.build(),
- currentUserId);
- }
- }
+ mPermissionManager.onPackageInstalled(pkg, permissionParamsBuilder.build(), userId);
}
res.name = pkgName;
res.uid = pkg.getUid();
@@ -21864,10 +21854,8 @@ public class PackageManagerService extends IPackageManager.Stub
if (sharedUserPkgs == null) {
sharedUserPkgs = Collections.emptyList();
}
- for (final int userId : allUserHandles) {
- mPermissionManager.onPackageUninstalled(packageName, deletedPs.appId,
- deletedPs.pkg, sharedUserPkgs, userId);
- }
+ mPermissionManager.onPackageUninstalled(packageName, deletedPs.appId,
+ deletedPs.pkg, sharedUserPkgs, UserHandle.USER_ALL);
}
clearPackagePreferredActivitiesLPw(
deletedPs.name, changedUsers, UserHandle.USER_ALL);
@@ -22084,11 +22072,12 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
+ // The method below will take care of removing obsolete permissions and granting
+ // install permissions.
+ mPermissionManager.onPackageInstalled(pkg,
+ PermissionManagerServiceInternal.PackageInstalledParams.DEFAULT,
+ UserHandle.USER_ALL);
for (final int userId : allUserHandles) {
- // The method below will take care of removing obsolete permissions and granting
- // install permissions.
- mPermissionManager.onPackageInstalled(pkg,
- PermissionManagerServiceInternal.PackageInstalledParams.DEFAULT, userId);
if (applyUserRestrictions) {
mSettings.writePermissionStateForUserLPr(userId, false);
}
@@ -22411,10 +22400,9 @@ public class PackageManagerService extends IPackageManager.Stub
}
removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), nextUserId, ps.appId);
clearPackagePreferredActivities(ps.name, nextUserId);
- mPermissionManager.onPackageUninstalled(ps.name, ps.appId, pkg, sharedUserPkgs,
- nextUserId);
mDomainVerificationManager.clearPackageForUser(ps.name, nextUserId);
}
+ mPermissionManager.onPackageUninstalled(ps.name, ps.appId, pkg, sharedUserPkgs, userId);
if (outInfo != null) {
if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
@@ -23636,18 +23624,6 @@ public class PackageManagerService extends IPackageManager.Stub
getPackageFromComponentString(R.string.config_defaultAppPredictionService));
}
- private @NonNull String[] dropNonSystemPackages(@NonNull String[] pkgNames) {
- return emptyIfNull(filter(pkgNames, String[]::new, mIsSystemPackage), String.class);
- }
-
- private Predicate<String> mIsSystemPackage = (pkgName) -> {
- if ("android".equals(pkgName)) {
- return true;
- }
- AndroidPackage pkg = mPackages.get(pkgName);
- return pkg != null && pkg.isSystem();
- };
-
@Override
public String getSystemCaptionsServicePackageName() {
return ensureSystemPackageName(
@@ -27271,7 +27247,7 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public @NonNull String[] getKnownPackageNames(int knownPackage, int userId) {
- return dropNonSystemPackages(getKnownPackageNamesInternal(knownPackage, userId));
+ return getKnownPackageNamesInternal(knownPackage, userId);
}
private String[] getKnownPackageNamesInternal(int knownPackage, int userId) {
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 81ea46514d3d..376326264d9c 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -31,6 +31,7 @@ import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.permission.LegacyPermissionDataProvider;
import com.android.server.pm.permission.LegacyPermissionState;
import com.android.server.pm.pkg.PackageStateUnserialized;
+import com.android.server.utils.SnapshotCache;
import java.io.File;
import java.util.ArrayList;
@@ -81,6 +82,7 @@ public class PackageSetting extends PackageSettingBase {
* object equality to check whether shared user settings are the same.
*/
SharedUserSetting sharedUser;
+
/**
* Temporary holding space for the shared user ID. While parsing package settings, the
* shared users tag may come after the packages. In this case, we must delay linking the
@@ -103,6 +105,19 @@ public class PackageSetting extends PackageSettingBase {
@NonNull
private UUID mDomainSetId;
+ /**
+ * Snapshot support.
+ */
+ private final SnapshotCache<PackageSetting> mSnapshot;
+
+ private SnapshotCache<PackageSetting> makeCache() {
+ return new SnapshotCache<PackageSetting>(this, this) {
+ @Override
+ public PackageSetting createSnapshot() {
+ return new PackageSetting(mSource, true);
+ }};
+ }
+
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public PackageSetting(String name, String realName, @NonNull File codePath,
String legacyNativeLibraryPathString, String primaryCpuAbiString,
@@ -118,6 +133,7 @@ public class PackageSetting extends PackageSettingBase {
this.sharedUserId = sharedUserId;
mDomainSetId = domainSetId;
copyMimeGroups(mimeGroups);
+ mSnapshot = makeCache();
}
/**
@@ -127,6 +143,7 @@ public class PackageSetting extends PackageSettingBase {
PackageSetting(PackageSetting orig) {
super(orig, orig.realName);
doCopy(orig);
+ mSnapshot = makeCache();
}
/**
@@ -137,6 +154,33 @@ public class PackageSetting extends PackageSettingBase {
PackageSetting(PackageSetting orig, String realPkgName) {
super(orig, realPkgName);
doCopy(orig);
+ mSnapshot = makeCache();
+ }
+
+ /**
+ * Create a snapshot. The copy constructor is already in use and cannot be modified
+ * for this purpose.
+ */
+ PackageSetting(PackageSetting orig, boolean snapshot) {
+ super(orig, snapshot);
+ // The existing doCopy() method cannot be used in here because sharedUser must be
+ // a snapshot, and not a reference. Also, the pkgState must be copied. However,
+ // this code should otherwise be kept in sync with doCopy().
+ appId = orig.appId;
+ pkg = orig.pkg;
+ sharedUser = orig.sharedUser == null ? null : orig.sharedUser.snapshot();
+ sharedUserId = orig.sharedUserId;
+ copyMimeGroups(orig.mimeGroups);
+ pkgState = orig.pkgState;
+ mDomainSetId = orig.getDomainSetId();
+ mSnapshot = new SnapshotCache.Sealed();
+ }
+
+ /**
+ * Return the package snapshot.
+ */
+ public PackageSetting snapshot() {
+ return mSnapshot.snapshot();
}
/** @see #pkg **/
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index 731d41c38f79..bf82bd8b09d5 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -169,6 +169,15 @@ public abstract class PackageSettingBase extends SettingBase {
doCopy(base);
}
+ // A copy constructor used to create snapshots. The boolean is present only to
+ // match up with the constructor in PackageSetting.
+ PackageSettingBase(PackageSettingBase orig, boolean snapshot) {
+ super(orig);
+ name = orig.name;
+ realName = orig.realName;
+ doCopy(orig);
+ }
+
public void setInstallerPackageName(String packageName) {
installSource = installSource.setInstallerPackage(packageName);
onChanged();
diff --git a/services/core/java/com/android/server/pm/SettingBase.java b/services/core/java/com/android/server/pm/SettingBase.java
index 0e8a278f3b6b..7b5c7e3a0c84 100644
--- a/services/core/java/com/android/server/pm/SettingBase.java
+++ b/services/core/java/com/android/server/pm/SettingBase.java
@@ -22,12 +22,13 @@ import android.content.pm.ApplicationInfo;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.pm.permission.LegacyPermissionState;
+import com.android.server.utils.Snappable;
import com.android.server.utils.Watchable;
import com.android.server.utils.WatchableImpl;
import com.android.server.utils.Watcher;
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-public abstract class SettingBase implements Watchable {
+public abstract class SettingBase implements Watchable, Snappable {
// TODO: make this variable protected, or even private with a getter and setter.
// Simply making it protected or private requires that the name be changed to conformm
// to the Android naming convention, and that touches quite a few files.
diff --git a/services/core/java/com/android/server/pm/SharedUserSetting.java b/services/core/java/com/android/server/pm/SharedUserSetting.java
index 9b1c08d9c321..8ddbe08e2572 100644
--- a/services/core/java/com/android/server/pm/SharedUserSetting.java
+++ b/services/core/java/com/android/server/pm/SharedUserSetting.java
@@ -26,6 +26,7 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.util.ArrayUtils;
import com.android.server.pm.parsing.pkg.AndroidPackage;
+import com.android.server.utils.SnapshotCache;
import libcore.util.EmptyArray;
@@ -49,12 +50,25 @@ public final class SharedUserSetting extends SettingBase {
// that all apps within the sharedUser run in the same selinux context.
int seInfoTargetSdkVersion;
- final ArraySet<PackageSetting> packages = new ArraySet<>();
+ final ArraySet<PackageSetting> packages;
final PackageSignatures signatures = new PackageSignatures();
Boolean signaturesChanged;
- ArrayMap<String, ParsedProcess> processes;
+ final ArrayMap<String, ParsedProcess> processes;
+
+ /**
+ * Snapshot support.
+ */
+ private final SnapshotCache<SharedUserSetting> mSnapshot;
+
+ private SnapshotCache<SharedUserSetting> makeCache() {
+ return new SnapshotCache<SharedUserSetting>(this, this) {
+ @Override
+ public SharedUserSetting createSnapshot() {
+ return new SharedUserSetting(mSource);
+ }};
+ }
SharedUserSetting(String _name, int _pkgFlags, int _pkgPrivateFlags) {
super(_pkgFlags, _pkgPrivateFlags);
@@ -62,6 +76,31 @@ public final class SharedUserSetting extends SettingBase {
uidPrivateFlags = _pkgPrivateFlags;
name = _name;
seInfoTargetSdkVersion = android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
+ packages = new ArraySet<>();
+ processes = new ArrayMap<>();
+ mSnapshot = makeCache();
+ }
+
+ // The copy constructor is used to create a snapshot
+ private SharedUserSetting(SharedUserSetting orig) {
+ super(orig);
+ name = orig.name;
+ uidFlags = orig.uidFlags;
+ uidPrivateFlags = orig.uidPrivateFlags;
+ packages = new ArraySet(orig.packages);
+ // A PackageParser.SigningDetails seems to consist solely of final attributes, so
+ // it is safe to copy the reference.
+ signatures.mSigningDetails = orig.signatures.mSigningDetails;
+ signaturesChanged = orig.signaturesChanged;
+ processes = new ArrayMap(orig.processes);
+ mSnapshot = new SnapshotCache.Sealed();
+ }
+
+ /**
+ * Return a read-only snapshot of this object.
+ */
+ public SharedUserSetting snapshot() {
+ return mSnapshot.snapshot();
}
@Override
@@ -80,9 +119,6 @@ public final class SharedUserSetting extends SettingBase {
void addProcesses(Map<String, ParsedProcess> newProcs) {
if (newProcs != null) {
final int numProcs = newProcs.size();
- if (processes == null) {
- processes = new ArrayMap<>(numProcs);
- }
for (String key : newProcs.keySet()) {
ParsedProcess newProc = newProcs.get(key);
ParsedProcess proc = processes.get(newProc.getName());
@@ -191,7 +227,7 @@ public final class SharedUserSetting extends SettingBase {
* Update tracked data about processes based on all known packages in the shared user ID.
*/
public void updateProcesses() {
- processes = null;
+ processes.clear();
for (int i = packages.size() - 1; i >= 0; i--) {
final AndroidPackage pkg = packages.valueAt(i).pkg;
if (pkg != null) {
@@ -230,14 +266,15 @@ public final class SharedUserSetting extends SettingBase {
this.signaturesChanged = sharedUser.signaturesChanged;
if (sharedUser.processes != null) {
final int numProcs = sharedUser.processes.size();
- this.processes = new ArrayMap<>(numProcs);
+ this.processes.clear();
+ this.processes.ensureCapacity(numProcs);
for (int i = 0; i < numProcs; i++) {
ParsedProcess proc =
new ParsedProcess(sharedUser.processes.valueAt(i));
this.processes.put(proc.getName(), proc);
}
} else {
- this.processes = null;
+ this.processes.clear();
}
onChanged();
return this;
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 30ddbb60080f..dfc14bd733df 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -2920,7 +2920,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
wasChanged = true;
}
- if ((flags & FLAG_PERMISSION_REVOKED_COMPAT) != 0) {
+ if ((flags & FLAG_PERMISSION_REVOKED_COMPAT) != 0
+ && !isPermissionSplitFromNonRuntime(permName,
+ pkg.getTargetSdkVersion())) {
flags &= ~FLAG_PERMISSION_REVOKED_COMPAT;
wasChanged = true;
// Hard restricted permissions cannot be held.
@@ -4038,17 +4040,14 @@ public class PermissionManagerService extends IPermissionManager.Stub {
*
* @param packageName The package that is updated
* @param pkg The package that is updated, or {@code null} if package is deleted
- * @param filterUserId If not {@link UserHandle.USER_ALL}, only restore the permission state for
- * this particular user
*/
- private void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg,
- @UserIdInt int filterUserId) {
+ private void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg) {
// If the package is being deleted, update the permissions of all the apps
final int flags =
(pkg == null ? UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG
: UPDATE_PERMISSIONS_REPLACE_PKG);
- updatePermissions(packageName, pkg, getVolumeUuidForPackage(pkg), flags,
- mDefaultPermissionCallback, filterUserId);
+ updatePermissions(
+ packageName, pkg, getVolumeUuidForPackage(pkg), flags, mDefaultPermissionCallback);
}
/**
@@ -4070,8 +4069,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
(fingerprintChanged
? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
: 0);
- updatePermissions(null, null, volumeUuid, flags, mDefaultPermissionCallback,
- UserHandle.USER_ALL);
+ updatePermissions(null, null, volumeUuid, flags, mDefaultPermissionCallback);
} finally {
PackageManager.uncorkPackageInfoCache();
}
@@ -4120,14 +4118,12 @@ public class PermissionManagerService extends IPermissionManager.Stub {
* all volumes
* @param flags Control permission for which apps should be updated
* @param callback Callback to call after permission changes
- * @param filterUserId If not {@link UserHandle.USER_ALL}, only restore the permission state for
- * this particular user
*/
private void updatePermissions(final @Nullable String changingPkgName,
final @Nullable AndroidPackage changingPkg,
final @Nullable String replaceVolumeUuid,
@UpdatePermissionFlags int flags,
- final @Nullable PermissionCallback callback, @UserIdInt int filterUserId) {
+ final @Nullable PermissionCallback callback) {
// TODO: Most of the methods exposing BasePermission internals [source package name,
// etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
// have package settings, we should make note of it elsewhere [map between
@@ -4163,7 +4159,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
// Only replace for packages on requested volume
final String volumeUuid = getVolumeUuidForPackage(pkg);
final boolean replace = replaceAll && Objects.equals(replaceVolumeUuid, volumeUuid);
- restorePermissionState(pkg, replace, changingPkgName, callback, filterUserId);
+ restorePermissionState(pkg, replace, changingPkgName, callback,
+ UserHandle.USER_ALL);
});
}
@@ -4172,7 +4169,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
final String volumeUuid = getVolumeUuidForPackage(changingPkg);
final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
&& Objects.equals(replaceVolumeUuid, volumeUuid);
- restorePermissionState(changingPkg, replace, changingPkgName, callback, filterUserId);
+ restorePermissionState(changingPkg, replace, changingPkgName, callback,
+ UserHandle.USER_ALL);
}
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
@@ -4839,18 +4837,20 @@ public class PermissionManagerService extends IPermissionManager.Stub {
private void onPackageInstalledInternal(@NonNull AndroidPackage pkg,
@NonNull PermissionManagerServiceInternal.PackageInstalledParams params,
- @UserIdInt int userId) {
- updatePermissions(pkg.getPackageName(), pkg, userId);
- addAllowlistedRestrictedPermissionsInternal(pkg,
- params.getAllowlistedRestrictedPermissions(),
- FLAG_PERMISSION_WHITELIST_INSTALLER, userId);
- final int autoRevokePermissionsMode = params.getAutoRevokePermissionsMode();
- if (autoRevokePermissionsMode == AppOpsManager.MODE_ALLOWED
- || autoRevokePermissionsMode == AppOpsManager.MODE_IGNORED) {
- setAutoRevokeExemptedInternal(pkg,
- autoRevokePermissionsMode == AppOpsManager.MODE_IGNORED, userId);
+ @UserIdInt int[] userIds) {
+ updatePermissions(pkg.getPackageName(), pkg);
+ for (final int userId : userIds) {
+ addAllowlistedRestrictedPermissionsInternal(pkg,
+ params.getAllowlistedRestrictedPermissions(),
+ FLAG_PERMISSION_WHITELIST_INSTALLER, userId);
+ final int autoRevokePermissionsMode = params.getAutoRevokePermissionsMode();
+ if (autoRevokePermissionsMode == AppOpsManager.MODE_ALLOWED
+ || autoRevokePermissionsMode == AppOpsManager.MODE_IGNORED) {
+ setAutoRevokeExemptedInternal(pkg,
+ autoRevokePermissionsMode == AppOpsManager.MODE_IGNORED, userId);
+ }
+ grantRequestedRuntimePermissionsInternal(pkg, params.getGrantedPermissions(), userId);
}
- grantRequestedRuntimePermissionsInternal(pkg, params.getGrantedPermissions(), userId);
}
private void addAllowlistedRestrictedPermissionsInternal(@NonNull AndroidPackage pkg,
@@ -4873,7 +4873,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
private void onPackageUninstalledInternal(@NonNull String packageName, int appId,
@Nullable AndroidPackage pkg, @NonNull List<AndroidPackage> sharedUserPkgs,
- @UserIdInt int userId) {
+ @UserIdInt int[] userIds) {
// TODO: Move these checks to check PackageState to be more reliable.
// System packages should always have an available APK.
if (pkg != null && pkg.isSystem()
@@ -4884,27 +4884,31 @@ public class PermissionManagerService extends IPermissionManager.Stub {
// If we are only marking a system package as uninstalled, we need to keep its
// pregranted permission state so that it still works once it gets reinstalled, thus
// only reset the user modifications to its permission state.
- resetRuntimePermissionsInternal(pkg, userId);
+ for (final int userId : userIds) {
+ resetRuntimePermissionsInternal(pkg, userId);
+ }
return;
}
- updatePermissions(packageName, null, userId);
- if (sharedUserPkgs.isEmpty()) {
- removeUidStateAndResetPackageInstallPermissionsFixed(appId, packageName, userId);
- } else {
- // Remove permissions associated with package. Since runtime
- // permissions are per user we have to kill the removed package
- // or packages running under the shared user of the removed
- // package if revoking the permissions requested only by the removed
- // package is successful and this causes a change in gids.
- final int userIdToKill = revokeSharedUserPermissionsForDeletedPackageInternal(pkg,
- sharedUserPkgs, userId);
- final boolean shouldKill = userIdToKill != UserHandle.USER_NULL;
- // If gids changed, kill all affected packages.
- if (shouldKill) {
- mHandler.post(() -> {
- // This has to happen with no lock held.
- killUid(appId, UserHandle.USER_ALL, KILL_APP_REASON_GIDS_CHANGED);
- });
+ updatePermissions(packageName, null);
+ for (final int userId : userIds) {
+ if (sharedUserPkgs.isEmpty()) {
+ removeUidStateAndResetPackageInstallPermissionsFixed(appId, packageName, userId);
+ } else {
+ // Remove permissions associated with package. Since runtime
+ // permissions are per user we have to kill the removed package
+ // or packages running under the shared user of the removed
+ // package if revoking the permissions requested only by the removed
+ // package is successful and this causes a change in gids.
+ final int userIdToKill = revokeSharedUserPermissionsForDeletedPackageInternal(pkg,
+ sharedUserPkgs, userId);
+ final boolean shouldKill = userIdToKill != UserHandle.USER_NULL;
+ // If gids changed, kill all affected packages.
+ if (shouldKill) {
+ mHandler.post(() -> {
+ // This has to happen with no lock held.
+ killUid(appId, UserHandle.USER_ALL, KILL_APP_REASON_GIDS_CHANGED);
+ });
+ }
}
}
}
@@ -5179,8 +5183,11 @@ public class PermissionManagerService extends IPermissionManager.Stub {
@NonNull PackageInstalledParams params, @UserIdInt int userId) {
Objects.requireNonNull(pkg, "pkg");
Objects.requireNonNull(params, "params");
- Preconditions.checkArgumentNonNegative(userId, "userId");
- onPackageInstalledInternal(pkg, params, userId);
+ Preconditions.checkArgument(userId >= UserHandle.USER_SYSTEM
+ || userId == UserHandle.USER_ALL, "userId");
+ final int[] userIds = userId == UserHandle.USER_ALL ? getAllUserIds()
+ : new int[] { userId };
+ onPackageInstalledInternal(pkg, params, userIds);
}
@Override
@@ -5195,8 +5202,11 @@ public class PermissionManagerService extends IPermissionManager.Stub {
@UserIdInt int userId) {
Objects.requireNonNull(packageName, "packageName");
Objects.requireNonNull(sharedUserPkgs, "sharedUserPkgs");
- Preconditions.checkArgumentNonNegative(userId, "userId");
- onPackageUninstalledInternal(packageName, appId, pkg, sharedUserPkgs, userId);
+ Preconditions.checkArgument(userId >= UserHandle.USER_SYSTEM
+ || userId == UserHandle.USER_ALL, "userId");
+ final int[] userIds = userId == UserHandle.USER_ALL ? getAllUserIds()
+ : new int[] { userId };
+ onPackageUninstalledInternal(packageName, appId, pkg, sharedUserPkgs, userIds);
}
@NonNull
diff --git a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
index 9026262db897..ab7135526746 100644
--- a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
+++ b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
@@ -189,12 +189,16 @@ public abstract class SoftRestrictedPermissionPolicy {
return false;
}
- // 3. The app has WRITE_MEDIA_STORAGE, OR
- // the app already has legacy external storage or requested it,
- // and is < R.
- return hasWriteMediaStorageGrantedForUid
- || ((hasLegacyExternalStorage || hasRequestedLegacyExternalStorage)
- && targetSDK < Build.VERSION_CODES.R);
+ // 3. The app targetSDK should be less than R
+ if (targetSDK >= Build.VERSION_CODES.R) {
+ return false;
+ }
+
+ // 4. The app has WRITE_MEDIA_STORAGE,
+ // OR the app already has legacy external storage
+ // OR the app requested legacy external storage
+ return hasWriteMediaStorageGrantedForUid || hasLegacyExternalStorage
+ || hasRequestedLegacyExternalStorage;
}
@Override
public boolean mayDenyExtraAppOpIfGranted() {
@@ -216,10 +220,8 @@ public abstract class SoftRestrictedPermissionPolicy {
return true;
}
- // The package doesn't have WRITE_MEDIA_STORAGE,
- // AND didn't request legacy storage to be preserved
- if (!hasWriteMediaStorageGrantedForUid
- && !hasRequestedPreserveLegacyExternalStorage) {
+ // The package doesn't request legacy storage to be preserved
+ if (!hasRequestedPreserveLegacyExternalStorage) {
return true;
}
diff --git a/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java b/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java
index 9c8ff685d14d..068626588745 100644
--- a/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java
+++ b/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java
@@ -125,10 +125,12 @@ final class RemoteSpeechRecognitionService extends ServiceConnector.Impl<IRecogn
}
});
+ // Eager local evaluation to avoid reading a different or null value at closure-run-time
+ final DelegatingListener listenerToStart = this.mDelegatingListener;
run(service ->
service.startListening(
recognizerIntent,
- mDelegatingListener,
+ listenerToStart,
attributionSource));
}
}
@@ -162,7 +164,9 @@ final class RemoteSpeechRecognitionService extends ServiceConnector.Impl<IRecogn
}
mRecordingInProgress = false;
- run(service -> service.stopListening(mDelegatingListener));
+ // Eager local evaluation to avoid reading a different or null value at closure-run-time
+ final DelegatingListener listenerToStop = this.mDelegatingListener;
+ run(service -> service.stopListening(listenerToStop));
}
}
diff --git a/services/core/java/com/android/server/vibrator/VibrationThread.java b/services/core/java/com/android/server/vibrator/VibrationThread.java
index 03863723a5e9..dd4e260c6d91 100644
--- a/services/core/java/com/android/server/vibrator/VibrationThread.java
+++ b/services/core/java/com/android/server/vibrator/VibrationThread.java
@@ -1294,21 +1294,32 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
@Override
public boolean shouldPlayWhenVibratorComplete(int vibratorId) {
if (controller.getVibratorInfo().getId() == vibratorId) {
+ mVibratorCallbackReceived = true;
mNextOffTime = SystemClock.uptimeMillis();
}
- // Timings are tightly controlled here, so never anticipate when vibrator is complete.
- return false;
+ // Timings are tightly controlled here, so only anticipate if the vibrator was supposed
+ // to be ON but has completed prematurely, to turn it back on as soon as possible.
+ return mNextOffTime < startTime && controller.getCurrentAmplitude() > 0;
}
@Override
public List<Step> play() {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "AmplitudeStep");
try {
+ long now = SystemClock.uptimeMillis();
+ long latency = now - startTime;
if (DEBUG) {
- long latency = SystemClock.uptimeMillis() - startTime;
Slog.d(TAG, "Running amplitude step with " + latency + "ms latency.");
}
+ if (mVibratorCallbackReceived && latency < 0) {
+ // This step was anticipated because the vibrator turned off prematurely.
+ // Turn it back on and return this same step to run at the exact right time.
+ mNextOffTime = turnVibratorBackOn(/* remainingDuration= */ -latency);
+ return Arrays.asList(new AmplitudeStep(startTime, controller, effect,
+ segmentIndex, mNextOffTime));
+ }
+
VibrationEffectSegment segment = effect.getSegments().get(segmentIndex);
if (!(segment instanceof StepSegment)) {
Slog.w(TAG, "Ignoring wrong segment for a AmplitudeStep: " + segment);
@@ -1321,17 +1332,16 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
return skipToNextSteps(/* segmentsSkipped= */ 1);
}
- long now = SystemClock.uptimeMillis();
float amplitude = stepSegment.getAmplitude();
if (amplitude == 0) {
- if (mNextOffTime > now) {
+ if (vibratorOffTimeout > now) {
// Amplitude cannot be set to zero, so stop the vibrator.
stopVibrating();
mNextOffTime = now;
}
} else {
if (startTime >= mNextOffTime) {
- // Vibrator has stopped. Turn vibrator back on for the duration of another
+ // Vibrator is OFF. Turn vibrator back on for the duration of another
// cycle before setting the amplitude.
long onDuration = getVibratorOnDuration(effect, segmentIndex);
if (onDuration > 0) {
@@ -1350,6 +1360,22 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
}
}
+ private long turnVibratorBackOn(long remainingDuration) {
+ long onDuration = getVibratorOnDuration(effect, segmentIndex);
+ if (onDuration <= 0) {
+ // Vibrator is supposed to go back off when this step starts, so just leave it off.
+ return vibratorOffTimeout;
+ }
+ onDuration += remainingDuration;
+ float expectedAmplitude = controller.getCurrentAmplitude();
+ mVibratorOnResult = startVibrating(onDuration);
+ if (mVibratorOnResult > 0) {
+ // Set the amplitude back to the value it was supposed to be playing at.
+ changeAmplitude(expectedAmplitude);
+ }
+ return SystemClock.uptimeMillis() + onDuration + CALLBACKS_EXTRA_TIMEOUT;
+ }
+
private long startVibrating(long duration) {
if (DEBUG) {
Slog.d(TAG, "Turning on vibrator " + controller.getVibratorInfo().getId() + " for "
@@ -1383,7 +1409,10 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
repeatIndex = -1;
}
if (i == startIndex) {
- return 1000;
+ // The repeating waveform keeps the vibrator ON all the time. Use a minimum
+ // of 1s duration to prevent short patterns from turning the vibrator ON too
+ // frequently.
+ return Math.max(timing, 1000);
}
}
if (i == segmentCount && effect.getRepeatIndex() < 0) {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index f3dbed574b06..44682525edd2 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -801,6 +801,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// Tracking cookie for the launch of this activity and it's task.
IBinder mLaunchCookie;
+ // Entering PiP is usually done in two phases, we put the task into pinned mode first and
+ // SystemUi sets the pinned mode on activity after transition is done.
+ boolean mWaitForEnteringPinnedMode;
+
private final Runnable mPauseTimeoutRunnable = new Runnable() {
@Override
public void run() {
@@ -7705,6 +7709,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// mode (see RootWindowContainer#moveActivityToPinnedRootTask). So once the windowing mode
// of activity is changed, it is the signal of the last step to update the PiP states.
if (!wasInPictureInPicture && inPinnedWindowingMode() && task != null) {
+ mWaitForEnteringPinnedMode = false;
mTaskSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(task, task.getBounds());
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 090a01aa6f1b..04c01736431d 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -6471,12 +6471,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
Slog.w(TAG, "Override application configuration: cannot find pid " + mPid);
return;
}
- if (wpc.getNightMode() == mNightMode) {
- return;
- }
- if (!wpc.setOverrideNightMode(mNightMode)) {
- return;
- }
+ wpc.setOverrideNightMode(mNightMode);
wpc.updateNightModeForAllActivities(mNightMode);
mPackageConfigPersister.updateFromImpl(wpc.mName, wpc.mUserId, this);
} finally {
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index 8fbe1775fd19..d52e9b608cdb 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -545,8 +545,8 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
* @return true if the nightMode has been changed.
*/
public boolean setOverrideNightMode(int nightMode) {
- final int currentUiMode = mFullConfiguration.uiMode;
- final int currentNightMode = getNightMode();
+ final int currentUiMode = mRequestedOverrideConfiguration.uiMode;
+ final int currentNightMode = currentUiMode & Configuration.UI_MODE_NIGHT_MASK;
final int validNightMode = nightMode & Configuration.UI_MODE_NIGHT_MASK;
if (currentNightMode == validNightMode) {
return false;
@@ -558,10 +558,6 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
return true;
}
- int getNightMode() {
- return mFullConfiguration.uiMode & Configuration.UI_MODE_NIGHT_MASK;
- }
-
public boolean isActivityTypeDream() {
return getActivityType() == ACTIVITY_TYPE_DREAM;
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 97c19ab72918..73d31bf7e0c8 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -1568,6 +1568,10 @@ public class DisplayPolicy {
layoutStatusBar(displayFrames, mBarContentFrames.get(TYPE_STATUS_BAR));
return;
}
+ if (win.mActivityRecord != null && win.mActivityRecord.mWaitForEnteringPinnedMode) {
+ // Skip layout of the window when in transition to pip mode.
+ return;
+ }
final WindowManager.LayoutParams attrs = win.getAttrs();
final int type = attrs.type;
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 9a6a51848317..32147215834f 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2191,6 +2191,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// from doing work and changing the activity visuals while animating
// TODO(task-org): Figure-out more structured way to do this long term.
r.setWindowingMode(intermediateWindowingMode);
+ r.mWaitForEnteringPinnedMode = true;
rootTask.setWindowingMode(WINDOWING_MODE_PINNED);
rootTask.setDeferTaskAppear(false);
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 777306aa13c5..936b2efa00ad 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -61,6 +61,8 @@ import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.SurfaceControl.METADATA_TASK_ID;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
@@ -4105,6 +4107,7 @@ class Task extends WindowContainer<WindowContainer> {
info.positionInParent = getRelativePosition();
info.pictureInPictureParams = getPictureInPictureParams(top);
+ info.displayCutoutInsets = getDisplayCutoutInsets(top);
info.topActivityInfo = mReuseActivitiesReport.top != null
? mReuseActivitiesReport.top.info
: null;
@@ -4139,6 +4142,18 @@ class Task extends WindowContainer<WindowContainer> {
? null : new PictureInPictureParams(topVisibleActivity.pictureInPictureArgs);
}
+ private Rect getDisplayCutoutInsets(Task top) {
+ if (top == null || top.mDisplayContent == null
+ || top.getDisplayInfo().displayCutout == null) return null;
+ final WindowState w = top.getTopVisibleAppMainWindow();
+ final int displayCutoutMode = w == null
+ ? WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
+ : w.getAttrs().layoutInDisplayCutoutMode;
+ return (displayCutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
+ || displayCutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES)
+ ? null : top.getDisplayInfo().displayCutout.getSafeInsets();
+ }
+
/**
* Returns a {@link TaskInfo} with information from this task.
*/
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index fd71d1bc1c38..193d92a3b2ff 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -14991,9 +14991,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
private void setNetworkLoggingActiveInternal(boolean active) {
- final boolean[] shouldSendNotification = new boolean[] {false};
- synchronized (getLockObject()) {
- mInjector.binderWithCleanCallingIdentity(() -> {
+ mInjector.binderWithCleanCallingIdentity(() -> {
+ boolean shouldSendNotification = false;
+ synchronized (getLockObject()) {
if (active) {
if (mNetworkLogger == null) {
final int affectedUserId = getNetworkLoggingAffectedUser();
@@ -15008,7 +15008,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
+ " service not being available yet.");
}
maybePauseDeviceWideLoggingLocked();
- shouldSendNotification[0] = shouldSendNetworkLoggingNotificationLocked();
+ shouldSendNotification = shouldSendNetworkLoggingNotificationLocked();
} else {
if (mNetworkLogger != null && !mNetworkLogger.stopNetworkLogging()) {
Slogf.wtf(LOG_TAG, "Network logging could not be stopped due to the logging"
@@ -15016,15 +15016,16 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
mNetworkLogger = null;
}
- });
- }
- if (active) {
- if (shouldSendNotification[0]) {
- sendNetworkLoggingNotification();
}
- } else {
- mInjector.getNotificationManager().cancel(SystemMessage.NOTE_NETWORK_LOGGING);
- }
+ if (active) {
+ if (shouldSendNotification) {
+ mHandler.post(() -> sendNetworkLoggingNotification());
+ }
+ } else {
+ mHandler.post(() -> mInjector.getNotificationManager().cancel(
+ SystemMessage.NOTE_NETWORK_LOGGING));
+ }
+ });
}
private @UserIdInt int getNetworkLoggingAffectedUser() {
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index 583797e69995..a254f68e8bed 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -514,8 +514,16 @@ public class AlarmManagerServiceTest {
}
private void setAllowWhileIdleAlarm(int type, long triggerTime, PendingIntent pi,
- boolean unrestricted) {
- final int flags = unrestricted ? FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED : FLAG_ALLOW_WHILE_IDLE;
+ boolean unrestricted, boolean compat) {
+ assertFalse("Alarm cannot be compat and unrestricted", unrestricted && compat);
+ final int flags;
+ if (unrestricted) {
+ flags = FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
+ } else if (compat) {
+ flags = FLAG_ALLOW_WHILE_IDLE_COMPAT;
+ } else {
+ flags = FLAG_ALLOW_WHILE_IDLE;
+ }
setTestAlarm(type, triggerTime, pi, 0, flags, TEST_CALLING_UID);
}
@@ -1600,13 +1608,13 @@ public class AlarmManagerServiceTest {
final long firstTrigger = mNowElapsedTest + 10;
for (int i = 0; i < quota; i++) {
setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + i,
- getNewMockPendingIntent(), false);
+ getNewMockPendingIntent(), false, false);
mNowElapsedTest = mTestTimer.getElapsed();
mTestTimer.expire();
}
// This one should get deferred on set.
setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + quota,
- getNewMockPendingIntent(), false);
+ getNewMockPendingIntent(), false, false);
final long expectedNextTrigger = firstTrigger + mAllowWhileIdleWindow;
assertEquals("Incorrect trigger when no quota left", expectedNextTrigger,
mTestTimer.getElapsed());
@@ -1619,6 +1627,108 @@ public class AlarmManagerServiceTest {
}
@Test
+ public void allowWhileIdleCompatAlarmsWhileDeviceIdle() throws Exception {
+ setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, 0);
+
+ final long window = mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW;
+ setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + window + 1000,
+ getNewMockPendingIntent());
+ assertNotNull(mService.mPendingIdleUntil);
+
+ final int quota = mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA;
+ final long firstTrigger = mNowElapsedTest + 10;
+ for (int i = 0; i < quota; i++) {
+ setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + i,
+ getNewMockPendingIntent(), false, true);
+ mNowElapsedTest = mTestTimer.getElapsed();
+ mTestTimer.expire();
+ }
+ // This one should get deferred on set.
+ setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + quota,
+ getNewMockPendingIntent(), false, true);
+ final long expectedNextTrigger = firstTrigger + window;
+ assertEquals("Incorrect trigger when no quota left", expectedNextTrigger,
+ mTestTimer.getElapsed());
+
+ // Bring the idle until alarm back.
+ setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, expectedNextTrigger - 50,
+ getNewMockPendingIntent());
+ assertEquals(expectedNextTrigger - 50, mService.mPendingIdleUntil.getWhenElapsed());
+ assertEquals(expectedNextTrigger - 50, mTestTimer.getElapsed());
+ }
+
+ @Test
+ public void allowWhileIdleCompatHistorySeparate() throws Exception {
+ when(mAppStateTracker.areAlarmsRestrictedByBatterySaver(TEST_CALLING_UID,
+ TEST_CALLING_PACKAGE)).thenReturn(true);
+ when(mAppStateTracker.isForceAllAppsStandbyEnabled()).thenReturn(true);
+
+ final int fullQuota = mService.mConstants.ALLOW_WHILE_IDLE_QUOTA;
+ final int compatQuota = mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA;
+
+ final long fullWindow = mAllowWhileIdleWindow;
+ final long compatWindow = mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW;
+
+ final long firstFullTrigger = mNowElapsedTest + 10;
+ for (int i = 0; i < fullQuota; i++) {
+ setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstFullTrigger + i,
+ getNewMockPendingIntent(), false, false);
+ mNowElapsedTest = mTestTimer.getElapsed();
+ mTestTimer.expire();
+ }
+ // This one should get deferred on set, as full quota is not available.
+ setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstFullTrigger + fullQuota,
+ getNewMockPendingIntent(), false, false);
+ final long expectedNextFullTrigger = firstFullTrigger + fullWindow;
+ assertEquals("Incorrect trigger when no quota left", expectedNextFullTrigger,
+ mTestTimer.getElapsed());
+ mService.removeLocked(TEST_CALLING_UID, REMOVE_REASON_UNDEFINED);
+
+ // The following should be allowed, as compat quota should be free.
+ for (int i = 0; i < compatQuota; i++) {
+ final long trigger = mNowElapsedTest + 1;
+ setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, trigger, getNewMockPendingIntent(),
+ false, true);
+ assertEquals(trigger, mTestTimer.getElapsed());
+ mNowElapsedTest = mTestTimer.getElapsed();
+ mTestTimer.expire();
+ }
+
+ // Refresh the state
+ mService.removeLocked(TEST_CALLING_UID, REMOVE_REASON_UNDEFINED);
+ mService.mAllowWhileIdleHistory.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER);
+ mService.mAllowWhileIdleCompatHistory.removeForPackage(TEST_CALLING_PACKAGE,
+ TEST_CALLING_USER);
+
+ // Now test with flipped order
+
+ final long firstCompatTrigger = mNowElapsedTest + 10;
+ for (int i = 0; i < compatQuota; i++) {
+ setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstCompatTrigger + i,
+ getNewMockPendingIntent(), false, true);
+ mNowElapsedTest = mTestTimer.getElapsed();
+ mTestTimer.expire();
+ }
+ // This one should get deferred on set, as full quota is not available.
+ setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstCompatTrigger + compatQuota,
+ getNewMockPendingIntent(), false, true);
+ final long expectedNextCompatTrigger = firstCompatTrigger + compatWindow;
+ assertEquals("Incorrect trigger when no quota left", expectedNextCompatTrigger,
+ mTestTimer.getElapsed());
+ mService.removeLocked(TEST_CALLING_UID, REMOVE_REASON_UNDEFINED);
+
+ // The following should be allowed, as full quota should be free.
+ for (int i = 0; i < fullQuota; i++) {
+ final long trigger = mNowElapsedTest + 1;
+ setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, trigger, getNewMockPendingIntent(),
+ false, false);
+ assertEquals(trigger, mTestTimer.getElapsed());
+ mNowElapsedTest = mTestTimer.getElapsed();
+ mTestTimer.expire();
+ }
+ }
+
+ @Test
public void allowWhileIdleUnrestricted() throws Exception {
setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, 0);
@@ -1634,7 +1744,7 @@ public class AlarmManagerServiceTest {
final long firstTrigger = mNowElapsedTest + 10;
for (int i = 0; i < numAlarms; i++) {
setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + i,
- getNewMockPendingIntent(), true);
+ getNewMockPendingIntent(), true, false);
}
// All of them should fire as expected.
for (int i = 0; i < numAlarms; i++) {
@@ -1736,7 +1846,7 @@ public class AlarmManagerServiceTest {
final int quota = mService.mConstants.ALLOW_WHILE_IDLE_QUOTA;
testQuotasDeferralOnSet(trigger -> setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, trigger,
- getNewMockPendingIntent(), false), quota, mAllowWhileIdleWindow);
+ getNewMockPendingIntent(), false, false), quota, mAllowWhileIdleWindow);
// Refresh the state
mService.removeLocked(TEST_CALLING_UID,
@@ -1744,7 +1854,7 @@ public class AlarmManagerServiceTest {
mService.mAllowWhileIdleHistory.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER);
testQuotasDeferralOnExpiration(trigger -> setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP,
- trigger, getNewMockPendingIntent(), false), quota, mAllowWhileIdleWindow);
+ trigger, getNewMockPendingIntent(), false, false), quota, mAllowWhileIdleWindow);
// Refresh the state
mService.removeLocked(TEST_CALLING_UID,
@@ -1752,7 +1862,36 @@ public class AlarmManagerServiceTest {
mService.mAllowWhileIdleHistory.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER);
testQuotasNoDeferral(trigger -> setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, trigger,
- getNewMockPendingIntent(), false), quota, mAllowWhileIdleWindow);
+ getNewMockPendingIntent(), false, false), quota, mAllowWhileIdleWindow);
+ }
+
+ @Test
+ public void allowWhileIdleCompatAlarmsInBatterySaver() throws Exception {
+ when(mAppStateTracker.areAlarmsRestrictedByBatterySaver(TEST_CALLING_UID,
+ TEST_CALLING_PACKAGE)).thenReturn(true);
+ when(mAppStateTracker.isForceAllAppsStandbyEnabled()).thenReturn(true);
+
+ final int quota = mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA;
+ final long window = mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW;
+
+ testQuotasDeferralOnSet(trigger -> setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, trigger,
+ getNewMockPendingIntent(), false, true), quota, window);
+
+ // Refresh the state
+ mService.removeLocked(TEST_CALLING_UID, REMOVE_REASON_UNDEFINED);
+ mService.mAllowWhileIdleCompatHistory.removeForPackage(TEST_CALLING_PACKAGE,
+ TEST_CALLING_USER);
+
+ testQuotasDeferralOnExpiration(trigger -> setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP,
+ trigger, getNewMockPendingIntent(), false, true), quota, window);
+
+ // Refresh the state
+ mService.removeLocked(TEST_CALLING_UID, REMOVE_REASON_UNDEFINED);
+ mService.mAllowWhileIdleCompatHistory.removeForPackage(TEST_CALLING_PACKAGE,
+ TEST_CALLING_USER);
+
+ testQuotasNoDeferral(trigger -> setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, trigger,
+ getNewMockPendingIntent(), false, true), quota, window);
}
@Test
@@ -2123,7 +2262,7 @@ public class AlarmManagerServiceTest {
final PendingIntent alarmPi = getNewMockPendingIntent();
final AlarmManager.AlarmClockInfo alarmClock = mock(AlarmManager.AlarmClockInfo.class);
mBinder.set(TEST_CALLING_PACKAGE, RTC_WAKEUP, 1234, WINDOW_EXACT, 0, 0,
- alarmPi, null, null, null, alarmClock);
+ alarmPi, null, null, null, alarmClock);
// Correct permission checks are invoked.
verify(mService).hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID);
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
index 91f49224fde8..5b067bc58da3 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
@@ -869,6 +869,446 @@ public class AppSearchImplTest {
}
@Test
+ public void testGetNextPageToken_query() throws Exception {
+ // Insert package1 schema
+ List<AppSearchSchema> schema1 =
+ ImmutableList.of(new AppSearchSchema.Builder("schema1").build());
+ mAppSearchImpl.setSchema(
+ "package1",
+ "database1",
+ schema1,
+ /*visibilityStore=*/ null,
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+ /*forceOverride=*/ false,
+ /*version=*/ 0);
+
+ // Insert two package1 documents
+ GenericDocument document1 =
+ new GenericDocument.Builder<>("namespace", "id1", "schema1").build();
+ GenericDocument document2 =
+ new GenericDocument.Builder<>("namespace", "id2", "schema1").build();
+ mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
+ mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
+
+ // Query for only 1 result per page
+ SearchSpec searchSpec =
+ new SearchSpec.Builder()
+ .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
+ .setResultCountPerPage(1)
+ .build();
+ SearchResultPage searchResultPage =
+ mAppSearchImpl.query("package1", "database1", "", searchSpec, /*logger=*/ null);
+
+ // Document2 will come first because it was inserted last and default return order is
+ // most recent.
+ assertThat(searchResultPage.getResults()).hasSize(1);
+ assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
+
+ long nextPageToken = searchResultPage.getNextPageToken();
+ searchResultPage = mAppSearchImpl.getNextPage("package1", nextPageToken);
+ assertThat(searchResultPage.getResults()).hasSize(1);
+ assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document1);
+ }
+
+ @Test
+ public void testGetNextPageWithDifferentPackage_query() throws Exception {
+ // Insert package1 schema
+ List<AppSearchSchema> schema1 =
+ ImmutableList.of(new AppSearchSchema.Builder("schema1").build());
+ mAppSearchImpl.setSchema(
+ "package1",
+ "database1",
+ schema1,
+ /*visibilityStore=*/ null,
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+ /*forceOverride=*/ false,
+ /*version=*/ 0);
+
+ // Insert two package1 documents
+ GenericDocument document1 =
+ new GenericDocument.Builder<>("namespace", "id1", "schema1").build();
+ GenericDocument document2 =
+ new GenericDocument.Builder<>("namespace", "id2", "schema1").build();
+ mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
+ mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
+
+ // Query for only 1 result per page
+ SearchSpec searchSpec =
+ new SearchSpec.Builder()
+ .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
+ .setResultCountPerPage(1)
+ .build();
+ SearchResultPage searchResultPage =
+ mAppSearchImpl.query("package1", "database1", "", searchSpec, /*logger=*/ null);
+
+ // Document2 will come first because it was inserted last and default return order is
+ // most recent.
+ assertThat(searchResultPage.getResults()).hasSize(1);
+ assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
+
+ long nextPageToken = searchResultPage.getNextPageToken();
+
+ // Try getting next page with the wrong package, package2
+ AppSearchException e =
+ assertThrows(
+ AppSearchException.class,
+ () -> mAppSearchImpl.getNextPage("package2", nextPageToken));
+ assertThat(e)
+ .hasMessageThat()
+ .contains("Package \"package2\" cannot use nextPageToken: " + nextPageToken);
+ assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_SECURITY_ERROR);
+
+ // Can continue getting next page for package1
+ searchResultPage = mAppSearchImpl.getNextPage("package1", nextPageToken);
+ assertThat(searchResultPage.getResults()).hasSize(1);
+ assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document1);
+ }
+
+ @Test
+ public void testGetNextPageToken_globalQuery() throws Exception {
+ // Insert package1 schema
+ List<AppSearchSchema> schema1 =
+ ImmutableList.of(new AppSearchSchema.Builder("schema1").build());
+ mAppSearchImpl.setSchema(
+ "package1",
+ "database1",
+ schema1,
+ /*visibilityStore=*/ null,
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+ /*forceOverride=*/ false,
+ /*version=*/ 0);
+
+ // Insert two package1 documents
+ GenericDocument document1 =
+ new GenericDocument.Builder<>("namespace", "id1", "schema1").build();
+ GenericDocument document2 =
+ new GenericDocument.Builder<>("namespace", "id2", "schema1").build();
+ mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
+ mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
+
+ // Query for only 1 result per page
+ SearchSpec searchSpec =
+ new SearchSpec.Builder()
+ .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
+ .setResultCountPerPage(1)
+ .build();
+ SearchResultPage searchResultPage =
+ mAppSearchImpl.globalQuery(
+ /*queryExpression=*/ "",
+ searchSpec,
+ "package1",
+ /*visibilityStore=*/ null,
+ Process.myUid(),
+ /*callerHasSystemAccess=*/ false,
+ /*logger=*/ null);
+
+ // Document2 will come first because it was inserted last and default return order is
+ // most recent.
+ assertThat(searchResultPage.getResults()).hasSize(1);
+ assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
+
+ long nextPageToken = searchResultPage.getNextPageToken();
+ searchResultPage = mAppSearchImpl.getNextPage("package1", nextPageToken);
+ assertThat(searchResultPage.getResults()).hasSize(1);
+ assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document1);
+ }
+
+ @Test
+ public void testGetNextPageWithDifferentPackage_globalQuery() throws Exception {
+ // Insert package1 schema
+ List<AppSearchSchema> schema1 =
+ ImmutableList.of(new AppSearchSchema.Builder("schema1").build());
+ mAppSearchImpl.setSchema(
+ "package1",
+ "database1",
+ schema1,
+ /*visibilityStore=*/ null,
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+ /*forceOverride=*/ false,
+ /*version=*/ 0);
+
+ // Insert two package1 documents
+ GenericDocument document1 =
+ new GenericDocument.Builder<>("namespace", "id1", "schema1").build();
+ GenericDocument document2 =
+ new GenericDocument.Builder<>("namespace", "id2", "schema1").build();
+ mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
+ mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
+
+ // Query for only 1 result per page
+ SearchSpec searchSpec =
+ new SearchSpec.Builder()
+ .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
+ .setResultCountPerPage(1)
+ .build();
+ SearchResultPage searchResultPage =
+ mAppSearchImpl.globalQuery(
+ /*queryExpression=*/ "",
+ searchSpec,
+ "package1",
+ /*visibilityStore=*/ null,
+ Process.myUid(),
+ /*callerHasSystemAccess=*/ false,
+ /*logger=*/ null);
+
+ // Document2 will come first because it was inserted last and default return order is
+ // most recent.
+ assertThat(searchResultPage.getResults()).hasSize(1);
+ assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
+
+ long nextPageToken = searchResultPage.getNextPageToken();
+
+ // Try getting next page with the wrong package, package2
+ AppSearchException e =
+ assertThrows(
+ AppSearchException.class,
+ () -> mAppSearchImpl.getNextPage("package2", nextPageToken));
+ assertThat(e)
+ .hasMessageThat()
+ .contains("Package \"package2\" cannot use nextPageToken: " + nextPageToken);
+ assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_SECURITY_ERROR);
+
+ // Can continue getting next page for package1
+ searchResultPage = mAppSearchImpl.getNextPage("package1", nextPageToken);
+ assertThat(searchResultPage.getResults()).hasSize(1);
+ assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document1);
+ }
+
+ @Test
+ public void testInvalidateNextPageToken_query() throws Exception {
+ // Insert package1 schema
+ List<AppSearchSchema> schema1 =
+ ImmutableList.of(new AppSearchSchema.Builder("schema1").build());
+ mAppSearchImpl.setSchema(
+ "package1",
+ "database1",
+ schema1,
+ /*visibilityStore=*/ null,
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+ /*forceOverride=*/ false,
+ /*version=*/ 0);
+
+ // Insert two package1 documents
+ GenericDocument document1 =
+ new GenericDocument.Builder<>("namespace", "id1", "schema1").build();
+ GenericDocument document2 =
+ new GenericDocument.Builder<>("namespace", "id2", "schema1").build();
+ mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
+ mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
+
+ // Query for only 1 result per page
+ SearchSpec searchSpec =
+ new SearchSpec.Builder()
+ .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
+ .setResultCountPerPage(1)
+ .build();
+ SearchResultPage searchResultPage =
+ mAppSearchImpl.query("package1", "database1", "", searchSpec, /*logger=*/ null);
+
+ // Document2 will come first because it was inserted last and default return order is
+ // most recent.
+ assertThat(searchResultPage.getResults()).hasSize(1);
+ assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
+
+ long nextPageToken = searchResultPage.getNextPageToken();
+
+ // Invalidate the token
+ mAppSearchImpl.invalidateNextPageToken("package1", nextPageToken);
+
+ // Can't get next page because we invalidated the token.
+ AppSearchException e =
+ assertThrows(
+ AppSearchException.class,
+ () -> mAppSearchImpl.getNextPage("package1", nextPageToken));
+ assertThat(e)
+ .hasMessageThat()
+ .contains("Package \"package1\" cannot use nextPageToken: " + nextPageToken);
+ assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_SECURITY_ERROR);
+ }
+
+ @Test
+ public void testInvalidateNextPageTokenWithDifferentPackage_query() throws Exception {
+ // Insert package1 schema
+ List<AppSearchSchema> schema1 =
+ ImmutableList.of(new AppSearchSchema.Builder("schema1").build());
+ mAppSearchImpl.setSchema(
+ "package1",
+ "database1",
+ schema1,
+ /*visibilityStore=*/ null,
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+ /*forceOverride=*/ false,
+ /*version=*/ 0);
+
+ // Insert two package1 documents
+ GenericDocument document1 =
+ new GenericDocument.Builder<>("namespace", "id1", "schema1").build();
+ GenericDocument document2 =
+ new GenericDocument.Builder<>("namespace", "id2", "schema1").build();
+ mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
+ mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
+
+ // Query for only 1 result per page
+ SearchSpec searchSpec =
+ new SearchSpec.Builder()
+ .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
+ .setResultCountPerPage(1)
+ .build();
+ SearchResultPage searchResultPage =
+ mAppSearchImpl.query("package1", "database1", "", searchSpec, /*logger=*/ null);
+
+ // Document2 will come first because it was inserted last and default return order is
+ // most recent.
+ assertThat(searchResultPage.getResults()).hasSize(1);
+ assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
+
+ long nextPageToken = searchResultPage.getNextPageToken();
+
+ // Try getting next page with the wrong package, package2
+ AppSearchException e =
+ assertThrows(
+ AppSearchException.class,
+ () -> mAppSearchImpl.invalidateNextPageToken("package2", nextPageToken));
+ assertThat(e)
+ .hasMessageThat()
+ .contains("Package \"package2\" cannot use nextPageToken: " + nextPageToken);
+ assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_SECURITY_ERROR);
+
+ // Can continue getting next page for package1
+ searchResultPage = mAppSearchImpl.getNextPage("package1", nextPageToken);
+ assertThat(searchResultPage.getResults()).hasSize(1);
+ assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document1);
+ }
+
+ @Test
+ public void testInvalidateNextPageToken_globalQuery() throws Exception {
+ // Insert package1 schema
+ List<AppSearchSchema> schema1 =
+ ImmutableList.of(new AppSearchSchema.Builder("schema1").build());
+ mAppSearchImpl.setSchema(
+ "package1",
+ "database1",
+ schema1,
+ /*visibilityStore=*/ null,
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+ /*forceOverride=*/ false,
+ /*version=*/ 0);
+
+ // Insert two package1 documents
+ GenericDocument document1 =
+ new GenericDocument.Builder<>("namespace", "id1", "schema1").build();
+ GenericDocument document2 =
+ new GenericDocument.Builder<>("namespace", "id2", "schema1").build();
+ mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
+ mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
+
+ // Query for only 1 result per page
+ SearchSpec searchSpec =
+ new SearchSpec.Builder()
+ .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
+ .setResultCountPerPage(1)
+ .build();
+ SearchResultPage searchResultPage =
+ mAppSearchImpl.globalQuery(
+ /*queryExpression=*/ "",
+ searchSpec,
+ "package1",
+ /*visibilityStore=*/ null,
+ Process.myUid(),
+ /*callerHasSystemAccess=*/ false,
+ /*logger=*/ null);
+
+ // Document2 will come first because it was inserted last and default return order is
+ // most recent.
+ assertThat(searchResultPage.getResults()).hasSize(1);
+ assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
+
+ long nextPageToken = searchResultPage.getNextPageToken();
+
+ // Invalidate the token
+ mAppSearchImpl.invalidateNextPageToken("package1", nextPageToken);
+
+ // Can't get next page because we invalidated the token.
+ AppSearchException e =
+ assertThrows(
+ AppSearchException.class,
+ () -> mAppSearchImpl.getNextPage("package1", nextPageToken));
+ assertThat(e)
+ .hasMessageThat()
+ .contains("Package \"package1\" cannot use nextPageToken: " + nextPageToken);
+ assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_SECURITY_ERROR);
+ }
+
+ @Test
+ public void testInvalidateNextPageTokenWithDifferentPackage_globalQuery() throws Exception {
+ // Insert package1 schema
+ List<AppSearchSchema> schema1 =
+ ImmutableList.of(new AppSearchSchema.Builder("schema1").build());
+ mAppSearchImpl.setSchema(
+ "package1",
+ "database1",
+ schema1,
+ /*visibilityStore=*/ null,
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+ /*forceOverride=*/ false,
+ /*version=*/ 0);
+
+ // Insert two package1 documents
+ GenericDocument document1 =
+ new GenericDocument.Builder<>("namespace", "id1", "schema1").build();
+ GenericDocument document2 =
+ new GenericDocument.Builder<>("namespace", "id2", "schema1").build();
+ mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
+ mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
+
+ // Query for only 1 result per page
+ SearchSpec searchSpec =
+ new SearchSpec.Builder()
+ .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
+ .setResultCountPerPage(1)
+ .build();
+ SearchResultPage searchResultPage =
+ mAppSearchImpl.globalQuery(
+ /*queryExpression=*/ "",
+ searchSpec,
+ "package1",
+ /*visibilityStore=*/ null,
+ Process.myUid(),
+ /*callerHasSystemAccess=*/ false,
+ /*logger=*/ null);
+
+ // Document2 will come first because it was inserted last and default return order is
+ // most recent.
+ assertThat(searchResultPage.getResults()).hasSize(1);
+ assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
+
+ long nextPageToken = searchResultPage.getNextPageToken();
+
+ // Try getting next page with the wrong package, package2
+ AppSearchException e =
+ assertThrows(
+ AppSearchException.class,
+ () -> mAppSearchImpl.invalidateNextPageToken("package2", nextPageToken));
+ assertThat(e)
+ .hasMessageThat()
+ .contains("Package \"package2\" cannot use nextPageToken: " + nextPageToken);
+ assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_SECURITY_ERROR);
+
+ // Can continue getting next page for package1
+ searchResultPage = mAppSearchImpl.getNextPage("package1", nextPageToken);
+ assertThat(searchResultPage.getResults()).hasSize(1);
+ assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document1);
+ }
+
+ @Test
public void testRemoveEmptyDatabase_noExceptionThrown() throws Exception {
SearchSpec searchSpec =
new SearchSpec.Builder()
@@ -1777,11 +2217,11 @@ public class AppSearchImplTest {
assertThrows(
IllegalStateException.class,
- () -> appSearchImpl.getNextPage(/*nextPageToken=*/ 1L));
+ () -> appSearchImpl.getNextPage("package", /*nextPageToken=*/ 1L));
assertThrows(
IllegalStateException.class,
- () -> appSearchImpl.invalidateNextPageToken(/*nextPageToken=*/ 1L));
+ () -> appSearchImpl.invalidateNextPageToken("package", /*nextPageToken=*/ 1L));
assertThrows(
IllegalStateException.class,
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
index 29f4aa976ef6..22fb76b1fbe5 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -198,6 +198,7 @@ public class PackageManagerSettingsTests {
new WatchableTester(settingsUnderTest, "noSuspendingPackage");
watcher.register();
settingsUnderTest.mPackages.put(PACKAGE_NAME_1, createPackageSetting(PACKAGE_NAME_1));
+ settingsUnderTest.readPackageRestrictionsLPr(0);
watcher.verifyChangeReported("put package 1");
// Collect a snapshot at the midway point (package 2 has not been added)
final Settings snapshot = settingsUnderTest.snapshot();
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
index 1596483cdbe1..2e5c24c1a95c 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
@@ -246,6 +246,81 @@ public class VibrationThreadTest {
}
@Test
+ public void vibrate_singleVibratorRepeatingShortAlwaysOnWaveform_turnsVibratorOnForASecond()
+ throws Exception {
+ FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
+ fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+
+ long vibrationId = 1;
+ int[] amplitudes = new int[]{1, 2, 3};
+ VibrationEffect effect = VibrationEffect.createWaveform(
+ new long[]{1, 10, 100}, amplitudes, 0);
+ VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+
+ assertTrue(waitUntil(t -> !fakeVibrator.getAmplitudes().isEmpty(), thread,
+ TEST_TIMEOUT_MILLIS));
+ thread.cancel();
+ waitForCompletion(thread);
+
+ verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
+ assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+ assertEquals(Arrays.asList(expectedOneShot(1000)), fakeVibrator.getEffectSegments());
+ }
+
+ @Test
+ public void vibrate_singleVibratorRepeatingLongAlwaysOnWaveform_turnsVibratorOnForACycle()
+ throws Exception {
+ FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
+ fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+
+ long vibrationId = 1;
+ int[] amplitudes = new int[]{1, 2, 3};
+ VibrationEffect effect = VibrationEffect.createWaveform(
+ new long[]{5000, 500, 50}, amplitudes, 0);
+ VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+
+ assertTrue(waitUntil(t -> !fakeVibrator.getAmplitudes().isEmpty(), thread,
+ TEST_TIMEOUT_MILLIS));
+ thread.cancel();
+ waitForCompletion(thread);
+
+ verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
+ assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+ assertEquals(Arrays.asList(expectedOneShot(5550)), fakeVibrator.getEffectSegments());
+ }
+
+
+ @Test
+ public void vibrate_singleVibratorRepeatingAlwaysOnWaveform_turnsVibratorBackOn()
+ throws Exception {
+ FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
+ fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+
+ long vibrationId = 1;
+ int[] amplitudes = new int[]{1, 2};
+ VibrationEffect effect = VibrationEffect.createWaveform(
+ new long[]{900, 50}, amplitudes, 0);
+ VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+
+ assertTrue(waitUntil(t -> fakeVibrator.getAmplitudes().size() > 2 * amplitudes.length,
+ thread, 1000 + TEST_TIMEOUT_MILLIS));
+ thread.cancel();
+ waitForCompletion(thread);
+
+ verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
+ assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+ assertEquals(2, fakeVibrator.getEffectSegments().size());
+ // First time turn vibrator ON for minimum of 1s.
+ assertEquals(1000L, fakeVibrator.getEffectSegments().get(0).getDuration());
+ // Vibrator turns off in the middle of the second execution of first step, turn it back ON
+ // for another 1s + remaining of 850ms.
+ assertEquals(1850, fakeVibrator.getEffectSegments().get(1).getDuration(), /* delta= */ 20);
+ // Set amplitudes for a cycle {1, 2}, start second loop then turn it back on to same value.
+ assertEquals(expectedAmplitudes(1, 2, 1, 1),
+ mVibratorProviders.get(VIBRATOR_ID).getAmplitudes().subList(0, 4));
+ }
+
+ @Test
public void vibrate_singleVibratorPredefinedCancel_cancelsVibrationImmediately()
throws Exception {
mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
index d0bf63a1680f..733d3f0f66ef 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
@@ -281,6 +281,34 @@ public class ZenModeConfigTest extends UiServiceTestCase {
assertNull(fromXml.pkg);
}
+ @Test
+ public void testRuleXml_getPkg_nullPkg() throws Exception {
+ String tag = "tag";
+
+ ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
+ rule.enabled = true;
+ rule.configurationActivity = new ComponentName("a", "a");
+
+ TypedXmlSerializer out = Xml.newFastSerializer();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ out.setOutput(new BufferedOutputStream(baos), "utf-8");
+ out.startDocument(null, true);
+ out.startTag(null, tag);
+ ZenModeConfig.writeRuleXml(rule, out);
+ out.endTag(null, tag);
+ out.endDocument();
+
+ TypedXmlPullParser parser = Xml.newFastPullParser();
+ parser.setInput(new BufferedInputStream(
+ new ByteArrayInputStream(baos.toByteArray())), null);
+ parser.nextTag();
+ ZenModeConfig.ZenRule fromXml = ZenModeConfig.readRuleXml(parser);
+ assertEquals("a", fromXml.getPkg());
+
+ fromXml.condition = new Condition(Uri.EMPTY, "", Condition.STATE_TRUE);
+ assertTrue(fromXml.isAutomaticActive());
+ }
+
private ZenModeConfig getMutedRingerConfig() {
ZenModeConfig config = new ZenModeConfig();
// Allow alarms, media
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index 00dbaf649ca2..4410404b0cd7 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -33,6 +33,7 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCRE
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+import static android.service.notification.Condition.STATE_TRUE;
import static android.util.StatsLog.ANNOTATION_ID_IS_UID;
import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE;
@@ -49,6 +50,7 @@ import static junit.framework.TestCase.assertTrue;
import static junit.framework.TestCase.fail;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -64,6 +66,8 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.AutomaticZenRule;
@@ -72,7 +76,9 @@ import android.app.NotificationManager.Policy;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.media.AudioAttributes;
@@ -81,6 +87,7 @@ import android.media.AudioManagerInternal;
import android.media.AudioSystem;
import android.media.VolumePolicy;
import android.net.Uri;
+import android.os.Binder;
import android.os.Process;
import android.os.UserHandle;
import android.provider.Settings;
@@ -105,6 +112,8 @@ import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.server.UiServiceTestCase;
import com.android.server.notification.ManagedServices.UserProfiles;
+import com.google.common.collect.ImmutableList;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -172,8 +181,14 @@ public class ZenModeHelperTest extends UiServiceTestCase {
mZenModeHelperSpy = spy(new ZenModeHelper(mContext, mTestableLooper.getLooper(),
mConditionProviders, mStatsEventBuilderFactory));
+ ResolveInfo ri = new ResolveInfo();
+ ri.activityInfo = new ActivityInfo();
+ when(mPackageManager.queryIntentActivitiesAsUser(any(), anyInt(), anyInt())).thenReturn(
+ ImmutableList.of(ri));
when(mPackageManager.getPackageUidAsUser(eq(CUSTOM_PKG_NAME), anyInt()))
.thenReturn(CUSTOM_PKG_UID);
+ when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(
+ new String[] {getContext().getPackageName()});
mZenModeHelperSpy.mPm = mPackageManager;
}
@@ -1486,7 +1501,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
mZenModeHelperSpy.mConfig.manualRule.component = new ComponentName("android",
CountdownConditionProvider.class.getName());
mZenModeHelperSpy.mConfig.manualRule.condition = new Condition(conditionId, "", "", "", 0,
- Condition.STATE_TRUE, Condition.FLAG_RELEVANT_NOW);
+ STATE_TRUE, Condition.FLAG_RELEVANT_NOW);
mZenModeHelperSpy.mConfig.manualRule.enabled = true;
ZenModeConfig originalConfig = mZenModeHelperSpy.mConfig.copy();
@@ -1592,10 +1607,12 @@ public class ZenModeHelperTest extends UiServiceTestCase {
}
@Test
- public void testAddAutomaticZenRule() {
+ public void testAddAutomaticZenRule_CA() {
AutomaticZenRule zenRule = new AutomaticZenRule("name",
+ null,
new ComponentName("android", "ScheduleConditionProvider"),
ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+ new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
String id = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule, "test");
@@ -1608,6 +1625,107 @@ public class ZenModeHelperTest extends UiServiceTestCase {
assertEquals(NotificationManager.zenModeFromInterruptionFilter(
zenRule.getInterruptionFilter(), -1), ruleInConfig.zenMode);
assertEquals(zenRule.getName(), ruleInConfig.name);
+ assertEquals("android", ruleInConfig.pkg);
+ }
+
+ @Test
+ public void testAddAutomaticZenRule_CPS() {
+ AutomaticZenRule zenRule = new AutomaticZenRule("name",
+ new ComponentName("android", "ScheduleConditionProvider"),
+ ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+ String id = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule, "test");
+
+ assertTrue(id != null);
+ ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id);
+ assertTrue(ruleInConfig != null);
+ assertEquals(zenRule.isEnabled(), ruleInConfig.enabled);
+ assertEquals(zenRule.isModified(), ruleInConfig.modified);
+ assertEquals(zenRule.getConditionId(), ruleInConfig.conditionId);
+ assertEquals(NotificationManager.zenModeFromInterruptionFilter(
+ zenRule.getInterruptionFilter(), -1), ruleInConfig.zenMode);
+ assertEquals(zenRule.getName(), ruleInConfig.name);
+ assertEquals("android", ruleInConfig.pkg);
+ }
+
+ @Test
+ public void testSetAutomaticZenRuleState_nullPkg() {
+ AutomaticZenRule zenRule = new AutomaticZenRule("name",
+ null,
+ new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"),
+ ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+ new ZenPolicy.Builder().build(),
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+
+ String id = mZenModeHelperSpy.addAutomaticZenRule(null, zenRule, "test");
+ mZenModeHelperSpy.setAutomaticZenRuleState(zenRule.getConditionId(),
+ new Condition(zenRule.getConditionId(), "", STATE_TRUE));
+
+ ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id);
+ assertEquals(STATE_TRUE, ruleInConfig.condition.state);
+ }
+
+ @Test
+ public void testUpdateAutomaticZenRule_nullPkg() {
+ AutomaticZenRule zenRule = new AutomaticZenRule("name",
+ null,
+ new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"),
+ ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+ new ZenPolicy.Builder().build(),
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+
+ String id = mZenModeHelperSpy.addAutomaticZenRule(null, zenRule, "test");
+
+ AutomaticZenRule zenRule2 = new AutomaticZenRule("NEW",
+ null,
+ new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"),
+ ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+ new ZenPolicy.Builder().build(),
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+
+ mZenModeHelperSpy.updateAutomaticZenRule(id, zenRule2, "");
+
+ ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id);
+ assertEquals("NEW", ruleInConfig.name);
+ }
+
+ @Test
+ public void testRemoveAutomaticZenRule_nullPkg() {
+ AutomaticZenRule zenRule = new AutomaticZenRule("name",
+ null,
+ new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"),
+ ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+ new ZenPolicy.Builder().build(),
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+
+ String id = mZenModeHelperSpy.addAutomaticZenRule(null, zenRule, "test");
+
+ assertTrue(id != null);
+ ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id);
+ assertTrue(ruleInConfig != null);
+ assertEquals(zenRule.getName(), ruleInConfig.name);
+
+ mZenModeHelperSpy.removeAutomaticZenRule(id, "test");
+ assertNull(mZenModeHelperSpy.mConfig.automaticRules.get(id));
+ }
+
+ @Test
+ public void testRemoveAutomaticZenRules_nullPkg() {
+ AutomaticZenRule zenRule = new AutomaticZenRule("name",
+ null,
+ new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"),
+ ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+ new ZenPolicy.Builder().build(),
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+ String id = mZenModeHelperSpy.addAutomaticZenRule(null, zenRule, "test");
+
+ assertTrue(id != null);
+ ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id);
+ assertTrue(ruleInConfig != null);
+ assertEquals(zenRule.getName(), ruleInConfig.name);
+
+ mZenModeHelperSpy.removeAutomaticZenRules(mContext.getPackageName(), "test");
+ assertNull(mZenModeHelperSpy.mConfig.automaticRules.get(id));
}
@Test
@@ -1624,17 +1742,17 @@ public class ZenModeHelperTest extends UiServiceTestCase {
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
String id2 = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule2, "test");
- Condition condition = new Condition(sharedUri, "", Condition.STATE_TRUE);
+ Condition condition = new Condition(sharedUri, "", STATE_TRUE);
mZenModeHelperSpy.setAutomaticZenRuleState(sharedUri, condition);
for (ZenModeConfig.ZenRule rule : mZenModeHelperSpy.mConfig.automaticRules.values()) {
if (rule.id.equals(id)) {
assertNotNull(rule.condition);
- assertTrue(rule.condition.state == Condition.STATE_TRUE);
+ assertTrue(rule.condition.state == STATE_TRUE);
}
if (rule.id.equals(id2)) {
assertNotNull(rule.condition);
- assertTrue(rule.condition.state == Condition.STATE_TRUE);
+ assertTrue(rule.condition.state == STATE_TRUE);
}
}