summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java30
-rw-r--r--apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java2
-rw-r--r--api/current.txt5
-rw-r--r--api/system-current.txt14
-rw-r--r--api/test-current.txt3
-rw-r--r--cmds/statsd/Android.bp20
-rw-r--r--cmds/statsd/src/anomaly/AnomalyTracker.cpp3
-rw-r--r--cmds/statsd/src/atoms.proto27
-rw-r--r--cmds/statsd/src/condition/StateConditionTracker.cpp (renamed from cmds/statsd/src/condition/StateTracker.cpp)24
-rw-r--r--cmds/statsd/src/condition/StateConditionTracker.h (renamed from cmds/statsd/src/condition/StateTracker.h)12
-rw-r--r--cmds/statsd/src/metrics/metrics_manager_util.cpp16
-rw-r--r--cmds/statsd/src/metrics/metrics_manager_util.h2
-rw-r--r--cmds/statsd/tests/condition/StateConditionTracker_test.cpp (renamed from cmds/statsd/tests/condition/StateTracker_test.cpp)6
-rw-r--r--core/java/android/app/ActivityManagerInternal.java37
-rw-r--r--core/java/android/app/ActivityTaskManager.java24
-rw-r--r--core/java/android/app/IActivityManager.aidl17
-rw-r--r--core/java/android/app/IActivityTaskManager.aidl12
-rw-r--r--core/java/android/app/Notification.java24
-rw-r--r--core/java/android/app/NotificationChannel.java8
-rw-r--r--core/java/android/content/Intent.java4
-rw-r--r--core/java/android/content/res/Configuration.java10
-rw-r--r--core/java/android/os/UserHandle.java11
-rw-r--r--core/java/android/os/UserManager.java116
-rw-r--r--core/java/android/os/UserManagerInternal.java2
-rw-r--r--core/java/android/service/notification/StatusBarNotification.java3
-rw-r--r--core/java/android/service/notification/ZenModeConfig.java2
-rw-r--r--core/java/android/view/DisplayInfo.java2
-rw-r--r--core/java/android/view/SurfaceControl.java26
-rw-r--r--core/java/android/view/ViewRootImpl.java23
-rw-r--r--core/java/android/view/WindowManager.java2
-rw-r--r--core/java/com/android/internal/app/ChooserActivity.java6
-rw-r--r--core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java11
-rw-r--r--core/java/com/android/internal/util/ScreenshotHelper.java77
-rw-r--r--core/jni/android_util_Process.cpp16
-rw-r--r--core/jni/android_view_SurfaceControl.cpp11
-rw-r--r--core/proto/android/view/displayinfo.proto1
-rw-r--r--core/res/res/values-en-rCA/strings.xml8
-rw-r--r--core/res/res/values-en-rXC/strings.xml8
-rw-r--r--core/tests/coretests/src/android/os/ProcessTest.java31
-rw-r--r--core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java18
-rw-r--r--core/tests/screenshothelpertests/Android.bp28
-rw-r--r--core/tests/screenshothelpertests/AndroidManifest.xml32
-rw-r--r--core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java98
-rw-r--r--libs/hwui/service/GraphicsStatsService.cpp6
-rw-r--r--libs/protoutil/include/android/util/ProtoOutputStream.h1
-rw-r--r--libs/protoutil/src/ProtoOutputStream.cpp28
-rw-r--r--packages/BackupEncryption/Android.bp24
-rw-r--r--packages/BackupEncryption/AndroidManifest.xml24
-rw-r--r--packages/BackupEncryption/proguard.flags1
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/Chunk.java (renamed from services/backup/java/com/android/server/backup/encryption/chunk/Chunk.java)18
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/ChunkHash.java (renamed from services/backup/java/com/android/server/backup/encryption/chunk/ChunkHash.java)3
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/ChunkListingMap.java (renamed from services/backup/java/com/android/server/backup/encryption/chunk/ChunkListingMap.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/ChunkOrderingType.java (renamed from services/backup/java/com/android/server/backup/encryption/chunk/ChunkOrderingType.java)3
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrdering.java (renamed from services/backup/java/com/android/server/backup/encryption/chunk/EncryptedChunkOrdering.java)3
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/BackupWriter.java (renamed from services/backup/java/com/android/server/backup/encryption/chunking/BackupWriter.java)2
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ByteRange.java (renamed from services/backup/java/com/android/server/backup/encryption/chunking/ByteRange.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ChunkEncryptor.java (renamed from services/backup/java/com/android/server/backup/encryption/chunking/ChunkEncryptor.java)4
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ChunkHasher.java (renamed from services/backup/java/com/android/server/backup/encryption/chunking/ChunkHasher.java)4
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/Chunker.java (renamed from services/backup/java/com/android/server/backup/encryption/chunking/Chunker.java)2
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutput.java (renamed from services/backup/java/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutput.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriter.java (renamed from services/backup/java/com/android/server/backup/encryption/chunking/DiffScriptBackupWriter.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/DiffScriptWriter.java (renamed from services/backup/java/com/android/server/backup/encryption/chunking/DiffScriptWriter.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/EncryptedChunk.java (renamed from services/backup/java/com/android/server/backup/encryption/chunking/EncryptedChunk.java)3
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/EncryptedChunkEncoder.java (renamed from services/backup/java/com/android/server/backup/encryption/chunking/EncryptedChunkEncoder.java)3
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoder.java (renamed from services/backup/java/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoder.java)3
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoder.java (renamed from services/backup/java/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoder.java)3
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/OutputStreamWrapper.java (renamed from services/backup/java/com/android/server/backup/encryption/chunking/OutputStreamWrapper.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/RawBackupWriter.java (renamed from services/backup/java/com/android/server/backup/encryption/chunking/RawBackupWriter.java)16
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriter.java (renamed from services/backup/java/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriter.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunker.java (renamed from services/backup/java/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunker.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/FingerprintMixer.java (renamed from services/backup/java/com/android/server/backup/encryption/chunking/cdc/FingerprintMixer.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/Hkdf.java (renamed from services/backup/java/com/android/server/backup/encryption/chunking/cdc/Hkdf.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpoint.java (renamed from services/backup/java/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpoint.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64.java (renamed from services/backup/java/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKey.java (renamed from services/backup/java/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKey.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManager.java (renamed from services/backup/java/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManager.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyGenerator.java (renamed from services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyGenerator.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTracker.java (renamed from services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyRotationTracker.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/storage/BackupEncryptionDb.java (renamed from services/backup/java/com/android/server/backup/encryption/storage/BackupEncryptionDb.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/storage/BackupEncryptionDbContract.java (renamed from services/backup/java/com/android/server/backup/encryption/storage/BackupEncryptionDbContract.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/storage/BackupEncryptionDbHelper.java (renamed from services/backup/java/com/android/server/backup/encryption/storage/BackupEncryptionDbHelper.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/storage/EncryptionDbException.java (renamed from services/backup/java/com/android/server/backup/encryption/storage/EncryptionDbException.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/storage/TertiaryKey.java (renamed from services/backup/java/com/android/server/backup/encryption/storage/TertiaryKey.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/storage/TertiaryKeysTable.java (renamed from services/backup/java/com/android/server/backup/encryption/storage/TertiaryKeysTable.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/BackupEncrypter.java (renamed from services/backup/java/com/android/server/backup/encryption/tasks/BackupEncrypter.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/BackupStreamEncrypter.java (renamed from services/backup/java/com/android/server/backup/encryption/tasks/BackupStreamEncrypter.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/DecryptedChunkOutput.java (renamed from services/backup/java/com/android/server/backup/encryption/tasks/DecryptedChunkOutput.java)0
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedRestoreException.java (renamed from services/backup/java/com/android/server/backup/encryption/tasks/EncryptedRestoreException.java)0
-rw-r--r--packages/BackupEncryption/test/robolectric/Android.bp32
-rw-r--r--packages/BackupEncryption/test/robolectric/AndroidManifest.xml24
-rw-r--r--packages/BackupEncryption/test/robolectric/config/robolectric.properties17
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/ChunkHashTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/chunk/ChunkHashTest.java)2
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/ChunkListingMapTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/chunk/ChunkListingMapTest.java)0
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/ChunkTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/chunk/ChunkTest.java)2
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrderingTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrderingTest.java)2
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ByteRangeTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/chunking/ByteRangeTest.java)0
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ChunkEncryptorTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/chunking/ChunkEncryptorTest.java)34
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ChunkHasherTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/chunking/ChunkHasherTest.java)2
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutputTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutputTest.java)0
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriterTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriterTest.java)0
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/EncryptedChunkTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/chunking/EncryptedChunkTest.java)2
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoderTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoderTest.java)2
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoderTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoderTest.java)2
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/RawBackupWriterTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/chunking/RawBackupWriterTest.java)2
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriterTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriterTest.java)0
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunkerTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunkerTest.java)0
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/FingerprintMixerTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/chunking/cdc/FingerprintMixerTest.java)0
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/HkdfTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/chunking/cdc/HkdfTest.java)0
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpointTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpointTest.java)0
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64Test.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64Test.java)0
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManagerTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManagerTest.java)0
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyTest.java)0
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyGeneratorTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/keys/TertiaryKeyGeneratorTest.java)0
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTrackerTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTrackerTest.java)0
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/storage/BackupEncryptionDbTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/storage/BackupEncryptionDbTest.java)0
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/storage/TertiaryKeysTableTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/storage/TertiaryKeysTableTest.java)0
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/BackupStreamEncrypterTest.java (renamed from services/robotests/backup/src/com/android/server/backup/encryption/tasks/BackupStreamEncrypterTest.java)0
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/testing/RandomInputStream.java (renamed from services/robotests/backup/src/com/android/server/backup/testing/RandomInputStream.java)0
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/testing/CryptoTestUtils.java (renamed from services/robotests/backup/src/com/android/server/backup/testing/CryptoTestUtils.java)2
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowInternalRecoveryServiceException.java (renamed from services/robotests/src/com/android/server/testing/shadows/ShadowInternalRecoveryServiceException.java)0
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowRecoveryController.java (renamed from services/robotests/src/com/android/server/testing/shadows/ShadowRecoveryController.java)0
-rw-r--r--packages/CarSystemUI/res/values/integers_car.xml2
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/CarSystemUIRootComponent.java1
-rw-r--r--packages/SettingsLib/res/values-te/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-uz/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/strings.xml2
-rw-r--r--packages/Shell/res/values-zh-rTW/strings.xml12
-rw-r--r--packages/SystemUI/docs/plugin_hooks.md5
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/NPVPlugin.java52
-rw-r--r--packages/SystemUI/res/layout/auth_biometric_contents.xml2
-rw-r--r--packages/SystemUI/res/layout/status_bar_expanded.xml2
-rw-r--r--packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml29
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml2
-rw-r--r--packages/SystemUI/res/values-en-rXC/strings.xml2
-rw-r--r--packages/SystemUI/src/com/android/systemui/ContextComponentHelper.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/ContextComponentResolver.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/CornerHandleView.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUI.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIApplication.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIBinder.java36
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistManager.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java114
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java41
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java155
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java54
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java108
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/QSSettingsController.kt36
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NPVPluginManager.kt92
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java69
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceViewTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java96
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/RankingBuilder.java105
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java3
-rw-r--r--packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-ru/strings.xml2
-rw-r--r--packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-ru/strings.xml2
-rw-r--r--packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-ru/strings.xml2
-rw-r--r--services/accessibility/java/com/android/server/accessibility/GlobalActionPerformer.java5
-rw-r--r--services/core/java/com/android/server/PackageWatchdog.java22
-rw-r--r--services/core/java/com/android/server/SystemService.java10
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java40
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java34
-rw-r--r--services/core/java/com/android/server/am/UserController.java89
-rw-r--r--services/core/java/com/android/server/camera/CameraServiceProxy.java59
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java25
-rw-r--r--services/core/java/com/android/server/notification/ZenLog.java1
-rw-r--r--services/core/java/com/android/server/notification/ZenModeHelper.java5
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java37
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerShellCommand.java156
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java351
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java45
-rw-r--r--services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java11
-rw-r--r--services/core/java/com/android/server/webkit/WebViewUpdater.java13
-rw-r--r--services/core/java/com/android/server/wm/ActivityStack.java83
-rw-r--r--services/core/java/com/android/server/wm/ActivityStackSupervisor.java32
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java7
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java50
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java3
-rw-r--r--services/core/java/com/android/server/wm/LaunchParamsController.java2
-rw-r--r--services/core/java/com/android/server/wm/RootActivityContainer.java54
-rw-r--r--services/core/java/com/android/server/wm/RunningTasks.java4
-rw-r--r--services/core/java/com/android/server/wm/TaskRecord.java51
-rw-r--r--services/core/java/com/android/server/wm/TaskStack.java14
-rw-r--r--services/core/java/com/android/server/wm/WindowProcessController.java10
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java2
-rw-r--r--services/core/java/com/android/server/wm/WindowSurfaceController.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/GlobalActionPerformerTest.java4
-rw-r--r--services/tests/uiservicestests/AndroidManifest.xml1
-rw-r--r--services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java7
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java292
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/StubTransaction.java5
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java90
-rw-r--r--services/usage/java/com/android/server/usage/UserUsageStatsService.java59
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java30
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java2
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java14
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java14
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java2
-rw-r--r--startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java47
-rw-r--r--startop/view_compiler/dex_builder_test/Android.bp12
-rw-r--r--startop/view_compiler/dex_builder_test/src/android/startop/test/ApkLayoutCompilerTest.java57
-rw-r--r--startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java5
-rw-r--r--startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java6
-rw-r--r--telephony/java/android/provider/Telephony.java22
-rw-r--r--telephony/java/android/telephony/SmsCbMessage.java45
-rw-r--r--telephony/java/android/telephony/ims/feature/ImsFeature.java13
-rw-r--r--telephony/java/android/telephony/ims/feature/MmTelFeature.java4
-rw-r--r--telephony/java/com/android/internal/telephony/CbGeoUtils.java3
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java32
-rw-r--r--tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java338
-rw-r--r--tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java14
-rw-r--r--wifi/java/android/net/wifi/WifiEnterpriseConfig.java73
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java18
-rw-r--r--wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java34
249 files changed, 3241 insertions, 1785 deletions
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
index 4b7a7f624a3e..32107b4e789e 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
@@ -119,9 +119,20 @@ public class UserLifecycleTests {
}
@Test
+ public void createUser() {
+ while (mRunner.keepRunning()) {
+ final int userId = createUserNoFlags();
+
+ mRunner.pauseTiming();
+ removeUser(userId);
+ mRunner.resumeTiming();
+ }
+ }
+
+ @Test
public void createAndStartUser() throws Exception {
while (mRunner.keepRunning()) {
- final int userId = createUser();
+ final int userId = createUserNoFlags();
final CountDownLatch latch = new CountDownLatch(1);
registerBroadcastReceiver(Intent.ACTION_USER_STARTED, latch, userId);
@@ -140,7 +151,7 @@ public class UserLifecycleTests {
while (mRunner.keepRunning()) {
mRunner.pauseTiming();
final int startUser = mAm.getCurrentUser();
- final int userId = createUser();
+ final int userId = createUserNoFlags();
mRunner.resumeTiming();
switchUser(userId);
@@ -197,7 +208,7 @@ public class UserLifecycleTests {
public void stopUser() throws Exception {
while (mRunner.keepRunning()) {
mRunner.pauseTiming();
- final int userId = createUser();
+ final int userId = createUserNoFlags();
final CountDownLatch latch = new CountDownLatch(1);
registerBroadcastReceiver(Intent.ACTION_USER_STARTED, latch, userId);
mIam.startUserInBackground(userId);
@@ -217,7 +228,7 @@ public class UserLifecycleTests {
while (mRunner.keepRunning()) {
mRunner.pauseTiming();
final int startUser = mAm.getCurrentUser();
- final int userId = createUser();
+ final int userId = createUserNoFlags();
final CountDownLatch latch = new CountDownLatch(1);
registerUserSwitchObserver(null, latch, userId);
mRunner.resumeTiming();
@@ -237,7 +248,7 @@ public class UserLifecycleTests {
while (mRunner.keepRunning()) {
mRunner.pauseTiming();
final int startUser = mAm.getCurrentUser();
- final int userId = createUser(UserInfo.FLAG_EPHEMERAL | UserInfo.FLAG_DEMO);
+ final int userId = createUserWithFlags(UserInfo.FLAG_EPHEMERAL | UserInfo.FLAG_DEMO);
switchUser(userId);
final CountDownLatch latch = new CountDownLatch(1);
InstrumentationRegistry.getContext().registerReceiver(new BroadcastReceiver() {
@@ -396,7 +407,6 @@ public class UserLifecycleTests {
public void managedProfileCreateUnlockInstallAndLaunchApp() throws Exception {
assumeTrue(mHasManagedUserFeature);
- final String packageName = "perftests.multiuser.apps.dummyapp";
while (mRunner.keepRunning()) {
mRunner.pauseTiming();
WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null);
@@ -433,12 +443,12 @@ public class UserLifecycleTests {
}
/** Creates a new user, returning its userId. */
- private int createUser() {
- return createUser(0);
+ private int createUserNoFlags() {
+ return createUserWithFlags(/* flags= */ 0);
}
/** Creates a new user with the given flags, returning its userId. */
- private int createUser(int flags) {
+ private int createUserWithFlags(int flags) {
int userId = mUm.createUser("TestUser", flags).id;
mUsersToRemove.add(userId);
return userId;
@@ -501,7 +511,7 @@ public class UserLifecycleTests {
private int initializeNewUserAndSwitchBack(boolean stopNewUser) throws Exception {
final int origUser = mAm.getCurrentUser();
// First, create and switch to testUser, waiting for its ACTION_USER_UNLOCKED
- final int testUser = createUser();
+ final int testUser = createUserNoFlags();
final CountDownLatch latch1 = new CountDownLatch(1);
registerBroadcastReceiver(Intent.ACTION_USER_UNLOCKED, latch1, testUser);
mAm.switchUser(testUser);
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index d0e38b4a4e36..65aaf20ecacb 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -67,6 +67,7 @@ import android.os.UserHandle;
import android.provider.Settings;
import android.util.ArrayMap;
import android.util.ArraySet;
+import android.util.AtomicFile;
import android.util.KeyValueListParser;
import android.util.MutableLong;
import android.util.Pair;
@@ -79,7 +80,6 @@ import android.util.Xml;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
-import com.android.internal.os.AtomicFile;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
diff --git a/api/current.txt b/api/current.txt
index 359ce3aa4373..26c90dff3c6b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5320,10 +5320,12 @@ package android.app {
ctor public Notification(android.os.Parcel);
method public android.app.Notification clone();
method public int describeContents();
+ method @Nullable public android.util.Pair<android.app.RemoteInput,android.app.Notification.Action> findRemoteInputActionPair(boolean);
method public boolean getAllowSystemGeneratedContextualActions();
method public int getBadgeIconType();
method @Nullable public android.app.Notification.BubbleMetadata getBubbleMetadata();
method public String getChannelId();
+ method @NonNull public java.util.List<android.app.Notification.Action> getContextualActions();
method public String getGroup();
method public int getGroupAlertBehavior();
method public android.graphics.drawable.Icon getLargeIcon();
@@ -5719,6 +5721,7 @@ package android.app {
method public String getDataMimeType();
method public android.net.Uri getDataUri();
method public android.os.Bundle getExtras();
+ method @NonNull public static java.util.List<android.app.Notification.MessagingStyle.Message> getMessagesFromBundleArray(@Nullable android.os.Parcelable[]);
method @Deprecated public CharSequence getSender();
method @Nullable public android.app.Person getSenderPerson();
method public CharSequence getText();
@@ -5816,6 +5819,7 @@ package android.app {
method public android.net.Uri getSound();
method public long[] getVibrationPattern();
method public boolean hasUserSetImportance();
+ method public boolean hasUserSetSound();
method public void setAllowBubbles(boolean);
method public void setBypassDnd(boolean);
method public void setDescription(String);
@@ -41736,6 +41740,7 @@ package android.service.notification {
method public int getUid();
method public android.os.UserHandle getUser();
method @Deprecated public int getUserId();
+ method public boolean isAppGroup();
method public boolean isClearable();
method public boolean isGroup();
method public boolean isOngoing();
diff --git a/api/system-current.txt b/api/system-current.txt
index 1c5f772f2e1b..2843916c25b7 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -521,8 +521,6 @@ package android.app {
}
public class Notification implements android.os.Parcelable {
- method @Nullable public android.util.Pair<android.app.RemoteInput,android.app.Notification.Action> findRemoteInputActionPair(boolean);
- method @NonNull public java.util.List<android.app.Notification.Action> getContextualActions();
field public static final String CATEGORY_CAR_EMERGENCY = "car_emergency";
field public static final String CATEGORY_CAR_INFORMATION = "car_information";
field public static final String CATEGORY_CAR_WARNING = "car_warning";
@@ -531,10 +529,6 @@ package android.app {
field public static final int FLAG_AUTOGROUP_SUMMARY = 1024; // 0x400
}
- public static final class Notification.MessagingStyle.Message {
- method @Nullable public static android.app.Notification.MessagingStyle.Message getMessageFromBundle(@NonNull android.os.Bundle);
- }
-
public static final class Notification.TvExtender implements android.app.Notification.Extender {
ctor public Notification.TvExtender();
ctor public Notification.TvExtender(android.app.Notification);
@@ -6710,10 +6704,6 @@ package android.service.notification {
field @NonNull public static final android.os.Parcelable.Creator<android.service.notification.SnoozeCriterion> CREATOR;
}
- public class StatusBarNotification implements android.os.Parcelable {
- method public boolean isAppGroup();
- }
-
}
package android.service.oemlock {
@@ -9319,7 +9309,7 @@ package android.telephony.ims.feature {
field public static final int STATE_UNAVAILABLE = 0; // 0x0
}
- public static class ImsFeature.Capabilities {
+ @Deprecated public static class ImsFeature.Capabilities {
field @Deprecated protected int mCapabilities;
}
@@ -9353,7 +9343,7 @@ package android.telephony.ims.feature {
public static class MmTelFeature.MmTelCapabilities extends android.telephony.ims.feature.ImsFeature.Capabilities {
ctor public MmTelFeature.MmTelCapabilities();
ctor @Deprecated public MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities);
- ctor public MmTelFeature.MmTelCapabilities(int);
+ ctor public MmTelFeature.MmTelCapabilities(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int);
method public final void addCapabilities(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int);
method public final boolean isCapable(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int);
method public final void removeCapabilities(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int);
diff --git a/api/test-current.txt b/api/test-current.txt
index 43b9086a8dec..6e28f67e9a68 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -97,8 +97,7 @@ package android.app {
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void removeStacksInWindowingModes(int[]) throws java.lang.SecurityException;
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void removeStacksWithActivityTypes(int[]) throws java.lang.SecurityException;
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void resizeDockedStack(android.graphics.Rect, android.graphics.Rect);
- method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void resizeStack(int, android.graphics.Rect) throws java.lang.SecurityException;
- method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void resizeStack(int, android.graphics.Rect, boolean);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void resizePinnedStack(int, android.graphics.Rect, boolean);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void resizeTask(int, android.graphics.Rect);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void setDisplayToSingleTaskInstance(int);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void setTaskWindowingMode(int, int, boolean) throws java.lang.SecurityException;
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 19fa64073183..c9a4b3ba6368 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -65,7 +65,7 @@ cc_defaults {
"src/condition/condition_util.cpp",
"src/condition/SimpleConditionTracker.cpp",
"src/condition/ConditionWizard.cpp",
- "src/condition/StateTracker.cpp",
+ "src/condition/StateConditionTracker.cpp",
"src/config/ConfigKey.cpp",
"src/config/ConfigListener.cpp",
"src/config/ConfigManager.cpp",
@@ -204,6 +204,10 @@ cc_test {
],
srcs: [
+ // atom_field_options.proto needs field_options.proto, but that is
+ // not included in libprotobuf-cpp-lite, so compile it here.
+ ":libprotobuf-internal-protos",
+
"src/atom_field_options.proto",
"src/atoms.proto",
"src/stats_log.proto",
@@ -227,7 +231,7 @@ cc_test {
"tests/FieldValue_test.cpp",
"tests/condition/CombinationConditionTracker_test.cpp",
"tests/condition/SimpleConditionTracker_test.cpp",
- "tests/condition/StateTracker_test.cpp",
+ "tests/condition/StateConditionTracker_test.cpp",
"tests/condition/ConditionTimer_test.cpp",
"tests/metrics/OringDurationTracker_test.cpp",
"tests/metrics/MaxDurationTracker_test.cpp",
@@ -262,11 +266,11 @@ cc_test {
],
proto: {
- type: "full",
+ type: "lite",
include_dirs: ["external/protobuf/src"],
},
- shared_libs: ["libprotobuf-cpp-full"],
+ shared_libs: ["libprotobuf-cpp-lite"],
}
@@ -279,6 +283,10 @@ cc_benchmark {
defaults: ["statsd_defaults"],
srcs: [
+ // atom_field_options.proto needs field_options.proto, but that is
+ // not included in libprotobuf-cpp-lite, so compile it here.
+ ":libprotobuf-internal-protos",
+
"src/atom_field_options.proto",
"src/atoms.proto",
"src/stats_log.proto",
@@ -293,7 +301,7 @@ cc_benchmark {
],
proto: {
- type: "full",
+ type: "lite",
include_dirs: ["external/protobuf/src"],
},
@@ -315,7 +323,7 @@ cc_benchmark {
shared_libs: [
"libgtest_prod",
"libstatslog",
- "libprotobuf-cpp-full",
+ "libprotobuf-cpp-lite",
],
}
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.cpp b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
index d1dcb5df7838..7ace44eef564 100644
--- a/cmds/statsd/src/anomaly/AnomalyTracker.cpp
+++ b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
@@ -24,6 +24,7 @@
#include "subscriber/IncidentdReporter.h"
#include "subscriber/SubscriberReporter.h"
+#include <inttypes.h>
#include <statslog.h>
#include <time.h>
@@ -224,7 +225,7 @@ void AnomalyTracker::declareAnomaly(const int64_t& timestampNs, int64_t metricId
}
if (!mSubscriptions.empty()) {
- ALOGI("An anomaly (%lld) %s has occurred! Informing subscribers.",
+ ALOGI("An anomaly (%" PRId64 ") %s has occurred! Informing subscribers.",
mAlert.id(), key.toString().c_str());
informSubscribers(key, metricId, metricValue);
} else {
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 2c8a5562c979..ae751ce6d7ab 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -334,6 +334,7 @@ message Atom {
BackGesture back_gesture_reported_reported = 224;
UpdateEngineUpdateAttemptReported update_engine_update_attempt_reported = 225;
UpdateEngineSuccessfulUpdateReported update_engine_successful_update_reported = 226;
+ CameraActionEvent camera_action_event = 227;
}
// Pulled events will start at field 10000.
@@ -7164,3 +7165,29 @@ message FrameTimingHistogram {
// It's required that len(time_millis) == len(frame_count)
repeated int64 frame_counts = 2;
}
+
+
+/**
+ * Information about camera facing and API level usage.
+ * Logged from:
+ * frameworks/base/services/core/java/com/android/server/camera/CameraServiceProxy.java
+ */
+message CameraActionEvent {
+ // Camera session duration
+ optional int64 duration = 1;
+
+ // Camera API level used
+ optional int32 api_level = 2;
+
+ // Name of client package
+ optional string package_name = 3;
+
+ // Camera facing
+ enum Facing {
+ UNKNOWN = 0;
+ BACK = 1;
+ FRONT = 2;
+ EXTERNAL = 3;
+ }
+ optional Facing facing = 4;
+}
diff --git a/cmds/statsd/src/condition/StateTracker.cpp b/cmds/statsd/src/condition/StateConditionTracker.cpp
index 18c7178dd7d7..7f3eeddba831 100644
--- a/cmds/statsd/src/condition/StateTracker.cpp
+++ b/cmds/statsd/src/condition/StateConditionTracker.cpp
@@ -16,7 +16,7 @@
#define DEBUG false // STOPSHIP if true
#include "Log.h"
-#include "StateTracker.h"
+#include "StateConditionTracker.h"
#include "guardrail/StatsdStats.h"
namespace android {
@@ -27,7 +27,7 @@ using std::string;
using std::unordered_set;
using std::vector;
-StateTracker::StateTracker(const ConfigKey& key, const int64_t& id, const int index,
+StateConditionTracker::StateConditionTracker(const ConfigKey& key, const int64_t& id, const int index,
const SimplePredicate& simplePredicate,
const unordered_map<int64_t, int>& trackerNameIndexMap,
const vector<Matcher> primaryKeys)
@@ -69,19 +69,19 @@ StateTracker::StateTracker(const ConfigKey& key, const int64_t& id, const int in
mInitialized = true;
}
-StateTracker::~StateTracker() {
- VLOG("~StateTracker()");
+StateConditionTracker::~StateConditionTracker() {
+ VLOG("~StateConditionTracker()");
}
-bool StateTracker::init(const vector<Predicate>& allConditionConfig,
+bool StateConditionTracker::init(const vector<Predicate>& allConditionConfig,
const vector<sp<ConditionTracker>>& allConditionTrackers,
const unordered_map<int64_t, int>& conditionIdIndexMap,
vector<bool>& stack) {
return mInitialized;
}
-void StateTracker::dumpState() {
- VLOG("StateTracker %lld DUMP:", (long long)mConditionId);
+void StateConditionTracker::dumpState() {
+ VLOG("StateConditionTracker %lld DUMP:", (long long)mConditionId);
for (const auto& value : mSlicedState) {
VLOG("\t%s -> %s", value.first.toString().c_str(), value.second.toString().c_str());
}
@@ -95,7 +95,7 @@ void StateTracker::dumpState() {
}
}
-bool StateTracker::hitGuardRail(const HashableDimensionKey& newKey) {
+bool StateConditionTracker::hitGuardRail(const HashableDimensionKey& newKey) {
if (mSlicedState.find(newKey) != mSlicedState.end()) {
// if the condition is not sliced or the key is not new, we are good!
return false;
@@ -114,7 +114,7 @@ bool StateTracker::hitGuardRail(const HashableDimensionKey& newKey) {
return false;
}
-void StateTracker::evaluateCondition(const LogEvent& event,
+void StateConditionTracker::evaluateCondition(const LogEvent& event,
const vector<MatchingState>& eventMatcherValues,
const vector<sp<ConditionTracker>>& mAllConditions,
vector<ConditionState>& conditionCache,
@@ -135,7 +135,7 @@ void StateTracker::evaluateCondition(const LogEvent& event,
return;
}
- VLOG("StateTracker evaluate event %s", event.ToString().c_str());
+ VLOG("StateConditionTracker evaluate event %s", event.ToString().c_str());
// Primary key can exclusive fields must be simple fields. so there won't be more than
// one keys matched.
@@ -151,7 +151,7 @@ void StateTracker::evaluateCondition(const LogEvent& event,
}
hitGuardRail(primaryKey);
- VLOG("StateTracker: key %s state %s", primaryKey.toString().c_str(), state.toString().c_str());
+ VLOG("StateConditionTracker: key %s state %s", primaryKey.toString().c_str(), state.toString().c_str());
auto it = mSlicedState.find(primaryKey);
if (it == mSlicedState.end()) {
@@ -176,7 +176,7 @@ void StateTracker::evaluateCondition(const LogEvent& event,
return;
}
-void StateTracker::isConditionMet(
+void StateConditionTracker::isConditionMet(
const ConditionKey& conditionParameters, const vector<sp<ConditionTracker>>& allConditions,
const bool isPartialLink,
vector<ConditionState>& conditionCache) const {
diff --git a/cmds/statsd/src/condition/StateTracker.h b/cmds/statsd/src/condition/StateConditionTracker.h
index 5ae4441713cd..0efe1fb3fcb2 100644
--- a/cmds/statsd/src/condition/StateTracker.h
+++ b/cmds/statsd/src/condition/StateConditionTracker.h
@@ -25,14 +25,14 @@ namespace android {
namespace os {
namespace statsd {
-class StateTracker : public virtual ConditionTracker {
+class StateConditionTracker : public virtual ConditionTracker {
public:
- StateTracker(const ConfigKey& key, const int64_t& id, const int index,
+ StateConditionTracker(const ConfigKey& key, const int64_t& id, const int index,
const SimplePredicate& simplePredicate,
const std::unordered_map<int64_t, int>& trackerNameIndexMap,
const vector<Matcher> primaryKeys);
- ~StateTracker();
+ ~StateConditionTracker();
bool init(const std::vector<Predicate>& allConditionConfig,
const std::vector<sp<ConditionTracker>>& allConditionTrackers,
@@ -46,8 +46,8 @@ public:
std::vector<bool>& changedCache) override;
/**
- * Note: dimensionFields will be ignored in StateTracker, because we demand metrics
- * must take the entire dimension fields from StateTracker. This is to make implementation
+ * Note: dimensionFields will be ignored in StateConditionTracker, because we demand metrics
+ * must take the entire dimension fields from StateConditionTracker. This is to make implementation
* simple and efficient.
*
* For example: wakelock duration by uid process states:
@@ -109,7 +109,7 @@ private:
// maps from [primary_key] to [primary_key, exclusive_state].
std::unordered_map<HashableDimensionKey, HashableDimensionKey> mSlicedState;
- FRIEND_TEST(StateTrackerTest, TestStateChange);
+ FRIEND_TEST(StateConditionTrackerTest, TestStateChange);
};
} // namespace statsd
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
index dd32c08faba3..40484f4fb86b 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -21,7 +21,7 @@
#include "../condition/CombinationConditionTracker.h"
#include "../condition/SimpleConditionTracker.h"
-#include "../condition/StateTracker.h"
+#include "../condition/StateConditionTracker.h"
#include "../external/StatsPullerManager.h"
#include "../matchers/CombinationLogMatchingTracker.h"
#include "../matchers/SimpleLogMatchingTracker.h"
@@ -35,6 +35,8 @@
#include "stats_util.h"
#include "statslog.h"
+#include <inttypes.h>
+
using std::set;
using std::string;
using std::unordered_map;
@@ -182,13 +184,13 @@ bool initLogTrackers(const StatsdConfig& config, const UidMap& uidMap,
}
/**
- * A StateTracker is built from a SimplePredicate which has only "start", and no "stop"
+ * A StateConditionTracker is built from a SimplePredicate which has only "start", and no "stop"
* or "stop_all". The start must be an atom matcher that matches a state atom. It must
* have dimension, the dimension must be the state atom's primary fields plus exclusive state
- * field. For example, the StateTracker is used in tracking UidProcessState and ScreenState.
+ * field. For example, the StateConditionTracker is used in tracking UidProcessState and ScreenState.
*
*/
-bool isStateTracker(const SimplePredicate& simplePredicate, vector<Matcher>* primaryKeys) {
+bool isStateConditionTracker(const SimplePredicate& simplePredicate, vector<Matcher>* primaryKeys) {
// 1. must not have "stop". must have "dimension"
if (!simplePredicate.has_stop() && simplePredicate.has_dimensions()) {
auto it = android::util::AtomsInfo::kStateAtomsFieldOptions.find(
@@ -240,8 +242,8 @@ bool initConditions(const ConfigKey& key, const StatsdConfig& config,
switch (condition.contents_case()) {
case Predicate::ContentsCase::kSimplePredicate: {
vector<Matcher> primaryKeys;
- if (isStateTracker(condition.simple_predicate(), &primaryKeys)) {
- allConditionTrackers.push_back(new StateTracker(key, condition.id(), index,
+ if (isStateConditionTracker(condition.simple_predicate(), &primaryKeys)) {
+ allConditionTrackers.push_back(new StateConditionTracker(key, condition.id(), index,
condition.simple_predicate(),
logTrackerMap, primaryKeys));
} else {
@@ -593,7 +595,7 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t
for (int i = 0; i < config.no_report_metric_size(); ++i) {
const auto no_report_metric = config.no_report_metric(i);
if (metricMap.find(no_report_metric) == metricMap.end()) {
- ALOGW("no_report_metric %lld not exist", no_report_metric);
+ ALOGW("no_report_metric %" PRId64 " not exist", no_report_metric);
return false;
}
noReportMetricIds.insert(no_report_metric);
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.h b/cmds/statsd/src/metrics/metrics_manager_util.h
index 028231ff908c..3704969039c4 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.h
+++ b/cmds/statsd/src/metrics/metrics_manager_util.h
@@ -113,7 +113,7 @@ bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap&
vector<int>& metricsWithActivation,
std::set<int64_t>& noReportMetricIds);
-bool isStateTracker(const SimplePredicate& simplePredicate, std::vector<Matcher>* primaryKeys);
+bool isStateConditionTracker(const SimplePredicate& simplePredicate, std::vector<Matcher>* primaryKeys);
} // namespace statsd
} // namespace os
diff --git a/cmds/statsd/tests/condition/StateTracker_test.cpp b/cmds/statsd/tests/condition/StateConditionTracker_test.cpp
index 9a66254afce0..fbf6efdcf966 100644
--- a/cmds/statsd/tests/condition/StateTracker_test.cpp
+++ b/cmds/statsd/tests/condition/StateConditionTracker_test.cpp
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "src/condition/StateTracker.h"
+#include "src/condition/StateConditionTracker.h"
#include "tests/statsd_test_util.h"
#include <gmock/gmock.h>
@@ -50,7 +50,7 @@ void makeUidProcStateEvent(int32_t uid, int32_t state, LogEvent* event) {
event->init();
}
-TEST(StateTrackerTest, TestStateChange) {
+TEST(StateConditionTrackerTest, TestStateChange) {
int uid1 = 111;
int uid2 = 222;
@@ -60,7 +60,7 @@ TEST(StateTrackerTest, TestStateChange) {
trackerNameIndexMap[StringToId("UidProcState")] = 0;
vector<Matcher> primaryFields;
primaryFields.push_back(getSimpleMatcher(kUidProcTag, 1));
- StateTracker tracker(ConfigKey(12, 123), 123, 0, getUidProcStatePredicate(),
+ StateConditionTracker tracker(ConfigKey(12, 123), 123, 0, getUidProcStatePredicate(),
trackerNameIndexMap, primaryFields);
LogEvent event(kUidProcTag, 0 /*timestamp*/);
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 1fd7e52314e3..92aabb591e03 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -18,6 +18,7 @@ package android.app;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.content.ComponentName;
import android.content.IIntentReceiver;
import android.content.IIntentSender;
@@ -30,7 +31,6 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.TransactionTooLargeException;
-import android.view.RemoteAnimationAdapter;
import java.util.ArrayList;
import java.util.List;
@@ -51,12 +51,12 @@ public abstract class ActivityManagerInternal {
/**
* Verify that calling app has access to the given provider.
*/
- public abstract String checkContentProviderAccess(String authority, int userId);
+ public abstract String checkContentProviderAccess(String authority, @UserIdInt int userId);
/**
* Verify that calling UID has access to the given provider.
*/
- public abstract int checkContentProviderUriPermission(Uri uri, int userId,
+ public abstract int checkContentProviderUriPermission(Uri uri, @UserIdInt int userId,
int callingUid, int modeFlags);
// Called by the power manager.
@@ -71,7 +71,7 @@ public abstract class ActivityManagerInternal {
/**
* Kill foreground apps from the specified user.
*/
- public abstract void killForegroundAppsForUser(int userHandle);
+ public abstract void killForegroundAppsForUser(@UserIdInt int userId);
/**
* Sets how long a {@link PendingIntent} can be temporarily whitelist to by bypass restrictions
@@ -174,7 +174,7 @@ public abstract class ActivityManagerInternal {
* Checks to see if the calling pid is allowed to handle the user. Returns adjusted user id as
* needed.
*/
- public abstract int handleIncomingUser(int callingPid, int callingUid, int userId,
+ public abstract int handleIncomingUser(int callingPid, int callingUid, @UserIdInt int userId,
boolean allowAll, int allowMode, String name, String callerPackage);
/** Checks if the calling binder pid as the permission. */
@@ -184,7 +184,7 @@ public abstract class ActivityManagerInternal {
public abstract int getCurrentUserId();
/** Returns true if the user is running. */
- public abstract boolean isUserRunning(int userId, int flags);
+ public abstract boolean isUserRunning(@UserIdInt int userId, int flags);
/** Trims memory usage in the system by removing/stopping unused application processes. */
public abstract void trimApplications();
@@ -211,7 +211,7 @@ public abstract class ActivityManagerInternal {
* @param started
*/
public abstract void updateBatteryStats(
- ComponentName activity, int uid, int userId, boolean resumed);
+ ComponentName activity, int uid, @UserIdInt int userId, boolean resumed);
/**
* Update UsageStats of the activity.
@@ -222,23 +222,23 @@ public abstract class ActivityManagerInternal {
* @param taskRoot TaskRecord's root
*/
public abstract void updateActivityUsageStats(
- ComponentName activity, int userId, int event, IBinder appToken,
+ ComponentName activity, @UserIdInt int userId, int event, IBinder appToken,
ComponentName taskRoot);
public abstract void updateForegroundTimeIfOnBattery(
String packageName, int uid, long cpuTimeDiff);
- public abstract void sendForegroundProfileChanged(int userId);
+ public abstract void sendForegroundProfileChanged(@UserIdInt int userId);
/**
* Returns whether the given user requires credential entry at this time. This is used to
* intercept activity launches for work apps when the Work Challenge is present.
*/
- public abstract boolean shouldConfirmCredentials(int userId);
+ public abstract boolean shouldConfirmCredentials(@UserIdInt int userId);
public abstract int[] getCurrentProfileIds();
public abstract UserInfo getCurrentUser();
- public abstract void ensureNotSpecialUser(int userId);
- public abstract boolean isCurrentProfile(int userId);
- public abstract boolean hasStartedUserState(int userId);
+ public abstract void ensureNotSpecialUser(@UserIdInt int userId);
+ public abstract boolean isCurrentProfile(@UserIdInt int userId);
+ public abstract boolean hasStartedUserState(@UserIdInt int userId);
public abstract void finishUserSwitch(Object uss);
/** Schedule the execution of all pending app GCs. */
@@ -261,15 +261,16 @@ public abstract class ActivityManagerInternal {
public abstract int broadcastIntentInPackage(String packageName, int uid, int realCallingUid,
int realCallingPid, Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle resultExtras, String requiredPermission,
- Bundle bOptions, boolean serialized, boolean sticky, int userId,
+ Bundle bOptions, boolean serialized, boolean sticky, @UserIdInt int userId,
boolean allowBackgroundActivityStarts);
public abstract ComponentName startServiceInPackage(int uid, Intent service,
- String resolvedType, boolean fgRequired, String callingPackage, int userId,
+ String resolvedType, boolean fgRequired, String callingPackage, @UserIdInt int userId,
boolean allowBackgroundActivityStarts) throws TransactionTooLargeException;
public abstract void disconnectActivityFromServices(Object connectionHolder, Object conns);
- public abstract void cleanUpServices(int userId, ComponentName component, Intent baseIntent);
- public abstract ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId);
+ public abstract void cleanUpServices(@UserIdInt int userId, ComponentName component,
+ Intent baseIntent);
+ public abstract ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, @UserIdInt int userId);
public abstract void ensureBootCompleted();
public abstract void updateOomLevelsForDisplay(int displayId);
public abstract boolean isActivityStartsLoggingEnabled();
@@ -328,7 +329,7 @@ public abstract class ActivityManagerInternal {
public abstract boolean isAppBad(ApplicationInfo info);
/** Remove pending backup for the given userId. */
- public abstract void clearPendingBackup(int userId);
+ public abstract void clearPendingBackup(@UserIdInt int userId);
/**
* When power button is very long pressed, call this interface to do some pre-shutdown work
diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java
index 4ef554dc64cc..ac8c9f466f33 100644
--- a/core/java/android/app/ActivityTaskManager.java
+++ b/core/java/android/app/ActivityTaskManager.java
@@ -202,21 +202,6 @@ public class ActivityTaskManager {
}
/**
- * Resizes the input stack id to the given bounds.
- * @param stackId Id of the stack to resize.
- * @param bounds Bounds to resize the stack to or {@code null} for fullscreen.
- */
- @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
- public void resizeStack(int stackId, Rect bounds) throws SecurityException {
- try {
- getService().resizeStack(stackId, bounds, false /* allowResizeInDockedMode */,
- false /* preserveWindows */, false /* animate */, -1 /* animationDuration */);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
* Removes stacks in the windowing modes from the system if they are of activity type
* ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
*/
@@ -362,10 +347,13 @@ public class ActivityTaskManager {
* @param animate Whether we should play an animation for resizing stack.
*/
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
- public void resizeStack(int stackId, Rect bounds, boolean animate) {
+ public void resizePinnedStack(int stackId, Rect bounds, boolean animate) {
try {
- getService().resizeStack(stackId, bounds, false, false, animate /* animate */,
- -1 /* animationDuration */);
+ if (animate) {
+ getService().animateResizePinnedStack(stackId, bounds, -1 /* animationDuration */);
+ } else {
+ getService().resizePinnedStack(bounds, null /* tempPinnedTaskBounds */);
+ }
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index dbe50c3d24a0..dca00a2bbd83 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -406,23 +406,6 @@ interface IActivityManager {
List<ActivityManager.StackInfo> getAllStackInfos();
@UnsupportedAppUsage
void moveTaskToStack(int taskId, int stackId, boolean toTop);
- /**
- * Resizes the input stack id to the given bounds.
- *
- * @param stackId Id of the stack to resize.
- * @param bounds Bounds to resize the stack to or {@code null} for fullscreen.
- * @param allowResizeInDockedMode True if the resize should be allowed when the docked stack is
- * active.
- * @param preserveWindows True if the windows of activities contained in the stack should be
- * preserved.
- * @param animate True if the stack resize should be animated.
- * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
- * default animation duration should be used.
- * @throws RemoteException
- */
- @UnsupportedAppUsage
- void resizeStack(int stackId, in Rect bounds, boolean allowResizeInDockedMode,
- boolean preserveWindows, boolean animate, int animationDuration);
void setFocusedStack(int stackId);
ActivityManager.StackInfo getFocusedStackInfo();
@UnsupportedAppUsage
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index 47b784b3eaaf..dda3bb53ebe3 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -234,21 +234,15 @@ interface IActivityTaskManager {
void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop);
void moveTaskToStack(int taskId, int stackId, boolean toTop);
/**
- * Resizes the input stack id to the given bounds.
+ * Resizes the input pinned stack to the given bounds with animation.
*
- * @param stackId Id of the stack to resize.
+ * @param stackId Id of the pinned stack to resize.
* @param bounds Bounds to resize the stack to or {@code null} for fullscreen.
- * @param allowResizeInDockedMode True if the resize should be allowed when the docked stack is
- * active.
- * @param preserveWindows True if the windows of activities contained in the stack should be
- * preserved.
- * @param animate True if the stack resize should be animated.
* @param animationDuration The duration of the resize animation in milliseconds or -1 if the
* default animation duration should be used.
* @throws RemoteException
*/
- void resizeStack(int stackId, in Rect bounds, boolean allowResizeInDockedMode,
- boolean preserveWindows, boolean animate, int animationDuration);
+ void animateResizePinnedStack(int stackId, in Rect bounds, int animationDuration);
boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop,
boolean animate, in Rect initialBounds, boolean showRecents);
/**
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index f065ff791dce..bb4e99873f26 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3274,11 +3274,8 @@ public class Notification implements Parcelable
*
* @param requiresFreeform requires the remoteinput to allow freeform or not.
* @return the result pair, {@code null} if no result is found.
- *
- * @hide
*/
@Nullable
- @SystemApi
public Pair<RemoteInput, Action> findRemoteInputActionPair(boolean requiresFreeform) {
if (actions == null) {
return null;
@@ -3301,11 +3298,9 @@ public class Notification implements Parcelable
}
/**
- * Returns the actions that are contextual out of the actions in this notification.
- *
- * @hide
+ * Returns the actions that are contextual (that is, suggested because of the content of the
+ * notification) out of the actions in this notification.
*/
- @SystemApi
public @NonNull List<Notification.Action> getContextualActions() {
if (actions == null) return Collections.emptyList();
@@ -7705,11 +7700,11 @@ public class Notification implements Parcelable
}
/**
- * @return A list of messages read from the bundles.
- *
- * @hide
+ * Returns a list of messages read from the given bundle list, e.g.
+ * {@link #EXTRA_MESSAGES} or {@link #EXTRA_HISTORIC_MESSAGES}.
*/
- public static List<Message> getMessagesFromBundleArray(Parcelable[] bundles) {
+ @NonNull
+ public static List<Message> getMessagesFromBundleArray(@Nullable Parcelable[] bundles) {
if (bundles == null) {
return new ArrayList<>();
}
@@ -7726,13 +7721,12 @@ public class Notification implements Parcelable
}
/**
- * @return The message that is stored in the bundle or null if the message couldn't be
- * resolved.
- *
+ * Returns the message that is stored in the bundle (e.g. one of the values in the lists
+ * in {@link #EXTRA_MESSAGES} or {@link #EXTRA_HISTORIC_MESSAGES}) or null if the
+ * message couldn't be resolved.
* @hide
*/
@Nullable
- @SystemApi
public static Message getMessageFromBundle(@NonNull Bundle bundle) {
try {
if (!bundle.containsKey(KEY_TEXT) || !bundle.containsKey(KEY_TIMESTAMP)) {
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 93e4ddcbb016..20d977b7da10 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -710,6 +710,14 @@ public final class NotificationChannel implements Parcelable {
}
/**
+ * Returns whether the user has chosen the sound of this channel.
+ * @see #getSound()
+ */
+ public boolean hasUserSetSound() {
+ return (mUserLockedFields & USER_LOCKED_SOUND) != 0;
+ }
+
+ /**
* @hide
*/
public void populateFromXmlForRestore(XmlPullParser parser, Context context) {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 2a17800dd446..3418b7be42d6 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -5413,8 +5413,8 @@ public class Intent implements Parcelable, Cloneable {
"android.intent.extra.ALLOW_MULTIPLE";
/**
- * The integer userHandle carried with broadcast intents related to addition, removal and
- * switching of users and managed profiles - {@link #ACTION_USER_ADDED},
+ * The integer userHandle (i.e. userId) carried with broadcast intents related to addition,
+ * removal and switching of users and managed profiles - {@link #ACTION_USER_ADDED},
* {@link #ACTION_USER_REMOVED} and {@link #ACTION_USER_SWITCHED}.
*
* @hide
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 861ae7ba122e..9cf54f41a64b 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -1222,7 +1222,15 @@ public final class Configuration implements Parcelable, Comparable<Configuration
.setVariant(variant)
.setScript(script)
.build();
- list.add(locale);
+ // Log a WTF here if a repeated locale is found to avoid throwing an
+ // exception in system server when LocaleList is created below
+ final int inListIndex = list.indexOf(locale);
+ if (inListIndex != -1) {
+ Slog.wtf(TAG, "Repeated locale (" + list.get(inListIndex) + ")"
+ + " found when trying to add: " + locale.toString());
+ } else {
+ list.add(locale);
+ }
} catch (IllformedLocaleException e) {
Slog.e(TAG, "readFromProto error building locale with: "
+ "language-" + language + ";country-" + country
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index 4e17f7e92013..0754dc78a629 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -128,8 +128,9 @@ public final class UserHandle implements Parcelable {
@UnsupportedAppUsage
public static final int AID_CACHE_GID_START = android.os.Process.FIRST_APPLICATION_CACHE_GID;
+ /** The userId represented by this UserHandle. */
@UnsupportedAppUsage
- final int mHandle;
+ final @UserIdInt int mHandle;
/**
* Checks to see if the user id is the same for the two uids, i.e., they belong to the same
@@ -270,7 +271,7 @@ public final class UserHandle implements Parcelable {
}
/** @hide */
- public static int getSharedAppGid(int userId, int appId) {
+ public static int getSharedAppGid(@UserIdInt int userId, @AppIdInt int appId) {
if (appId >= AID_APP_START && appId <= AID_APP_END) {
return (appId - AID_APP_START) + AID_SHARED_GID_START;
} else if (appId >= AID_ROOT && appId <= AID_APP_START) {
@@ -300,7 +301,7 @@ public final class UserHandle implements Parcelable {
}
/** @hide */
- public static int getCacheAppGid(int userId, int appId) {
+ public static int getCacheAppGid(@UserIdInt int userId, @AppIdInt int appId) {
if (appId >= AID_APP_START && appId <= AID_APP_END) {
return getUid(userId, (appId - AID_APP_START) + AID_CACHE_GID_START);
} else {
@@ -432,8 +433,8 @@ public final class UserHandle implements Parcelable {
/** @hide */
@UnsupportedAppUsage
- public UserHandle(int h) {
- mHandle = h;
+ public UserHandle(@UserIdInt int userId) {
+ mHandle = userId;
}
/**
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index a7fa96bc1d90..baf748f4a20d 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1794,14 +1794,14 @@ public class UserManager {
/**
* Returns the UserInfo object describing a specific user.
* Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
- * @param userHandle the user handle of the user whose information is being requested.
+ * @param userId the user handle of the user whose information is being requested.
* @return the UserInfo object for a specific user.
* @hide
*/
@UnsupportedAppUsage
- public UserInfo getUserInfo(@UserIdInt int userHandle) {
+ public UserInfo getUserInfo(@UserIdInt int userId) {
try {
- return mService.getUserInfo(userHandle);
+ return mService.getUserInfo(userId);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2066,15 +2066,15 @@ public class UserManager {
*
* @param name the user's name
* @param flags flags that identify the type of user and other properties.
- * @param userHandle new user will be a profile of this user.
+ * @param userId new user will be a profile of this user.
*
* @return the {@link UserInfo} object for the created user, or null if the user
* could not be created.
* @hide
*/
@UnsupportedAppUsage
- public UserInfo createProfileForUser(String name, int flags, @UserIdInt int userHandle) {
- return createProfileForUser(name, flags, userHandle, null);
+ public UserInfo createProfileForUser(String name, int flags, @UserIdInt int userId) {
+ return createProfileForUser(name, flags, userId, null);
}
/**
@@ -2084,17 +2084,17 @@ public class UserManager {
*
* @param name the user's name
* @param flags flags that identify the type of user and other properties.
- * @param userHandle new user will be a profile of this user.
+ * @param userId new user will be a profile of this user.
* @param disallowedPackages packages that will not be installed in the profile being created.
*
* @return the {@link UserInfo} object for the created user, or null if the user
* could not be created.
* @hide
*/
- public UserInfo createProfileForUser(String name, int flags, @UserIdInt int userHandle,
+ public UserInfo createProfileForUser(String name, int flags, @UserIdInt int userId,
String[] disallowedPackages) {
try {
- return mService.createProfileForUser(name, flags, userHandle, disallowedPackages);
+ return mService.createProfileForUser(name, flags, userId, disallowedPackages);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2109,9 +2109,9 @@ public class UserManager {
* @hide
*/
public UserInfo createProfileForUserEvenWhenDisallowed(String name, int flags,
- @UserIdInt int userHandle, String[] disallowedPackages) {
+ @UserIdInt int userId, String[] disallowedPackages) {
try {
- return mService.createProfileForUserEvenWhenDisallowed(name, flags, userHandle,
+ return mService.createProfileForUserEvenWhenDisallowed(name, flags, userId,
disallowedPackages);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
@@ -2280,12 +2280,12 @@ public class UserManager {
* @hide
* Marks the guest user for deletion to allow a new guest to be created before deleting
* the current user who is a guest.
- * @param userHandle
+ * @param userId
* @return
*/
- public boolean markGuestForDeletion(@UserIdInt int userHandle) {
+ public boolean markGuestForDeletion(@UserIdInt int userId) {
try {
- return mService.markGuestForDeletion(userHandle);
+ return mService.markGuestForDeletion(userId);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2317,16 +2317,16 @@ public class UserManager {
* <p>Requires {@link android.Manifest.permission#MANAGE_USERS} and
* {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permissions.
*
- * @param userHandle the id of the user to become admin
+ * @param userId the id of the user to become admin
* @hide
*/
@RequiresPermission(allOf = {
Manifest.permission.INTERACT_ACROSS_USERS_FULL,
Manifest.permission.MANAGE_USERS
})
- public void setUserAdmin(@UserIdInt int userHandle) {
+ public void setUserAdmin(@UserIdInt int userId) {
try {
- mService.setUserAdmin(userHandle);
+ mService.setUserAdmin(userId);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2337,9 +2337,9 @@ public class UserManager {
*
* @hide
*/
- public void evictCredentialEncryptionKey(@UserIdInt int userHandle) {
+ public void evictCredentialEncryptionKey(@UserIdInt int userId) {
try {
- mService.evictCredentialEncryptionKey(userHandle);
+ mService.evictCredentialEncryptionKey(userId);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2400,9 +2400,9 @@ public class UserManager {
Manifest.permission.INTERACT_ACROSS_USERS_FULL,
Manifest.permission.MANAGE_USERS
})
- public @Nullable String getUserAccount(@UserIdInt int userHandle) {
+ public @Nullable String getUserAccount(@UserIdInt int userId) {
try {
- return mService.getUserAccount(userHandle);
+ return mService.getUserAccount(userId);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2416,9 +2416,9 @@ public class UserManager {
Manifest.permission.INTERACT_ACROSS_USERS_FULL,
Manifest.permission.MANAGE_USERS
})
- public void setUserAccount(@UserIdInt int userHandle, @Nullable String accountName) {
+ public void setUserAccount(@UserIdInt int userId, @Nullable String accountName) {
try {
- mService.setUserAccount(userHandle, accountName);
+ mService.setUserAccount(userId, accountName);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2477,20 +2477,19 @@ public class UserManager {
}
/**
- * Returns list of the profiles of userHandle including
- * userHandle itself.
+ * Returns list of the profiles of userId including userId itself.
* Note that this returns both enabled and not enabled profiles. See
* {@link #getEnabledProfiles(int)} if you need only the enabled ones.
*
* Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
- * @param userHandle profiles of this user will be returned.
+ * @param userId profiles of this user will be returned.
* @return the list of profiles.
* @hide
*/
@UnsupportedAppUsage
- public List<UserInfo> getProfiles(@UserIdInt int userHandle) {
+ public List<UserInfo> getProfiles(@UserIdInt int userId) {
try {
- return mService.getProfiles(userHandle, false /* enabledOnly */);
+ return mService.getProfiles(userId, false /* enabledOnly */);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2512,19 +2511,18 @@ public class UserManager {
}
/**
- * Returns list of the profiles of userHandle including
- * userHandle itself.
+ * Returns list of the profiles of userId including userId itself.
* Note that this returns only enabled.
*
* Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
- * @param userHandle profiles of this user will be returned.
+ * @param userId profiles of this user will be returned.
* @return the list of profiles.
* @hide
*/
@UnsupportedAppUsage
- public List<UserInfo> getEnabledProfiles(@UserIdInt int userHandle) {
+ public List<UserInfo> getEnabledProfiles(@UserIdInt int userId) {
try {
- return mService.getProfiles(userHandle, true /* enabledOnly */);
+ return mService.getProfiles(userId, true /* enabledOnly */);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2584,14 +2582,14 @@ public class UserManager {
/**
* Returns the device credential owner id of the profile from
- * which this method is called, or userHandle if called from a user that
+ * which this method is called, or userId if called from a user that
* is not a profile.
*
* @hide
*/
- public int getCredentialOwnerProfile(@UserIdInt int userHandle) {
+ public int getCredentialOwnerProfile(@UserIdInt int userId) {
try {
- return mService.getCredentialOwnerProfile(userHandle);
+ return mService.getCredentialOwnerProfile(userId);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2604,9 +2602,9 @@ public class UserManager {
* @hide
*/
@UnsupportedAppUsage
- public UserInfo getProfileParent(@UserIdInt int userHandle) {
+ public UserInfo getProfileParent(@UserIdInt int userId) {
try {
- return mService.getProfileParent(userHandle);
+ return mService.getProfileParent(userId);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2785,13 +2783,13 @@ public class UserManager {
/**
* Removes a user and all associated data.
* Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
- * @param userHandle the integer handle of the user, where 0 is the primary user.
+ * @param userId the integer handle of the user.
* @hide
*/
@UnsupportedAppUsage
- public boolean removeUser(@UserIdInt int userHandle) {
+ public boolean removeUser(@UserIdInt int userId) {
try {
- return mService.removeUser(userHandle);
+ return mService.removeUser(userId);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2823,9 +2821,9 @@ public class UserManager {
* @see {@link #removeUser(int)}
* @hide
*/
- public boolean removeUserEvenWhenDisallowed(@UserIdInt int userHandle) {
+ public boolean removeUserEvenWhenDisallowed(@UserIdInt int userId) {
try {
- return mService.removeUserEvenWhenDisallowed(userHandle);
+ return mService.removeUserEvenWhenDisallowed(userId);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2835,13 +2833,13 @@ public class UserManager {
* Updates the user's name.
* Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
*
- * @param userHandle the user's integer handle
+ * @param userId the user's integer id
* @param name the new name for the user
* @hide
*/
- public void setUserName(@UserIdInt int userHandle, String name) {
+ public void setUserName(@UserIdInt int userId, String name) {
try {
- mService.setUserName(userHandle, name);
+ mService.setUserName(userId, name);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2862,13 +2860,13 @@ public class UserManager {
/**
* Sets the user's photo.
- * @param userHandle the user for whom to change the photo.
+ * @param userId the user for whom to change the photo.
* @param icon the bitmap to set as the photo.
* @hide
*/
- public void setUserIcon(@UserIdInt int userHandle, Bitmap icon) {
+ public void setUserIcon(@UserIdInt int userId, Bitmap icon) {
try {
- mService.setUserIcon(userHandle, icon);
+ mService.setUserIcon(userId, icon);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2889,15 +2887,15 @@ public class UserManager {
/**
* Returns a file descriptor for the user's photo. PNG data can be read from this file.
- * @param userHandle the user whose photo we want to read.
+ * @param userId the user whose photo we want to read.
* @return a {@link Bitmap} of the user's photo, or null if there's no photo.
* @see com.android.internal.util.UserIcons#getDefaultUserIcon for a default.
* @hide
*/
@UnsupportedAppUsage
- public Bitmap getUserIcon(@UserIdInt int userHandle) {
+ public Bitmap getUserIcon(@UserIdInt int userId) {
try {
- ParcelFileDescriptor fd = mService.getUserIcon(userHandle);
+ ParcelFileDescriptor fd = mService.getUserIcon(userId);
if (fd != null) {
try {
return BitmapFactory.decodeFileDescriptor(fd.getFileDescriptor());
@@ -2999,27 +2997,27 @@ public class UserManager {
}
/**
- * Returns a serial number on this device for a given userHandle. User handles can be recycled
+ * Returns a serial number on this device for a given userId. User handles can be recycled
* when deleting and creating users, but serial numbers are not reused until the device is wiped.
- * @param userHandle
- * @return a serial number associated with that user, or -1 if the userHandle is not valid.
+ * @param userId
+ * @return a serial number associated with that user, or -1 if the userId is not valid.
* @hide
*/
@UnsupportedAppUsage
- public int getUserSerialNumber(@UserIdInt int userHandle) {
+ public int getUserSerialNumber(@UserIdInt int userId) {
try {
- return mService.getUserSerialNumber(userHandle);
+ return mService.getUserSerialNumber(userId);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
}
/**
- * Returns a userHandle on this device for a given user serial number. User handles can be
+ * Returns a userId on this device for a given user serial number. User handles can be
* recycled when deleting and creating users, but serial numbers are not reused until the device
* is wiped.
* @param userSerialNumber
- * @return the userHandle associated with that user serial number, or -1 if the serial number
+ * @return the userId associated with that user serial number, or -1 if the serial number
* is not valid.
* @hide
*/
diff --git a/core/java/android/os/UserManagerInternal.java b/core/java/android/os/UserManagerInternal.java
index ddd949d64a1f..a5b71f64668d 100644
--- a/core/java/android/os/UserManagerInternal.java
+++ b/core/java/android/os/UserManagerInternal.java
@@ -137,7 +137,7 @@ public abstract class UserManagerInternal {
String[] disallowedPackages);
/**
- * Same as {@link UserManager#removeUser(int userHandle)}, but bypasses the check for
+ * Same as {@link UserManager#removeUser(int userId)}, but bypasses the check for
* {@link UserManager#DISALLOW_REMOVE_USER} and
* {@link UserManager#DISALLOW_REMOVE_MANAGED_PROFILE} and does not require the
* {@link android.Manifest.permission#MANAGE_USERS} permission.
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 205df7e12483..b8378a3474ac 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -170,10 +170,7 @@ public class StatusBarNotification implements Parcelable {
/**
* Returns true if application asked that this notification be part of a group.
- *
- * @hide
*/
- @SystemApi
public boolean isAppGroup() {
if (getNotification().getGroup() != null || getNotification().getSortKey() != null) {
return true;
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index bfab580ea077..937990f7e88e 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -1639,7 +1639,7 @@ public class ZenModeConfig implements Parcelable {
@UnsupportedAppUsage
public String name; // required for automatic
@UnsupportedAppUsage
- public int zenMode;
+ public int zenMode; // ie: Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
@UnsupportedAppUsage
public Uri conditionId; // required for automatic
public Condition condition; // optional
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 2efebf6457ab..7e22dd9f0ac8 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -18,6 +18,7 @@ package android.view;
import static android.view.DisplayInfoProto.APP_HEIGHT;
import static android.view.DisplayInfoProto.APP_WIDTH;
+import static android.view.DisplayInfoProto.FLAGS;
import static android.view.DisplayInfoProto.LOGICAL_HEIGHT;
import static android.view.DisplayInfoProto.LOGICAL_WIDTH;
import static android.view.DisplayInfoProto.NAME;
@@ -708,6 +709,7 @@ public final class DisplayInfo implements Parcelable {
protoOutputStream.write(APP_WIDTH, appWidth);
protoOutputStream.write(APP_HEIGHT, appHeight);
protoOutputStream.write(NAME, name);
+ protoOutputStream.write(FLAGS, flags);
protoOutputStream.end(token);
}
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 522ad642ef0d..d5559aaa7146 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -105,8 +105,6 @@ public final class SurfaceControl implements Parcelable {
long relativeToObject, int zorder);
private static native void nativeSetPosition(long transactionObj, long nativeObject,
float x, float y);
- private static native void nativeSetGeometryAppliesWithResize(long transactionObj,
- long nativeObject);
private static native void nativeSetSize(long transactionObj, long nativeObject, int w, int h);
private static native void nativeSetTransparentRegionHint(long transactionObj,
long nativeObject, Region region);
@@ -1104,16 +1102,6 @@ public final class SurfaceControl implements Parcelable {
/**
* @hide
*/
- public void setGeometryAppliesWithResize() {
- checkNotReleased();
- synchronized(SurfaceControl.class) {
- sGlobalTransaction.setGeometryAppliesWithResize(this);
- }
- }
-
- /**
- * @hide
- */
public void setBufferSize(int w, int h) {
checkNotReleased();
synchronized(SurfaceControl.class) {
@@ -2488,20 +2476,6 @@ public final class SurfaceControl implements Parcelable {
}
/**
- * If the buffer size changes in this transaction, position and crop updates specified
- * in this transaction will not complete until a buffer of the new size
- * arrives. As transform matrix and size are already frozen in this fashion,
- * this enables totally freezing the surface until the resize has completed
- * (at which point the geometry influencing aspects of this transaction will then occur)
- * @hide
- */
- public Transaction setGeometryAppliesWithResize(SurfaceControl sc) {
- sc.checkNotReleased();
- nativeSetGeometryAppliesWithResize(mNativeObject, sc.mNativeObject);
- return this;
- }
-
- /**
* Sets the security of the surface. Setting the flag is equivalent to creating the
* Surface with the {@link #SECURE} flag.
* @hide
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 3a51eaa5d7d1..85aba3c3f535 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -468,7 +468,6 @@ public final class ViewRootImpl implements ViewParent,
private final UnhandledKeyManager mUnhandledKeyManager = new UnhandledKeyManager();
boolean mWindowAttributesChanged = false;
- int mWindowAttributesChangesFlag = 0;
// These can be accessed by any thread, must be protected with a lock.
// Surface can never be reassigned or cleared (use Surface.clear()).
@@ -865,7 +864,6 @@ public final class ViewRootImpl implements ViewParent,
mSoftInputMode = attrs.softInputMode;
mWindowAttributesChanged = true;
- mWindowAttributesChangesFlag = WindowManager.LayoutParams.EVERYTHING_CHANGED;
mAttachInfo.mRootView = view;
mAttachInfo.mScalingRequired = mTranslator != null;
mAttachInfo.mApplicationScale =
@@ -1269,14 +1267,12 @@ public final class ViewRootImpl implements ViewParent,
attrs.systemUiVisibility = mWindowAttributes.systemUiVisibility;
attrs.subtreeSystemUiVisibility = mWindowAttributes.subtreeSystemUiVisibility;
- mWindowAttributesChangesFlag = mWindowAttributes.copyFrom(attrs);
- if ((mWindowAttributesChangesFlag
- & WindowManager.LayoutParams.TRANSLUCENT_FLAGS_CHANGED) != 0) {
+ final int changes = mWindowAttributes.copyFrom(attrs);
+ if ((changes & WindowManager.LayoutParams.TRANSLUCENT_FLAGS_CHANGED) != 0) {
// Recompute system ui visibility.
mAttachInfo.mRecomputeGlobalAttributes = true;
}
- if ((mWindowAttributesChangesFlag
- & WindowManager.LayoutParams.LAYOUT_CHANGED) != 0) {
+ if ((changes & WindowManager.LayoutParams.LAYOUT_CHANGED) != 0) {
// Request to update light center.
mAttachInfo.mNeedsUpdateLightCenter = true;
}
@@ -2037,8 +2033,6 @@ public final class ViewRootImpl implements ViewParent,
}
}
- mWindowAttributesChangesFlag = 0;
-
Rect frame = mWinFrame;
if (mFirst) {
mFullRedrawNeeded = true;
@@ -3313,14 +3307,19 @@ public final class ViewRootImpl implements ViewParent,
public void requestTransparentRegion(View child) {
// the test below should not fail unless someone is messing with us
checkThread();
- if (mView == child) {
+ if (mView != child) {
+ return;
+ }
+
+ if ((mView.mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) == 0) {
mView.mPrivateFlags |= View.PFLAG_REQUEST_TRANSPARENT_REGIONS;
// Need to make sure we re-evaluate the window attributes next
// time around, to ensure the window has the correct format.
mWindowAttributesChanged = true;
- mWindowAttributesChangesFlag = 0;
- requestLayout();
}
+
+ // Always request layout to apply the latest transparent region.
+ requestLayout();
}
/**
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 9cd356f6d653..b2d70321178e 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -2891,8 +2891,6 @@ public interface WindowManager extends ViewManager {
public static final int COLOR_MODE_CHANGED = 1 << 26;
/** {@hide} */
public static final int INSET_FLAGS_CHANGED = 1 << 27;
- /** {@hide} */
- public static final int EVERYTHING_CHANGED = 0xffffffff;
// internal buffer to backup/restore parameters under compatibility mode.
private int[] mCompatibilityParamsBackup = null;
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index faeecda7250c..de77aaae1653 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -493,6 +493,9 @@ public class ChooserActivity extends ResolverActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
final long intentReceivedTime = System.currentTimeMillis();
+ // This is the only place this value is being set. Effectively final.
+ mIsAppPredictorComponentAvailable = isAppPredictionServiceAvailable();
+
mIsSuccessfullySelected = false;
Intent intent = getIntent();
Parcelable targetParcelable = intent.getParcelableExtra(Intent.EXTRA_INTENT);
@@ -619,9 +622,6 @@ public class ChooserActivity extends ResolverActivity {
.addTaggedData(MetricsEvent.FIELD_SHARESHEET_MIMETYPE, target.getType())
.addTaggedData(MetricsEvent.FIELD_TIME_TO_APP_TARGETS, systemCost));
- // This is the only place this value is being set. Effectively final.
- mIsAppPredictorComponentAvailable = isAppPredictionServiceAvailable();
-
AppPredictor appPredictor = getAppPredictorForDirectShareIfEnabled();
if (appPredictor != null) {
mDirectShareAppTargetCache = new HashMap<>();
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index 7c50337a780f..5142d3cd2b99 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -50,10 +50,19 @@ public final class SystemUiDeviceConfigFlags {
// Flags related to controls
/**
- * (boolean) Wether to have split behavior when opening QS
+ * (boolean) Whether to have split behavior when opening QS
*/
public static final String QS_SPLIT_ENABLED = "qs_split_enabled";
+ /**
+ * (int) Open settings panels for WiFi and BT tiles
+ * 0 - default behavior, link to settings
+ * 1 - open panel on long press, click remains the same
+ * 2 - open panel on click, long press remains the same
+ * 3 - use details on long press
+ */
+ public static final String QS_USE_SETTINGS_PANELS = "qs_use_settings_panels";
+
// Flags related to Smart Suggestions - these are read in SmartReplyConstants.
/** (boolean) Whether to enable smart suggestions in notifications. */
diff --git a/core/java/com/android/internal/util/ScreenshotHelper.java b/core/java/com/android/internal/util/ScreenshotHelper.java
index 7fd94c6859fb..cac691cf7d45 100644
--- a/core/java/com/android/internal/util/ScreenshotHelper.java
+++ b/core/java/com/android/internal/util/ScreenshotHelper.java
@@ -1,6 +1,7 @@
package com.android.internal.util;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -13,6 +14,8 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
+import java.util.function.Consumer;
+
public class ScreenshotHelper {
private static final String TAG = "ScreenshotHelper";
@@ -34,17 +37,58 @@ public class ScreenshotHelper {
}
/**
+ * Request a screenshot be taken with a specific timeout.
+ *
+ * Added to support reducing unit test duration; the method variant without a timeout argument
+ * is recommended for general use.
+ *
+ * @param screenshotType The type of screenshot, for example either
+ * {@link android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN}
+ * or
+ * {@link android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION}
+ * @param hasStatus {@code true} if the status bar is currently showing. {@code false}
+ * if
+ * not.
+ * @param hasNav {@code true} if the navigation bar is currently showing. {@code
+ * false}
+ * if not.
+ * @param handler A handler used in case the screenshot times out
+ * @param completionConsumer Consumes `false` if a screenshot was not taken, and `true` if the
+ * screenshot was taken.
+ */
+ public void takeScreenshot(final int screenshotType, final boolean hasStatus,
+ final boolean hasNav, @NonNull Handler handler,
+ @Nullable Consumer<Boolean> completionConsumer) {
+ takeScreenshot(screenshotType, hasStatus, hasNav, SCREENSHOT_TIMEOUT_MS, handler,
+ completionConsumer);
+ }
+
+ /**
* Request a screenshot be taken.
*
- * @param screenshotType The type of screenshot, for example either
- * {@link android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN}
- * or {@link android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION}
- * @param hasStatus {@code true} if the status bar is currently showing. {@code false} if not.
- * @param hasNav {@code true} if the navigation bar is currently showing. {@code false} if not.
- * @param handler A handler used in case the screenshot times out
+ * Added to support reducing unit test duration; the method variant without a timeout argument
+ * is recommended for general use.
+ *
+ * @param screenshotType The type of screenshot, for example either
+ * {@link android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN}
+ * or
+ * {@link android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION}
+ * @param hasStatus {@code true} if the status bar is currently showing. {@code false}
+ * if
+ * not.
+ * @param hasNav {@code true} if the navigation bar is currently showing. {@code
+ * false}
+ * if not.
+ * @param timeoutMs If the screenshot hasn't been completed within this time period,
+ * the screenshot attempt will be cancelled and `completionConsumer`
+ * will be run.
+ * @param handler A handler used in case the screenshot times out
+ * @param completionConsumer Consumes `false` if a screenshot was not taken, and `true` if the
+ * screenshot was taken.
*/
public void takeScreenshot(final int screenshotType, final boolean hasStatus,
- final boolean hasNav, @NonNull Handler handler) {
+ final boolean hasNav, long timeoutMs, @NonNull Handler handler,
+ @Nullable Consumer<Boolean> completionConsumer) {
synchronized (mScreenshotLock) {
if (mScreenshotConnection != null) {
return;
@@ -54,7 +98,8 @@ public class ScreenshotHelper {
final Intent serviceIntent = new Intent();
final Runnable mScreenshotTimeout = new Runnable() {
- @Override public void run() {
+ @Override
+ public void run() {
synchronized (mScreenshotLock) {
if (mScreenshotConnection != null) {
mContext.unbindService(mScreenshotConnection);
@@ -62,6 +107,9 @@ public class ScreenshotHelper {
notifyScreenshotError();
}
}
+ if (completionConsumer != null) {
+ completionConsumer.accept(false);
+ }
}
};
@@ -86,15 +134,22 @@ public class ScreenshotHelper {
handler.removeCallbacks(mScreenshotTimeout);
}
}
+ if (completionConsumer != null) {
+ completionConsumer.accept(true);
+ }
}
};
msg.replyTo = new Messenger(h);
- msg.arg1 = hasStatus ? 1: 0;
- msg.arg2 = hasNav ? 1: 0;
+ msg.arg1 = hasStatus ? 1 : 0;
+ msg.arg2 = hasNav ? 1 : 0;
+
try {
messenger.send(msg);
} catch (RemoteException e) {
Log.e(TAG, "Couldn't take screenshot: " + e);
+ if (completionConsumer != null) {
+ completionConsumer.accept(false);
+ }
}
}
}
@@ -115,7 +170,7 @@ public class ScreenshotHelper {
Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
UserHandle.CURRENT)) {
mScreenshotConnection = conn;
- handler.postDelayed(mScreenshotTimeout, SCREENSHOT_TIMEOUT_MS);
+ handler.postDelayed(mScreenshotTimeout, timeoutMs);
}
}
}
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index a52a7ed982ec..4cb2d1502610 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -658,6 +658,12 @@ static jlong android_os_Process_getTotalMemory(JNIEnv* env, jobject clazz)
return si.totalram;
}
+/*
+ * The outFields array is initialized to -1 to allow the caller to identify
+ * when the status file (and therefore the process) they specified is invalid.
+ * This array should not be overwritten or cleared before we know that the
+ * status file can be read.
+ */
void android_os_Process_readProcLines(JNIEnv* env, jobject clazz, jstring fileStr,
jobjectArray reqFields, jlongArray outFields)
{
@@ -706,14 +712,14 @@ void android_os_Process_readProcLines(JNIEnv* env, jobject clazz, jstring fileSt
return;
}
- //ALOGI("Clearing %" PRId32 " sizes", count);
- for (i=0; i<count; i++) {
- sizesArray[i] = 0;
- }
-
int fd = open(file.string(), O_RDONLY | O_CLOEXEC);
if (fd >= 0) {
+ //ALOGI("Clearing %" PRId32 " sizes", count);
+ for (i=0; i<count; i++) {
+ sizesArray[i] = 0;
+ }
+
const size_t BUFFER_SIZE = 4096;
char* buffer = (char*)malloc(BUFFER_SIZE);
int len = read(fd, buffer, BUFFER_SIZE-1);
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 67f52f464efa..bf0f10eb50c6 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -397,15 +397,6 @@ static void nativeSetGeometry(JNIEnv* env, jclass clazz, jlong transactionObj, j
transaction->setGeometry(ctrl, source, dst, orientation);
}
-static void nativeSetGeometryAppliesWithResize(JNIEnv* env, jclass clazz,
-jlong transactionObj,
- jlong nativeObject) {
- auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
-
- SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
- transaction->setGeometryAppliesWithResize(ctrl);
-}
-
static void nativeSetSize(JNIEnv* env, jclass clazz, jlong transactionObj,
jlong nativeObject, jint w, jint h) {
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
@@ -1295,8 +1286,6 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
(void*)nativeSetRelativeLayer },
{"nativeSetPosition", "(JJFF)V",
(void*)nativeSetPosition },
- {"nativeSetGeometryAppliesWithResize", "(JJ)V",
- (void*)nativeSetGeometryAppliesWithResize },
{"nativeSetSize", "(JJII)V",
(void*)nativeSetSize },
{"nativeSetTransparentRegionHint", "(JJLandroid/graphics/Region;)V",
diff --git a/core/proto/android/view/displayinfo.proto b/core/proto/android/view/displayinfo.proto
index 49c0a290c368..984be2a2e417 100644
--- a/core/proto/android/view/displayinfo.proto
+++ b/core/proto/android/view/displayinfo.proto
@@ -33,4 +33,5 @@ message DisplayInfoProto {
// The human-readable name of the display.
// Eg: "Built-in Screen"
optional string name = 5;
+ optional int32 flags = 6;
}
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index b2f9183e4457..797d75f5a54f 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1256,10 +1256,10 @@
<string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string>
<string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string>
<string name="wifi_available_action_all_networks" msgid="4368435796357931006">"All networks"</string>
- <string name="wifi_suggestion_title" msgid="6396033039578436801">"Allow suggested Wi‑Fi networks?"</string>
- <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> suggested networks. Device may connect automatically."</string>
- <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Allow"</string>
- <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"No, thanks"</string>
+ <string name="wifi_suggestion_title" msgid="9099832833531486167">"Connect to Wi‑Fi networks?"</string>
+ <string name="wifi_suggestion_content" msgid="5883181205841582873">"Suggested by <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string>
+ <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string>
<string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi will turn on automatically"</string>
<string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"When you\'re near a high‑quality saved network"</string>
<string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Don\'t turn back on"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index a6aa60430425..7ea76500e4ea 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -1256,10 +1256,10 @@
<string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‏‎‎‏‏‎‏‎‏‎‏‎Tap to see all networks‎‏‎‎‏‎"</string>
<string name="wifi_available_action_connect" msgid="2635699628459488788">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‏‏‏‏‎‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‎‎Connect‎‏‎‎‏‎"</string>
<string name="wifi_available_action_all_networks" msgid="4368435796357931006">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‏‎‏‏‎‎‎‏‏‏‎‏‎‎‎‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎All networks‎‏‎‎‏‎"</string>
- <string name="wifi_suggestion_title" msgid="6396033039578436801">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‎‎‎‏‎‏‎‎‏‎‏‏‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‎‏‎‎‏‏‎‎‎‎‎‏‎Allow suggested Wi‑Fi networks?‎‏‎‎‏‎"</string>
- <string name="wifi_suggestion_content" msgid="5603992011371520746">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎ suggested networks. Device may connect automatically.‎‏‎‎‏‎"</string>
- <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‎‏‏‎‎‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‏‎‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎‏‏‎‏‎Allow‎‏‎‎‏‎"</string>
- <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‎‎‎‎‏‎‏‏‎‎‎‏‎‎‎‎‏‏‎‎‎‎‏‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‎‎‏‎‏‎‎‎No thanks‎‏‎‎‏‎"</string>
+ <string name="wifi_suggestion_title" msgid="9099832833531486167">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‎‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‏‎‏‎‎‏‎‎‏‏‏‏‏‏‏‎‏‎‏‏‏‎Connect to Wi‑Fi networks?‎‏‎‎‏‎"</string>
+ <string name="wifi_suggestion_content" msgid="5883181205841582873">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‎‏‎‏‎‏‎‎‎‎‏‎‎‎‏‎‎‎‏‎‏‏‏‎‎‎‏‏‎‏‏‏‎‎‎‏‎‎‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎Suggested by ‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+ <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎‏‎‏‎‏‎‏‎‎‏‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‎‏‎‏‎Yes‎‏‎‎‏‎"</string>
+ <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‏‏‏‎‏‎‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‎‏‎No‎‏‎‎‏‎"</string>
<string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎‏‏‎‏‎‎‎‏‎‏‎‎‎‏‎‎‎‏‏‏‎‏‎‎‎Wi‑Fi will turn on automatically‎‏‎‎‏‎"</string>
<string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎‎‎‎‏‏‎‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‎When you\'re near a high quality saved network‎‏‎‎‏‎"</string>
<string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‎‏‏‎‏‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‎Don\'t turn back on‎‏‎‎‏‎"</string>
diff --git a/core/tests/coretests/src/android/os/ProcessTest.java b/core/tests/coretests/src/android/os/ProcessTest.java
index 9de450196fa0..ae4edb97aab0 100644
--- a/core/tests/coretests/src/android/os/ProcessTest.java
+++ b/core/tests/coretests/src/android/os/ProcessTest.java
@@ -17,13 +17,12 @@
package android.os;
-import androidx.test.filters.MediumTest;
-
import junit.framework.TestCase;
public class ProcessTest extends TestCase {
- @MediumTest
+ private static final int BAD_PID = 0;
+
public void testProcessGetUidFromName() throws Exception {
assertEquals(android.os.Process.SYSTEM_UID, Process.getUidForName("system"));
assertEquals(Process.BLUETOOTH_UID, Process.getUidForName("bluetooth"));
@@ -37,7 +36,6 @@ public class ProcessTest extends TestCase {
Process.getUidForName("u3_a100"));
}
- @MediumTest
public void testProcessGetUidFromNameFailure() throws Exception {
// Failure cases
assertEquals(-1, Process.getUidForName("u2a_foo"));
@@ -49,4 +47,29 @@ public class ProcessTest extends TestCase {
assertEquals(-1, Process.getUidForName("u2jhsajhfkjhsafkhskafhkashfkjashfkjhaskjfdhakj3"));
}
+ /**
+ * Tests getUidForPid() by ensuring that it returns the correct value when the process queried
+ * doesn't exist.
+ */
+ public void testGetUidForPidInvalidPid() {
+ assertEquals(-1, Process.getUidForPid(BAD_PID));
+ }
+
+ /**
+ * Tests getParentPid() by ensuring that it returns the correct value when the process queried
+ * doesn't exist.
+ */
+ public void testGetParentPidInvalidPid() {
+ assertEquals(-1, Process.getParentPid(BAD_PID));
+ }
+
+ /**
+ * Tests getThreadGroupLeader() by ensuring that it returns the correct value when the
+ * thread queried doesn't exist.
+ */
+ public void testGetThreadGroupLeaderInvalidTid() {
+ // This function takes a TID instead of a PID but BAD_PID should also be a bad TID.
+ assertEquals(-1, Process.getThreadGroupLeader(BAD_PID));
+ }
+
}
diff --git a/core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java b/core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java
index 6161108d4d70..a5a98a98f0be 100644
--- a/core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java
+++ b/core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java
@@ -19,6 +19,8 @@ package android.service.notification;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -181,6 +183,22 @@ public class StatusBarNotificationTest {
logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_STYLE));
}
+ @Test
+ public void testIsAppGroup() {
+ StatusBarNotification sbn = getNotification(PKG, GROUP_ID_1, CHANNEL_ID);
+ assertTrue(sbn.isAppGroup());
+
+ sbn = getNotification(PKG, null, CHANNEL_ID);
+ assertFalse(sbn.isAppGroup());
+
+ Notification.Builder nb = getNotificationBuilder(null, CHANNEL_ID)
+ .setSortKey("something");
+
+ sbn = getNotification(PKG, nb);
+ assertTrue(sbn.isAppGroup());
+
+ }
+
private StatusBarNotification getNotification(String pkg, String group, String channelId) {
return getNotification(pkg, getNotificationBuilder(group, channelId));
}
diff --git a/core/tests/screenshothelpertests/Android.bp b/core/tests/screenshothelpertests/Android.bp
new file mode 100644
index 000000000000..3d54b68b7ddc
--- /dev/null
+++ b/core/tests/screenshothelpertests/Android.bp
@@ -0,0 +1,28 @@
+android_test {
+ name: "ScreenshotHelperTests",
+
+ srcs: [
+ "src/**/*.java",
+ ],
+
+ static_libs: [
+ "frameworks-base-testutils",
+ "androidx.test.runner",
+ "androidx.test.rules",
+ "androidx.test.ext.junit",
+ "mockito-target-minus-junit4",
+ "platform-test-annotations",
+ ],
+
+ libs: [
+ "android.test.runner",
+ "android.test.base",
+ "android.test.mock",
+ ],
+
+ platform_apis: true,
+ test_suites: ["device-tests"],
+
+ certificate: "platform",
+}
+
diff --git a/core/tests/screenshothelpertests/AndroidManifest.xml b/core/tests/screenshothelpertests/AndroidManifest.xml
new file mode 100644
index 000000000000..2e12ef4db358
--- /dev/null
+++ b/core/tests/screenshothelpertests/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ android:installLocation="internalOnly"
+ package="com.android.internal.util"
+ android:sharedUserId="android.uid.systemui" >
+
+ <application >
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.internal.util"
+ android:label="Screenshot Helper Tests" />
+
+ <protected-broadcast android:name="android.intent.action.USER_PRESENT" />
+
+</manifest>
diff --git a/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java b/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java
new file mode 100644
index 000000000000..848364584ef3
--- /dev/null
+++ b/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
+import static android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.fail;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public final class ScreenshotHelperTest {
+ private Context mContext;
+ private ScreenshotHelper mScreenshotHelper;
+ private Handler mHandler;
+
+
+ @Before
+ public void setUp() {
+ // `ScreenshotHelper.notifyScreenshotError()` calls `Context.sendBroadcastAsUser()` and
+ // `Context.bindServiceAsUser`.
+ //
+ // This raises a `SecurityException` if the device is locked. Calling either `Context`
+ // method results in a broadcast of `android.intent.action. USER_PRESENT`. Only the system
+ // process is allowed to broadcast that `Intent`.
+ mContext = Mockito.spy(Context.class);
+ Mockito.doNothing().when(mContext).sendBroadcastAsUser(any(), any());
+ Mockito.doReturn(true).when(mContext).bindServiceAsUser(any(), any(), anyInt(), any());
+
+ mHandler = new Handler(Looper.getMainLooper());
+ mScreenshotHelper = new ScreenshotHelper(mContext);
+ }
+
+ @Test
+ public void testFullscreenScreenshot() {
+ mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN, false, false, mHandler, null);
+ }
+
+ @Test
+ public void testSelectedRegionScreenshot() {
+ mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_SELECTED_REGION, false, false, mHandler,
+ null);
+ }
+
+ @Test
+ public void testScreenshotTimesOut() {
+ long timeoutMs = 10;
+
+ CountDownLatch lock = new CountDownLatch(1);
+ mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN, false, false, timeoutMs,
+ mHandler,
+ worked -> {
+ assertFalse(worked);
+ lock.countDown();
+ });
+
+ try {
+ // Add tolerance for delay to prevent flakes.
+ long awaitDurationMs = timeoutMs + 100;
+ if (!lock.await(awaitDurationMs, TimeUnit.MILLISECONDS)) {
+ fail("lock never freed");
+ }
+ } catch (InterruptedException e) {
+ fail("lock interrupted");
+ }
+ }
+}
diff --git a/libs/hwui/service/GraphicsStatsService.cpp b/libs/hwui/service/GraphicsStatsService.cpp
index 8b5912b2081a..12c5b836f711 100644
--- a/libs/hwui/service/GraphicsStatsService.cpp
+++ b/libs/hwui/service/GraphicsStatsService.cpp
@@ -282,9 +282,9 @@ void dumpAsTextToFd(protos::GraphicsStatsProto* proto, int fd) {
return;
}
dprintf(fd, "\nPackage: %s", proto->package_name().c_str());
- dprintf(fd, "\nVersion: %lld", proto->version_code());
- dprintf(fd, "\nStats since: %lldns", proto->stats_start());
- dprintf(fd, "\nStats end: %lldns", proto->stats_end());
+ dprintf(fd, "\nVersion: %" PRId64, proto->version_code());
+ dprintf(fd, "\nStats since: %" PRId64 "ns", proto->stats_start());
+ dprintf(fd, "\nStats end: %" PRId64 "ns", proto->stats_end());
auto summary = proto->summary();
dprintf(fd, "\nTotal frames rendered: %d", summary.total_frames());
dprintf(fd, "\nJanky frames: %d (%.2f%%)", summary.janky_frames(),
diff --git a/libs/protoutil/include/android/util/ProtoOutputStream.h b/libs/protoutil/include/android/util/ProtoOutputStream.h
index a6af4757a140..42bf03e6de05 100644
--- a/libs/protoutil/include/android/util/ProtoOutputStream.h
+++ b/libs/protoutil/include/android/util/ProtoOutputStream.h
@@ -98,6 +98,7 @@ public:
bool write(uint64_t fieldId, double val);
bool write(uint64_t fieldId, float val);
bool write(uint64_t fieldId, int val);
+ bool write(uint64_t fieldId, long val);
bool write(uint64_t fieldId, long long val);
bool write(uint64_t fieldId, bool val);
bool write(uint64_t fieldId, std::string val);
diff --git a/libs/protoutil/src/ProtoOutputStream.cpp b/libs/protoutil/src/ProtoOutputStream.cpp
index 6cfa357b580b..ea9b79a0353f 100644
--- a/libs/protoutil/src/ProtoOutputStream.cpp
+++ b/libs/protoutil/src/ProtoOutputStream.cpp
@@ -116,6 +116,34 @@ ProtoOutputStream::write(uint64_t fieldId, int val)
}
bool
+ProtoOutputStream::write(uint64_t fieldId, long val)
+{
+ if (mCompact) return false;
+ const uint32_t id = (uint32_t)fieldId;
+ switch (fieldId & FIELD_TYPE_MASK) {
+ case FIELD_TYPE_DOUBLE: writeDoubleImpl(id, (double)val); break;
+ case FIELD_TYPE_FLOAT: writeFloatImpl(id, (float)val); break;
+ case FIELD_TYPE_INT64: writeInt64Impl(id, (long long)val); break;
+ case FIELD_TYPE_UINT64: writeUint64Impl(id, (uint64_t)val); break;
+ case FIELD_TYPE_INT32: writeInt32Impl(id, (int)val); break;
+ case FIELD_TYPE_FIXED64: writeFixed64Impl(id, (uint64_t)val); break;
+ case FIELD_TYPE_FIXED32: writeFixed32Impl(id, (uint32_t)val); break;
+ case FIELD_TYPE_UINT32: writeUint32Impl(id, (uint32_t)val); break;
+ case FIELD_TYPE_SFIXED32: writeSFixed32Impl(id, (int)val); break;
+ case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (long long)val); break;
+ case FIELD_TYPE_SINT32: writeZigzagInt32Impl(id, (int)val); break;
+ case FIELD_TYPE_SINT64: writeZigzagInt64Impl(id, (long long)val); break;
+ case FIELD_TYPE_ENUM: writeEnumImpl(id, (int)val); break;
+ case FIELD_TYPE_BOOL: writeBoolImpl(id, val != 0); break;
+ default:
+ ALOGW("Field type %d is not supported when writing long val.",
+ (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT));
+ return false;
+ }
+ return true;
+}
+
+bool
ProtoOutputStream::write(uint64_t fieldId, long long val)
{
return internalWrite(fieldId, val, "long long");
diff --git a/packages/BackupEncryption/Android.bp b/packages/BackupEncryption/Android.bp
new file mode 100644
index 000000000000..50dbcdb1b4c7
--- /dev/null
+++ b/packages/BackupEncryption/Android.bp
@@ -0,0 +1,24 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+android_app {
+ name: "BackupEncryption",
+ srcs: ["src/**/*.java"],
+ optimize: { enabled: false },
+ platform_apis: true,
+ certificate: "platform",
+ privileged: true,
+} \ No newline at end of file
diff --git a/packages/BackupEncryption/AndroidManifest.xml b/packages/BackupEncryption/AndroidManifest.xml
new file mode 100644
index 000000000000..a705df5a425b
--- /dev/null
+++ b/packages/BackupEncryption/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.server.backup.encryption"
+ android:sharedUserId="android.uid.system" >
+
+ <application android:allowBackup="false" />
+</manifest>
diff --git a/packages/BackupEncryption/proguard.flags b/packages/BackupEncryption/proguard.flags
new file mode 100644
index 000000000000..851ce8caab43
--- /dev/null
+++ b/packages/BackupEncryption/proguard.flags
@@ -0,0 +1 @@
+-keep class com.android.server.backup.encryption
diff --git a/services/backup/java/com/android/server/backup/encryption/chunk/Chunk.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/Chunk.java
index 5bec1a94e915..ba328609a77e 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunk/Chunk.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/Chunk.java
@@ -1,3 +1,19 @@
+/*
+ * 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.server.backup.encryption.chunk;
import android.util.proto.ProtoInputStream;
@@ -51,4 +67,4 @@ public class Chunk {
public byte[] getHash() {
return mHash;
}
-} \ No newline at end of file
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/chunk/ChunkHash.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/ChunkHash.java
index 1ae598ec9920..1630eb8ff4e8 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunk/ChunkHash.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/ChunkHash.java
@@ -11,12 +11,13 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunk;
import com.android.internal.util.Preconditions;
+
import java.util.Arrays;
import java.util.Base64;
diff --git a/services/backup/java/com/android/server/backup/encryption/chunk/ChunkListingMap.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/ChunkListingMap.java
index a44890118717..a44890118717 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunk/ChunkListingMap.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/ChunkListingMap.java
diff --git a/services/backup/java/com/android/server/backup/encryption/chunk/ChunkOrderingType.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/ChunkOrderingType.java
index df36c9409732..8cb028e46e9d 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunk/ChunkOrderingType.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/ChunkOrderingType.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunk;
@@ -21,6 +21,7 @@ import static com.android.server.backup.encryption.chunk.ChunksMetadataProto.EXP
import static com.android.server.backup.encryption.chunk.ChunksMetadataProto.INLINE_LENGTHS;
import android.annotation.IntDef;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
diff --git a/services/backup/java/com/android/server/backup/encryption/chunk/EncryptedChunkOrdering.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrdering.java
index 3a6d1f62faaa..edf1b9abb822 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunk/EncryptedChunkOrdering.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrdering.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunk;
@@ -38,6 +38,7 @@ public class EncryptedChunkOrdering {
private final byte[] mEncryptedChunkOrdering;
+ /** Get the encrypted chunk ordering */
public byte[] encryptedChunkOrdering() {
return mEncryptedChunkOrdering;
}
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/BackupWriter.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/BackupWriter.java
index 68d9d145139f..baa820cbd558 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunking/BackupWriter.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/BackupWriter.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunking;
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/ByteRange.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ByteRange.java
index 004d9e3b45f1..004d9e3b45f1 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunking/ByteRange.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ByteRange.java
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/ChunkEncryptor.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ChunkEncryptor.java
index 812cfbd76e31..48abc8cc4088 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunking/ChunkEncryptor.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ChunkEncryptor.java
@@ -11,16 +11,18 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunking;
import com.android.server.backup.encryption.chunk.ChunkHash;
+
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
+
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/ChunkHasher.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ChunkHasher.java
index 145b7bf82517..02d498ccd726 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunking/ChunkHasher.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ChunkHasher.java
@@ -11,14 +11,16 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunking;
import com.android.server.backup.encryption.chunk.ChunkHash;
+
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
+
import javax.crypto.Mac;
import javax.crypto.SecretKey;
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/Chunker.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/Chunker.java
index b91913e5fc80..c9a6293ed060 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunking/Chunker.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/Chunker.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunking;
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutput.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutput.java
index ae2e150de4bc..ae2e150de4bc 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutput.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutput.java
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/DiffScriptBackupWriter.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriter.java
index 69fb5cbf606d..69fb5cbf606d 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunking/DiffScriptBackupWriter.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriter.java
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/DiffScriptWriter.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/DiffScriptWriter.java
index 49d15712d4cc..49d15712d4cc 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunking/DiffScriptWriter.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/DiffScriptWriter.java
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/EncryptedChunk.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/EncryptedChunk.java
index 1f936eb2bfa5..cde59fa189de 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunking/EncryptedChunk.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/EncryptedChunk.java
@@ -11,13 +11,14 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunking;
import com.android.internal.util.Preconditions;
import com.android.server.backup.encryption.chunk.ChunkHash;
+
import java.util.Arrays;
import java.util.Objects;
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/EncryptedChunkEncoder.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/EncryptedChunkEncoder.java
index eaf701ce0bf5..16beda32af17 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunking/EncryptedChunkEncoder.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/EncryptedChunkEncoder.java
@@ -11,12 +11,13 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunking;
import com.android.server.backup.encryption.chunk.ChunkOrderingType;
+
import java.io.IOException;
/** Encodes an {@link EncryptedChunk} as bytes to write to the encrypted backup file. */
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoder.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoder.java
index 5c902cad7495..7b38dd4a1dc3 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoder.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoder.java
@@ -11,13 +11,14 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunking;
import com.android.server.backup.encryption.chunk.ChunkOrderingType;
import com.android.server.backup.encryption.chunk.ChunksMetadataProto;
+
import java.io.IOException;
/**
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoder.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoder.java
index 4b849818f1c3..567f75d59513 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoder.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoder.java
@@ -11,13 +11,14 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunking;
import com.android.server.backup.encryption.chunk.ChunkOrderingType;
import com.android.server.backup.encryption.chunk.ChunksMetadataProto;
+
import java.io.IOException;
/**
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/OutputStreamWrapper.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/OutputStreamWrapper.java
index 4aea60121810..4aea60121810 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunking/OutputStreamWrapper.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/OutputStreamWrapper.java
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/RawBackupWriter.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/RawBackupWriter.java
index 839dc7c7b5ce..b211b0fc9470 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunking/RawBackupWriter.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/RawBackupWriter.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunking;
@@ -21,18 +21,18 @@ import java.io.OutputStream;
/** Writes data straight to an output stream. */
public class RawBackupWriter implements BackupWriter {
- private final OutputStream outputStream;
- private long bytesWritten;
+ private final OutputStream mOutputStream;
+ private long mBytesWritten;
/** Constructs a new writer which writes bytes to the given output stream. */
public RawBackupWriter(OutputStream outputStream) {
- this.outputStream = outputStream;
+ this.mOutputStream = outputStream;
}
@Override
public void writeBytes(byte[] bytes) throws IOException {
- outputStream.write(bytes);
- bytesWritten += bytes.length;
+ mOutputStream.write(bytes);
+ mBytesWritten += bytes.length;
}
@Override
@@ -42,11 +42,11 @@ public class RawBackupWriter implements BackupWriter {
@Override
public long getBytesWritten() {
- return bytesWritten;
+ return mBytesWritten;
}
@Override
public void flush() throws IOException {
- outputStream.flush();
+ mOutputStream.flush();
}
}
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriter.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriter.java
index 0e4bd58345d5..0e4bd58345d5 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriter.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriter.java
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunker.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunker.java
index 18011f620b24..18011f620b24 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunker.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunker.java
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/cdc/FingerprintMixer.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/FingerprintMixer.java
index e9f30505c112..e9f30505c112 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunking/cdc/FingerprintMixer.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/FingerprintMixer.java
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/cdc/Hkdf.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/Hkdf.java
index 6f4f549ab2d7..6f4f549ab2d7 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunking/cdc/Hkdf.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/Hkdf.java
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpoint.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpoint.java
index e867e7c1b801..e867e7c1b801 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpoint.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpoint.java
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64.java
index 1e14ffa5ad77..1e14ffa5ad77 100644
--- a/services/backup/java/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64.java
diff --git a/services/backup/java/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKey.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKey.java
index f356b4f102e2..f356b4f102e2 100644
--- a/services/backup/java/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKey.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKey.java
diff --git a/services/backup/java/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManager.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManager.java
index c89076b9928f..c89076b9928f 100644
--- a/services/backup/java/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManager.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManager.java
diff --git a/services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyGenerator.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyGenerator.java
index a425c720b9b8..a425c720b9b8 100644
--- a/services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyGenerator.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyGenerator.java
diff --git a/services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyRotationTracker.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTracker.java
index ec90f6c8c95e..ec90f6c8c95e 100644
--- a/services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyRotationTracker.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTracker.java
diff --git a/services/backup/java/com/android/server/backup/encryption/storage/BackupEncryptionDb.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/BackupEncryptionDb.java
index 9f6c03a6f393..9f6c03a6f393 100644
--- a/services/backup/java/com/android/server/backup/encryption/storage/BackupEncryptionDb.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/BackupEncryptionDb.java
diff --git a/services/backup/java/com/android/server/backup/encryption/storage/BackupEncryptionDbContract.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/BackupEncryptionDbContract.java
index 5e8a8d9fc2ae..5e8a8d9fc2ae 100644
--- a/services/backup/java/com/android/server/backup/encryption/storage/BackupEncryptionDbContract.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/BackupEncryptionDbContract.java
diff --git a/services/backup/java/com/android/server/backup/encryption/storage/BackupEncryptionDbHelper.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/BackupEncryptionDbHelper.java
index c70634248dca..c70634248dca 100644
--- a/services/backup/java/com/android/server/backup/encryption/storage/BackupEncryptionDbHelper.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/BackupEncryptionDbHelper.java
diff --git a/services/backup/java/com/android/server/backup/encryption/storage/EncryptionDbException.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/EncryptionDbException.java
index 82f7dead1b50..82f7dead1b50 100644
--- a/services/backup/java/com/android/server/backup/encryption/storage/EncryptionDbException.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/EncryptionDbException.java
diff --git a/services/backup/java/com/android/server/backup/encryption/storage/TertiaryKey.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/TertiaryKey.java
index 39a2c6ebb9c3..39a2c6ebb9c3 100644
--- a/services/backup/java/com/android/server/backup/encryption/storage/TertiaryKey.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/TertiaryKey.java
diff --git a/services/backup/java/com/android/server/backup/encryption/storage/TertiaryKeysTable.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/TertiaryKeysTable.java
index d8d40c402a84..d8d40c402a84 100644
--- a/services/backup/java/com/android/server/backup/encryption/storage/TertiaryKeysTable.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/TertiaryKeysTable.java
diff --git a/services/backup/java/com/android/server/backup/encryption/tasks/BackupEncrypter.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/BackupEncrypter.java
index 95d0d97b4073..95d0d97b4073 100644
--- a/services/backup/java/com/android/server/backup/encryption/tasks/BackupEncrypter.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/BackupEncrypter.java
diff --git a/services/backup/java/com/android/server/backup/encryption/tasks/BackupStreamEncrypter.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/BackupStreamEncrypter.java
index 45798d32885a..45798d32885a 100644
--- a/services/backup/java/com/android/server/backup/encryption/tasks/BackupStreamEncrypter.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/BackupStreamEncrypter.java
diff --git a/services/backup/java/com/android/server/backup/encryption/tasks/DecryptedChunkOutput.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/DecryptedChunkOutput.java
index e3df3c1eb96f..e3df3c1eb96f 100644
--- a/services/backup/java/com/android/server/backup/encryption/tasks/DecryptedChunkOutput.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/DecryptedChunkOutput.java
diff --git a/services/backup/java/com/android/server/backup/encryption/tasks/EncryptedRestoreException.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedRestoreException.java
index 487c0d92f6fd..487c0d92f6fd 100644
--- a/services/backup/java/com/android/server/backup/encryption/tasks/EncryptedRestoreException.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedRestoreException.java
diff --git a/packages/BackupEncryption/test/robolectric/Android.bp b/packages/BackupEncryption/test/robolectric/Android.bp
new file mode 100644
index 000000000000..6d1abbb61a8e
--- /dev/null
+++ b/packages/BackupEncryption/test/robolectric/Android.bp
@@ -0,0 +1,32 @@
+// 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.
+
+android_robolectric_test {
+ name: "BackupEncryptionRoboTests",
+ srcs: [
+ "src/**/*.java",
+ ":FrameworksServicesRoboShadows",
+ ],
+ java_resource_dirs: ["config"],
+ libs: [
+ "platform-test-annotations",
+ "testng",
+ ],
+ instrumentation_for: "BackupEncryption",
+}
+
+filegroup {
+ name: "BackupEncryptionRoboShadows",
+ srcs: ["src/com/android/server/testing/shadows/**/*.java"],
+}
diff --git a/packages/BackupEncryption/test/robolectric/AndroidManifest.xml b/packages/BackupEncryption/test/robolectric/AndroidManifest.xml
new file mode 100644
index 000000000000..ae5cdd918abd
--- /dev/null
+++ b/packages/BackupEncryption/test/robolectric/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ coreApp="true"
+ package="com.android.server.backup.encryption.robotests">
+
+ <application/>
+
+</manifest>
diff --git a/packages/BackupEncryption/test/robolectric/config/robolectric.properties b/packages/BackupEncryption/test/robolectric/config/robolectric.properties
new file mode 100644
index 000000000000..26fceb3f84a4
--- /dev/null
+++ b/packages/BackupEncryption/test/robolectric/config/robolectric.properties
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+sdk=NEWEST_SDK
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/chunk/ChunkHashTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/ChunkHashTest.java
index 3f57240bc0e9..c12464c50175 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/chunk/ChunkHashTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/ChunkHashTest.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunk;
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/chunk/ChunkListingMapTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/ChunkListingMapTest.java
index 24e5573b891d..24e5573b891d 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/chunk/ChunkListingMapTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/ChunkListingMapTest.java
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/chunk/ChunkTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/ChunkTest.java
index 17c9a86169be..1796f56ce17a 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/chunk/ChunkTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/ChunkTest.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunk;
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrderingTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrderingTest.java
index 0bf14174e5c3..c6b29b7b7236 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrderingTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrderingTest.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunk;
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/ByteRangeTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ByteRangeTest.java
index 8df08262c9fa..8df08262c9fa 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/ByteRangeTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ByteRangeTest.java
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/ChunkEncryptorTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ChunkEncryptorTest.java
index d0e5fb335da9..19e3b28f85e7 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/ChunkEncryptorTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ChunkEncryptorTest.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunking;
@@ -78,22 +78,22 @@ public class ChunkEncryptorTest {
// Return NONCE_1, then NONCE_2 for invocations of mSecureRandomMock.nextBytes().
doAnswer(
- new Answer<Void>() {
- private int mInvocation = 0;
-
- @Override
- public Void answer(InvocationOnMock invocation) {
- byte[] nonceDestination = invocation.getArgument(0);
- System.arraycopy(
- NONCES[this.mInvocation],
- 0,
- nonceDestination,
- 0,
- GCM_NONCE_LENGTH_BYTES);
- this.mInvocation++;
- return null;
- }
- })
+ new Answer<Void>() {
+ private int mInvocation = 0;
+
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ byte[] nonceDestination = invocation.getArgument(0);
+ System.arraycopy(
+ NONCES[this.mInvocation],
+ 0,
+ nonceDestination,
+ 0,
+ GCM_NONCE_LENGTH_BYTES);
+ this.mInvocation++;
+ return null;
+ }
+ })
.when(mSecureRandomMock)
.nextBytes(any(byte[].class));
}
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/ChunkHasherTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ChunkHasherTest.java
index 2bbbf2857146..72a927db743d 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/ChunkHasherTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ChunkHasherTest.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunking;
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutputTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutputTest.java
index 823a63c22da4..823a63c22da4 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutputTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutputTest.java
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriterTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriterTest.java
index 2af6f2bee8ff..2af6f2bee8ff 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriterTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriterTest.java
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/EncryptedChunkTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/EncryptedChunkTest.java
index 8e801a133909..325b601e2ccb 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/EncryptedChunkTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/EncryptedChunkTest.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunking;
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoderTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoderTest.java
index 2f872beacd17..634acdc42eaf 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoderTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoderTest.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunking;
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoderTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoderTest.java
index 978bddb7301a..d231603e18b1 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoderTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoderTest.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunking;
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/RawBackupWriterTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/RawBackupWriterTest.java
index 19ef8fb339ba..966d3e2d583d 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/RawBackupWriterTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/RawBackupWriterTest.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.encryption.chunking;
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriterTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriterTest.java
index 73baf80a2c70..73baf80a2c70 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriterTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriterTest.java
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunkerTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunkerTest.java
index 77b734785424..77b734785424 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunkerTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunkerTest.java
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/cdc/FingerprintMixerTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/FingerprintMixerTest.java
index 936b5dca033d..936b5dca033d 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/cdc/FingerprintMixerTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/FingerprintMixerTest.java
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/cdc/HkdfTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/HkdfTest.java
index 549437454e9c..549437454e9c 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/cdc/HkdfTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/HkdfTest.java
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpointTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpointTest.java
index 277dc372e73c..277dc372e73c 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpointTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpointTest.java
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64Test.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64Test.java
index 729580cf5101..729580cf5101 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64Test.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64Test.java
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManagerTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManagerTest.java
index 5342efa18a97..5342efa18a97 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManagerTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManagerTest.java
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyTest.java
index 89977f82c145..89977f82c145 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyTest.java
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/keys/TertiaryKeyGeneratorTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyGeneratorTest.java
index 48216f8d7aca..48216f8d7aca 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/keys/TertiaryKeyGeneratorTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyGeneratorTest.java
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTrackerTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTrackerTest.java
index 49bb410ceb65..49bb410ceb65 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTrackerTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTrackerTest.java
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/storage/BackupEncryptionDbTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/storage/BackupEncryptionDbTest.java
index 87f21bfa59c2..87f21bfa59c2 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/storage/BackupEncryptionDbTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/storage/BackupEncryptionDbTest.java
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/storage/TertiaryKeysTableTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/storage/TertiaryKeysTableTest.java
index 319ec89f445e..319ec89f445e 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/storage/TertiaryKeysTableTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/storage/TertiaryKeysTableTest.java
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/tasks/BackupStreamEncrypterTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/BackupStreamEncrypterTest.java
index 21c4e07577da..21c4e07577da 100644
--- a/services/robotests/backup/src/com/android/server/backup/encryption/tasks/BackupStreamEncrypterTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/BackupStreamEncrypterTest.java
diff --git a/services/robotests/backup/src/com/android/server/backup/testing/RandomInputStream.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/testing/RandomInputStream.java
index 998da0bf9696..998da0bf9696 100644
--- a/services/robotests/backup/src/com/android/server/backup/testing/RandomInputStream.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/testing/RandomInputStream.java
diff --git a/services/robotests/backup/src/com/android/server/backup/testing/CryptoTestUtils.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/CryptoTestUtils.java
index 0428796f51fa..3f3494d2c22c 100644
--- a/services/robotests/backup/src/com/android/server/backup/testing/CryptoTestUtils.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/CryptoTestUtils.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.backup.testing;
diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowInternalRecoveryServiceException.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowInternalRecoveryServiceException.java
index 9c06d81ce550..9c06d81ce550 100644
--- a/services/robotests/src/com/android/server/testing/shadows/ShadowInternalRecoveryServiceException.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowInternalRecoveryServiceException.java
diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowRecoveryController.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowRecoveryController.java
index 7dad8a4e3ff3..7dad8a4e3ff3 100644
--- a/services/robotests/src/com/android/server/testing/shadows/ShadowRecoveryController.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowRecoveryController.java
diff --git a/packages/CarSystemUI/res/values/integers_car.xml b/packages/CarSystemUI/res/values/integers_car.xml
index 862ba751aa55..fb67b302a4ae 100644
--- a/packages/CarSystemUI/res/values/integers_car.xml
+++ b/packages/CarSystemUI/res/values/integers_car.xml
@@ -32,6 +32,6 @@
at will result in remaining closed the panel if released-->
<integer name="notification_settle_close_percentage">80</integer>
<!-- The delay before the unlock dialog pops up -->
- <integer name="unlock_dialog_delay_ms">3000</integer>
+ <integer name="unlock_dialog_delay_ms">0</integer>
</resources>
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIRootComponent.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIRootComponent.java
index d6b766b80939..27146fbac789 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIRootComponent.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIRootComponent.java
@@ -26,6 +26,7 @@ import dagger.Component;
DependencyProvider.class,
DependencyBinder.class,
ServiceBinder.class,
+ SystemUIBinder.class,
SystemUIFactory.ContextHolder.class,
SystemUIModule.class,
CarSystemUIModule.class
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index e591121d4b59..83636dc19beb 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -143,7 +143,7 @@
<string name="data_usage_ota" msgid="5377889154805560860">"సిస్టమ్ అప్‌డేట్‌లు"</string>
<string name="tether_settings_title_usb" msgid="6688416425801386511">"USB టీథరింగ్"</string>
<string name="tether_settings_title_wifi" msgid="3277144155960302049">"పోర్టబుల్ హాట్‌స్పాట్"</string>
- <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"బ్లూటూత్ టెథెరింగ్"</string>
+ <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"బ్లూటూత్ టీథరింగ్"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"టీథరింగ్"</string>
<string name="tether_settings_title_all" msgid="8356136101061143841">"టీథరింగ్ &amp; పోర్టబుల్ హాట్‌స్పాట్"</string>
<string name="managed_user_title" msgid="8109605045406748842">"అన్ని కార్యాలయ అనువర్తనాలు"</string>
@@ -376,7 +376,7 @@
<string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"ప్రొటానోమలీ (ఎరుపు-ఆకుపచ్చ రంగు)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"ట్రైటనోమలీ (నీలం-పసుపు రంగు)"</string>
<string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"రంగు సవరణ"</string>
- <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ఈ ఫీచ‌ర్‌ ప్రయోగాత్మకమైనది, పనితీరుపై ప్రభావం చూపవచ్చు."</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ఈ లక్షణం ప్రయోగాత్మకమైనది మరియు పనితీరుపై ప్రభావం చూపవచ్చు."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ద్వారా భర్తీ చేయబడింది"</string>
<string name="power_remaining_settings_home_page" msgid="4845022416859002011">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="6123167166221295462">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> సమయం మిగిలి ఉంది"</string>
@@ -414,7 +414,7 @@
<string name="disabled" msgid="9206776641295849915">"నిలిపివేయబడింది"</string>
<string name="external_source_trusted" msgid="2707996266575928037">"అనుమతించినవి"</string>
<string name="external_source_untrusted" msgid="2677442511837596726">"అనుమతించబడలేదు"</string>
- <string name="install_other_apps" msgid="6986686991775883017">"తెలియని యాప్‌లను ఇన్‌స్టాల్ చేయడం"</string>
+ <string name="install_other_apps" msgid="6986686991775883017">"తెలియని యాప్‌లను ఇన్‌స్టాల్ చేయండి"</string>
<string name="home" msgid="3256884684164448244">"సెట్టింగ్‌ల హోమ్"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 0d3e8de0559d..5dca4759a629 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -201,7 +201,7 @@
<string name="vpn_settings_not_available" msgid="956841430176985598">"Ushbu foydalanuvchi uchun VPN sozlamalari mavjud emas"</string>
<string name="tethering_settings_not_available" msgid="6765770438438291012">"Ushbu foydalanuvchi uchun Modem rejimi sozlamalari mavjud emas"</string>
<string name="apn_settings_not_available" msgid="7873729032165324000">"Ushbu foydalanuvchi uchun Internetga kirish nuqtasi (APN) sozlamalari mavjud emas"</string>
- <string name="enable_adb" msgid="7982306934419797485">"USB orqali nosozliklarni aniqlash"</string>
+ <string name="enable_adb" msgid="7982306934419797485">"USB orqali nosozliklarni tuzatish"</string>
<string name="enable_adb_summary" msgid="4881186971746056635">"USB orqali kompyuterga ulanganda tuzatish rejimi yoqilsin"</string>
<string name="clear_adb_keys" msgid="4038889221503122743">"USB orqali nosozliklarni tuzatishni taqiqlash"</string>
<string name="bugreport_in_power" msgid="7923901846375587241">"Xatoliklar hisoboti"</string>
@@ -264,7 +264,7 @@
<string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mobil internet har doim yoniq tursin, hatto Wi-Fi yoniq bo‘lsa ham (bir tarmoqdan ikkinchisiga tezroq o‘tish uchun)."</string>
<string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Modem rejimida apparatli tezlashtirishdan foydalanish (agar mavjud bo‘lsa)"</string>
<string name="adb_warning_title" msgid="6234463310896563253">"USB orqali nosozliklarni tuzatishga ruxsat berilsinmi?"</string>
- <string name="adb_warning_message" msgid="7316799925425402244">"USB orqali nosozliklarni aniqlash faqat dasturlash maqsadlarida yoqiladi. Undan maʼlumotlarni qurilmangiz va kompyuter o‘rtasida ko‘chirish, ilovalarni xabarnomasiz o‘rnatish va jurnal maʼlumotlarini o‘qish uchun foydalaniladi."</string>
+ <string name="adb_warning_message" msgid="7316799925425402244">"USB orqali nosozliklarni tuzatish faqat dasturlash maqsadlarida yoqiladi. Undan ma‘lumotlarni qurilmangiz va kompyuter o‘rtasida ko‘chirish, ilovalarni xabarnomasiz o‘rnatish va jurnal ma‘lumotlarini o‘qish uchun foydalaniladi."</string>
<string name="adb_keys_warning_message" msgid="5659849457135841625">"USB orqali nosozliklarni tuzatishga berilgan ruxsat siz hisobingizga kirgan barcha kompyuterlar uchun bekor qilinsinmi?"</string>
<string name="dev_settings_warning_title" msgid="7244607768088540165">"Dasturlash sozlamalariga ruxsat berilsinmi?"</string>
<string name="dev_settings_warning_message" msgid="2298337781139097964">"Bu sozlamalar faqat dasturlash maqsadlariga mo‘ljallangan. Shuning uchun, ular qurilmangizga va undagi ilovalariga shikast yetkazib, noto‘g‘ri ishlashiga sabab bo‘lishi mumkin."</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index c64130210d37..e85199f9ca0d 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -329,7 +329,7 @@
<string name="show_all_anrs" msgid="4924885492787069007">"顯示背景 ANR"</string>
<string name="show_all_anrs_summary" msgid="6636514318275139826">"為背景應用程式顯示「應用程式無回應」對話方塊"</string>
<string name="show_notification_channel_warnings" msgid="1399948193466922683">"顯示通知管道警告"</string>
- <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"當應用程式未經有效管道發布通知時,在畫面上顯示警告"</string>
+ <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"當應用程式未經有效管道發佈通知時,在畫面上顯示警告"</string>
<string name="force_allow_on_external" msgid="3215759785081916381">"強制允許將應用程式寫入外部儲存空間"</string>
<string name="force_allow_on_external_summary" msgid="3640752408258034689">"允許將任何應用程式寫入外部儲存空間 (無論資訊清單值為何)"</string>
<string name="force_resizable_activities" msgid="8615764378147824985">"將活動強制設為可調整大小"</string>
diff --git a/packages/Shell/res/values-zh-rTW/strings.xml b/packages/Shell/res/values-zh-rTW/strings.xml
index 96671c8c0175..fc6397dc2013 100644
--- a/packages/Shell/res/values-zh-rTW/strings.xml
+++ b/packages/Shell/res/values-zh-rTW/strings.xml
@@ -25,9 +25,9 @@
<string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"系統即將在手機上顯示錯誤報告"</string>
<string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"選取即可分享錯誤報告"</string>
<string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"輕觸即可分享錯誤報告"</string>
- <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"選取即可分享不包含螢幕截圖的錯誤報告;你也可以等候螢幕畫面擷取完畢"</string>
- <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"輕觸即可分享無螢幕截圖的錯誤報告;你也可以等候螢幕畫面擷取完畢"</string>
- <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"輕觸即可分享無螢幕截圖的錯誤報告;你也可以等候螢幕畫面擷取完畢"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"選取即可分享不包含螢幕擷取畫面的錯誤報告;你也可以等候螢幕畫面擷取完畢"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"輕觸即可分享無螢幕擷圖的錯誤報告;你也可以等候螢幕畫面擷取完畢"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"輕觸即可分享無螢幕擷圖的錯誤報告;你也可以等候螢幕畫面擷取完畢"</string>
<string name="bugreport_confirm" msgid="5917407234515812495">"錯誤報告的資料來自系統的各種記錄檔,當中可能包含敏感資料 (例如應用程式使用情形和位置資料)。請務必只與你信任的使用者和應用程式分享錯誤報告。"</string>
<string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"不要再顯示"</string>
<string name="bugreport_storage_title" msgid="5332488144740527109">"錯誤報告"</string>
@@ -35,9 +35,9 @@
<string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"無法在 ZIP 檔案中加入錯誤報告"</string>
<string name="bugreport_unnamed" msgid="2800582406842092709">"未命名"</string>
<string name="bugreport_info_action" msgid="2158204228510576227">"詳細資料"</string>
- <string name="bugreport_screenshot_action" msgid="8677781721940614995">"螢幕截圖"</string>
- <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"已成功拍攝螢幕截圖。"</string>
- <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"無法拍攝螢幕截圖。"</string>
+ <string name="bugreport_screenshot_action" msgid="8677781721940614995">"螢幕擷取畫面"</string>
+ <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"已成功拍攝螢幕擷取畫面。"</string>
+ <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"無法拍攝螢幕擷取畫面。"</string>
<string name="bugreport_info_dialog_title" msgid="1355948594292983332">"錯誤報告 <xliff:g id="ID">#%d</xliff:g> 的詳細資料"</string>
<string name="bugreport_info_name" msgid="4414036021935139527">"檔案名稱"</string>
<string name="bugreport_info_title" msgid="2306030793918239804">"錯誤標題"</string>
diff --git a/packages/SystemUI/docs/plugin_hooks.md b/packages/SystemUI/docs/plugin_hooks.md
index 9fe2e181971a..2fb0c996111a 100644
--- a/packages/SystemUI/docs/plugin_hooks.md
+++ b/packages/SystemUI/docs/plugin_hooks.md
@@ -56,6 +56,11 @@ Expected interface: [ClockPlugin](/packages/SystemUI/plugin/src/com/android/syst
Use: Allows replacement of the keyguard main clock.
+### Action: com.android.systemui.action.PLUGIN_NPV
+Expected interface: [NPVPlugin](/packages/SystemUI/plugin/src/com/android/systemui/plugins/NPVPlugin.java)
+
+Use: Attach a view under QQS for prototyping.
+
# Global plugin dependencies
These classes can be accessed by any plugin using PluginDependency as long as they @Requires them.
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/NPVPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NPVPlugin.java
new file mode 100644
index 000000000000..1426266a7048
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NPVPlugin.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.plugins;
+
+import android.view.View;
+import android.widget.FrameLayout;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+/**
+ * Plugin to attach custom views under QQS.
+ *
+ * A parent view is provided to the plugin to which they can add Views.
+ * <br>
+ * The parent is a {@link FrameLayout} with same background as QS and 96dp height.
+ *
+ * {@see NPVPluginManager}
+ * {@see status_bar_expanded_plugin_frame}
+ */
+@ProvidesInterface(action = NPVPlugin.ACTION, version = NPVPlugin.VERSION)
+public interface NPVPlugin extends Plugin {
+ String ACTION = "com.android.systemui.action.PLUGIN_NPV";
+ int VERSION = 1;
+
+ /**
+ * Attach views to the parent.
+ *
+ * @param parent a {@link FrameLayout} to which to attach views. Preferably a root view.
+ * @return a view attached to parent.
+ */
+ View attachToRoot(FrameLayout parent);
+
+ /**
+ * Indicate to the plugin when it is listening (QS expanded)
+ * @param listening
+ */
+ default void setListening(boolean listening) {};
+}
diff --git a/packages/SystemUI/res/layout/auth_biometric_contents.xml b/packages/SystemUI/res/layout/auth_biometric_contents.xml
index aed200f69bc3..925e4fad103d 100644
--- a/packages/SystemUI/res/layout/auth_biometric_contents.xml
+++ b/packages/SystemUI/res/layout/auth_biometric_contents.xml
@@ -56,7 +56,7 @@
android:scaleType="fitXY" />
<TextView
- android:id="@+id/error"
+ android:id="@+id/indicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="24dp"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 7a9400887c75..e7c6b2574f5f 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -111,4 +111,6 @@
android:visibility="invisible"
android:background="@drawable/qs_navbar_scrim" />
+ <include layout="@layout/status_bar_expanded_plugin_frame"/>
+
</com.android.systemui.statusbar.phone.NotificationPanelView>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml b/packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml
new file mode 100644
index 000000000000..4849dfb777ed
--- /dev/null
+++ b/packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/plugin_frame"
+ android:theme="@style/qs_theme"
+ android:layout_width="@dimen/qs_panel_width"
+ android:layout_height="96dp"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginTop="@*android:dimen/quick_qs_total_height"
+ android:layout_marginLeft="@dimen/notification_side_paddings"
+ android:layout_marginRight="@dimen/notification_side_paddings"
+ android:visibility="gone"
+ android:background="@drawable/qs_background_primary"/> \ No newline at end of file
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 938cb0dd3b12..9903cc04e97a 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -401,7 +401,6 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"Tap again to open"</string>
<string name="keyguard_unlock" msgid="6035822649218712063">"Swipe up to open"</string>
- <string name="keyguard_retry" msgid="5221600879614948709">"Swipe up to try again"</string>
<string name="do_disclosure_generic" msgid="5615898451805157556">"This device is managed by your organisation"</string>
<string name="do_disclosure_with_name" msgid="5640615509915445501">"This device is managed by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="4872890986869209950">"Swipe from icon for phone"</string>
@@ -545,7 +544,6 @@
<string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"This keeps it in view until you unpin. Touch &amp; hold Home to unpin."</string>
<string name="screen_pinning_toast" msgid="2266705122951934150">"To unpin this screen, touch &amp; hold Back and Overview buttons"</string>
<string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"To unpin this screen, touch &amp; hold Back and Home buttons"</string>
- <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"To unpin this screen, swipe up &amp; hold"</string>
<string name="screen_pinning_positive" msgid="3783985798366751226">"Got it"</string>
<string name="screen_pinning_negative" msgid="3741602308343880268">"No, thanks"</string>
<string name="screen_pinning_start" msgid="1022122128489278317">"Screen pinned"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 139215aa196f..d8c862affe08 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -401,7 +401,6 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‏‏‏‏‎‏‎‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‎‎‎‏‎‎‎‏‎‏‎‏‎‏‏‎Less urgent notifications below‎‏‎‎‏‎"</string>
<string name="notification_tap_again" msgid="7590196980943943842">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‏‎‏‏‏‎‎‏‎‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‎‎‎‎‏‏‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‏‎‎Tap again to open‎‏‎‎‏‎"</string>
<string name="keyguard_unlock" msgid="6035822649218712063">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‏‏‏‎‎‎‎‏‏‎‎‏‎‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎Swipe up to open‎‏‎‎‏‎"</string>
- <string name="keyguard_retry" msgid="5221600879614948709">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‏‏‎‏‏‎‏‎‎‏‎‏‎‏‎‏‏‎‏‏‎‏‎‎‎‏‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‏‎‎‏‎‏‎Swipe up to try again‎‏‎‎‏‎"</string>
<string name="do_disclosure_generic" msgid="5615898451805157556">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‎‎‎‎‎‏‏‎‎‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎This device is managed by your organization‎‏‎‎‏‎"</string>
<string name="do_disclosure_with_name" msgid="5640615509915445501">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎‏‏‎‏‎‏‎‎‎‏‏‏‏‏‏‎‏‎This device is managed by ‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="phone_hint" msgid="4872890986869209950">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‏‎‏‏‎‏‎‏‏‏‏‎‎Swipe from icon for phone‎‏‎‎‏‎"</string>
@@ -545,7 +544,6 @@
<string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎‏‏‎‏‎‎‏‏‏‎‏‎‏‏‏‎‏‏‎‎‏‎‏‎‎‎‎‏‎‏‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‏‎This keeps it in view until you unpin. Touch &amp; hold Home to unpin.‎‏‎‎‏‎"</string>
<string name="screen_pinning_toast" msgid="2266705122951934150">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‎‏‏‎‎‎‎‎‎‎‎‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‎‎To unpin this screen, touch &amp; hold Back and Overview buttons‎‏‎‎‏‎"</string>
<string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‏‏‎‎‏‏‎‏‏‎‎‎‎‏‎‏‏‎‏‎‏‏‎‏‎‎‏‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‏‎‎‎‎‎‏‎To unpin this screen, touch &amp; hold Back and Home buttons‎‏‎‎‏‎"</string>
- <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‏‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‏‏‏‏‎‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‏‎‏‎‏‎‏‏‏‎‏‏‏‏‏‎‎To unpin this screen, swipe up &amp; hold‎‏‎‎‏‎"</string>
<string name="screen_pinning_positive" msgid="3783985798366751226">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‎‎‎‎‎‏‎‏‏‎‎‎‏‎‏‏‏‏‎‏‎‎‏‏‏‏‏‏‎‏‎‎Got it‎‏‎‎‏‎"</string>
<string name="screen_pinning_negative" msgid="3741602308343880268">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎‏‎‎‏‎‎‏‏‎‎‎No thanks‎‏‎‎‏‎"</string>
<string name="screen_pinning_start" msgid="1022122128489278317">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‏‏‏‎‏‎‎‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎‏‎‎‎‏‏‎‏‎‏‎‏‏‎‏‏‎‏‎‏‏‎‏‏‎‏‏‎‏‎Screen pinned‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/src/com/android/systemui/ContextComponentHelper.java b/packages/SystemUI/src/com/android/systemui/ContextComponentHelper.java
index 62826d806adc..5fe5792219c3 100644
--- a/packages/SystemUI/src/com/android/systemui/ContextComponentHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ContextComponentHelper.java
@@ -24,4 +24,7 @@ import android.app.Service;
public interface ContextComponentHelper {
/** Turns a classname into an instance of the class or returns null. */
Service resolveService(String className);
+
+ /** Turns a classname into an instance of the class or returns null. */
+ SystemUI resolveSystemUI(String className);
}
diff --git a/packages/SystemUI/src/com/android/systemui/ContextComponentResolver.java b/packages/SystemUI/src/com/android/systemui/ContextComponentResolver.java
index e8f019688997..cee21c167fa0 100644
--- a/packages/SystemUI/src/com/android/systemui/ContextComponentResolver.java
+++ b/packages/SystemUI/src/com/android/systemui/ContextComponentResolver.java
@@ -22,17 +22,22 @@ import java.util.Map;
import javax.inject.Inject;
import javax.inject.Provider;
+import javax.inject.Singleton;
/**
* Used during Service and Activity instantiation to make them injectable.
*/
+@Singleton
public class ContextComponentResolver implements ContextComponentHelper {
private final Map<Class<?>, Provider<Service>> mServiceCreators;
+ private final Map<Class<?>, Provider<SystemUI>> mSystemUICreators;
@Inject
ContextComponentResolver(
- Map<Class<?>, Provider<Service>> serviceCreators) {
+ Map<Class<?>, Provider<Service>> serviceCreators,
+ Map<Class<?>, Provider<SystemUI>> systemUICreators) {
mServiceCreators = serviceCreators;
+ mSystemUICreators = systemUICreators;
}
/**
@@ -43,6 +48,14 @@ public class ContextComponentResolver implements ContextComponentHelper {
return resolve(className, mServiceCreators);
}
+ /**
+ * Looks up the SystemUI class name to see if Dagger has an instance of it.
+ */
+ @Override
+ public SystemUI resolveSystemUI(String className) {
+ return resolve(className, mSystemUICreators);
+ }
+
private <T> T resolve(String className, Map<Class<?>, Provider<T>> creators) {
for (Map.Entry<Class<?>, Provider<T>> p : creators.entrySet()) {
if (p.getKey().getName().equals(className)) {
diff --git a/packages/SystemUI/src/com/android/systemui/CornerHandleView.java b/packages/SystemUI/src/com/android/systemui/CornerHandleView.java
index a94952c5bc19..6209c2c36206 100644
--- a/packages/SystemUI/src/com/android/systemui/CornerHandleView.java
+++ b/packages/SystemUI/src/com/android/systemui/CornerHandleView.java
@@ -19,6 +19,7 @@ package com.android.systemui;
import android.animation.ArgbEvaluator;
import android.content.Context;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
@@ -27,6 +28,7 @@ import android.util.DisplayMetrics;
import android.view.ContextThemeWrapper;
import android.view.View;
+import com.android.internal.graphics.ColorUtils;
import com.android.settingslib.Utils;
/**
@@ -107,6 +109,7 @@ public class CornerHandleView extends View {
mPaint.setColor((int) ArgbEvaluator.getInstance().evaluate(darkIntensity,
mLightColor,
mDarkColor));
+ updateShadow();
if (getVisibility() == VISIBLE) {
invalidate();
}
@@ -118,6 +121,21 @@ public class CornerHandleView extends View {
canvas.drawPath(mPath, mPaint);
}
+ private void updateShadow() {
+ if (ColorUtils.calculateLuminance(mPaint.getColor()) > 0.7f) {
+ mPaint.setShadowLayer(/** radius */ 5,/** shadowDx */ 0, /** shadowDy */ -1,
+ /** color */ ColorUtils.setAlphaComponent(/** color */ Color.BLACK,
+ /** alpha */ 102));
+ } else {
+ mPaint.setShadowLayer(/** radius */ 0, /** shadowDx */ 0, /** shadowDy */ 0,
+ /** color */ Color.TRANSPARENT);
+ }
+
+ if (getVisibility() == VISIBLE) {
+ invalidate();
+ }
+ }
+
private static float convertDpToPixel(float dp, Context context) {
return dp * ((float) context.getResources().getDisplayMetrics().densityDpi
/ DisplayMetrics.DENSITY_DEFAULT);
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUI.java b/packages/SystemUI/src/com/android/systemui/SystemUI.java
index 78a12467cd1c..30fbef6cbefb 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUI.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUI.java
@@ -24,7 +24,6 @@ import android.os.Bundle;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Map;
-import java.util.function.Function;
public abstract class SystemUI implements SysUiServiceProvider {
public Context mContext;
@@ -62,7 +61,4 @@ public abstract class SystemUI implements SysUiServiceProvider {
n.addExtras(extras);
}
-
- public interface Injector extends Function<Context, SystemUI> {
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 1c210b177ae7..56b5d080acc0 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -54,6 +54,8 @@ public class SystemUIApplication extends Application implements SysUiServiceProv
public static final String TAG = "SystemUIService";
private static final boolean DEBUG = false;
+ private ContextComponentHelper mComponentHelper;
+
/**
* Hold a reference on the stuff we start.
*/
@@ -78,6 +80,8 @@ public class SystemUIApplication extends Application implements SysUiServiceProv
Trace.TRACE_TAG_APP);
log.traceBegin("DependencyInjection");
mContextAvailableCallback.onContextAvailable(this);
+ mComponentHelper = SystemUIFactory
+ .getInstance().getRootComponent().getContextComponentHelper();
log.traceEnd();
// Set the application theme that is inherited by all services. Note that setting the
@@ -186,14 +190,12 @@ public class SystemUIApplication extends Application implements SysUiServiceProv
if (DEBUG) Log.d(TAG, "loading: " + clsName);
log.traceBegin("StartServices" + clsName);
long ti = System.currentTimeMillis();
- Class cls;
try {
- cls = Class.forName(clsName);
- Object o = cls.newInstance();
- if (o instanceof SystemUI.Injector) {
- o = ((SystemUI.Injector) o).apply(this);
+ SystemUI obj = mComponentHelper.resolveSystemUI(clsName);
+ if (obj == null) {
+ obj = (SystemUI) Class.forName(clsName).newInstance();
}
- mServices[i] = (SystemUI) o;
+ mServices[i] = obj;
} catch (ClassNotFoundException ex) {
throw new RuntimeException(ex);
} catch (IllegalAccessException ex) {
@@ -211,7 +213,7 @@ public class SystemUIApplication extends Application implements SysUiServiceProv
// Warn if initialization of component takes too long
ti = System.currentTimeMillis() - ti;
if (ti > 1000) {
- Log.w(TAG, "Initialization of " + cls.getName() + " took " + ti + " ms");
+ Log.w(TAG, "Initialization of " + clsName + " took " + ti + " ms");
}
if (mBootCompleted) {
mServices[i].onBootCompleted();
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/SystemUIBinder.java
new file mode 100644
index 000000000000..88d659039b4b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIBinder.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui;
+
+import com.android.systemui.keyguard.KeyguardViewMediator;
+
+import dagger.Binds;
+import dagger.Module;
+import dagger.multibindings.ClassKey;
+import dagger.multibindings.IntoMap;
+
+/**
+ * Services and Activities that are injectable should go here.
+ */
+@Module
+public abstract class SystemUIBinder {
+ /** Inject into KeyguardViewMediator. */
+ @Binds
+ @IntoMap
+ @ClassKey(KeyguardViewMediator.class)
+ public abstract SystemUI bindKeyguardViewMediator(KeyguardViewMediator sysui);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java b/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java
index b77667e339af..6ce673b0e9b6 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java
@@ -38,10 +38,18 @@ import dagger.Component;
DependencyProvider.class,
DependencyBinder.class,
ServiceBinder.class,
+ SystemUIBinder.class,
SystemUIFactory.ContextHolder.class,
SystemUIModule.class,
SystemUIDefaultModule.class})
public interface SystemUIRootComponent {
+
+ /**
+ * Creates a GarbageMonitor.
+ */
+ @Singleton
+ ContextComponentHelper getContextComponentHelper();
+
/**
* Main dependency providing module.
*/
@@ -66,7 +74,7 @@ public interface SystemUIRootComponent {
InjectionInflationController.ViewCreator createViewCreator();
/**
- * Creatse a GarbageMonitor.
+ * Creates a GarbageMonitor.
*/
@Singleton
GarbageMonitor createGarbageMonitor();
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
index 9cf738541276..5dd3cb1d8bdc 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
@@ -383,6 +383,15 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
mIsLearned =
mLearningCount >= getLearningCount() || mLearningTimeElapsed >= getLearningTimeMs();
+
+ mHandler.post(this::recordLearnTimeElapsed);
+ }
+
+ private void recordLearnTimeElapsed() {
+ if (mContext != null) {
+ Settings.Secure.putLong(
+ mContext.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, mLearningTimeElapsed);
+ }
}
private void resetConsecutiveTaskSwitches() {
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index e42eb0a19f74..eb60b3db7a11 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -21,6 +21,7 @@ import android.os.AsyncTask;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
@@ -163,8 +164,10 @@ public class AssistManager implements ConfigurationChangedReceiver {
mAssistUtils = new AssistUtils(context);
mAssistDisclosure = new AssistDisclosure(context, new Handler());
mPhoneStateMonitor = new PhoneStateMonitor(context);
- mHandleController =
- new AssistHandleBehaviorController(context, mAssistUtils, new Handler());
+ final HandlerThread assistHandleThread = new HandlerThread("AssistHandleThread");
+ assistHandleThread.start();
+ mHandleController = new AssistHandleBehaviorController(
+ context, mAssistUtils, assistHandleThread.getThreadHandler());
registerVoiceInteractionSessionListener();
mInterestingConfigChanges = new InterestingConfigChanges(ActivityInfo.CONFIG_ORIENTATION
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.java
index 74cc9c39741e..a68b61e4da45 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.java
@@ -154,18 +154,18 @@ public class AuthBiometricFaceView extends AuthBiometricView {
@Override
protected void handleResetAfterError() {
- resetErrorView(mContext, mErrorView);
+ resetErrorView(mContext, mIndicatorView);
}
@Override
protected void handleResetAfterHelp() {
- resetErrorView(mContext, mErrorView);
+ resetErrorView(mContext, mIndicatorView);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mIconController = new IconController(mContext, mIconView, mErrorView);
+ mIconController = new IconController(mContext, mIconView, mIndicatorView);
}
@Override
@@ -174,7 +174,7 @@ public class AuthBiometricFaceView extends AuthBiometricView {
if (newState == STATE_AUTHENTICATING_ANIMATING_IN ||
(newState == STATE_AUTHENTICATING && mSize == AuthDialog.SIZE_MEDIUM)) {
- resetErrorView(mContext, mErrorView);
+ resetErrorView(mContext, mIndicatorView);
}
// Do this last since the state variable gets updated.
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
index f26083998c76..df14a1716571 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
@@ -21,6 +21,8 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.hardware.biometrics.BiometricPrompt;
import android.os.Bundle;
@@ -127,8 +129,8 @@ public abstract class AuthBiometricView extends LinearLayout {
return mBiometricView.findViewById(R.id.description);
}
- public TextView getErrorView() {
- return mBiometricView.findViewById(R.id.error);
+ public TextView getIndicatorView() {
+ return mBiometricView.findViewById(R.id.indicator);
}
public ImageView getIconView() {
@@ -150,7 +152,7 @@ public abstract class AuthBiometricView extends LinearLayout {
private TextView mSubtitleView;
private TextView mDescriptionView;
protected ImageView mIconView;
- @VisibleForTesting protected TextView mErrorView;
+ @VisibleForTesting protected TextView mIndicatorView;
@VisibleForTesting Button mNegativeButton;
@VisibleForTesting Button mPositiveButton;
@VisibleForTesting Button mTryAgainButton;
@@ -165,6 +167,7 @@ public abstract class AuthBiometricView extends LinearLayout {
private float mIconOriginalY;
protected boolean mDialogSizeAnimating;
+ protected Bundle mSavedState;
/**
* Delay after authentication is confirmed, before the dialog should be animated away.
@@ -252,7 +255,7 @@ public abstract class AuthBiometricView extends LinearLayout {
mTitleView.setVisibility(View.GONE);
mSubtitleView.setVisibility(View.GONE);
mDescriptionView.setVisibility(View.GONE);
- mErrorView.setVisibility(View.GONE);
+ mIndicatorView.setVisibility(View.GONE);
mNegativeButton.setVisibility(View.GONE);
final float iconPadding = getResources()
@@ -284,7 +287,7 @@ public abstract class AuthBiometricView extends LinearLayout {
final float opacity = (float) animation.getAnimatedValue();
mTitleView.setAlpha(opacity);
- mErrorView.setAlpha(opacity);
+ mIndicatorView.setAlpha(opacity);
mNegativeButton.setAlpha(opacity);
mTryAgainButton.setAlpha(opacity);
@@ -304,7 +307,7 @@ public abstract class AuthBiometricView extends LinearLayout {
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
mTitleView.setVisibility(View.VISIBLE);
- mErrorView.setVisibility(View.VISIBLE);
+ mIndicatorView.setVisibility(View.VISIBLE);
mNegativeButton.setVisibility(View.VISIBLE);
mTryAgainButton.setVisibility(View.VISIBLE);
@@ -339,6 +342,7 @@ public abstract class AuthBiometricView extends LinearLayout {
public void updateState(@BiometricState int newState) {
Log.v(TAG, "newState: " + newState);
+
switch (newState) {
case STATE_AUTHENTICATING_ANIMATING_IN:
case STATE_AUTHENTICATING:
@@ -353,7 +357,7 @@ public abstract class AuthBiometricView extends LinearLayout {
if (mSize != AuthDialog.SIZE_SMALL) {
mPositiveButton.setVisibility(View.GONE);
mNegativeButton.setVisibility(View.GONE);
- mErrorView.setVisibility(View.INVISIBLE);
+ mIndicatorView.setVisibility(View.INVISIBLE);
}
mHandler.postDelayed(() -> mCallback.onAction(Callback.ACTION_AUTHENTICATED),
getDelayAfterAuthenticatedDurationMs());
@@ -364,9 +368,10 @@ public abstract class AuthBiometricView extends LinearLayout {
mNegativeButton.setText(R.string.cancel);
mNegativeButton.setContentDescription(getResources().getString(R.string.cancel));
mPositiveButton.setEnabled(true);
- mErrorView.setTextColor(mTextColorHint);
- mErrorView.setText(R.string.biometric_dialog_tap_confirm);
- mErrorView.setVisibility(View.VISIBLE);
+ mPositiveButton.setVisibility(View.VISIBLE);
+ mIndicatorView.setTextColor(mTextColorHint);
+ mIndicatorView.setText(R.string.biometric_dialog_tap_confirm);
+ mIndicatorView.setVisibility(View.VISIBLE);
break;
case STATE_ERROR:
@@ -409,6 +414,27 @@ public abstract class AuthBiometricView extends LinearLayout {
updateState(STATE_HELP);
}
+ public void onSaveState(@NonNull Bundle outState) {
+ outState.putInt(AuthDialog.KEY_BIOMETRIC_TRY_AGAIN_VISIBILITY,
+ mTryAgainButton.getVisibility());
+ outState.putInt(AuthDialog.KEY_BIOMETRIC_STATE, mState);
+ outState.putString(AuthDialog.KEY_BIOMETRIC_INDICATOR_STRING,
+ mIndicatorView.getText().toString());
+ outState.putBoolean(AuthDialog.KEY_BIOMETRIC_INDICATOR_ERROR_SHOWING,
+ mHandler.hasCallbacks(mResetErrorRunnable));
+ outState.putBoolean(AuthDialog.KEY_BIOMETRIC_INDICATOR_HELP_SHOWING,
+ mHandler.hasCallbacks(mResetHelpRunnable));
+ outState.putInt(AuthDialog.KEY_BIOMETRIC_DIALOG_SIZE, mSize);
+ }
+
+ /**
+ * Invoked after inflation but before being attached to window.
+ * @param savedState
+ */
+ public void restoreState(@Nullable Bundle savedState) {
+ mSavedState = savedState;
+ }
+
private void setTextOrHide(TextView view, String string) {
if (TextUtils.isEmpty(string)) {
view.setVisibility(View.GONE);
@@ -429,25 +455,28 @@ public abstract class AuthBiometricView extends LinearLayout {
private void showTemporaryMessage(String message, Runnable resetMessageRunnable) {
removePendingAnimations();
- mErrorView.setText(message);
- mErrorView.setTextColor(mTextColorError);
- mErrorView.setVisibility(View.VISIBLE);
+ mIndicatorView.setText(message);
+ mIndicatorView.setTextColor(mTextColorError);
+ mIndicatorView.setVisibility(View.VISIBLE);
mHandler.postDelayed(resetMessageRunnable, BiometricPrompt.HIDE_DIALOG_DELAY);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- initializeViews();
+ onFinishInflateInternal();
}
+ /**
+ * After inflation, but before things like restoreState, onAttachedToWindow, etc.
+ */
@VisibleForTesting
- void initializeViews() {
+ void onFinishInflateInternal() {
mTitleView = mInjector.getTitleView();
mSubtitleView = mInjector.getSubtitleView();
mDescriptionView = mInjector.getDescriptionView();
mIconView = mInjector.getIconView();
- mErrorView = mInjector.getErrorView();
+ mIndicatorView = mInjector.getIndicatorView();
mNegativeButton = mInjector.getNegativeButton();
mPositiveButton = mInjector.getPositiveButton();
mTryAgainButton = mInjector.getTryAgainButton();
@@ -474,13 +503,49 @@ public abstract class AuthBiometricView extends LinearLayout {
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
+ onAttachedToWindowInternal();
+ }
+
+ /**
+ * Contains all the testable logic that should be invoked when {@link #onAttachedToWindow()} is
+ * invoked.
+ */
+ @VisibleForTesting
+ void onAttachedToWindowInternal() {
setText(mTitleView, mBundle.getString(BiometricPrompt.KEY_TITLE));
setText(mNegativeButton, mBundle.getString(BiometricPrompt.KEY_NEGATIVE_TEXT));
setTextOrHide(mSubtitleView, mBundle.getString(BiometricPrompt.KEY_SUBTITLE));
setTextOrHide(mDescriptionView, mBundle.getString(BiometricPrompt.KEY_DESCRIPTION));
- updateState(STATE_AUTHENTICATING_ANIMATING_IN);
+ if (mSavedState == null) {
+ updateState(STATE_AUTHENTICATING_ANIMATING_IN);
+ } else {
+ // Restore as much state as possible first
+ updateState(mSavedState.getInt(AuthDialog.KEY_BIOMETRIC_STATE));
+
+ // Restore positive button state
+ mTryAgainButton.setVisibility(
+ mSavedState.getInt(AuthDialog.KEY_BIOMETRIC_TRY_AGAIN_VISIBILITY));
+
+ // Restore indicator text state
+ final String indicatorText =
+ mSavedState.getString(AuthDialog.KEY_BIOMETRIC_INDICATOR_STRING);
+ if (mSavedState.getBoolean(AuthDialog.KEY_BIOMETRIC_INDICATOR_HELP_SHOWING)) {
+ onHelp(indicatorText);
+ } else if (mSavedState.getBoolean(AuthDialog.KEY_BIOMETRIC_INDICATOR_ERROR_SHOWING)) {
+ onAuthenticationFailed(indicatorText);
+ }
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+
+ // Empty the handler, otherwise things like ACTION_AUTHENTICATED may be duplicated once
+ // the new dialog is restored.
+ mHandler.removeCallbacksAndMessages(null /* all */);
}
@Override
@@ -521,13 +586,24 @@ public abstract class AuthBiometricView extends LinearLayout {
@Override
public void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
+ onLayoutInternal();
+ }
+ /**
+ * Contains all the testable logic that should be invoked when
+ * {@link #onLayout(boolean, int, int, int, int)}, is invoked.
+ */
+ @VisibleForTesting
+ void onLayoutInternal() {
// Start with initial size only once. Subsequent layout changes don't matter since we
// only care about the initial icon position.
if (mIconOriginalY == 0) {
mIconOriginalY = mIconView.getY();
- updateSize(mRequireConfirmation ? AuthDialog.SIZE_MEDIUM
- : AuthDialog.SIZE_SMALL);
+ if (mSavedState == null) {
+ updateSize(mRequireConfirmation ? AuthDialog.SIZE_MEDIUM : AuthDialog.SIZE_SMALL);
+ } else {
+ updateSize(mSavedState.getInt(AuthDialog.KEY_BIOMETRIC_DIALOG_SIZE));
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 9cb5fcf4de00..e198060da9aa 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -17,6 +17,8 @@
package com.android.systemui.biometrics;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Binder;
@@ -269,7 +271,8 @@ public class AuthContainerView extends LinearLayout
}
@Override
- public void show(WindowManager wm) {
+ public void show(WindowManager wm, @Nullable Bundle savedState) {
+ mBiometricView.restoreState(savedState);
wm.addView(this, getLayoutParams(mWindowToken));
}
@@ -308,13 +311,8 @@ public class AuthContainerView extends LinearLayout
}
@Override
- public void onSaveState(Bundle outState) {
-
- }
-
- @Override
- public void restoreState(Bundle savedState) {
-
+ public void onSaveState(@NonNull Bundle outState) {
+ mBiometricView.onSaveState(outState);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index dcd01c682726..ab89034c3b65 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -272,11 +272,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
+ " type: " + type);
}
- if (savedState != null) {
- // SavedState is only non-null if it's from onConfigurationChanged. Restore the state
- // even though it may be removed / re-created again
- newDialog.restoreState(savedState);
- } else if (mCurrentDialog != null) {
+ if (mCurrentDialog != null) {
// If somehow we're asked to show a dialog, the old one doesn't need to be animated
// away. This can happen if the app cancels and re-starts auth during configuration
// change. This is ugly because we also have to do things on onConfigurationChanged
@@ -286,7 +282,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
mReceiver = (IBiometricServiceReceiverInternal) args.arg2;
mCurrentDialog = newDialog;
- mCurrentDialog.show(mWindowManager);
+ mCurrentDialog.show(mWindowManager, savedState);
}
private void onDialogDismissed(@DismissedReason int reason) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
index a6a857ca5945..fb904231c175 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
@@ -17,7 +17,8 @@
package com.android.systemui.biometrics;
import android.annotation.IntDef;
-import android.hardware.biometrics.BiometricPrompt;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.os.Bundle;
import android.view.WindowManager;
@@ -28,28 +29,12 @@ import java.lang.annotation.RetentionPolicy;
* Interface for the biometric dialog UI.
*/
public interface AuthDialog {
-
- // TODO: Clean up save/restore state
- String[] KEYS_TO_BACKUP = {
- BiometricPrompt.KEY_TITLE,
- BiometricPrompt.KEY_USE_DEFAULT_TITLE,
- BiometricPrompt.KEY_SUBTITLE,
- BiometricPrompt.KEY_DESCRIPTION,
- BiometricPrompt.KEY_POSITIVE_TEXT,
- BiometricPrompt.KEY_NEGATIVE_TEXT,
- BiometricPrompt.KEY_REQUIRE_CONFIRMATION,
- BiometricPrompt.KEY_ALLOW_DEVICE_CREDENTIAL,
- BiometricPrompt.KEY_FROM_CONFIRM_DEVICE_CREDENTIAL,
-
- BiometricDialogView.KEY_TRY_AGAIN_VISIBILITY,
- BiometricDialogView.KEY_CONFIRM_VISIBILITY,
- BiometricDialogView.KEY_CONFIRM_ENABLED,
- BiometricDialogView.KEY_STATE,
- BiometricDialogView.KEY_ERROR_TEXT_VISIBILITY,
- BiometricDialogView.KEY_ERROR_TEXT_STRING,
- BiometricDialogView.KEY_ERROR_TEXT_IS_TEMPORARY,
- BiometricDialogView.KEY_ERROR_TEXT_COLOR,
- };
+ String KEY_BIOMETRIC_TRY_AGAIN_VISIBILITY = "try_agian_visibility";
+ String KEY_BIOMETRIC_STATE = "state";
+ String KEY_BIOMETRIC_INDICATOR_STRING = "indicator_string"; // error / help / hint
+ String KEY_BIOMETRIC_INDICATOR_ERROR_SHOWING = "error_is_temporary";
+ String KEY_BIOMETRIC_INDICATOR_HELP_SHOWING = "hint_is_temporary";
+ String KEY_BIOMETRIC_DIALOG_SIZE = "size";
int SIZE_UNKNOWN = 0;
int SIZE_SMALL = 1;
@@ -68,7 +53,7 @@ public interface AuthDialog {
* Show the dialog.
* @param wm
*/
- void show(WindowManager wm);
+ void show(WindowManager wm, @Nullable Bundle savedState);
/**
* Dismiss the dialog without sending a callback.
@@ -107,13 +92,7 @@ public interface AuthDialog {
* Save the current state.
* @param outState
*/
- void onSaveState(Bundle outState);
-
- /**
- * Restore a previous state.
- * @param savedState
- */
- void restoreState(Bundle savedState);
+ void onSaveState(@NonNull Bundle outState);
/**
* Get the client's package name
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
index 89d08d795128..b985e1c2a4d4 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
@@ -23,6 +23,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
+import android.annotation.Nullable;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.graphics.Outline;
@@ -738,7 +739,10 @@ public abstract class BiometricDialogView extends LinearLayout implements AuthDi
}
@Override
- public void show(WindowManager wm) {
+ public void show(WindowManager wm, @Nullable Bundle savedState) {
+ if (savedState != null) {
+ restoreState(savedState);
+ }
wm.addView(this, getLayoutParams(mWindowToken));
}
@@ -832,7 +836,6 @@ public abstract class BiometricDialogView extends LinearLayout implements AuthDi
bundle.putInt(KEY_DIALOG_SIZE, mSize);
}
- @Override
public void restoreState(Bundle bundle) {
mRestoredState = bundle;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 13d6470a351f..cc250b46c040 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -168,7 +168,7 @@ public class BubbleStackView extends FrameLayout {
* Callback to run after the flyout hides. Also called if a new flyout is shown before the
* previous one animates out.
*/
- private Runnable mAfterFlyoutHides;
+ private Runnable mFlyoutOnHide;
/** Layout change listener that moves the stack to the nearest valid position on rotation. */
private OnLayoutChangeListener mOrientationChangedListener;
@@ -1366,111 +1366,106 @@ public class BubbleStackView extends FrameLayout {
@VisibleForTesting
void animateInFlyoutForBubble(Bubble bubble) {
final CharSequence updateMessage = bubble.getUpdateMessage(getContext());
-
if (!bubble.showFlyoutForBubble()) {
// In case flyout was suppressed for this update, reset now.
bubble.setSuppressFlyout(false);
return;
}
-
if (updateMessage == null
|| isExpanded()
|| mIsExpansionAnimating
|| mIsGestureInProgress
- || mBubbleToExpandAfterFlyoutCollapse != null) {
+ || mBubbleToExpandAfterFlyoutCollapse != null
+ || bubble.getIconView() == null) {
// Skip the message if none exists, we're expanded or animating expansion, or we're
- // about to expand a bubble from the previous tapped flyout.
+ // about to expand a bubble from the previous tapped flyout, or if bubble view is null.
return;
}
-
- if (bubble.getIconView() != null) {
- // Temporarily suppress the dot while the flyout is visible.
- bubble.getIconView().setSuppressDot(
- true /* suppressDot */, false /* animate */);
-
- mFlyout.removeCallbacks(mAnimateInFlyout);
- mFlyoutDragDeltaX = 0f;
-
- if (mAfterFlyoutHides != null) {
- mAfterFlyoutHides.run();
+ mFlyoutDragDeltaX = 0f;
+ clearFlyoutOnHide();
+ mFlyoutOnHide = () -> {
+ resetDot(bubble);
+ if (mBubbleToExpandAfterFlyoutCollapse == null) {
+ return;
}
-
- mAfterFlyoutHides = () -> {
- final boolean suppressDot = !bubble.showBubbleDot();
- // If we're going to suppress the dot, make it visible first so it'll
- // visibly animate away.
- if (suppressDot) {
- bubble.getIconView().setSuppressDot(
- false /* suppressDot */, false /* animate */);
- }
- // Reset dot suppression. If we're not suppressing due to DND, then
- // stop suppressing it with no animation (since the flyout has
- // transformed into the dot). If we are suppressing due to DND, animate
- // it away.
- bubble.getIconView().setSuppressDot(
- suppressDot /* suppressDot */,
- suppressDot /* animate */);
-
- if (mBubbleToExpandAfterFlyoutCollapse != null) {
- mBubbleData.setSelectedBubble(mBubbleToExpandAfterFlyoutCollapse);
- mBubbleData.setExpanded(true);
- mBubbleToExpandAfterFlyoutCollapse = null;
- }
- };
-
- mFlyout.setVisibility(INVISIBLE);
-
- // Post in case layout isn't complete and getWidth returns 0.
- post(() -> {
- // An auto-expanding bubble could have been posted during the time it takes to
- // layout.
- if (isExpanded()) {
- return;
- }
-
- final Runnable afterShow = () -> {
- mAnimateInFlyout = () -> {
- mFlyout.setVisibility(VISIBLE);
- bubble.getIconView().setSuppressDot(
- true /* suppressDot */, false /* animate */);
- mFlyoutDragDeltaX =
- mStackAnimationController.isStackOnLeftSide()
- ? -mFlyout.getWidth()
- : mFlyout.getWidth();
- animateFlyoutCollapsed(false /* collapsed */, 0 /* velX */);
- mFlyout.postDelayed(mHideFlyout, FLYOUT_HIDE_AFTER);
- };
-
- mFlyout.postDelayed(mAnimateInFlyout, 200);
+ mBubbleData.setSelectedBubble(mBubbleToExpandAfterFlyoutCollapse);
+ mBubbleData.setExpanded(true);
+ mBubbleToExpandAfterFlyoutCollapse = null;
+ };
+ mFlyout.setVisibility(INVISIBLE);
+
+ // Temporarily suppress the dot while the flyout is visible.
+ bubble.getIconView().setSuppressDot(
+ true /* suppressDot */, false /* animate */);
+
+ // Start flyout expansion. Post in case layout isn't complete and getWidth returns 0.
+ post(() -> {
+ // An auto-expanding bubble could have been posted during the time it takes to
+ // layout.
+ if (isExpanded()) {
+ return;
+ }
+ final Runnable expandFlyoutAfterDelay = () -> {
+ mAnimateInFlyout = () -> {
+ mFlyout.setVisibility(VISIBLE);
+ mFlyoutDragDeltaX =
+ mStackAnimationController.isStackOnLeftSide()
+ ? -mFlyout.getWidth()
+ : mFlyout.getWidth();
+ animateFlyoutCollapsed(false /* collapsed */, 0 /* velX */);
+ mFlyout.postDelayed(mHideFlyout, FLYOUT_HIDE_AFTER);
};
-
- mFlyout.setupFlyoutStartingAsDot(
- updateMessage, mStackAnimationController.getStackPosition(), getWidth(),
- mStackAnimationController.isStackOnLeftSide(),
- bubble.getIconView().getBadgeColor(),
- afterShow,
- mAfterFlyoutHides,
- bubble.getIconView().getDotCenter());
- mFlyout.bringToFront();
- });
- }
-
+ mFlyout.postDelayed(mAnimateInFlyout, 200);
+ };
+ mFlyout.setupFlyoutStartingAsDot(
+ updateMessage, mStackAnimationController.getStackPosition(), getWidth(),
+ mStackAnimationController.isStackOnLeftSide(),
+ bubble.getIconView().getBadgeColor() /* dotColor */,
+ expandFlyoutAfterDelay /* onLayoutComplete */,
+ mFlyoutOnHide,
+ bubble.getIconView().getDotCenter());
+ mFlyout.bringToFront();
+ });
mFlyout.removeCallbacks(mHideFlyout);
mFlyout.postDelayed(mHideFlyout, FLYOUT_HIDE_AFTER);
logBubbleEvent(bubble, StatsLog.BUBBLE_UICHANGED__ACTION__FLYOUT);
}
- /** Hide the flyout immediately and cancel any pending hide runnables. */
- private void hideFlyoutImmediate() {
- if (mAfterFlyoutHides != null) {
- mAfterFlyoutHides.run();
+ private void resetDot(Bubble bubble) {
+ final boolean suppressDot = !bubble.showBubbleDot();
+ // If we're going to suppress the dot, make it visible first so it'll
+ // visibly animate away.
+
+ if (suppressDot) {
+ bubble.getIconView().setSuppressDot(
+ false /* suppressDot */, false /* animate */);
}
+ // Reset dot suppression. If we're not suppressing due to DND, then
+ // stop suppressing it with no animation (since the flyout has
+ // transformed into the dot). If we are suppressing due to DND, animate
+ // it away.
+ bubble.getIconView().setSuppressDot(
+ suppressDot /* suppressDot */,
+ suppressDot /* animate */);
+ }
+ /** Hide the flyout immediately and cancel any pending hide runnables. */
+ private void hideFlyoutImmediate() {
+ clearFlyoutOnHide();
mFlyout.removeCallbacks(mAnimateInFlyout);
mFlyout.removeCallbacks(mHideFlyout);
mFlyout.hideFlyout();
}
+ private void clearFlyoutOnHide() {
+ mFlyout.removeCallbacks(mAnimateInFlyout);
+ if (mFlyoutOnHide == null) {
+ return;
+ }
+ mFlyoutOnHide.run();
+ mFlyoutOnHide = null;
+ }
+
@Override
public void getBoundsOnScreen(Rect outRect) {
if (!mIsExpanded) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java
index 603c4169c169..4512aa822e3b 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java
@@ -61,7 +61,7 @@ public class BubbleView extends FrameLayout {
// mBubbleIconFactory cannot be static because it depends on Context.
private BubbleIconFactory mBubbleIconFactory;
- private boolean mSuppressDot = false;
+ private boolean mSuppressDot;
private Bubble mBubble;
@@ -140,6 +140,7 @@ public class BubbleView extends FrameLayout {
public void setAppIcon(Drawable appIcon) {
mUserBadgedAppIcon = appIcon;
}
+
/**
* @return the {@link ExpandableNotificationRow} view to display notification content when the
* bubble is expanded.
@@ -154,7 +155,6 @@ public class BubbleView extends FrameLayout {
updateDotVisibility(animate, null /* after */);
}
-
/**
* Sets whether or not to hide the dot even if we'd otherwise show it. This is used while the
* flyout is visible or animating, to hide the dot until the flyout visually transforms into it.
@@ -166,7 +166,7 @@ public class BubbleView extends FrameLayout {
/** Sets the position of the 'new' dot, animating it out and back in if requested. */
void setDotPosition(boolean onLeft, boolean animate) {
- if (animate && onLeft != mBadgedImageView.getDotOnLeft() && !mSuppressDot) {
+ if (animate && onLeft != mBadgedImageView.getDotOnLeft() && shouldShowDot()) {
animateDot(false /* showDot */, () -> {
mBadgedImageView.setDotOnLeft(onLeft);
animateDot(true /* showDot */, null);
@@ -190,12 +190,12 @@ public class BubbleView extends FrameLayout {
* after animation if requested.
*/
private void updateDotVisibility(boolean animate, Runnable after) {
- boolean showDot = mBubble.showBubbleDot() && !mSuppressDot;
-
+ final boolean showDot = shouldShowDot();
if (animate) {
animateDot(showDot, after);
} else {
mBadgedImageView.setShowDot(showDot);
+ mBadgedImageView.setDotScale(showDot ? 1f : 0f);
}
}
@@ -203,27 +203,25 @@ public class BubbleView extends FrameLayout {
* Animates the badge to show or hide.
*/
private void animateDot(boolean showDot, Runnable after) {
- if (mBadgedImageView.isShowingDot() != showDot) {
- if (showDot) {
- mBadgedImageView.setShowDot(true);
- }
- mBadgedImageView.clearAnimation();
- mBadgedImageView.animate().setDuration(200)
- .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
- .setUpdateListener((valueAnimator) -> {
- float fraction = valueAnimator.getAnimatedFraction();
- fraction = showDot ? fraction : 1f - fraction;
- mBadgedImageView.setDotScale(fraction);
- }).withEndAction(() -> {
- if (!showDot) {
- mBadgedImageView.setShowDot(false);
- }
-
- if (after != null) {
- after.run();
- }
- }).start();
+ if (mBadgedImageView.isShowingDot() == showDot) {
+ return;
}
+ // Do NOT wait until after animation ends to setShowDot
+ // to avoid overriding more recent showDot states.
+ mBadgedImageView.setShowDot(showDot);
+ mBadgedImageView.clearAnimation();
+ mBadgedImageView.animate().setDuration(200)
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+ .setUpdateListener((valueAnimator) -> {
+ float fraction = valueAnimator.getAnimatedFraction();
+ fraction = showDot ? fraction : 1f - fraction;
+ mBadgedImageView.setDotScale(fraction);
+ }).withEndAction(() -> {
+ mBadgedImageView.setDotScale(showDot ? 1f : 0f);
+ if (after != null) {
+ after.run();
+ }
+ }).start();
}
void updateViews() {
@@ -273,7 +271,11 @@ public class BubbleView extends FrameLayout {
iconPath.transform(matrix);
mBadgedImageView.drawDot(iconPath);
- animateDot(mBubble.showBubbleDot() /* showDot */, null /* after */);
+ animateDot(shouldShowDot(), null /* after */);
+ }
+
+ boolean shouldShowDot() {
+ return mBubble.showBubbleDot() && !mSuppressDot;
}
int getBadgeColor() {
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 3f598ffad709..c9c6a0c6868b 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -614,7 +614,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
- mScreenshotHelper.takeScreenshot(1, true, true, mHandler);
+ mScreenshotHelper.takeScreenshot(1, true, true, mHandler, null);
MetricsLogger.action(mContext,
MetricsEvent.ACTION_SCREENSHOT_POWER_MENU);
}
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
index 7b22a49fc88a..29606347f009 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
@@ -111,7 +111,12 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
mBitmap = mWallpaperManager.getBitmap();
mWallpaperManager.forgetLoadedWallpaper();
if (mBitmap != null) {
- mSurfaceSize.set(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
+ float scale = (float) mScissor.height() / mBitmap.getHeight();
+ int surfaceHeight = Math.max(mScissor.height(), mBitmap.getHeight());
+ int surfaceWidth = scale > 1f
+ ? Math.round(mBitmap.getWidth() * scale)
+ : mBitmap.getWidth();
+ mSurfaceSize.set(0, 0, surfaceWidth, surfaceHeight);
}
}
return mBitmap != null;
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index e69688079e57..d2a9c750bbc6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -99,6 +99,8 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import javax.inject.Inject;
+
/**
* Mediates requests related to the keyguard. This includes queries about the
* state of the keyguard, power management events that effect whether the keyguard
@@ -216,6 +218,7 @@ public class KeyguardViewMediator extends SystemUI {
private boolean mBootSendUserPresent;
private boolean mShuttingDown;
private boolean mDozing;
+ private final FalsingManager mFalsingManager;
/** High level access to the power manager for WakeLocks */
private PowerManager mPM;
@@ -678,6 +681,13 @@ public class KeyguardViewMediator extends SystemUI {
}
};
+ @Inject
+ public KeyguardViewMediator(FalsingManager falsingManager) {
+ super();
+
+ mFalsingManager = falsingManager;
+ }
+
public void userActivity() {
mPM.userActivity(SystemClock.uptimeMillis(), false);
}
@@ -1603,7 +1613,7 @@ public class KeyguardViewMediator extends SystemUI {
Trace.beginSection("KeyguardViewMediator#handleMessage START_KEYGUARD_EXIT_ANIM");
StartKeyguardExitAnimParams params = (StartKeyguardExitAnimParams) msg.obj;
handleStartKeyguardExitAnimation(params.startTime, params.fadeoutDuration);
- Dependency.get(FalsingManager.class).onSucccessfulUnlock();
+ mFalsingManager.onSucccessfulUnlock();
Trace.endSection();
break;
case KEYGUARD_DONE_PENDING_TIMEOUT:
@@ -2075,11 +2085,10 @@ public class KeyguardViewMediator extends SystemUI {
public StatusBarKeyguardViewManager registerStatusBar(StatusBar statusBar,
ViewGroup container, NotificationPanelView panelView,
BiometricUnlockController biometricUnlockController, ViewGroup lockIconContainer,
- View notificationContainer, KeyguardBypassController bypassController,
- FalsingManager falsingManager) {
+ View notificationContainer, KeyguardBypassController bypassController) {
mStatusBarKeyguardViewManager.registerStatusBar(statusBar, container, panelView,
biometricUnlockController, mDismissCallbackRegistry, lockIconContainer,
- notificationContainer, bypassController, falsingManager);
+ notificationContainer, bypassController, mFalsingManager);
return mStatusBarKeyguardViewManager;
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 17402905b21a..3be3422a36ad 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -16,6 +16,9 @@
package com.android.systemui.pip.phone;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.app.IActivityManager;
@@ -182,7 +185,6 @@ public class PipManager implements BasePipManager {
ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
mInputConsumerController = InputConsumerController.getPipInputConsumer();
- mInputConsumerController.registerInputConsumer();
mMediaController = new PipMediaController(context, mActivityManager);
mMenuController = new PipMenuActivityController(context, mActivityManager, mMediaController,
mInputConsumerController);
@@ -190,6 +192,18 @@ public class PipManager implements BasePipManager {
mMenuController, mInputConsumerController);
mAppOpsListener = new PipAppOpsListener(context, mActivityManager,
mTouchHandler.getMotionHelper());
+
+ // If SystemUI restart, and it already existed a pinned stack,
+ // register the pip input consumer to ensure touch can send to it.
+ try {
+ ActivityManager.StackInfo stackInfo = mActivityTaskManager.getStackInfo(
+ WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
+ if (stackInfo != null) {
+ mInputConsumerController.registerInputConsumer();
+ }
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index 21f58128322d..4f2a6d82a08e 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -48,7 +48,6 @@ import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ParceledListSlice;
import android.graphics.Color;
-import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
@@ -64,7 +63,6 @@ import android.util.Pair;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
-import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.WindowManager.LayoutParams;
import android.view.accessibility.AccessibilityManager;
@@ -92,6 +90,7 @@ public class PipMenuActivity extends Activity {
public static final int MESSAGE_UPDATE_ACTIONS = 4;
public static final int MESSAGE_UPDATE_DISMISS_FRACTION = 5;
public static final int MESSAGE_ANIMATION_ENDED = 6;
+ public static final int MESSAGE_TOUCH_EVENT = 7;
private static final int INITIAL_DISMISS_DELAY = 3500;
private static final int POST_INTERACTION_DISMISS_DELAY = 2000;
@@ -128,10 +127,6 @@ public class PipMenuActivity extends Activity {
}
};
- private PipTouchState mTouchState;
- private PointF mDownPosition = new PointF();
- private PointF mDownDelta = new PointF();
- private ViewConfiguration mViewConfig;
private Handler mHandler = new Handler();
private Messenger mToControllerMessenger;
private Messenger mMessenger = new Messenger(new Handler() {
@@ -169,6 +164,12 @@ public class PipMenuActivity extends Activity {
mAllowTouches = true;
break;
}
+
+ case MESSAGE_TOUCH_EVENT: {
+ final MotionEvent ev = (MotionEvent) msg.obj;
+ dispatchTouchEvent(ev);
+ break;
+ }
}
}
});
@@ -184,15 +185,7 @@ public class PipMenuActivity extends Activity {
protected void onCreate(@Nullable Bundle savedInstanceState) {
// Set the flags to allow us to watch for outside touches and also hide the menu and start
// manipulating the PIP in the same touch gesture
- mViewConfig = ViewConfiguration.get(this);
- mTouchState = new PipTouchState(mViewConfig, mHandler, () -> {
- if (mMenuState == MENU_STATE_CLOSE) {
- showPipMenu();
- } else {
- expandPip();
- }
- });
- getWindow().addFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | LayoutParams.FLAG_SLIPPERY);
+ getWindow().addFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
super.onCreate(savedInstanceState);
setContentView(R.layout.pip_menu_activity);
@@ -204,32 +197,6 @@ public class PipMenuActivity extends Activity {
mViewRoot.setBackground(mBackgroundDrawable);
mMenuContainer = findViewById(R.id.menu_container);
mMenuContainer.setAlpha(0);
- mMenuContainer.setOnTouchListener((v, event) -> {
- mTouchState.onTouchEvent(event);
- switch (event.getAction()) {
- case MotionEvent.ACTION_UP:
- if (mTouchState.isDoubleTap() || mMenuState == MENU_STATE_FULL) {
- // Expand to fullscreen if this is a double tap or we are already expanded
- expandPip();
- } else if (!mTouchState.isWaitingForDoubleTap()) {
- // User has stalled long enough for this not to be a drag or a double tap,
- // just expand the menu if necessary
- if (mMenuState == MENU_STATE_CLOSE) {
- showPipMenu();
- }
- } else {
- // Next touch event _may_ be the second tap for the double-tap, schedule a
- // fallback runnable to trigger the menu if no touch event occurs before the
- // next tap
- mTouchState.scheduleDoubleTapTimeoutCallback();
- }
- // Fall through
- case MotionEvent.ACTION_CANCEL:
- mTouchState.reset();
- break;
- }
- return true;
- });
mSettingsButton = findViewById(R.id.settings);
mSettingsButton.setAlpha(0);
mSettingsButton.setOnClickListener((v) -> {
@@ -240,7 +207,11 @@ public class PipMenuActivity extends Activity {
mDismissButton = findViewById(R.id.dismiss);
mDismissButton.setAlpha(0);
mDismissButton.setOnClickListener(v -> dismissPip());
- findViewById(R.id.expand_button).setOnClickListener(v -> expandPip());
+ findViewById(R.id.expand_button).setOnClickListener(v -> {
+ if (mMenuContainer.getAlpha() != 0) {
+ expandPip();
+ }
+ });
mActionsGroup = findViewById(R.id.actions_group);
mBetweenActionPaddingLand = getResources().getDimensionPixelSize(
R.dimen.pip_between_action_padding_land);
@@ -298,27 +269,14 @@ public class PipMenuActivity extends Activity {
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (!mAllowTouches) {
- return super.dispatchTouchEvent(ev);
+ return false;
}
// On the first action outside the window, hide the menu
switch (ev.getAction()) {
case MotionEvent.ACTION_OUTSIDE:
hideMenu();
- break;
- case MotionEvent.ACTION_DOWN:
- mDownPosition.set(ev.getX(), ev.getY());
- mDownDelta.set(0f, 0f);
- break;
- case MotionEvent.ACTION_MOVE:
- mDownDelta.set(ev.getX() - mDownPosition.x, ev.getY() - mDownPosition.y);
- if (mDownDelta.length() > mViewConfig.getScaledTouchSlop()
- && mMenuState != MENU_STATE_NONE) {
- // Restore the input consumer and let that drive the movement of this menu
- notifyRegisterInputConsumer();
- cancelDelayedFinish();
- }
- break;
+ return true;
}
return super.dispatchTouchEvent(ev);
}
@@ -381,7 +339,6 @@ public class PipMenuActivity extends Activity {
if (allowMenuTimeout) {
repostDelayedFinish(POST_INTERACTION_DISMISS_DELAY);
}
- notifyUnregisterInputConsumer();
}
}
@@ -506,11 +463,13 @@ public class PipMenuActivity extends Activity {
actionView.setContentDescription(action.getContentDescription());
if (action.isEnabled()) {
actionView.setOnClickListener(v -> {
- try {
- action.getActionIntent().send();
- } catch (CanceledException e) {
- Log.w(TAG, "Failed to send action", e);
- }
+ mHandler.post(() -> {
+ try {
+ action.getActionIntent().send();
+ } catch (CanceledException e) {
+ Log.w(TAG, "Failed to send action", e);
+ }
+ });
});
}
actionView.setEnabled(action.isEnabled());
@@ -554,18 +513,6 @@ public class PipMenuActivity extends Activity {
mBackgroundDrawable.setAlpha(alpha);
}
- private void notifyRegisterInputConsumer() {
- Message m = Message.obtain();
- m.what = PipMenuActivityController.MESSAGE_REGISTER_INPUT_CONSUMER;
- sendMessage(m, "Could not notify controller to register input consumer");
- }
-
- private void notifyUnregisterInputConsumer() {
- Message m = Message.obtain();
- m.what = PipMenuActivityController.MESSAGE_UNREGISTER_INPUT_CONSUMER;
- sendMessage(m, "Could not notify controller to unregister input consumer");
- }
-
private void notifyMenuStateChange(int menuState) {
mMenuState = menuState;
Message m = Message.obtain();
@@ -583,11 +530,6 @@ public class PipMenuActivity extends Activity {
}, false /* notifyMenuVisibility */, false /* isDismissing */);
}
- private void minimizePip() {
- sendEmptyMessage(PipMenuActivityController.MESSAGE_MINIMIZE_PIP,
- "Could not notify controller to minimize PIP");
- }
-
private void dismissPip() {
// Do not notify menu visibility when hiding the menu, the controller will do this when it
// handles the message
@@ -597,12 +539,6 @@ public class PipMenuActivity extends Activity {
}, false /* notifyMenuVisibility */, true /* isDismissing */);
}
- private void showPipMenu() {
- Message m = Message.obtain();
- m.what = PipMenuActivityController.MESSAGE_SHOW_MENU;
- sendMessage(m, "Could not notify controller to show PIP menu");
- }
-
private void showSettings() {
final Pair<ComponentName, Integer> topPipActivityInfo =
PipUtils.getTopPinnedActivity(this, ActivityManager.getService());
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
index 14459d6b8111..62c59e5842ff 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
@@ -37,6 +37,7 @@ import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.Log;
+import android.view.MotionEvent;
import com.android.systemui.pip.phone.PipMediaController.ActionListener;
import com.android.systemui.shared.system.InputConsumerController;
@@ -156,14 +157,6 @@ public class PipMenuActivityController {
mListeners.forEach(l -> l.onPipShowMenu());
break;
}
- case MESSAGE_REGISTER_INPUT_CONSUMER: {
- mInputConsumerController.registerInputConsumer();
- break;
- }
- case MESSAGE_UNREGISTER_INPUT_CONSUMER: {
- mInputConsumerController.unregisterInputConsumer();
- break;
- }
case MESSAGE_UPDATE_ACTIVITY_CALLBACK: {
mToActivityMessenger = msg.replyTo;
setStartActivityRequested(false);
@@ -212,15 +205,12 @@ public class PipMenuActivityController {
}
public void onActivityPinned() {
- if (mMenuState == MENU_STATE_NONE) {
- // If the menu is not visible, then re-register the input consumer if it is not already
- // registered
- mInputConsumerController.registerInputConsumer();
- }
+ mInputConsumerController.registerInputConsumer();
}
public void onActivityUnpinned() {
hideMenu();
+ mInputConsumerController.unregisterInputConsumer();
setStartActivityRequested(false);
}
@@ -495,11 +485,7 @@ public class PipMenuActivityController {
Log.d(TAG, "onMenuStateChanged() mMenuState=" + mMenuState
+ " menuState=" + menuState + " resize=" + resize);
}
- if (menuState == MENU_STATE_NONE) {
- mInputConsumerController.registerInputConsumer();
- } else {
- mInputConsumerController.unregisterInputConsumer();
- }
+
if (menuState != mMenuState) {
mListeners.forEach(l -> l.onPipMenuStateChanged(menuState, resize));
if (menuState == MENU_STATE_FULL) {
@@ -521,6 +507,22 @@ public class PipMenuActivityController {
mStartActivityRequestedTime = requested ? SystemClock.uptimeMillis() : 0;
}
+ /**
+ * Handles touch event sent from pip input consumer.
+ */
+ void handleTouchEvent(MotionEvent ev) {
+ if (mToActivityMessenger != null) {
+ Message m = Message.obtain();
+ m.what = PipMenuActivity.MESSAGE_TOUCH_EVENT;
+ m.obj = ev;
+ try {
+ mToActivityMessenger.send(m);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not dispatch touch event", e);
+ }
+ }
+ }
+
public void dump(PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " ";
pw.println(prefix + TAG);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
index 9c65994425ed..fa6047755619 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -551,9 +551,8 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call
return true;
}
- mActivityTaskManager.resizeStack(stackInfo.stackId, toBounds,
- false /* allowResizeInDockedMode */, true /* preserveWindows */,
- true /* animate */, duration);
+ mActivityTaskManager.animateResizePinnedStack(stackInfo.stackId, toBounds,
+ duration);
mBounds.set(toBounds);
} catch (RemoteException e) {
Log.e(TAG, "Could not animate resize pinned stack to bounds: " + toBounds, e);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index b05058a92650..30cf412671bc 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -363,6 +363,8 @@ public class PipTouchHandler {
// Update the touch state
mTouchState.onTouchEvent(ev);
+ boolean shouldDeliverToMenu = mMenuState != MENU_STATE_NONE;
+
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN: {
mMotionHelper.synchronizePinnedStackBounds();
@@ -378,6 +380,8 @@ public class PipTouchHandler {
break;
}
}
+
+ shouldDeliverToMenu = !mTouchState.isDragging();
break;
}
case MotionEvent.ACTION_UP: {
@@ -394,6 +398,7 @@ public class PipTouchHandler {
// Fall through to clean up
}
case MotionEvent.ACTION_CANCEL: {
+ shouldDeliverToMenu = !mTouchState.startedDragging() && !mTouchState.isDragging();
mTouchState.reset();
break;
}
@@ -425,7 +430,20 @@ public class PipTouchHandler {
break;
}
}
- return mMenuState == MENU_STATE_NONE;
+
+ // Deliver the event to PipMenuActivity to handle button click if the menu has shown.
+ if (shouldDeliverToMenu) {
+ final MotionEvent cloneEvent = MotionEvent.obtain(ev);
+ // Send the cancel event and cancel menu timeout if it starts to drag.
+ if (mTouchState.startedDragging()) {
+ cloneEvent.setAction(MotionEvent.ACTION_CANCEL);
+ mMenuController.pokeMenu();
+ }
+
+ mMenuController.handleTouchEvent(cloneEvent);
+ }
+
+ return true;
}
/**
@@ -741,11 +759,11 @@ public class PipTouchHandler {
mMotionHelper.animateToClosestSnapTarget(mMovementBounds, null /* updateListener */,
null /* animatorListener */);
setMinimizedStateInternal(false);
+ } else if (mTouchState.isDoubleTap()) {
+ // Expand to fullscreen if this is a double tap
+ mMotionHelper.expandPip();
} else if (mMenuState != MENU_STATE_FULL) {
- if (mTouchState.isDoubleTap()) {
- // Expand to fullscreen if this is a double tap
- mMotionHelper.expandPip();
- } else if (!mTouchState.isWaitingForDoubleTap()) {
+ if (!mTouchState.isWaitingForDoubleTap()) {
// User has stalled long enough for this not to be a drag or a double tap, just
// expand the menu
mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
@@ -756,9 +774,6 @@ public class PipTouchHandler {
// next tap
mTouchState.scheduleDoubleTapTimeoutCallback();
}
- } else {
- mMenuController.hideMenu();
- mMotionHelper.expandPip();
}
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
index 69efbc8575e0..e3f65ef812fb 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
@@ -106,6 +106,7 @@ public class PipTouchState {
mIsDoubleTap = !mPreviouslyDragging &&
(mDownTouchTime - mLastDownTouchTime) < DOUBLE_TAP_TIMEOUT;
mIsWaitingForDoubleTap = false;
+ mIsDragging = false;
mLastDownTouchTime = mDownTouchTime;
if (mDoubleTapTimeoutCallback != null) {
mHandler.removeCallbacks(mDoubleTapTimeoutCallback);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index 5f2614ef4479..918af4f0cd4c 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -441,8 +441,8 @@ public class PipManager implements BasePipManager {
}
try {
int animationDurationMs = -1;
- mActivityTaskManager.resizeStack(mPinnedStackId, mCurrentPipBounds,
- true, true, true, animationDurationMs);
+ mActivityTaskManager.animateResizePinnedStack(mPinnedStackId, mCurrentPipBounds,
+ animationDurationMs);
} catch (RemoteException e) {
Log.e(TAG, "resizeStack failed", e);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 37113cfac2f3..1211e135d1b7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -107,11 +107,6 @@ public class QuickQSPanel extends QSPanel {
}
@Override
- protected boolean shouldShowDetail() {
- return !mExpanded;
- }
-
- @Override
protected void drawTile(TileRecord r, State state) {
if (state instanceof SignalState) {
SignalState copy = new SignalState();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
index b135f7b27c3f..effea6a877b8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
@@ -159,8 +159,11 @@ public class TileLifecycleManager extends BroadcastReceiver implements
mBindTryCount++;
try {
mIsBound = mContext.bindServiceAsUser(mIntent, this,
- Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE
- | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS, mUser);
+ Context.BIND_AUTO_CREATE
+ | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE
+ | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS
+ | Context.BIND_WAIVE_PRIORITY,
+ mUser);
} catch (SecurityException e) {
Log.e(TAG, "Failed to bind to service", e);
mIsBound = false;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 90455395db45..3d6ee4cf9617 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -63,6 +63,8 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.PagedTileLayout.TilePage;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.QuickStatusBarHeader;
+import com.android.systemui.qs.tiles.QSSettingsControllerKt;
+import com.android.systemui.qs.tiles.QSSettingsPanel;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -121,9 +123,16 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
*/
abstract public int getMetricsCategory();
+ /**
+ * Experimental option on whether to use settings panels. Only loaded on creation, so the tile
+ * needs to be removed and added for this to take effect.
+ */
+ protected final QSSettingsPanel mQSSettingsPanelOption;
+
protected QSTileImpl(QSHost host) {
mHost = host;
mContext = host.getContext();
+ mQSSettingsPanelOption = QSSettingsControllerKt.getQSSettingsPanelOption();
}
@NonNull
@@ -288,6 +297,10 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
}
protected void handleLongClick() {
+ if (mQSSettingsPanelOption == QSSettingsPanel.USE_DETAIL) {
+ showDetail(true);
+ return;
+ }
Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard(
getLongClickIntent(), 0);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QSSettingsController.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/QSSettingsController.kt
new file mode 100644
index 000000000000..c7ef0be508aa
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QSSettingsController.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles
+
+import android.provider.DeviceConfig
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
+
+enum class QSSettingsPanel {
+ DEFAULT,
+ OPEN_LONG_PRESS,
+ OPEN_CLICK,
+ USE_DETAIL
+}
+
+fun getQSSettingsPanelOption(): QSSettingsPanel =
+ when (DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
+ SystemUiDeviceConfigFlags.QS_USE_SETTINGS_PANELS, 0)) {
+ 1 -> QSSettingsPanel.OPEN_LONG_PRESS
+ 2 -> QSSettingsPanel.OPEN_CLICK
+ 3 -> QSSettingsPanel.USE_DETAIL
+ else -> QSSettingsPanel.DEFAULT
+ } \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 0e7362c3d081..b79b662a2bd7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -56,6 +56,7 @@ import javax.inject.Inject;
/** Quick settings tile: Wifi **/
public class WifiTile extends QSTileImpl<SignalState> {
private static final Intent WIFI_SETTINGS = new Intent(Settings.ACTION_WIFI_SETTINGS);
+ private static final Intent WIFI_PANEL = new Intent(Settings.Panel.ACTION_WIFI);
protected final NetworkController mController;
private final AccessPointController mWifiController;
@@ -112,11 +113,16 @@ public class WifiTile extends QSTileImpl<SignalState> {
@Override
public Intent getLongClickIntent() {
- return WIFI_SETTINGS;
+ if (mQSSettingsPanelOption == QSSettingsPanel.OPEN_LONG_PRESS) return WIFI_PANEL;
+ else return WIFI_SETTINGS;
}
@Override
protected void handleClick() {
+ if (mQSSettingsPanelOption == QSSettingsPanel.OPEN_CLICK) {
+ mActivityStarter.postStartActivityDismissingKeyguard(WIFI_PANEL, 0);
+ return;
+ }
// Secondary clicks are header clicks, just toggle.
mState.copyTo(mStateBeforeClick);
boolean wifiEnabled = mState.value;
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 2964889f1399..6f5fe8b629fb 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
@@ -31,6 +31,7 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BA
import android.annotation.NonNull;
import android.app.Notification;
+import android.app.Notification.MessagingStyle.Message;
import android.app.NotificationChannel;
import android.app.NotificationManager.Policy;
import android.app.Person;
@@ -89,7 +90,6 @@ public final class NotificationEntry {
public StatusBarNotification notification;
private Ranking mRanking;
- public NotificationChannel channel;
public long lastAudiblyAlertedMs;
public boolean noisy;
public boolean ambient;
@@ -243,7 +243,6 @@ public final class NotificationEntry {
public void setRanking(@NonNull Ranking ranking) {
mRanking = ranking;
- channel = ranking.getChannel();
lastAudiblyAlertedMs = ranking.getLastAudiblyAlertedMillis();
importance = ranking.getImportance();
ambient = ranking.isAmbient();
@@ -259,6 +258,10 @@ public final class NotificationEntry {
canBubble = ranking.canBubble();
}
+ public NotificationChannel getChannel() {
+ return mRanking.getChannel();
+ }
+
public void setInterruption() {
interruption = true;
}
@@ -545,21 +548,18 @@ public final class NotificationEntry {
if (!ArrayUtils.isEmpty(replyTexts)) {
return true;
}
- Parcelable[] messages = extras.getParcelableArray(Notification.EXTRA_MESSAGES);
- if (messages != null && messages.length > 0) {
- Parcelable message = messages[messages.length - 1];
- if (message instanceof Bundle) {
- Notification.MessagingStyle.Message lastMessage =
- Notification.MessagingStyle.Message.getMessageFromBundle(
- (Bundle) message);
- if (lastMessage != null) {
- Person senderPerson = lastMessage.getSenderPerson();
- if (senderPerson == null) {
- return true;
- }
- Person user = extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON);
- return Objects.equals(user, senderPerson);
+ List<Message> messages = Message.getMessagesFromBundleArray(
+ extras.getParcelableArray(Notification.EXTRA_MESSAGES));
+ if (messages != null && !messages.isEmpty()) {
+ Message lastMessage = messages.get(messages.size() -1);
+
+ if (lastMessage != null) {
+ Person senderPerson = lastMessage.getSenderPerson();
+ if (senderPerson == null) {
+ return true;
}
+ Person user = extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON);
+ return Objects.equals(user, senderPerson);
}
}
return false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 12d537d3c646..0f6ce2153488 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -520,7 +520,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
public boolean getIsNonblockable() {
boolean isNonblockable = Dependency.get(NotificationBlockingHelperManager.class)
.isNonblockable(mStatusBarNotification.getPackageName(),
- mEntry.channel.getId());
+ mEntry.getChannel().getId());
// If the SystemNotifAsyncTask hasn't finished running or retrieved a value, we'll try once
// again, but in-place on the main thread this time. This should rarely ever get called.
@@ -532,13 +532,13 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
mEntry.mIsSystemNotification = isSystemNotification(mContext, mStatusBarNotification);
}
- isNonblockable |= mEntry.channel.isImportanceLockedByOEM();
- isNonblockable |= mEntry.channel.isImportanceLockedByCriticalDeviceFunction();
+ isNonblockable |= mEntry.getChannel().isImportanceLockedByOEM();
+ isNonblockable |= mEntry.getChannel().isImportanceLockedByCriticalDeviceFunction();
if (!isNonblockable && mEntry != null && mEntry.mIsSystemNotification != null) {
if (mEntry.mIsSystemNotification) {
- if (mEntry.channel != null
- && !mEntry.channel.isBlockableSystem()) {
+ if (mEntry.getChannel() != null
+ && !mEntry.getChannel().isBlockableSystem()) {
isNonblockable = true;
}
}
@@ -2389,7 +2389,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
public ArraySet<NotificationChannel> getUniqueChannels() {
ArraySet<NotificationChannel> channels = new ArraySet<>();
- channels.add(mEntry.channel);
+ channels.add(mEntry.getChannel());
// If this is a summary, then add in the children notification channels for the
// same user and pkg.
@@ -2398,7 +2398,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
final int numChildren = childrenRows.size();
for (int i = 0; i < numChildren; i++) {
final ExpandableNotificationRow childRow = childrenRows.get(i);
- final NotificationChannel childChannel = childRow.getEntry().channel;
+ final NotificationChannel childChannel = childRow.getEntry().getChannel();
final StatusBarNotification childSbn = childRow.getStatusBarNotification();
if (childSbn.getUser().equals(mStatusBarNotification.getUser()) &&
childSbn.getPackageName().equals(mStatusBarNotification.getPackageName())) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 8f7671a5dd96..3e8825d735da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -316,7 +316,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
iNotificationManager,
mVisualStabilityManager,
packageName,
- row.getEntry().channel,
+ row.getEntry().getChannel(),
row.getUniqueChannels(),
sbn,
mCheckSaveListener,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NPVPluginManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NPVPluginManager.kt
new file mode 100644
index 000000000000..7dcc2fcfe2b2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NPVPluginManager.kt
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone
+
+import android.content.Context
+import android.view.View
+import android.widget.FrameLayout
+import com.android.systemui.plugins.NPVPlugin
+import com.android.systemui.plugins.PluginListener
+import com.android.systemui.qs.TouchAnimator
+import com.android.systemui.shared.plugins.PluginManager
+
+/**
+ * Manages the NPVPlugin view and state
+ *
+ * Abstracts NPVPlugin from NPV and helps animate on expansion and respond to changes in Config.
+ */
+class NPVPluginManager(
+ var parent: FrameLayout,
+ val pluginManager: PluginManager
+) : PluginListener<NPVPlugin> {
+
+ private var plugin: NPVPlugin? = null
+ private var animator = createAnimator()
+
+ private fun createAnimator() = TouchAnimator.Builder()
+ .addFloat(parent, "alpha", 1f, 0f)
+ .addFloat(parent, "scaleY", 1f, 0f)
+ .build()
+
+ init {
+ pluginManager.addPluginListener(NPVPlugin.ACTION, this, NPVPlugin::class.java, false)
+ parent.pivotY = 0f
+ }
+
+ override fun onPluginConnected(plugin: NPVPlugin, pluginContext: Context) {
+ parent.removeAllViews()
+ plugin.attachToRoot(parent)
+ this.plugin = plugin
+ parent.visibility = View.VISIBLE
+ }
+
+ fun changeVisibility(visibility: Int) {
+ parent.visibility = if (plugin != null) visibility else View.GONE
+ }
+
+ fun destroy() {
+ plugin?.onDestroy()
+ pluginManager.removePluginListener(this)
+ }
+
+ override fun onPluginDisconnected(plugin: NPVPlugin) {
+ if (this.plugin == plugin) {
+ this.plugin = null
+ parent.removeAllViews()
+ parent.visibility = View.GONE
+ }
+ }
+
+ fun setListening(listening: Boolean) {
+ plugin?.setListening(listening)
+ }
+
+ fun setExpansion(expansion: Float, headerTranslation: Float, heightDiff: Float) {
+ parent.setTranslationY(expansion * heightDiff + headerTranslation)
+ if (!expansion.isNaN()) animator.setPosition(expansion)
+ }
+
+ fun replaceFrameLayout(newParent: FrameLayout) {
+ newParent.visibility = parent.visibility
+ parent.removeAllViews()
+ plugin?.attachToRoot(newParent)
+ parent = newParent
+ animator = createAnimator()
+ }
+
+ fun getHeight() = if (plugin != null) parent.height else 0
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 256c8e4e264f..f91b03ed087d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -393,6 +393,10 @@ public class NotificationPanelView extends PanelView implements
private boolean mAllowExpandForSmallExpansion;
private Runnable mExpandAfterLayoutRunnable;
+ private PluginManager mPluginManager;
+ private FrameLayout mPluginFrame;
+ private NPVPluginManager mNPVPluginManager;
+
@Inject
public NotificationPanelView(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
InjectionInflationController injectionInflationController,
@@ -400,7 +404,8 @@ public class NotificationPanelView extends PanelView implements
PulseExpansionHandler pulseExpansionHandler,
DynamicPrivacyController dynamicPrivacyController,
KeyguardBypassController bypassController,
- FalsingManager falsingManager) {
+ FalsingManager falsingManager,
+ PluginManager pluginManager) {
super(context, attrs);
setWillNotDraw(!DEBUG);
mInjectionInflationController = injectionInflationController;
@@ -431,6 +436,7 @@ public class NotificationPanelView extends PanelView implements
});
mBottomAreaShadeAlphaAnimator.setDuration(160);
mBottomAreaShadeAlphaAnimator.setInterpolator(Interpolators.ALPHA_OUT);
+ mPluginManager = pluginManager;
}
/**
@@ -465,6 +471,9 @@ public class NotificationPanelView extends PanelView implements
mKeyguardBottomArea = findViewById(R.id.keyguard_bottom_area);
mQsNavbarScrim = findViewById(R.id.qs_navbar_scrim);
mLastOrientation = getResources().getConfiguration().orientation;
+ mPluginFrame = findViewById(R.id.plugin_frame);
+ mNPVPluginManager = new NPVPluginManager(mPluginFrame, mPluginManager);
+
initBottomArea();
@@ -584,6 +593,19 @@ public class NotificationPanelView extends PanelView implements
lp.gravity = panelGravity;
mNotificationStackScroller.setLayoutParams(lp);
}
+ int sideMargin = res.getDimensionPixelOffset(R.dimen.notification_side_paddings);
+ int topMargin =
+ res.getDimensionPixelOffset(com.android.internal.R.dimen.quick_qs_total_height);
+ lp = (FrameLayout.LayoutParams) mPluginFrame.getLayoutParams();
+ if (lp.width != qsWidth || lp.gravity != panelGravity || lp.leftMargin != sideMargin
+ || lp.rightMargin != sideMargin || lp.topMargin != topMargin) {
+ lp.width = qsWidth;
+ lp.gravity = panelGravity;
+ lp.leftMargin = sideMargin;
+ lp.rightMargin = sideMargin;
+ lp.topMargin = topMargin;
+ mPluginFrame.setLayoutParams(lp);
+ }
}
@Override
@@ -650,6 +672,43 @@ public class NotificationPanelView extends PanelView implements
if (mOnReinflationListener != null) {
mOnReinflationListener.run();
}
+ reinflatePluginContainer();
+ }
+
+ @Override
+ public void onUiModeChanged() {
+ reinflatePluginContainer();
+ }
+
+ private void reinflatePluginContainer() {
+ int index = indexOfChild(mPluginFrame);
+ removeView(mPluginFrame);
+ mPluginFrame = (FrameLayout) mInjectionInflationController
+ .injectable(LayoutInflater.from(mContext)).inflate(
+ R.layout.status_bar_expanded_plugin_frame,
+ this,
+ false);
+ addView(mPluginFrame, index);
+
+ Resources res = getResources();
+ int qsWidth = res.getDimensionPixelSize(R.dimen.qs_panel_width);
+ int panelGravity = getResources().getInteger(R.integer.notification_panel_layout_gravity);
+ FrameLayout.LayoutParams lp;
+ int sideMargin = res.getDimensionPixelOffset(R.dimen.notification_side_paddings);
+ int topMargin =
+ res.getDimensionPixelOffset(com.android.internal.R.dimen.quick_qs_total_height);
+ lp = (FrameLayout.LayoutParams) mPluginFrame.getLayoutParams();
+ if (lp.width != qsWidth || lp.gravity != panelGravity || lp.leftMargin != sideMargin
+ || lp.rightMargin != sideMargin || lp.topMargin != topMargin) {
+ lp.width = qsWidth;
+ lp.gravity = panelGravity;
+ lp.leftMargin = sideMargin;
+ lp.rightMargin = sideMargin;
+ lp.topMargin = topMargin;
+ mPluginFrame.setLayoutParams(lp);
+ }
+
+ mNPVPluginManager.replaceFrameLayout(mPluginFrame);
}
private void initBottomArea() {
@@ -679,6 +738,7 @@ public class NotificationPanelView extends PanelView implements
int oldMaxHeight = mQsMaxExpansionHeight;
if (mQs != null) {
mQsMinExpansionHeight = mKeyguardShowing ? 0 : mQs.getQsMinExpansionHeight();
+ mQsMinExpansionHeight += mNPVPluginManager.getHeight();
mQsMaxExpansionHeight = mQs.getDesiredHeight();
mNotificationStackScroller.setMaxTopPadding(
mQsMaxExpansionHeight + mQsNotificationTopPadding);
@@ -1784,6 +1844,9 @@ public class NotificationPanelView extends PanelView implements
mBarState != StatusBarState.KEYGUARD && (!mQsExpanded
|| mQsExpansionFromOverscroll));
updateEmptyShadeView();
+ mNPVPluginManager.changeVisibility((mBarState != StatusBarState.KEYGUARD)
+ ? View.VISIBLE
+ : View.INVISIBLE);
mQsNavbarScrim.setVisibility(mBarState == StatusBarState.SHADE && mQsExpanded
&& !mStackScrollerOverscrolling && mQsScrimEnabled
? View.VISIBLE
@@ -1840,6 +1903,8 @@ public class NotificationPanelView extends PanelView implements
if (mQs == null) return;
float qsExpansionFraction = getQsExpansionFraction();
mQs.setQsExpansion(qsExpansionFraction, getHeaderTranslation());
+ int heightDiff = mQs.getDesiredHeight() - mQs.getQsMinExpansionHeight();
+ mNPVPluginManager.setExpansion(qsExpansionFraction, getHeaderTranslation(), heightDiff);
mNotificationStackScroller.setQsExpansionFraction(qsExpansionFraction);
}
@@ -2260,6 +2325,7 @@ public class NotificationPanelView extends PanelView implements
appearAmount = mNotificationStackScroller.calculateAppearFractionBypass();
}
startHeight = -mQs.getQsMinExpansionHeight();
+ startHeight -= mNPVPluginManager.getHeight();
}
float translation = MathUtils.lerp(startHeight, 0,
Math.min(1.0f, appearAmount))
@@ -2400,6 +2466,7 @@ public class NotificationPanelView extends PanelView implements
mKeyguardStatusBar.setListening(listening);
if (mQs == null) return;
mQs.setListening(listening);
+ mNPVPluginManager.setListening(listening);
}
@Override
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 fe96ef764875..6b12c6158948 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1263,7 +1263,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
getBouncerContainer(), mNotificationPanel, mBiometricUnlockController,
mStatusBarWindow.findViewById(R.id.lock_icon_container), mStackScroller,
- mKeyguardBypassController, mFalsingManager);
+ mKeyguardBypassController);
mKeyguardIndicationController
.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index 94ca9e9c9b51..819a7f6fde1a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -29,6 +29,7 @@ import android.util.Log;
import androidx.test.InstrumentationRegistry;
+import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.util.Assert;
@@ -78,6 +79,7 @@ public abstract class SysuiTestCase {
// A lot of tests get the FalsingManager, often via several layers of indirection.
// None of them actually need it.
mDependency.injectTestDependency(FalsingManager.class, new FalsingManagerFake());
+ mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
}
@After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceViewTest.java
index 128e819ccedd..b907cdb54bbf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceViewTest.java
@@ -63,7 +63,7 @@ public class AuthBiometricFaceViewTest extends SysuiTestCase {
mFaceView.mNegativeButton = mNegativeButton;
mFaceView.mPositiveButton = mPositiveButton;
mFaceView.mTryAgainButton = mTryAgainButton;
- mFaceView.mErrorView = mErrorView;
+ mFaceView.mIndicatorView = mErrorView;
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
index ffcb293ba398..fc1870738375 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
@@ -17,12 +17,15 @@
package com.android.systemui.biometrics;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.content.Context;
+import android.hardware.biometrics.BiometricPrompt;
+import android.os.Bundle;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
@@ -55,10 +58,10 @@ public class AuthBiometricViewTest extends SysuiTestCase {
@Mock private TextView mTitleView;
@Mock private TextView mSubtitleView;
@Mock private TextView mDescriptionView;
- @Mock private TextView mErrorView;
+ @Mock private TextView mIndicatorView;
@Mock private ImageView mIconView;
- TestableBiometricView mBiometricView;
+ private TestableBiometricView mBiometricView;
@Before
public void setup() {
@@ -87,8 +90,8 @@ public class AuthBiometricViewTest extends SysuiTestCase {
verify(mCallback, never()).onAction(anyInt());
verify(mBiometricView.mNegativeButton).setText(eq(R.string.cancel));
verify(mBiometricView.mPositiveButton).setEnabled(eq(true));
- verify(mErrorView).setText(eq(R.string.biometric_dialog_tap_confirm));
- verify(mErrorView).setVisibility(eq(View.VISIBLE));
+ verify(mIndicatorView).setText(eq(R.string.biometric_dialog_tap_confirm));
+ verify(mIndicatorView).setVisibility(eq(View.VISIBLE));
}
@Test
@@ -193,11 +196,88 @@ public class AuthBiometricViewTest extends SysuiTestCase {
verify(mCallback, never()).onAction(eq(AuthBiometricView.Callback.ACTION_USER_CANCELED));
}
+ @Test
+ public void testRestoresState() {
+ final boolean requireConfirmation = true; // set/init from AuthController
+
+ Button tryAgainButton = new Button(mContext);
+ TextView indicatorView = new TextView(mContext);
+ initDialog(mContext, mCallback, new MockInjector() {
+ @Override
+ public Button getTryAgainButton() {
+ return tryAgainButton;
+ }
+ @Override
+ public TextView getIndicatorView() {
+ return indicatorView;
+ }
+ });
+
+ final String failureMessage = "testFailureMessage";
+ mBiometricView.setRequireConfirmation(requireConfirmation);
+ mBiometricView.onAuthenticationFailed(failureMessage);
+ waitForIdleSync();
+
+ Bundle state = new Bundle();
+ mBiometricView.onSaveState(state);
+
+ assertEquals(View.VISIBLE, tryAgainButton.getVisibility());
+ assertEquals(View.VISIBLE, state.getInt(AuthDialog.KEY_BIOMETRIC_TRY_AGAIN_VISIBILITY));
+
+ assertEquals(AuthBiometricView.STATE_ERROR, mBiometricView.mState);
+ assertEquals(AuthBiometricView.STATE_ERROR, state.getInt(AuthDialog.KEY_BIOMETRIC_STATE));
+
+ assertEquals(View.VISIBLE, mBiometricView.mIndicatorView.getVisibility());
+ assertTrue(state.getBoolean(AuthDialog.KEY_BIOMETRIC_INDICATOR_ERROR_SHOWING));
+
+ assertEquals(failureMessage, mBiometricView.mIndicatorView.getText());
+ assertEquals(failureMessage, state.getString(AuthDialog.KEY_BIOMETRIC_INDICATOR_STRING));
+
+ // TODO: Test dialog size. Should move requireConfirmation to buildBiometricPromptBundle
+
+ // Create new dialog and restore the previous state into it
+ Button tryAgainButton2 = new Button(mContext);
+ TextView indicatorView2 = new TextView(mContext);
+ initDialog(mContext, mCallback, state, new MockInjector() {
+ @Override
+ public Button getTryAgainButton() {
+ return tryAgainButton2;
+ }
+ @Override
+ public TextView getIndicatorView() {
+ return indicatorView2;
+ }
+ });
+ mBiometricView.setRequireConfirmation(requireConfirmation);
+ waitForIdleSync();
+
+ // Test restored state
+ assertEquals(View.VISIBLE, tryAgainButton.getVisibility());
+ assertEquals(AuthBiometricView.STATE_ERROR, mBiometricView.mState);
+ assertEquals(View.VISIBLE, mBiometricView.mIndicatorView.getVisibility());
+ assertEquals(failureMessage, mBiometricView.mIndicatorView.getText());
+ }
+
+ private Bundle buildBiometricPromptBundle() {
+ Bundle bundle = new Bundle();
+ bundle.putCharSequence(BiometricPrompt.KEY_TITLE, "Title");
+ bundle.putCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT, "Negative");
+ return bundle;
+ }
+
private void initDialog(Context context, AuthBiometricView.Callback callback,
- MockInjector injector) {
+ Bundle savedState, MockInjector injector) {
mBiometricView = new TestableBiometricView(context, null, injector);
+ mBiometricView.setBiometricPromptBundle(buildBiometricPromptBundle());
mBiometricView.setCallback(callback);
- mBiometricView.initializeViews();
+ mBiometricView.restoreState(savedState);
+ mBiometricView.onFinishInflateInternal();
+ mBiometricView.onAttachedToWindowInternal();
+ }
+
+ private void initDialog(Context context, AuthBiometricView.Callback callback,
+ MockInjector injector) {
+ initDialog(context, callback, null /* savedState */, injector);
}
private class MockInjector extends AuthBiometricView.Injector {
@@ -232,8 +312,8 @@ public class AuthBiometricViewTest extends SysuiTestCase {
}
@Override
- public TextView getErrorView() {
- return mErrorView;
+ public TextView getIndicatorView() {
+ return mIndicatorView;
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index a5e468e0545d..eb7be4fa6332 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -147,7 +147,7 @@ public class AuthControllerTest extends SysuiTestCase {
public void testShowInvoked_whenSystemRequested()
throws Exception {
showDialog(BiometricPrompt.TYPE_FACE);
- verify(mDialog1).show(any());
+ verify(mDialog1).show(any(), any());
}
@Test
@@ -215,7 +215,7 @@ public class AuthControllerTest extends SysuiTestCase {
@Test
public void testShowNewDialog_beforeOldDialogDismissed_SkipsAnimations() throws Exception {
showDialog(BiometricPrompt.TYPE_FACE);
- verify(mDialog1).show(any());
+ verify(mDialog1).show(any(), any());
showDialog(BiometricPrompt.TYPE_FACE);
@@ -223,13 +223,13 @@ public class AuthControllerTest extends SysuiTestCase {
verify(mDialog1).dismissWithoutCallback(eq(false) /* animate */);
// Second dialog should be shown without animation
- verify(mDialog2).show(any());
+ verify(mDialog2).show(any(), any());
}
@Test
public void testConfigurationPersists_whenOnConfigurationChanged() throws Exception {
showDialog(BiometricPrompt.TYPE_FACE);
- verify(mDialog1).show(any());
+ verify(mDialog1).show(any(), any());
mBiometricDialogImpl.onConfigurationChanged(new Configuration());
@@ -241,10 +241,7 @@ public class AuthControllerTest extends SysuiTestCase {
// Saved state is restored into new dialog
ArgumentCaptor<Bundle> captor2 = ArgumentCaptor.forClass(Bundle.class);
- verify(mDialog2).restoreState(captor2.capture());
-
- // Dialog for new configuration skips intro
- verify(mDialog2).show(any());
+ verify(mDialog2).show(any(), captor2.capture());
// TODO: This should check all values we want to save/restore
assertEquals(captor.getValue(), captor2.getValue());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
index ba434d4fd0bd..448c80ef3c57 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
@@ -71,8 +71,8 @@ import com.android.systemui.statusbar.notification.collection.NotificationData;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.phone.DozeParameters;
-import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.StatusBarWindowController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -165,7 +165,8 @@ public class BubbleControllerTest extends SysuiTestCase {
// Return non-null notification data from the NEM
when(mNotificationEntryManager.getNotificationData()).thenReturn(mNotificationData);
when(mNotificationData.get(mRow.getEntry().key)).thenReturn(mRow.getEntry());
- when(mNotificationData.getChannel(mRow.getEntry().key)).thenReturn(mRow.getEntry().channel);
+ when(mNotificationData.getChannel(mRow.getEntry().key)).thenReturn(
+ mRow.getEntry().getChannel());
mZenModeConfig.suppressedVisualEffects = 0;
when(mZenModeController.getConfig()).thenReturn(mZenModeConfig);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
index 264a5400f1a5..7cd58193a3e7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -306,12 +306,21 @@ public class NotificationTestHelper {
userHandle,
null /* overrideGroupKey */,
System.currentTimeMillis());
- NotificationEntry entry = NotificationEntry.buildForTest(sbn);
+ final NotificationChannel channel =
+ new NotificationChannel(
+ notification.getChannelId(),
+ notification.getChannelId(),
+ importance);
+ channel.setBlockableSystem(true);
+
+ NotificationEntry entry = new NotificationEntry(
+ sbn,
+ new RankingBuilder()
+ .setKey(sbn.getKey())
+ .setChannel(channel)
+ .build());
entry.setRow(row);
entry.createIcons(mContext, sbn);
- entry.channel = new NotificationChannel(
- notification.getChannelId(), notification.getChannelId(), importance);
- entry.channel.setBlockableSystem(true);
row.setEntry(entry);
row.getNotificationInflater().addInflationFlags(extraInflationFlags);
NotificationContentInflaterTest.runThenWaitForInflation(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/RankingBuilder.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/RankingBuilder.java
new file mode 100644
index 000000000000..bbdc4b7fc360
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/RankingBuilder.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.SnoozeCriterion;
+
+import java.util.ArrayList;
+
+/**
+ * Standard builder class for Ranking objects. For use in tests that need to craft the underlying
+ * Ranking object of a NotificationEntry.
+ */
+public class RankingBuilder {
+ private String mKey = "test_key";
+ private int mRank = 0;
+ private boolean mMatchesInterruptionFilter = false;
+ private int mVisibilityOverride = 0;
+ private int mSuppressedVisualEffects = 0;
+ private int mImportance = 0;
+ private CharSequence mExplanation = "test_explanation";
+ private String mOverrideGroupKey = null;
+ private NotificationChannel mChannel = null;
+ private ArrayList<String> mOverridePeople = null;
+ private ArrayList<SnoozeCriterion> mSnoozeCriteria = null;
+ private boolean mShowBadge = false;
+ private int mUserSentiment = 0;
+ private boolean mHidden = false;
+ private long mLastAudiblyAlertedMs = 0;
+ private boolean mNoisy = false;
+ private ArrayList<Notification.Action> mSmartActions = null;
+ private ArrayList<CharSequence> mSmartReplies = null;
+ private boolean mCanBubble = false;
+
+ public RankingBuilder setKey(String key) {
+ mKey = key;
+ return this;
+ }
+
+ public RankingBuilder setImportance(int importance) {
+ mImportance = importance;
+ return this;
+ }
+
+ public RankingBuilder setUserSentiment(int userSentiment) {
+ mUserSentiment = userSentiment;
+ return this;
+ }
+
+ public RankingBuilder setChannel(NotificationChannel channel) {
+ mChannel = channel;
+ return this;
+ }
+
+ public RankingBuilder setSmartActions(ArrayList<Notification.Action> smartActions) {
+ mSmartActions = smartActions;
+ return this;
+ }
+
+ public RankingBuilder setSmartReplies(ArrayList<CharSequence> smartReplies) {
+ mSmartReplies = smartReplies;
+ return this;
+ }
+
+ public Ranking build() {
+ final Ranking ranking = new Ranking();
+ ranking.populate(
+ mKey,
+ mRank,
+ mMatchesInterruptionFilter,
+ mVisibilityOverride,
+ mSuppressedVisualEffects,
+ mImportance,
+ mExplanation,
+ mOverrideGroupKey,
+ mChannel,
+ mOverridePeople,
+ mSnoozeCriteria,
+ mShowBadge,
+ mUserSentiment,
+ mHidden,
+ mLastAudiblyAlertedMs,
+ mNoisy,
+ mSmartActions,
+ mSmartReplies,
+ mCanBubble);
+ return ranking;
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
index ed719d99a980..45173a2ef797 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
@@ -145,7 +145,7 @@ public class NotificationDataTest extends SysuiTestCase {
override.putParcelable(OVERRIDE_CHANNEL, NOTIFICATION_CHANNEL);
mNotificationData.rankingOverrides.put(mRow.getEntry().key, override);
mNotificationData.add(mRow.getEntry());
- assertEquals(NOTIFICATION_CHANNEL, mRow.getEntry().channel);
+ assertEquals(NOTIFICATION_CHANNEL, mRow.getEntry().getChannel());
}
@Test
@@ -343,7 +343,7 @@ public class NotificationDataTest extends SysuiTestCase {
new NotificationEntry(mMockStatusBarNotification, ranking);
assertEquals(systemGeneratedSmartActions, entry.systemGeneratedSmartActions);
- assertEquals(NOTIFICATION_CHANNEL, entry.channel);
+ assertEquals(NOTIFICATION_CHANNEL, entry.getChannel());
assertEquals(Ranking.USER_SENTIMENT_NEGATIVE, entry.userSentiment);
assertEquals(snoozeCriterions, entry.snoozeCriteria);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index d526d104630e..a14557bd9684 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -51,6 +51,7 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationTestHelper;
+import com.android.systemui.statusbar.RankingBuilder;
import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer;
@@ -327,8 +328,11 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
// Give each child a unique channel id/name.
int i = 0;
for (ExpandableNotificationRow childRow : childRows) {
- childRow.getEntry().channel =
- new NotificationChannel("id" + i, "dinnertime" + i, IMPORTANCE_DEFAULT);
+ childRow.getEntry().setRanking(new RankingBuilder()
+ .setChannel(
+ new NotificationChannel(
+ "id" + i, "dinnertime" + i, IMPORTANCE_DEFAULT))
+ .build());
i++;
}
@@ -364,7 +368,7 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
public void testGetIsNonblockable_oemLocked() throws Exception {
ExpandableNotificationRow row =
mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification());
- row.getEntry().channel.setImportanceLockedByOEM(true);
+ row.getEntry().getChannel().setImportanceLockedByOEM(true);
assertTrue(row.getIsNonblockable());
}
@@ -373,7 +377,7 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
public void testGetIsNonblockable_criticalDeviceFunction() throws Exception {
ExpandableNotificationRow row =
mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification());
- row.getEntry().channel.setImportanceLockedByCriticalDeviceFunction(true);
+ row.getEntry().getChannel().setImportanceLockedByCriticalDeviceFunction(true);
assertTrue(row.getIsNonblockable());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java
index 3c91b3f1bdd3..a26cdbd30b47 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java
@@ -41,8 +41,10 @@ import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.statusbar.NotificationTestHelper;
+import com.android.systemui.statusbar.RankingBuilder;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.util.Assert;
@@ -73,6 +75,7 @@ public class NotificationBlockingHelperManagerTest extends SysuiTestCase {
public void setUp() {
Assert.sMainLooper = TestableLooper.get(this).getLooper();
MockitoAnnotations.initMocks(this);
+ mDependency.injectMockDependency(BubbleController.class);
when(mGutsManager.openGuts(
any(View.class),
anyInt(),
@@ -82,6 +85,7 @@ public class NotificationBlockingHelperManagerTest extends SysuiTestCase {
when(mMenuRow.getLongpressMenuItem(any(Context.class))).thenReturn(mMenuItem);
mDependency.injectTestDependency(NotificationGutsManager.class, mGutsManager);
mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
+ mDependency.injectMockDependency(BubbleController.class);
mHelper = new NotificationTestHelper(mContext);
@@ -138,8 +142,11 @@ public class NotificationBlockingHelperManagerTest extends SysuiTestCase {
ExpandableNotificationRow groupRow = createBlockableGroupRowSpy(10);
int i = 0;
for (ExpandableNotificationRow childRow : groupRow.getNotificationChildren()) {
- childRow.getEntry().channel =
- new NotificationChannel(Integer.toString(i++), "", IMPORTANCE_DEFAULT);
+ childRow.getEntry().setRanking(new RankingBuilder()
+ .setChannel(
+ new NotificationChannel(
+ Integer.toString(i++), "", IMPORTANCE_DEFAULT))
+ .build());
}
groupRow.getEntry().userSentiment = USER_SENTIMENT_NEGATIVE;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index 795948470295..09c4179185fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -62,6 +62,7 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationTestHelper;
+import com.android.systemui.statusbar.RankingBuilder;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -498,7 +499,10 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
try {
ExpandableNotificationRow row = mHelper.createRow(nb.build());
- row.getEntry().channel = mTestNotificationChannel;
+ row.getEntry().setRanking(
+ new RankingBuilder()
+ .setChannel(mTestNotificationChannel)
+ .build());
return row;
} catch (Exception e) {
fail();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
index 98e1692c2368..096acf9d9ce4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
@@ -40,6 +40,7 @@ import android.view.ViewGroup;
import androidx.test.filters.SmallTest;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
+import com.android.systemui.statusbar.RankingBuilder;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.utils.leaks.LeakCheckedTest;
@@ -60,9 +61,11 @@ public class NotificationMenuRowTest extends LeakCheckedTest {
public void setup() {
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
mRow = mock(ExpandableNotificationRow.class);
- NotificationEntry entry = NotificationEntry.buildForTest(
- mock(StatusBarNotification.class));
- entry.channel = mock(NotificationChannel.class);
+ NotificationEntry entry = new NotificationEntry(
+ mock(StatusBarNotification.class),
+ new RankingBuilder()
+ .setChannel(mock(NotificationChannel.class))
+ .build());
when(mRow.getEntry()).thenReturn(entry);
}
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 a96efd7d2fc2..86ab3a70c3ac 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
@@ -38,6 +38,7 @@ import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.KeyguardAffordanceView;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationShelf;
@@ -195,7 +196,7 @@ public class NotificationPanelViewTest extends SysuiTestCase {
SystemUIFactory.getInstance().getRootComponent()),
coordinator, expansionHandler, mock(DynamicPrivacyController.class),
bypassController,
- mFalsingManager);
+ mFalsingManager, mock(PluginManager.class));
mNotificationStackScroller = mNotificationStackScrollLayout;
mKeyguardStatusView = NotificationPanelViewTest.this.mKeyguardStatusView;
mKeyguardStatusBar = NotificationPanelViewTest.this.mKeyguardStatusBar;
diff --git a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-ru/strings.xml b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-ru/strings.xml
index 0ff85fe39c99..dc77981e6c95 100644
--- a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-ru/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-ru/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="display_cutout_emulation_overlay" msgid="1677693377327336341">"В правом углу"</string>
+ <string name="display_cutout_emulation_overlay" msgid="1677693377327336341">"Сделать вырез в углу"</string>
</resources>
diff --git a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-ru/strings.xml b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-ru/strings.xml
index 2493da34af1f..a02eaf7bdc26 100644
--- a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-ru/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-ru/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="display_cutout_emulation_overlay" msgid="5323179900047630217">"Сверху и снизу"</string>
+ <string name="display_cutout_emulation_overlay" msgid="5323179900047630217">"Увеличить вырез вдвое"</string>
</resources>
diff --git a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-ru/strings.xml b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-ru/strings.xml
index 89ac1c3e1b11..1d1656d2862e 100644
--- a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-ru/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-ru/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="display_cutout_emulation_overlay" msgid="6424539415439220018">"Сверху"</string>
+ <string name="display_cutout_emulation_overlay" msgid="6424539415439220018">"Сделать вырез выше"</string>
</resources>
diff --git a/services/accessibility/java/com/android/server/accessibility/GlobalActionPerformer.java b/services/accessibility/java/com/android/server/accessibility/GlobalActionPerformer.java
index 672518cc17ed..b9b2654b93cc 100644
--- a/services/accessibility/java/com/android/server/accessibility/GlobalActionPerformer.java
+++ b/services/accessibility/java/com/android/server/accessibility/GlobalActionPerformer.java
@@ -24,10 +24,7 @@ import android.os.Binder;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.SystemClock;
-import android.view.IWindowManager;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
@@ -191,7 +188,7 @@ public class GlobalActionPerformer {
ScreenshotHelper screenshotHelper = (mScreenshotHelperSupplier != null)
? mScreenshotHelperSupplier.get() : new ScreenshotHelper(mContext);
screenshotHelper.takeScreenshot(android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN,
- true, true, new Handler(Looper.getMainLooper()));
+ true, true, new Handler(Looper.getMainLooper()), null);
return true;
}
}
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index e194f721b8d2..5672a13991d8 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -284,28 +284,6 @@ public class PackageWatchdog {
}
/**
- * Returns packages observed by {@code observer}
- *
- * @return an empty set if {@code observer} has some packages observerd from a previous boot
- * but has not registered itself in the current boot to receive notifications. Returns null
- * if there are no active packages monitored from any boot.
- */
- @Nullable
- public Set<String> getPackages(PackageHealthObserver observer) {
- synchronized (mLock) {
- for (int i = 0; i < mAllObservers.size(); i++) {
- if (observer.getName().equals(mAllObservers.keyAt(i))) {
- if (observer.equals(mAllObservers.valueAt(i).mRegisteredObserver)) {
- return mAllObservers.valueAt(i).mPackages.keySet();
- }
- return Collections.emptySet();
- }
- }
- }
- return null;
- }
-
- /**
* Called when a process fails either due to a crash or ANR.
*
* <p>For each package contained in the process, one registered observer with the least user
diff --git a/services/core/java/com/android/server/SystemService.java b/services/core/java/com/android/server/SystemService.java
index 4151c7269934..5e659b64dbbe 100644
--- a/services/core/java/com/android/server/SystemService.java
+++ b/services/core/java/com/android/server/SystemService.java
@@ -168,7 +168,7 @@ public abstract class SystemService {
* calls this method).
*/
@Deprecated
- public void onStartUser(@UserIdInt int userHandle) {}
+ public void onStartUser(@UserIdInt int userId) {}
/**
* Called when a new user is starting, for system services to initialize any per-user
@@ -189,7 +189,7 @@ public abstract class SystemService {
* default calls this method).
*/
@Deprecated
- public void onUnlockUser(@UserIdInt int userHandle) {}
+ public void onUnlockUser(@UserIdInt int userId) {}
/**
* Called when an existing user is in the process of being unlocked. This
@@ -218,7 +218,7 @@ public abstract class SystemService {
* (which by default calls this method).
*/
@Deprecated
- public void onSwitchUser(@UserIdInt int userHandle) {}
+ public void onSwitchUser(@UserIdInt int userId) {}
/**
* Called when switching to a different foreground user, for system services that have
@@ -243,7 +243,7 @@ public abstract class SystemService {
* calls this method).
*/
@Deprecated
- public void onStopUser(@UserIdInt int userHandle) {}
+ public void onStopUser(@UserIdInt int userId) {}
/**
* Called when an existing user is stopping, for system services to finalize any per-user
@@ -268,7 +268,7 @@ public abstract class SystemService {
* default calls this method).
*/
@Deprecated
- public void onCleanupUser(@UserIdInt int userHandle) {}
+ public void onCleanupUser(@UserIdInt int userId) {}
/**
* Called when an existing user is stopping, for system services to finalize any per-user
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 9b1eb3a62185..09bfb7a1adca 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -6098,16 +6098,16 @@ public class ActivityManagerService extends IActivityManager.Stub
return ptw != null ? ptw.tag : null;
}
- private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
+ private ProviderInfo getProviderInfoLocked(String authority, @UserIdInt int userId,
+ int pmFlags) {
ProviderInfo pi = null;
- ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
+ ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
if (cpr != null) {
pi = cpr.info;
} else {
try {
pi = AppGlobals.getPackageManager().resolveContentProvider(
- authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
- userHandle);
+ authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags, userId);
} catch (RemoteException ex) {
}
}
@@ -6324,13 +6324,6 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
- public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
- boolean preserveWindows, boolean animate, int animationDuration) {
- mActivityTaskManager.resizeStack(stackId, destBounds, allowResizeInDockedMode,
- preserveWindows, animate, animationDuration);
- }
-
- @Override
public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
int userId) {
return mActivityTaskManager.getRecentTasks(maxNum, flags, userId);
@@ -9170,7 +9163,16 @@ public class ActivityManagerService extends IActivityManager.Stub
Integer.toString(currentUserId), currentUserId);
mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
Integer.toString(currentUserId), currentUserId);
- mSystemServiceManager.startUser(t, currentUserId);
+
+ // On Automotive, at this point the system user has already been started and unlocked,
+ // and some of the tasks we do here have already been done. So skip those in that case.
+ // TODO(b/132262830): this workdound shouldn't be necessary once we move the
+ // headless-user start logic to UserManager-land
+ final boolean bootingSystemUser = currentUserId == UserHandle.USER_SYSTEM;
+
+ if (bootingSystemUser) {
+ mSystemServiceManager.startUser(t, currentUserId);
+ }
synchronized (this) {
// Only start up encryption-aware persistent apps; once user is
@@ -9199,12 +9201,6 @@ public class ActivityManagerService extends IActivityManager.Stub
t.traceEnd();
}
- // On Automotive, at this point the system user has already been started and unlocked,
- // and some of the tasks we do here have already been done. So skip those in that case.
- // TODO(b/132262830): this workdound shouldn't be necessary once we move the
- // headless-user start logic to UserManager-land
- final boolean bootingSystemUser = currentUserId == UserHandle.USER_SYSTEM;
-
if (bootingSystemUser) {
t.traceBegin("startHomeOnAllDisplays");
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
@@ -15345,11 +15341,11 @@ public class ActivityManagerService extends IActivityManager.Stub
intent.getAction());
final String[] packageNames = intent.getStringArrayExtra(
Intent.EXTRA_CHANGED_PACKAGE_LIST);
- final int userHandle = intent.getIntExtra(
+ final int userIdExtra = intent.getIntExtra(
Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
mAtmInternal.onPackagesSuspendedChanged(packageNames, suspended,
- userHandle);
+ userIdExtra);
break;
}
break;
@@ -18068,7 +18064,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
- public void killForegroundAppsForUser(int userHandle) {
+ public void killForegroundAppsForUser(@UserIdInt int userId) {
synchronized (ActivityManagerService.this) {
final ArrayList<ProcessRecord> procs = new ArrayList<>();
final int NP = mProcessList.mProcessNames.getMap().size();
@@ -18083,7 +18079,7 @@ public class ActivityManagerService extends IActivityManager.Stub
continue;
}
if (app.removed
- || (app.userId == userHandle && app.hasForegroundActivities())) {
+ || (app.userId == userId && app.hasForegroundActivities())) {
procs.add(app);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 8b8c40e1346b..d46c62662faf 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -2481,8 +2481,6 @@ final class ActivityManagerShellCommand extends ShellCommand {
switch (op) {
case "move-task":
return runStackMoveTask(pw);
- case "resize":
- return runStackResize(pw);
case "resize-animated":
return runStackResizeAnimated(pw);
case "resize-docked-stack":
@@ -2561,17 +2559,6 @@ final class ActivityManagerShellCommand extends ShellCommand {
return 0;
}
- int runStackResize(PrintWriter pw) throws RemoteException {
- String stackIdStr = getNextArgRequired();
- int stackId = Integer.parseInt(stackIdStr);
- final Rect bounds = getBounds();
- if (bounds == null) {
- getErrPrintWriter().println("Error: invalid input bounds");
- return -1;
- }
- return resizeStack(stackId, bounds, 0);
- }
-
int runStackResizeAnimated(PrintWriter pw) throws RemoteException {
String stackIdStr = getNextArgRequired();
int stackId = Integer.parseInt(stackIdStr);
@@ -2585,16 +2572,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
return -1;
}
}
- return resizeStackUnchecked(stackId, bounds, 0, true);
- }
-
- int resizeStackUnchecked(int stackId, Rect bounds, int delayMs, boolean animate)
- throws RemoteException {
- try {
- mTaskInterface.resizeStack(stackId, bounds, false, false, animate, -1);
- Thread.sleep(delayMs);
- } catch (InterruptedException e) {
- }
+ mTaskInterface.animateResizePinnedStack(stackId, bounds, -1);
return 0;
}
@@ -2609,14 +2587,6 @@ final class ActivityManagerShellCommand extends ShellCommand {
return 0;
}
- int resizeStack(int stackId, Rect bounds, int delayMs) throws RemoteException {
- if (bounds == null) {
- getErrPrintWriter().println("Error: invalid input bounds");
- return -1;
- }
- return resizeStackUnchecked(stackId, bounds, delayMs, false);
- }
-
int runStackPositionTask(PrintWriter pw) throws RemoteException {
String taskIdStr = getNextArgRequired();
int taskId = Integer.parseInt(taskIdStr);
@@ -3195,8 +3165,6 @@ final class ActivityManagerShellCommand extends ShellCommand {
pw.println(" move-task <TASK_ID> <STACK_ID> [true|false]");
pw.println(" Move <TASK_ID> from its current stack to the top (true) or");
pw.println(" bottom (false) of <STACK_ID>.");
- pw.println(" resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
- pw.println(" Change <STACK_ID> size and position to <LEFT,TOP,RIGHT,BOTTOM>.");
pw.println(" resize-animated <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
pw.println(" Same as resize, but allow animation.");
pw.println(" resize-docked-stack <LEFT,TOP,RIGHT,BOTTOM> [<TASK_LEFT,TASK_TOP,TASK_RIGHT,TASK_BOTTOM>]");
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 5fe72ddfaf91..5c8e530faf70 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -841,7 +841,7 @@ class UserController implements Handler.Callback {
* @return user id to lock. UserHandler.USER_NULL will be returned if no user should be locked.
*/
@GuardedBy("mLock")
- private int updateUserToLockLU(int userId) {
+ private int updateUserToLockLU(@UserIdInt int userId) {
int userIdToLock = userId;
if (mDelayUserDataLocking && !getUserInfo(userId).isEphemeral()
&& !hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND, userId)) {
@@ -869,7 +869,7 @@ class UserController implements Handler.Callback {
* {@code userId}. The returned list includes {@code userId}.
*/
@GuardedBy("mLock")
- private @NonNull int[] getUsersToStopLU(int userId) {
+ private @NonNull int[] getUsersToStopLU(@UserIdInt int userId) {
int startedUsersSize = mStartedUsers.size();
IntArray userIds = new IntArray();
userIds.add(userId);
@@ -892,7 +892,7 @@ class UserController implements Handler.Callback {
return userIds.toArray();
}
- private void forceStopUser(int userId, String reason) {
+ private void forceStopUser(@UserIdInt int userId, String reason) {
mInjector.activityManagerForceStopPackage(userId, reason);
Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
@@ -965,7 +965,7 @@ class UserController implements Handler.Callback {
}
}
- boolean startUser(final int userId, final boolean foreground) {
+ boolean startUser(final @UserIdInt int userId, final boolean foreground) {
return startUser(userId, foreground, null);
}
@@ -1002,7 +1002,7 @@ class UserController implements Handler.Callback {
* @return true if the user has been successfully started
*/
boolean startUser(
- final int userId,
+ final @UserIdInt int userId,
final boolean foreground,
@Nullable IProgressListener unlockListener) {
@@ -1018,7 +1018,7 @@ class UserController implements Handler.Callback {
}
}
- private boolean startUserInternal(int userId, boolean foreground,
+ private boolean startUserInternal(@UserIdInt int userId, boolean foreground,
@Nullable IProgressListener unlockListener, @NonNull TimingsTraceAndSlog t) {
Slog.i(TAG, "Starting userid:" + userId + " fg:" + foreground);
@@ -1257,7 +1257,8 @@ class UserController implements Handler.Callback {
}
}
- boolean unlockUser(final int userId, byte[] token, byte[] secret, IProgressListener listener) {
+ boolean unlockUser(final @UserIdInt int userId, byte[] token, byte[] secret,
+ IProgressListener listener) {
checkCallingPermission(INTERACT_ACROSS_USERS_FULL, "unlockUser");
final long binderToken = Binder.clearCallingIdentity();
try {
@@ -1273,12 +1274,12 @@ class UserController implements Handler.Callback {
* when the credential-encrypted storage isn't tied to a user-provided
* PIN or pattern.
*/
- private boolean maybeUnlockUser(final int userId) {
+ private boolean maybeUnlockUser(final @UserIdInt int userId) {
// Try unlocking storage using empty token
return unlockUserCleared(userId, null, null, null);
}
- private static void notifyFinished(int userId, IProgressListener listener) {
+ private static void notifyFinished(@UserIdInt int userId, IProgressListener listener) {
if (listener == null) return;
try {
listener.onFinished(userId, null);
@@ -1286,7 +1287,7 @@ class UserController implements Handler.Callback {
}
}
- private boolean unlockUserCleared(final int userId, byte[] token, byte[] secret,
+ private boolean unlockUserCleared(final @UserIdInt int userId, byte[] token, byte[] secret,
IProgressListener listener) {
UserState uss;
if (!StorageManager.isUserKeyUnlocked(userId)) {
@@ -1384,7 +1385,7 @@ class UserController implements Handler.Callback {
getSwitchingFromSystemUserMessage(), getSwitchingToSystemUserMessage());
}
- private void dispatchForegroundProfileChanged(int userId) {
+ private void dispatchForegroundProfileChanged(@UserIdInt int userId) {
final int observerCount = mUserSwitchObservers.beginBroadcast();
for (int i = 0; i < observerCount; i++) {
try {
@@ -1397,7 +1398,7 @@ class UserController implements Handler.Callback {
}
/** Called on handler thread */
- void dispatchUserSwitchComplete(int userId) {
+ void dispatchUserSwitchComplete(@UserIdInt int userId) {
mInjector.getWindowManager().setSwitchingUser(false);
final int observerCount = mUserSwitchObservers.beginBroadcast();
for (int i = 0; i < observerCount; i++) {
@@ -1409,7 +1410,7 @@ class UserController implements Handler.Callback {
mUserSwitchObservers.finishBroadcast();
}
- private void dispatchLockedBootComplete(int userId) {
+ private void dispatchLockedBootComplete(@UserIdInt int userId) {
final int observerCount = mUserSwitchObservers.beginBroadcast();
for (int i = 0; i < observerCount; i++) {
try {
@@ -1596,7 +1597,7 @@ class UserController implements Handler.Callback {
}
- int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
+ int handleIncomingUser(int callingPid, int callingUid, @UserIdInt int userId, boolean allowAll,
int allowMode, String name, String callerPackage) {
final int callingUserId = UserHandle.getUserId(callingUid);
if (callingUserId == userId) {
@@ -1682,12 +1683,12 @@ class UserController implements Handler.Callback {
return targetUserId;
}
- int unsafeConvertIncomingUser(int userId) {
+ int unsafeConvertIncomingUser(@UserIdInt int userId) {
return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
? getCurrentUserId(): userId;
}
- void ensureNotSpecialUser(int userId) {
+ void ensureNotSpecialUser(@UserIdInt int userId) {
if (userId >= 0) {
return;
}
@@ -1700,7 +1701,7 @@ class UserController implements Handler.Callback {
mUserSwitchObservers.register(observer, name);
}
- void sendForegroundProfileChanged(int userId) {
+ void sendForegroundProfileChanged(@UserIdInt int userId) {
mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, userId, 0).sendToTarget();
}
@@ -1709,13 +1710,13 @@ class UserController implements Handler.Callback {
mUserSwitchObservers.unregister(observer);
}
- UserState getStartedUserState(int userId) {
+ UserState getStartedUserState(@UserIdInt int userId) {
synchronized (mLock) {
return mStartedUsers.get(userId);
}
}
- boolean hasStartedUserState(int userId) {
+ boolean hasStartedUserState(@UserIdInt int userId) {
synchronized (mLock) {
return mStartedUsers.get(userId) != null;
}
@@ -1804,7 +1805,7 @@ class UserController implements Handler.Callback {
}
}
- boolean isUserRunning(int userId, int flags) {
+ boolean isUserRunning(@UserIdInt int userId, int flags) {
UserState state = getStartedUserState(userId);
if (state == null) {
return false;
@@ -1920,7 +1921,7 @@ class UserController implements Handler.Callback {
}
@GuardedBy("mLock")
- private boolean isCurrentUserLU(int userId) {
+ private boolean isCurrentUserLU(@UserIdInt int userId) {
return userId == getCurrentOrTargetUserIdLU();
}
@@ -1929,7 +1930,7 @@ class UserController implements Handler.Callback {
return ums != null ? ums.getUserIds() : new int[] { 0 };
}
- private UserInfo getUserInfo(int userId) {
+ private UserInfo getUserInfo(@UserIdInt int userId) {
return mInjector.getUserManager().getUserInfo(userId);
}
@@ -1943,7 +1944,7 @@ class UserController implements Handler.Callback {
*
* It doesn't handle other special user IDs such as {@link UserHandle#USER_CURRENT}.
*/
- int[] expandUserId(int userId) {
+ int[] expandUserId(@UserIdInt int userId) {
if (userId != UserHandle.USER_ALL) {
return new int[] {userId};
} else {
@@ -1951,7 +1952,7 @@ class UserController implements Handler.Callback {
}
}
- boolean exists(int userId) {
+ boolean exists(@UserIdInt int userId) {
return mInjector.getUserManager().exists(userId);
}
@@ -1967,16 +1968,16 @@ class UserController implements Handler.Callback {
}
}
- private void enforceShellRestriction(String restriction, int userHandle) {
+ private void enforceShellRestriction(String restriction, @UserIdInt int userId) {
if (Binder.getCallingUid() == SHELL_UID) {
- if (userHandle < 0 || hasUserRestriction(restriction, userHandle)) {
+ if (userId < 0 || hasUserRestriction(restriction, userId)) {
throw new SecurityException("Shell does not have permission to access user "
- + userHandle);
+ + userId);
}
}
}
- boolean hasUserRestriction(String restriction, int userId) {
+ boolean hasUserRestriction(String restriction, @UserIdInt int userId) {
return mInjector.getUserManager().hasUserRestriction(restriction, userId);
}
@@ -1994,7 +1995,7 @@ class UserController implements Handler.Callback {
}
}
- boolean isUserOrItsParentRunning(int userId) {
+ boolean isUserOrItsParentRunning(@UserIdInt int userId) {
synchronized (mLock) {
if (isUserRunning(userId, 0)) {
return true;
@@ -2007,7 +2008,7 @@ class UserController implements Handler.Callback {
}
}
- boolean isCurrentProfile(int userId) {
+ boolean isCurrentProfile(@UserIdInt int userId) {
synchronized (mLock) {
return ArrayUtils.contains(mCurrentProfileIds, userId);
}
@@ -2019,7 +2020,7 @@ class UserController implements Handler.Callback {
}
}
- void onUserRemoved(int userId) {
+ void onUserRemoved(@UserIdInt int userId) {
synchronized (mLock) {
int size = mUserProfileGroupIds.size();
for (int i = size - 1; i >= 0; i--) {
@@ -2037,7 +2038,7 @@ class UserController implements Handler.Callback {
* Returns whether the given user requires credential entry at this time. This is used to
* intercept activity launches for work apps when the Work Challenge is present.
*/
- protected boolean shouldConfirmCredentials(int userId) {
+ protected boolean shouldConfirmCredentials(@UserIdInt int userId) {
synchronized (mLock) {
if (mStartedUsers.get(userId) == null) {
return false;
@@ -2265,7 +2266,7 @@ class UserController implements Handler.Callback {
IIntentReceiver resultTo, int resultCode, String resultData,
Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid,
- int realCallingPid, int userId) {
+ int realCallingPid, @UserIdInt int userId) {
// TODO b/64165549 Verify that mLock is not held before calling AMS methods
synchronized (mService) {
return mService.broadcastIntentLocked(null, null, intent, resolvedType, resultTo,
@@ -2282,11 +2283,11 @@ class UserController implements Handler.Callback {
WindowManagerService getWindowManager() {
return mService.mWindowManager;
}
- void activityManagerOnUserStopped(int userId) {
+ void activityManagerOnUserStopped(@UserIdInt int userId) {
LocalServices.getService(ActivityTaskManagerInternal.class).onUserStopped(userId);
}
- void systemServiceManagerCleanupUser(int userId) {
+ void systemServiceManagerCleanupUser(@UserIdInt int userId) {
mService.mSystemServiceManager.cleanupUser(userId);
}
@@ -2330,7 +2331,7 @@ class UserController implements Handler.Callback {
}
}
- void sendPreBootBroadcast(int userId, boolean quiet, final Runnable onFinish) {
+ void sendPreBootBroadcast(@UserIdInt int userId, boolean quiet, final Runnable onFinish) {
new PreBootBroadcaster(mService, userId, null, quiet) {
@Override
public void onFinished() {
@@ -2339,7 +2340,7 @@ class UserController implements Handler.Callback {
}.sendNext();
}
- void activityManagerForceStopPackage(int userId, String reason) {
+ void activityManagerForceStopPackage(@UserIdInt int userId, String reason) {
synchronized (mService) {
mService.forceStopPackageLocked(null, -1, false, false, true, false, false,
userId, reason);
@@ -2351,11 +2352,11 @@ class UserController implements Handler.Callback {
return mService.checkComponentPermission(permission, pid, uid, owningUid, exported);
}
- protected void startHomeActivity(int userId, String reason) {
+ protected void startHomeActivity(@UserIdInt int userId, String reason) {
mService.mAtmInternal.startHomeActivity(userId, reason);
}
- void startUserWidgets(int userId) {
+ void startUserWidgets(@UserIdInt int userId) {
AppWidgetManagerInternal awm = LocalServices.getService(AppWidgetManagerInternal.class);
if (awm != null) {
// Out of band, because this is called during a sequence with
@@ -2370,13 +2371,13 @@ class UserController implements Handler.Callback {
mService.mAtmInternal.updateUserConfiguration();
}
- void clearBroadcastQueueForUser(int userId) {
+ void clearBroadcastQueueForUser(@UserIdInt int userId) {
synchronized (mService) {
mService.clearBroadcastQueueForUserLocked(userId);
}
}
- void loadUserRecents(int userId) {
+ void loadUserRecents(@UserIdInt int userId) {
mService.mAtmInternal.loadRecentTasksForUser(userId);
}
@@ -2384,7 +2385,7 @@ class UserController implements Handler.Callback {
mService.startPersistentApps(matchFlags);
}
- void installEncryptionUnawareProviders(int userId) {
+ void installEncryptionUnawareProviders(@UserIdInt int userId) {
mService.installEncryptionUnawareProviders(userId);
}
@@ -2417,11 +2418,11 @@ class UserController implements Handler.Callback {
}
}
- void stackSupervisorRemoveUser(int userId) {
+ void stackSupervisorRemoveUser(@UserIdInt int userId) {
mService.mAtmInternal.removeUser(userId);
}
- protected boolean stackSupervisorSwitchUser(int userId, UserState uss) {
+ protected boolean stackSupervisorSwitchUser(@UserIdInt int userId, UserState uss) {
return mService.mAtmInternal.switchUser(userId, uss);
}
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index 8de259516890..09f52860e069 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -36,6 +36,7 @@ import android.os.UserManager;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
+import android.util.StatsLog;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -44,6 +45,9 @@ import com.android.server.ServiceThread;
import com.android.server.SystemService;
import com.android.server.wm.WindowManagerInternal;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -102,6 +106,9 @@ public class CameraServiceProxy extends SystemService
private final boolean mNotifyNfc;
+ private ScheduledThreadPoolExecutor mLogWriterService = new ScheduledThreadPoolExecutor(
+ /*corePoolSize*/ 1);
+
/**
* Structure to track camera usage
*/
@@ -204,6 +211,9 @@ public class CameraServiceProxy extends SystemService
mNotifyNfc = SystemProperties.getInt(NFC_NOTIFICATION_PROP, 0) > 0;
if (DEBUG) Slog.v(TAG, "Notify NFC behavior is " + (mNotifyNfc ? "active" : "disabled"));
+ // Don't keep any extra logging threads if not needed
+ mLogWriterService.setKeepAliveTime(1, TimeUnit.SECONDS);
+ mLogWriterService.allowCoreThreadTimeOut(true);
}
@Override
@@ -279,6 +289,51 @@ public class CameraServiceProxy extends SystemService
}
}
+ private class EventWriterTask implements Runnable {
+ private ArrayList<CameraUsageEvent> mEventList;
+ private static final long WRITER_SLEEP_MS = 100;
+
+ public EventWriterTask(ArrayList<CameraUsageEvent> eventList) {
+ mEventList = eventList;
+ }
+
+ @Override
+ public void run() {
+ if (mEventList != null) {
+ for (CameraUsageEvent event : mEventList) {
+ logCameraUsageEvent(event);
+ try {
+ Thread.sleep(WRITER_SLEEP_MS);
+ } catch (InterruptedException e) {}
+ }
+ mEventList.clear();
+ }
+ }
+
+ /**
+ * Write camera usage events to stats log.
+ * Package-private
+ */
+ private void logCameraUsageEvent(CameraUsageEvent e) {
+ int facing = StatsLog.CAMERA_ACTION_EVENT__FACING__UNKNOWN;
+ switch(e.mCameraFacing) {
+ case ICameraServiceProxy.CAMERA_FACING_BACK:
+ facing = StatsLog.CAMERA_ACTION_EVENT__FACING__BACK;
+ break;
+ case ICameraServiceProxy.CAMERA_FACING_FRONT:
+ facing = StatsLog.CAMERA_ACTION_EVENT__FACING__FRONT;
+ break;
+ case ICameraServiceProxy.CAMERA_FACING_EXTERNAL:
+ facing = StatsLog.CAMERA_ACTION_EVENT__FACING__EXTERNAL;
+ break;
+ default:
+ Slog.w(TAG, "Unknown camera facing: " + e.mCameraFacing);
+ }
+ StatsLog.write(StatsLog.CAMERA_ACTION_EVENT, e.getDuration(), e.mAPILevel,
+ e.mClientName, facing);
+ }
+ }
+
/**
* Dump camera usage events to log.
* Package-private
@@ -315,6 +370,10 @@ public class CameraServiceProxy extends SystemService
.setPackageName(e.mClientName);
mLogger.write(l);
}
+
+ mLogWriterService.execute(new EventWriterTask(
+ new ArrayList<CameraUsageEvent>(mCameraUsageHistory)));
+
mCameraUsageHistory.clear();
}
final long ident = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index db8d0988e75c..f71b3627135d 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -457,7 +457,7 @@ public class NotificationManagerService extends SystemService {
private static final int MY_UID = Process.myUid();
private static final int MY_PID = Process.myPid();
private static final IBinder WHITELIST_TOKEN = new Binder();
- private RankingHandler mRankingHandler;
+ protected RankingHandler mRankingHandler;
private long mLastOverRateLogTime;
private float mMaxPackageEnqueueRate = DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE;
@@ -1550,10 +1550,12 @@ public class NotificationManagerService extends SystemService {
@VisibleForTesting
void clearNotifications() {
- mEnqueuedNotifications.clear();
- mNotificationList.clear();
- mNotificationsByKey.clear();
- mSummaryByGroupKey.clear();
+ synchronized (mNotificationList) {
+ mEnqueuedNotifications.clear();
+ mNotificationList.clear();
+ mNotificationsByKey.clear();
+ mSummaryByGroupKey.clear();
+ }
}
@VisibleForTesting
@@ -1605,11 +1607,6 @@ public class NotificationManagerService extends SystemService {
void setPreferencesHelper(PreferencesHelper prefHelper) { mPreferencesHelper = prefHelper; }
@VisibleForTesting
- void setRankingHandler(RankingHandler rankingHandler) {
- mRankingHandler = rankingHandler;
- }
-
- @VisibleForTesting
void setZenHelper(ZenModeHelper zenHelper) {
mZenModeHelper = zenHelper;
}
@@ -1641,7 +1638,7 @@ public class NotificationManagerService extends SystemService {
// TODO: All tests should use this init instead of the one-off setters above.
@VisibleForTesting
- void init(Looper looper, IPackageManager packageManager,
+ void init(Looper looper, RankingHandler rankingHandler, IPackageManager packageManager,
PackageManager packageManagerClient,
LightsManager lightsManager, NotificationListeners notificationListeners,
NotificationAssistants notificationAssistants, ConditionProviders conditionProviders,
@@ -1675,7 +1672,6 @@ public class NotificationManagerService extends SystemService {
mUm = userManager;
mHandler = new WorkerHandler(looper);
- mRankingThread.start();
String[] extractorNames;
try {
extractorNames = resources.getStringArray(R.array.config_notificationSignalExtractors);
@@ -1684,7 +1680,7 @@ public class NotificationManagerService extends SystemService {
}
mUsageStats = usageStats;
mMetricsLogger = new MetricsLogger();
- mRankingHandler = new RankingHandlerWorker(mRankingThread.getLooper());
+ mRankingHandler = rankingHandler;
mConditionProviders = conditionProviders;
mZenModeHelper = new ZenModeHelper(getContext(), mHandler.getLooper(), mConditionProviders);
mZenModeHelper.addCallback(new ZenModeHelper.Callback() {
@@ -1829,8 +1825,9 @@ public class NotificationManagerService extends SystemService {
}, mUserProfiles);
final File systemDir = new File(Environment.getDataDirectory(), "system");
+ mRankingThread.start();
- init(Looper.myLooper(),
+ init(Looper.myLooper(), new RankingHandlerWorker(mRankingThread.getLooper()),
AppGlobals.getPackageManager(), getContext().getPackageManager(),
getLocalService(LightsManager.class),
new NotificationListeners(AppGlobals.getPackageManager()),
diff --git a/services/core/java/com/android/server/notification/ZenLog.java b/services/core/java/com/android/server/notification/ZenLog.java
index c6af7566a8bd..8f05636eed9c 100644
--- a/services/core/java/com/android/server/notification/ZenLog.java
+++ b/services/core/java/com/android/server/notification/ZenLog.java
@@ -179,6 +179,7 @@ public class ZenLog {
case TYPE_SUPPRESSOR_CHANGED: return "suppressor_changed";
case TYPE_LISTENER_HINTS_CHANGED: return "listener_hints_changed";
case TYPE_SET_NOTIFICATION_POLICY: return "set_notification_policy";
+ case TYPE_SET_CONSOLIDATED_ZEN_POLICY: return "set_consolidated_policy";
default: return "unknown";
}
}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index ee948b28e546..f63aa5256078 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -954,12 +954,11 @@ public class ZenModeHelper {
}
private void applyCustomPolicy(ZenPolicy policy, ZenRule rule) {
- if (rule.zenMode == NotificationManager.INTERRUPTION_FILTER_NONE) {
+ if (rule.zenMode == Global.ZEN_MODE_NO_INTERRUPTIONS) {
policy.apply(new ZenPolicy.Builder()
.disallowAllSounds()
.build());
- } else if (rule.zenMode
- == NotificationManager.INTERRUPTION_FILTER_ALARMS) {
+ } else if (rule.zenMode == Global.ZEN_MODE_ALARMS) {
policy.apply(new ZenPolicy.Builder()
.disallowAllSounds()
.allowAlarms(true)
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index ab77cc6de819..b124c4b18efa 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -113,6 +113,7 @@ import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures;
import android.Manifest;
+import android.annotation.AppIdInt;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -12059,11 +12060,12 @@ public class PackageManagerService extends IPackageManager.Stub
| IntentFilter.MATCH_ADJUSTMENT_NORMAL;
}
- private void killApplication(String pkgName, int appId, String reason) {
+ private void killApplication(String pkgName, @AppIdInt int appId, String reason) {
killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
}
- private void killApplication(String pkgName, int appId, int userId, String reason) {
+ private void killApplication(String pkgName, @AppIdInt int appId,
+ @UserIdInt int userId, String reason) {
// Request the ActivityManager to kill the process(only for existing packages)
// so that we do not end up in a confused state while the user is still using the older
// version of the application while the new one gets installed.
@@ -12438,7 +12440,7 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
- boolean includeStopped, int appId, int[] userIds, int[] instantUserIds) {
+ boolean includeStopped, @AppIdInt int appId, int[] userIds, int[] instantUserIds) {
if (ArrayUtils.isEmpty(userIds) && ArrayUtils.isEmpty(instantUserIds)) {
return;
}
@@ -18903,7 +18905,8 @@ public class PackageManagerService extends IPackageManager.Stub
* Remove entries from the keystore daemon. Will only remove it if the
* {@code appId} is valid.
*/
- private static void removeKeystoreDataIfNeeded(UserManagerInternal um, int userId, int appId) {
+ private static void removeKeystoreDataIfNeeded(UserManagerInternal um, @UserIdInt int userId,
+ @AppIdInt int appId) {
if (appId < 0) {
return;
}
@@ -18989,7 +18992,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
@Override
- public void getPackageSizeInfo(final String packageName, int userHandle,
+ public void getPackageSizeInfo(final String packageName, int userId,
final IPackageStatsObserver observer) {
throw new UnsupportedOperationException(
"Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
@@ -22494,24 +22497,24 @@ public class PackageManagerService extends IPackageManager.Stub
}
/** Called by UserManagerService */
- void cleanUpUser(UserManagerService userManager, int userHandle) {
+ void cleanUpUser(UserManagerService userManager, @UserIdInt int userId) {
synchronized (mLock) {
- mDirtyUsers.remove(userHandle);
- mUserNeedsBadging.delete(userHandle);
- mSettings.removeUserLPw(userHandle);
- mPendingBroadcasts.remove(userHandle);
- mInstantAppRegistry.onUserRemovedLPw(userHandle);
- removeUnusedPackagesLPw(userManager, userHandle);
+ mDirtyUsers.remove(userId);
+ mUserNeedsBadging.delete(userId);
+ mSettings.removeUserLPw(userId);
+ mPendingBroadcasts.remove(userId);
+ mInstantAppRegistry.onUserRemovedLPw(userId);
+ removeUnusedPackagesLPw(userManager, userId);
}
}
/**
- * We're removing userHandle and would like to remove any downloaded packages
+ * We're removing userId and would like to remove any downloaded packages
* that are no longer in use by any other user.
- * @param userHandle the user being removed
+ * @param userId the user being removed
*/
@GuardedBy("mLock")
- private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
+ private void removeUnusedPackagesLPw(UserManagerService userManager, final int userId) {
final boolean DEBUG_CLEAN_APKS = false;
int [] users = userManager.getUserIds();
Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
@@ -22535,7 +22538,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
} else {
for (int i = 0; i < users.length; i++) {
- if (users[i] != userHandle && ps.getInstalled(users[i])) {
+ if (users[i] != userId && ps.getInstalled(users[i])) {
keep = true;
if (DEBUG_CLEAN_APKS) {
Slog.i(TAG, " Keeping package " + packageName + " for user "
@@ -22551,7 +22554,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
//end run
mHandler.post(() -> deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
- userHandle, 0));
+ userId, 0));
}
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index af1a095c6871..fe529a152364 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -276,7 +276,7 @@ class PackageManagerShellCommand extends ShellCommand {
case "get-harmful-app-warning":
return runGetHarmfulAppWarning();
case "get-stagedsessions":
- return getStagedSessions();
+ return runListStagedSessions();
case "uninstall-system-updates":
return uninstallSystemUpdates();
case "rollback-app":
@@ -348,53 +348,6 @@ class PackageManagerShellCommand extends ShellCommand {
return 1;
}
- private int getStagedSessions() {
- final IndentingPrintWriter pw = new IndentingPrintWriter(
- getOutPrintWriter(), /* singleIndent */ " ", /* wrapLength */ 120);
- try {
- List<SessionInfo> stagedSessions =
- mInterface.getPackageInstaller().getStagedSessions().getList();
- final SparseArray<SessionInfo> sessionById = new SparseArray<>(stagedSessions.size());
- for (SessionInfo session : stagedSessions) {
- sessionById.put(session.getSessionId(), session);
- }
- for (SessionInfo session: stagedSessions) {
- if (session.getParentSessionId() != SessionInfo.INVALID_ID) {
- continue;
- }
- printStagedSession(session, pw);
- if (session.isMultiPackage()) {
- pw.increaseIndent();
- final int[] childIds = session.getChildSessionIds();
- for (int i = 0; i < childIds.length; i++) {
- final SessionInfo childSession = sessionById.get(childIds[i]);
- if (childSession == null) {
- pw.println("sessionId = " + childIds[i] + "; not found");
- } else {
- printStagedSession(childSession, pw);
- }
- }
- pw.decreaseIndent();
- }
- }
- } catch (RemoteException e) {
- pw.println("Failure ["
- + e.getClass().getName() + " - "
- + e.getMessage() + "]");
- return 0;
- }
- return 1;
- }
-
- private static void printStagedSession(SessionInfo session, PrintWriter pw) {
- pw.println("sessionId = " + session.getSessionId()
- + "; appPackageName = " + session.getAppPackageName()
- + "; isStaged = " + session.isStaged()
- + "; isReady = " + session.isStagedSessionReady()
- + "; isApplied = " + session.isStagedSessionApplied()
- + "; isFailed = " + session.isStagedSessionFailed() + ";");
- }
-
private int uninstallSystemUpdates() {
final PrintWriter pw = getOutPrintWriter();
List<String> failedUninstalls = new LinkedList<>();
@@ -567,6 +520,8 @@ class PackageManagerShellCommand extends ShellCommand {
return runListPermissionGroups();
case "permissions":
return runListPermissions();
+ case "staged-sessions":
+ return runListStagedSessions();
case "users":
ServiceManager.getService("user").shellCommand(
getInFileDescriptor(), getOutFileDescriptor(), getErrFileDescriptor(),
@@ -904,6 +859,103 @@ class PackageManagerShellCommand extends ShellCommand {
return 0;
}
+ private static class SessionDump {
+ boolean onlyParent; // Show parent sessions only
+ boolean onlyReady; // Show only staged sessions that are in ready state
+ boolean onlySessionId; // Show sessionId only
+ }
+
+ // Returns true if the provided flag is a session flag and given SessionDump was updated
+ private boolean setSessionFlag(String flag, SessionDump sessionDump) {
+ switch (flag) {
+ case "--only-parent":
+ sessionDump.onlyParent = true;
+ break;
+ case "--only-ready":
+ sessionDump.onlyReady = true;
+ break;
+ case "--only-sessionid":
+ sessionDump.onlySessionId = true;
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+
+ private int runListStagedSessions() {
+ final IndentingPrintWriter pw = new IndentingPrintWriter(
+ getOutPrintWriter(), /* singleIndent */ " ", /* wrapLength */ 120);
+
+ SessionDump sessionDump = new SessionDump();
+ String opt;
+ while ((opt = getNextOption()) != null) {
+ if (!setSessionFlag(opt, sessionDump)) {
+ pw.println("Error: Unknown option: " + opt);
+ return -1;
+ }
+ }
+
+ try {
+ List<SessionInfo> stagedSessions =
+ mInterface.getPackageInstaller().getStagedSessions().getList();
+ printSessionList(pw, stagedSessions, sessionDump);
+ } catch (RemoteException e) {
+ pw.println("Failure ["
+ + e.getClass().getName() + " - "
+ + e.getMessage() + "]");
+ return -1;
+ }
+ return 1;
+ }
+
+ private void printSessionList(IndentingPrintWriter pw, List<SessionInfo> stagedSessions,
+ SessionDump sessionDump) {
+ final SparseArray<SessionInfo> sessionById = new SparseArray<>(stagedSessions.size());
+ for (SessionInfo session : stagedSessions) {
+ sessionById.put(session.getSessionId(), session);
+ }
+ for (SessionInfo session: stagedSessions) {
+ if (sessionDump.onlyReady && !session.isStagedSessionReady()) {
+ continue;
+ }
+ if (session.getParentSessionId() != SessionInfo.INVALID_ID) {
+ continue;
+ }
+ printSession(pw, session, sessionDump);
+ if (session.isMultiPackage() && !sessionDump.onlyParent) {
+ pw.increaseIndent();
+ final int[] childIds = session.getChildSessionIds();
+ for (int i = 0; i < childIds.length; i++) {
+ final SessionInfo childSession = sessionById.get(childIds[i]);
+ if (childSession == null) {
+ if (sessionDump.onlySessionId) {
+ pw.println(childIds[i]);
+ } else {
+ pw.println("sessionId = " + childIds[i] + "; not found");
+ }
+ } else {
+ printSession(pw, childSession, sessionDump);
+ }
+ }
+ pw.decreaseIndent();
+ }
+ }
+ }
+
+ private static void printSession(PrintWriter pw, SessionInfo session, SessionDump sessionDump) {
+ if (sessionDump.onlySessionId) {
+ pw.println(session.getSessionId());
+ return;
+ }
+ pw.println("sessionId = " + session.getSessionId()
+ + "; appPackageName = " + session.getAppPackageName()
+ + "; isStaged = " + session.isStaged()
+ + "; isReady = " + session.isStagedSessionReady()
+ + "; isApplied = " + session.isStagedSessionApplied()
+ + "; isFailed = " + session.isStagedSessionFailed() + ";");
+ }
+
private Intent parseIntentAndUser() throws URISyntaxException {
mTargetUser = UserHandle.USER_CURRENT;
mBrief = false;
@@ -3108,6 +3160,12 @@ class PackageManagerShellCommand extends ShellCommand {
pw.println(" -d: only list dangerous permissions");
pw.println(" -u: list only the permissions users will see");
pw.println("");
+ pw.println(" list staged-sessions [--only-ready] [--only-sessionid] [--only-parent]");
+ pw.println(" Displays list of all staged sessions on device.");
+ pw.println(" --only-ready: show only staged sessions that are ready");
+ pw.println(" --only-sessionid: show only sessionId of each session");
+ pw.println(" --only-parent: hide all children sessions");
+ pw.println("");
pw.println(" resolve-activity [--brief] [--components] [--query-flags FLAGS]");
pw.println(" [--user USER_ID] INTENT");
pw.println(" Prints the activity that resolves to the given INTENT.");
@@ -3345,7 +3403,7 @@ class PackageManagerShellCommand extends ShellCommand {
pw.println(" uninstall-system-updates");
pw.println(" Remove updates to all system applications and fall back to their /system " +
"version.");
- pw.println();
+ pw.println("");
pw.println(" get-moduleinfo [--all | --installed] [module-name]");
pw.println(" Displays module info. If module-name is specified only that info is shown");
pw.println(" By default, without any argument only installed modules are shown.");
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 65fb35d34c01..81723cbe22c5 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -404,10 +404,10 @@ public class UserManagerService extends IUserManager.Stub {
return;
}
final IntentSender target = intent.getParcelableExtra(Intent.EXTRA_INTENT);
- final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_ID, UserHandle.USER_NULL);
+ final int userId = intent.getIntExtra(Intent.EXTRA_USER_ID, UserHandle.USER_NULL);
// Call setQuietModeEnabled on bg thread to avoid ANR
BackgroundThread.getHandler().post(() ->
- setQuietModeEnabled(userHandle, false, target, /* callingPackage */ null));
+ setQuietModeEnabled(userId, false, target, /* callingPackage */ null));
}
};
@@ -482,9 +482,9 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public void onStartUser(int userHandle) {
+ public void onStartUser(@UserIdInt int userId) {
synchronized (mUms.mUsersLock) {
- final UserData user = mUms.getUserDataLU(userHandle);
+ final UserData user = mUms.getUserDataLU(userId);
if (user != null) {
user.startRealtime = SystemClock.elapsedRealtime();
}
@@ -492,9 +492,9 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public void onUnlockUser(int userHandle) {
+ public void onUnlockUser(@UserIdInt int userId) {
synchronized (mUms.mUsersLock) {
- final UserData user = mUms.getUserDataLU(userHandle);
+ final UserData user = mUms.getUserDataLU(userId);
if (user != null) {
user.unlockRealtime = SystemClock.elapsedRealtime();
}
@@ -502,9 +502,9 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public void onStopUser(int userHandle) {
+ public void onStopUser(@UserIdInt int userId) {
synchronized (mUms.mUsersLock) {
- final UserData user = mUms.getUserDataLU(userHandle);
+ final UserData user = mUms.getUserDataLU(userId);
if (user != null) {
user.startRealtime = 0;
user.unlockRealtime = 0;
@@ -610,7 +610,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public String getUserAccount(int userId) {
+ public String getUserAccount(@UserIdInt int userId) {
checkManageUserAndAcrossUsersFullPermission("get user account");
synchronized (mUsersLock) {
return mUsers.get(userId).account;
@@ -618,7 +618,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public void setUserAccount(int userId, String accountName) {
+ public void setUserAccount(@UserIdInt int userId, String accountName) {
checkManageUserAndAcrossUsersFullPermission("set user account");
UserData userToUpdate = null;
synchronized (mPackagesLock) {
@@ -676,7 +676,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public List<UserInfo> getProfiles(int userId, boolean enabledOnly) {
+ public List<UserInfo> getProfiles(@UserIdInt int userId, boolean enabledOnly) {
boolean returnFullInfo = true;
if (userId != UserHandle.getCallingUserId()) {
checkManageOrCreateUsersPermission("getting profiles related to user " + userId);
@@ -694,7 +694,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public int[] getProfileIds(int userId, boolean enabledOnly) {
+ public int[] getProfileIds(@UserIdInt int userId, boolean enabledOnly) {
if (userId != UserHandle.getCallingUserId()) {
checkManageOrCreateUsersPermission("getting profiles related to user " + userId);
}
@@ -710,7 +710,8 @@ public class UserManagerService extends IUserManager.Stub {
/** Assume permissions already checked and caller's identity cleared */
@GuardedBy("mUsersLock")
- private List<UserInfo> getProfilesLU(int userId, boolean enabledOnly, boolean fullInfo) {
+ private List<UserInfo> getProfilesLU(@UserIdInt int userId, boolean enabledOnly,
+ boolean fullInfo) {
IntArray profileIds = getProfileIdsLU(userId, enabledOnly);
ArrayList<UserInfo> users = new ArrayList<>(profileIds.size());
for (int i = 0; i < profileIds.size(); i++) {
@@ -733,7 +734,7 @@ public class UserManagerService extends IUserManager.Stub {
* Assume permissions already checked and caller's identity cleared
*/
@GuardedBy("mUsersLock")
- private IntArray getProfileIdsLU(int userId, boolean enabledOnly) {
+ private IntArray getProfileIdsLU(@UserIdInt int userId, boolean enabledOnly) {
UserInfo user = getUserInfoLU(userId);
IntArray result = new IntArray(mUsers.size());
if (user == null) {
@@ -761,28 +762,28 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public int getCredentialOwnerProfile(int userHandle) {
+ public int getCredentialOwnerProfile(@UserIdInt int userId) {
checkManageUsersPermission("get the credential owner");
- if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userHandle)) {
+ if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
synchronized (mUsersLock) {
- UserInfo profileParent = getProfileParentLU(userHandle);
+ UserInfo profileParent = getProfileParentLU(userId);
if (profileParent != null) {
return profileParent.id;
}
}
}
- return userHandle;
+ return userId;
}
@Override
- public boolean isSameProfileGroup(int userId, int otherUserId) {
+ public boolean isSameProfileGroup(@UserIdInt int userId, int otherUserId) {
if (userId == otherUserId) return true;
checkManageUsersPermission("check if in the same profile group");
return isSameProfileGroupNoChecks(userId, otherUserId);
}
- private boolean isSameProfileGroupNoChecks(int userId, int otherUserId) {
+ private boolean isSameProfileGroupNoChecks(@UserIdInt int userId, int otherUserId) {
synchronized (mUsersLock) {
UserInfo userInfo = getUserInfoLU(userId);
if (userInfo == null || userInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
@@ -798,27 +799,27 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public UserInfo getProfileParent(int userHandle) {
+ public UserInfo getProfileParent(@UserIdInt int userId) {
checkManageUsersPermission("get the profile parent");
synchronized (mUsersLock) {
- return getProfileParentLU(userHandle);
+ return getProfileParentLU(userId);
}
}
@Override
- public int getProfileParentId(int userHandle) {
+ public int getProfileParentId(@UserIdInt int userId) {
checkManageUsersPermission("get the profile parent");
- return mLocalService.getProfileParentId(userHandle);
+ return mLocalService.getProfileParentId(userId);
}
@GuardedBy("mUsersLock")
- private UserInfo getProfileParentLU(int userHandle) {
- UserInfo profile = getUserInfoLU(userHandle);
+ private UserInfo getProfileParentLU(@UserIdInt int userId) {
+ UserInfo profile = getUserInfoLU(userId);
if (profile == null) {
return null;
}
int parentUserId = profile.profileGroupId;
- if (parentUserId == userHandle || parentUserId == UserInfo.NO_PROFILE_GROUP_ID) {
+ if (parentUserId == userId || parentUserId == UserInfo.NO_PROFILE_GROUP_ID) {
return null;
} else {
return getUserInfoLU(parentUserId);
@@ -848,7 +849,7 @@ public class UserManagerService extends IUserManager.Stub {
@Override
public boolean requestQuietModeEnabled(@NonNull String callingPackage, boolean enableQuietMode,
- int userHandle, @Nullable IntentSender target) {
+ @UserIdInt int userId, @Nullable IntentSender target) {
Preconditions.checkNotNull(callingPackage);
if (enableQuietMode && target != null) {
@@ -862,17 +863,17 @@ public class UserManagerService extends IUserManager.Stub {
boolean result = false;
if (enableQuietMode) {
setQuietModeEnabled(
- userHandle, true /* enableQuietMode */, target, callingPackage);
+ userId, true /* enableQuietMode */, target, callingPackage);
result = true;
} else {
boolean needToShowConfirmCredential =
- mLockPatternUtils.isSecure(userHandle)
- && !StorageManager.isUserKeyUnlocked(userHandle);
+ mLockPatternUtils.isSecure(userId)
+ && !StorageManager.isUserKeyUnlocked(userId);
if (needToShowConfirmCredential) {
- showConfirmCredentialToDisableQuietMode(userHandle, target);
+ showConfirmCredentialToDisableQuietMode(userId, target);
} else {
setQuietModeEnabled(
- userHandle, false /* enableQuietMode */, target, callingPackage);
+ userId, false /* enableQuietMode */, target, callingPackage);
result = true;
}
}
@@ -922,16 +923,16 @@ public class UserManagerService extends IUserManager.Stub {
+ "default launcher nor has MANAGE_USERS/MODIFY_QUIET_MODE permission");
}
- private void setQuietModeEnabled(int userHandle, boolean enableQuietMode,
+ private void setQuietModeEnabled(@UserIdInt int userId, boolean enableQuietMode,
IntentSender target, @Nullable String callingPackage) {
final UserInfo profile, parent;
final UserData profileUserData;
synchronized (mUsersLock) {
- profile = getUserInfoLU(userHandle);
- parent = getProfileParentLU(userHandle);
+ profile = getUserInfoLU(userId);
+ parent = getProfileParentLU(userId);
if (profile == null || !profile.isManagedProfile()) {
- throw new IllegalArgumentException("User " + userHandle + " is not a profile");
+ throw new IllegalArgumentException("User " + userId + " is not a profile");
}
if (profile.isQuietModeEnabled() == enableQuietMode) {
Slog.i(LOG_TAG, "Quiet mode is already " + enableQuietMode);
@@ -945,17 +946,17 @@ public class UserManagerService extends IUserManager.Stub {
}
try {
if (enableQuietMode) {
- ActivityManager.getService().stopUser(userHandle, /* force */true, null);
+ ActivityManager.getService().stopUser(userId, /* force */true, null);
LocalServices.getService(ActivityManagerInternal.class)
- .killForegroundAppsForUser(userHandle);
+ .killForegroundAppsForUser(userId);
} else {
IProgressListener callback = target != null
? new DisableQuietModeUserUnlockedCallback(target)
: null;
ActivityManager.getService().startUserInBackgroundWithListener(
- userHandle, callback);
+ userId, callback);
}
- logQuietModeEnabled(userHandle, enableQuietMode, callingPackage);
+ logQuietModeEnabled(userId, enableQuietMode, callingPackage);
} catch (RemoteException e) {
// Should not happen, same process.
e.rethrowAsRuntimeException();
@@ -964,11 +965,11 @@ public class UserManagerService extends IUserManager.Stub {
enableQuietMode);
}
- private void logQuietModeEnabled(int userHandle, boolean enableQuietMode,
+ private void logQuietModeEnabled(@UserIdInt int userId, boolean enableQuietMode,
@Nullable String callingPackage) {
UserData userData;
synchronized (mUsersLock) {
- userData = getUserDataLU(userHandle);
+ userData = getUserDataLU(userId);
}
if (userData == null) {
return;
@@ -987,11 +988,11 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public boolean isQuietModeEnabled(int userHandle) {
+ public boolean isQuietModeEnabled(@UserIdInt int userId) {
synchronized (mPackagesLock) {
UserInfo info;
synchronized (mUsersLock) {
- info = getUserInfoLU(userHandle);
+ info = getUserInfoLU(userId);
}
if (info == null || !info.isManagedProfile()) {
return false;
@@ -1004,15 +1005,14 @@ public class UserManagerService extends IUserManager.Stub {
* Show confirm credential screen to unlock user in order to turn off quiet mode.
*/
private void showConfirmCredentialToDisableQuietMode(
- @UserIdInt int userHandle, @Nullable IntentSender target) {
+ @UserIdInt int userId, @Nullable IntentSender target) {
// otherwise, we show a profile challenge to trigger decryption of the user
final KeyguardManager km = (KeyguardManager) mContext.getSystemService(
Context.KEYGUARD_SERVICE);
- // We should use userHandle not credentialOwnerUserId here, as even if it is unified
+ // We should use userId not credentialOwnerUserId here, as even if it is unified
// lock, confirm screenlock page will know and show personal challenge, and unlock
// work profile when personal challenge is correct
- final Intent unlockIntent = km.createConfirmDeviceCredentialIntent(null, null,
- userHandle);
+ final Intent unlockIntent = km.createConfirmDeviceCredentialIntent(null, null, userId);
if (unlockIntent == null) {
return;
}
@@ -1021,7 +1021,7 @@ public class UserManagerService extends IUserManager.Stub {
if (target != null) {
callBackIntent.putExtra(Intent.EXTRA_INTENT, target);
}
- callBackIntent.putExtra(Intent.EXTRA_USER_ID, userHandle);
+ callBackIntent.putExtra(Intent.EXTRA_USER_ID, userId);
callBackIntent.setPackage(mContext.getPackageName());
callBackIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(
@@ -1039,7 +1039,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public void setUserEnabled(int userId) {
+ public void setUserEnabled(@UserIdInt int userId) {
checkManageUsersPermission("enable user");
synchronized (mPackagesLock) {
UserInfo info;
@@ -1054,7 +1054,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public void setUserAdmin(int userId) {
+ public void setUserAdmin(@UserIdInt int userId) {
checkManageUserAndAcrossUsersFullPermission("set user admin");
synchronized (mPackagesLock) {
@@ -1097,7 +1097,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public UserInfo getUserInfo(int userId) {
+ public UserInfo getUserInfo(@UserIdInt int userId) {
checkManageOrCreateUsersPermission("query user");
synchronized (mUsersLock) {
return userWithName(getUserInfoLU(userId));
@@ -1128,7 +1128,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public boolean isManagedProfile(int userId) {
+ public boolean isManagedProfile(@UserIdInt int userId) {
checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "isManagedProfile");
synchronized (mUsersLock) {
UserInfo userInfo = getUserInfoLU(userId);
@@ -1137,19 +1137,19 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public boolean isUserUnlockingOrUnlocked(int userId) {
+ public boolean isUserUnlockingOrUnlocked(@UserIdInt int userId) {
checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "isUserUnlockingOrUnlocked");
return mLocalService.isUserUnlockingOrUnlocked(userId);
}
@Override
- public boolean isUserUnlocked(int userId) {
+ public boolean isUserUnlocked(@UserIdInt int userId) {
checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "isUserUnlocked");
return mLocalService.isUserUnlocked(userId);
}
@Override
- public boolean isUserRunning(int userId) {
+ public boolean isUserRunning(@UserIdInt int userId) {
checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "isUserRunning");
return mLocalService.isUserRunning(userId);
}
@@ -1190,7 +1190,8 @@ public class UserManagerService extends IUserManager.Stub {
}
}
- private void checkManageOrInteractPermIfCallerInOtherProfileGroup(int userId, String name) {
+ private void checkManageOrInteractPermIfCallerInOtherProfileGroup(@UserIdInt int userId,
+ String name) {
int callingUserId = UserHandle.getCallingUserId();
if (callingUserId == userId || isSameProfileGroupNoChecks(callingUserId, userId) ||
hasManageUsersPermission()) {
@@ -1204,7 +1205,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public boolean isDemoUser(int userId) {
+ public boolean isDemoUser(@UserIdInt int userId) {
int callingUserId = UserHandle.getCallingUserId();
if (callingUserId != userId && !hasManageUsersPermission()) {
throw new SecurityException("You need MANAGE_USERS permission to query if u=" + userId
@@ -1224,7 +1225,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public boolean canHaveRestrictedProfile(int userId) {
+ public boolean canHaveRestrictedProfile(@UserIdInt int userId) {
checkManageUsersPermission("canHaveRestrictedProfile");
synchronized (mUsersLock) {
final UserInfo userInfo = getUserInfoLU(userId);
@@ -1260,7 +1261,7 @@ public class UserManagerService extends IUserManager.Stub {
* Should be locked on mUsers before calling this.
*/
@GuardedBy("mUsersLock")
- private UserInfo getUserInfoLU(int userId) {
+ private UserInfo getUserInfoLU(@UserIdInt int userId) {
final UserData userData = mUsers.get(userId);
// If it is partial and not in the process of being removed, return as unknown user.
if (userData != null && userData.info.partial && !mRemovingUserIds.get(userId)) {
@@ -1271,7 +1272,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@GuardedBy("mUsersLock")
- private UserData getUserDataLU(int userId) {
+ private UserData getUserDataLU(@UserIdInt int userId) {
final UserData userData = mUsers.get(userId);
// If it is partial and not in the process of being removed, return as unknown user.
if (userData != null && userData.info.partial && !mRemovingUserIds.get(userId)) {
@@ -1284,7 +1285,7 @@ public class UserManagerService extends IUserManager.Stub {
* Obtains {@link #mUsersLock} and return UserInfo from mUsers.
* <p>No permissions checking or any addition checks are made</p>
*/
- private UserInfo getUserInfoNoChecks(int userId) {
+ private UserInfo getUserInfoNoChecks(@UserIdInt int userId) {
synchronized (mUsersLock) {
final UserData userData = mUsers.get(userId);
return userData != null ? userData.info : null;
@@ -1295,19 +1296,19 @@ public class UserManagerService extends IUserManager.Stub {
* Obtains {@link #mUsersLock} and return UserData from mUsers.
* <p>No permissions checking or any addition checks are made</p>
*/
- private UserData getUserDataNoChecks(int userId) {
+ private UserData getUserDataNoChecks(@UserIdInt int userId) {
synchronized (mUsersLock) {
return mUsers.get(userId);
}
}
/** Called by PackageManagerService */
- public boolean exists(int userId) {
+ public boolean exists(@UserIdInt int userId) {
return mLocalService.exists(userId);
}
@Override
- public void setUserName(int userId, String name) {
+ public void setUserName(@UserIdInt int userId, String name) {
checkManageUsersPermission("rename users");
boolean changed = false;
synchronized (mPackagesLock) {
@@ -1333,7 +1334,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public void setUserIcon(int userId, Bitmap bitmap) {
+ public void setUserIcon(@UserIdInt int userId, Bitmap bitmap) {
checkManageUsersPermission("update users");
if (hasUserRestriction(UserManager.DISALLOW_SET_USER_ICON, userId)) {
Log.w(LOG_TAG, "Cannot set user icon. DISALLOW_SET_USER_ICON is enabled.");
@@ -1344,7 +1345,7 @@ public class UserManagerService extends IUserManager.Stub {
- private void sendUserInfoChangedBroadcast(int userId) {
+ private void sendUserInfoChangedBroadcast(@UserIdInt int userId) {
Intent changedIntent = new Intent(Intent.ACTION_USER_INFO_CHANGED);
changedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
changedIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
@@ -1389,7 +1390,7 @@ public class UserManagerService extends IUserManager.Stub {
return null;
}
- public void makeInitialized(int userId) {
+ public void makeInitialized(@UserIdInt int userId) {
checkManageUsersPermission("makeInitialized");
boolean scheduleWriteUser = false;
UserData userData;
@@ -1447,8 +1448,8 @@ public class UserManagerService extends IUserManager.Stub {
/**
* See {@link UserManagerInternal#setDevicePolicyUserRestrictions}
*/
- private void setDevicePolicyUserRestrictionsInner(int userId, @Nullable Bundle restrictions,
- boolean isDeviceOwner, int cameraRestrictionScope) {
+ private void setDevicePolicyUserRestrictionsInner(@UserIdInt int userId,
+ @Nullable Bundle restrictions, boolean isDeviceOwner, int cameraRestrictionScope) {
final Bundle global = new Bundle();
final Bundle local = new Bundle();
@@ -1505,8 +1506,8 @@ public class UserManagerService extends IUserManager.Stub {
* empty, record is removed from the array.
* @return whether restrictions bundle is different from the old one.
*/
- private boolean updateRestrictionsIfNeededLR(int userId, @Nullable Bundle restrictions,
- SparseArray<Bundle> restrictionsArray) {
+ private boolean updateRestrictionsIfNeededLR(@UserIdInt int userId,
+ @Nullable Bundle restrictions, SparseArray<Bundle> restrictionsArray) {
final boolean changed =
!UserRestrictionsUtils.areEqual(restrictionsArray.get(userId), restrictions);
if (changed) {
@@ -1520,7 +1521,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@GuardedBy("mRestrictionsLock")
- private Bundle computeEffectiveUserRestrictionsLR(int userId) {
+ private Bundle computeEffectiveUserRestrictionsLR(@UserIdInt int userId) {
final Bundle baseRestrictions =
UserRestrictionsUtils.nonNull(mBaseUserRestrictions.get(userId));
final Bundle global = UserRestrictionsUtils.mergeAll(mDevicePolicyGlobalUserRestrictions);
@@ -1538,14 +1539,14 @@ public class UserManagerService extends IUserManager.Stub {
}
@GuardedBy("mRestrictionsLock")
- private void invalidateEffectiveUserRestrictionsLR(int userId) {
+ private void invalidateEffectiveUserRestrictionsLR(@UserIdInt int userId) {
if (DBG) {
Log.d(LOG_TAG, "invalidateEffectiveUserRestrictions userId=" + userId);
}
mCachedEffectiveUserRestrictions.remove(userId);
}
- private Bundle getEffectiveUserRestrictions(int userId) {
+ private Bundle getEffectiveUserRestrictions(@UserIdInt int userId) {
synchronized (mRestrictionsLock) {
Bundle restrictions = mCachedEffectiveUserRestrictions.get(userId);
if (restrictions == null) {
@@ -1558,7 +1559,7 @@ public class UserManagerService extends IUserManager.Stub {
/** @return a specific user restriction that's in effect currently. */
@Override
- public boolean hasUserRestriction(String restrictionKey, int userId) {
+ public boolean hasUserRestriction(String restrictionKey, @UserIdInt int userId) {
return mLocalService.hasUserRestriction(restrictionKey, userId);
}
@@ -1593,7 +1594,7 @@ public class UserManagerService extends IUserManager.Stub {
* and {@link UserManager#RESTRICTION_SOURCE_PROFILE_OWNER}
*/
@Override
- public int getUserRestrictionSource(String restrictionKey, int userId) {
+ public int getUserRestrictionSource(String restrictionKey, @UserIdInt int userId) {
List<EnforcingUser> enforcingUsers = getUserRestrictionSources(restrictionKey, userId);
// Get "bitwise or" of restriction sources for all enforcing users.
int result = UserManager.RESTRICTION_NOT_SET;
@@ -1652,12 +1653,12 @@ public class UserManagerService extends IUserManager.Stub {
* {@link Bundle}.
*/
@Override
- public Bundle getUserRestrictions(int userId) {
+ public Bundle getUserRestrictions(@UserIdInt int userId) {
return UserRestrictionsUtils.clone(getEffectiveUserRestrictions(userId));
}
@Override
- public boolean hasBaseUserRestriction(String restrictionKey, int userId) {
+ public boolean hasBaseUserRestriction(String restrictionKey, @UserIdInt int userId) {
checkManageUsersPermission("hasBaseUserRestriction");
if (!UserRestrictionsUtils.isValidRestriction(restrictionKey)) {
return false;
@@ -1669,7 +1670,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public void setUserRestriction(String key, boolean value, int userId) {
+ public void setUserRestriction(String key, boolean value, @UserIdInt int userId) {
checkManageUsersPermission("setUserRestriction");
if (!UserRestrictionsUtils.isValidRestriction(key)) {
return;
@@ -1695,7 +1696,7 @@ public class UserManagerService extends IUserManager.Stub {
*/
@GuardedBy("mRestrictionsLock")
private void updateUserRestrictionsInternalLR(
- @Nullable Bundle newBaseRestrictions, int userId) {
+ @Nullable Bundle newBaseRestrictions, @UserIdInt int userId) {
final Bundle prevAppliedRestrictions = UserRestrictionsUtils.nonNull(
mAppliedUserRestrictions.get(userId));
@@ -1779,7 +1780,7 @@ public class UserManagerService extends IUserManager.Stub {
// Package private for the inner class.
@GuardedBy("mRestrictionsLock")
- void applyUserRestrictionsLR(int userId) {
+ void applyUserRestrictionsLR(@UserIdInt int userId) {
updateUserRestrictionsInternalLR(null, userId);
}
@@ -1831,7 +1832,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public boolean canAddMoreManagedProfiles(int userId, boolean allowedToRemoveOne) {
+ public boolean canAddMoreManagedProfiles(@UserIdInt int userId, boolean allowedToRemoveOne) {
checkManageUsersPermission("check if more managed profiles can be added.");
if (ActivityManager.isLowRamDeviceStatic()) {
return false;
@@ -2661,7 +2662,7 @@ public class UserManagerService extends IUserManager.Stub {
/**
* Removes the app restrictions file for a specific package and user id, if it exists.
*/
- private static void cleanAppRestrictionsForPackageLAr(String pkg, int userId) {
+ private static void cleanAppRestrictionsForPackageLAr(String pkg, @UserIdInt int userId) {
File dir = Environment.getUserSystemDirectory(userId);
File resFile = new File(dir, packageToRestrictionsFileName(pkg));
if (resFile.exists()) {
@@ -2670,23 +2671,23 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public UserInfo createProfileForUser(String name, int flags, int userId,
+ public UserInfo createProfileForUser(String name, int flags, @UserIdInt int userId,
String[] disallowedPackages) {
checkManageOrCreateUsersPermission(flags);
return createUserInternal(name, flags, userId, disallowedPackages);
}
@Override
- public UserInfo createProfileForUserEvenWhenDisallowed(String name, int flags, int userId,
- String[] disallowedPackages) {
+ public UserInfo createProfileForUserEvenWhenDisallowed(String name, int flags,
+ @UserIdInt int userId, String[] disallowedPackages) {
checkManageOrCreateUsersPermission(flags);
return createUserInternalUnchecked(name, flags, userId, disallowedPackages);
}
@Override
- public boolean removeUserEvenWhenDisallowed(@UserIdInt int userHandle) {
+ public boolean removeUserEvenWhenDisallowed(@UserIdInt int userId) {
checkManageOrCreateUsersPermission("Only the system can remove users");
- return removeUserUnchecked(userHandle);
+ return removeUserUnchecked(userId);
}
@Override
@@ -2871,7 +2872,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@VisibleForTesting
- void removeUserInfo(int userId) {
+ void removeUserInfo(@UserIdInt int userId) {
synchronized (mUsers) {
mUsers.remove(userId);
}
@@ -2923,11 +2924,11 @@ public class UserManagerService extends IUserManager.Stub {
/**
* Mark this guest user for deletion to allow us to create another guest
* and switch to that user before actually removing this guest.
- * @param userHandle the userid of the current guest
+ * @param userId the userid of the current guest
* @return whether the user could be marked for deletion
*/
@Override
- public boolean markGuestForDeletion(int userHandle) {
+ public boolean markGuestForDeletion(@UserIdInt int userId) {
checkManageUsersPermission("Only the system can remove users");
if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
UserManager.DISALLOW_REMOVE_USER, false)) {
@@ -2940,8 +2941,8 @@ public class UserManagerService extends IUserManager.Stub {
final UserData userData;
synchronized (mPackagesLock) {
synchronized (mUsersLock) {
- userData = mUsers.get(userHandle);
- if (userHandle == 0 || userData == null || mRemovingUserIds.get(userHandle)) {
+ userData = mUsers.get(userId);
+ if (userId == 0 || userData == null || mRemovingUserIds.get(userId)) {
return false;
}
}
@@ -2968,16 +2969,16 @@ public class UserManagerService extends IUserManager.Stub {
/**
* Removes a user and all data directories created for that user. This method should be called
* after the user's processes have been terminated.
- * @param userHandle the user's id
+ * @param userId the user's id
*/
@Override
- public boolean removeUser(int userHandle) {
- Slog.i(LOG_TAG, "removeUser u" + userHandle);
+ public boolean removeUser(@UserIdInt int userId) {
+ Slog.i(LOG_TAG, "removeUser u" + userId);
checkManageOrCreateUsersPermission("Only the system can remove users");
final boolean isManagedProfile;
synchronized (mUsersLock) {
- UserInfo userInfo = getUserInfoLU(userHandle);
+ UserInfo userInfo = getUserInfoLU(userId);
isManagedProfile = userInfo != null && userInfo.isManagedProfile();
}
String restriction = isManagedProfile
@@ -2986,39 +2987,39 @@ public class UserManagerService extends IUserManager.Stub {
Log.w(LOG_TAG, "Cannot remove user. " + restriction + " is enabled.");
return false;
}
- return removeUserUnchecked(userHandle);
+ return removeUserUnchecked(userId);
}
- private boolean removeUserUnchecked(int userHandle) {
+ private boolean removeUserUnchecked(@UserIdInt int userId) {
long ident = Binder.clearCallingIdentity();
try {
final UserData userData;
int currentUser = ActivityManager.getCurrentUser();
- if (currentUser == userHandle) {
+ if (currentUser == userId) {
Log.w(LOG_TAG, "Current user cannot be removed.");
return false;
}
synchronized (mPackagesLock) {
synchronized (mUsersLock) {
- userData = mUsers.get(userHandle);
- if (userHandle == UserHandle.USER_SYSTEM) {
+ userData = mUsers.get(userId);
+ if (userId == UserHandle.USER_SYSTEM) {
Log.e(LOG_TAG, "System user cannot be removed.");
return false;
}
if (userData == null) {
Log.e(LOG_TAG, String.format(
- "Cannot remove user %d, invalid user id provided.", userHandle));
+ "Cannot remove user %d, invalid user id provided.", userId));
return false;
}
- if (mRemovingUserIds.get(userHandle)) {
+ if (mRemovingUserIds.get(userId)) {
Log.e(LOG_TAG, String.format(
- "User %d is already scheduled for removal.", userHandle));
+ "User %d is already scheduled for removal.", userId));
return false;
}
- addRemovingUserIdLocked(userHandle);
+ addRemovingUserIdLocked(userId);
}
// Set this to a partially created user, so that the user will be purged
@@ -3031,7 +3032,7 @@ public class UserManagerService extends IUserManager.Stub {
writeUserLP(userData);
}
try {
- mAppOpsService.removeUser(userHandle);
+ mAppOpsService.removeUser(userId);
} catch (RemoteException e) {
Log.w(LOG_TAG, "Unable to notify AppOpsService of removing user.", e);
}
@@ -3043,17 +3044,17 @@ public class UserManagerService extends IUserManager.Stub {
sendProfileRemovedBroadcast(userData.info.profileGroupId, userData.info.id);
}
- if (DBG) Slog.i(LOG_TAG, "Stopping user " + userHandle);
+ if (DBG) Slog.i(LOG_TAG, "Stopping user " + userId);
int res;
try {
- res = ActivityManager.getService().stopUser(userHandle, /* force= */ true,
+ res = ActivityManager.getService().stopUser(userId, /* force= */ true,
new IStopUserCallback.Stub() {
@Override
- public void userStopped(int userId) {
- finishRemoveUser(userId);
+ public void userStopped(int userIdParam) {
+ finishRemoveUser(userIdParam);
}
@Override
- public void userStopAborted(int userId) {
+ public void userStopAborted(int userIdParam) {
}
});
} catch (RemoteException e) {
@@ -3068,7 +3069,7 @@ public class UserManagerService extends IUserManager.Stub {
@GuardedBy("mUsersLock")
@VisibleForTesting
- void addRemovingUserIdLocked(int userId) {
+ void addRemovingUserIdLocked(@UserIdInt int userId) {
// We remember deleted user IDs to prevent them from being
// reused during the current boot; they can still be reused
// after a reboot or recycling of userIds.
@@ -3080,14 +3081,14 @@ public class UserManagerService extends IUserManager.Stub {
}
}
- void finishRemoveUser(final int userHandle) {
- if (DBG) Slog.i(LOG_TAG, "finishRemoveUser " + userHandle);
+ void finishRemoveUser(final @UserIdInt int userId) {
+ if (DBG) Slog.i(LOG_TAG, "finishRemoveUser " + userId);
// Let other services shutdown any activity and clean up their state before completely
// wiping the user's system directory and removing from the user list
long ident = Binder.clearCallingIdentity();
try {
Intent addedIntent = new Intent(Intent.ACTION_USER_REMOVED);
- addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle);
+ addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
mContext.sendOrderedBroadcastAsUser(addedIntent, UserHandle.ALL,
android.Manifest.permission.MANAGE_USERS,
@@ -3097,15 +3098,15 @@ public class UserManagerService extends IUserManager.Stub {
if (DBG) {
Slog.i(LOG_TAG,
"USER_REMOVED broadcast sent, cleaning up user data "
- + userHandle);
+ + userId);
}
new Thread() {
@Override
public void run() {
// Clean up any ActivityTaskManager state
LocalServices.getService(ActivityTaskManagerInternal.class)
- .onUserStopped(userHandle);
- removeUserState(userHandle);
+ .onUserStopped(userId);
+ removeUserState(userId);
}
}.start();
}
@@ -3117,47 +3118,46 @@ public class UserManagerService extends IUserManager.Stub {
}
}
- private void removeUserState(final int userHandle) {
+ private void removeUserState(final @UserIdInt int userId) {
try {
- mContext.getSystemService(StorageManager.class).destroyUserKey(userHandle);
+ mContext.getSystemService(StorageManager.class).destroyUserKey(userId);
} catch (IllegalStateException e) {
// This may be simply because the user was partially created.
- Slog.i(LOG_TAG,
- "Destroying key for user " + userHandle + " failed, continuing anyway", e);
+ Slog.i(LOG_TAG, "Destroying key for user " + userId + " failed, continuing anyway", e);
}
// Cleanup gatekeeper secure user id
try {
final IGateKeeperService gk = GateKeeper.getService();
if (gk != null) {
- gk.clearSecureUserId(userHandle);
+ gk.clearSecureUserId(userId);
}
} catch (Exception ex) {
Slog.w(LOG_TAG, "unable to clear GK secure user id");
}
// Cleanup package manager settings
- mPm.cleanUpUser(this, userHandle);
+ mPm.cleanUpUser(this, userId);
// Clean up all data before removing metadata
- mUserDataPreparer.destroyUserData(userHandle,
+ mUserDataPreparer.destroyUserData(userId,
StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
// Remove this user from the list
synchronized (mUsersLock) {
- mUsers.remove(userHandle);
- mIsUserManaged.delete(userHandle);
+ mUsers.remove(userId);
+ mIsUserManaged.delete(userId);
}
synchronized (mUserStates) {
- mUserStates.delete(userHandle);
+ mUserStates.delete(userId);
}
synchronized (mRestrictionsLock) {
- mBaseUserRestrictions.remove(userHandle);
- mAppliedUserRestrictions.remove(userHandle);
- mCachedEffectiveUserRestrictions.remove(userHandle);
- mDevicePolicyLocalUserRestrictions.remove(userHandle);
- if (mDevicePolicyGlobalUserRestrictions.get(userHandle) != null) {
- mDevicePolicyGlobalUserRestrictions.remove(userHandle);
+ mBaseUserRestrictions.remove(userId);
+ mAppliedUserRestrictions.remove(userId);
+ mCachedEffectiveUserRestrictions.remove(userId);
+ mDevicePolicyLocalUserRestrictions.remove(userId);
+ if (mDevicePolicyGlobalUserRestrictions.get(userId) != null) {
+ mDevicePolicyGlobalUserRestrictions.remove(userId);
applyUserRestrictionsForAllUsersLR();
}
}
@@ -3166,12 +3166,12 @@ public class UserManagerService extends IUserManager.Stub {
writeUserListLP();
}
// Remove user file
- AtomicFile userFile = new AtomicFile(new File(mUsersDir, userHandle + XML_SUFFIX));
+ AtomicFile userFile = new AtomicFile(new File(mUsersDir, userId + XML_SUFFIX));
userFile.delete();
updateUserIds();
if (RELEASE_DELETED_USER_ID) {
synchronized (mUsers) {
- mRemovingUserIds.delete(userHandle);
+ mRemovingUserIds.delete(userId);
}
}
}
@@ -3191,7 +3191,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public Bundle getApplicationRestrictionsForUser(String packageName, int userId) {
+ public Bundle getApplicationRestrictionsForUser(String packageName, @UserIdInt int userId) {
if (UserHandle.getCallingUserId() != userId
|| !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) {
checkSystemOrRoot("get application restrictions for other user/app " + packageName);
@@ -3204,7 +3204,7 @@ public class UserManagerService extends IUserManager.Stub {
@Override
public void setApplicationRestrictions(String packageName, Bundle restrictions,
- int userId) {
+ @UserIdInt int userId) {
checkSystemOrRoot("set application restrictions");
if (restrictions != null) {
restrictions.setDefusable(true);
@@ -3238,7 +3238,8 @@ public class UserManagerService extends IUserManager.Stub {
}
@GuardedBy("mAppRestrictionsLock")
- private static Bundle readApplicationRestrictionsLAr(String packageName, int userId) {
+ private static Bundle readApplicationRestrictionsLAr(String packageName,
+ @UserIdInt int userId) {
AtomicFile restrictionsFile =
new AtomicFile(new File(Environment.getUserSystemDirectory(userId),
packageToRestrictionsFileName(packageName)));
@@ -3332,7 +3333,7 @@ public class UserManagerService extends IUserManager.Stub {
@GuardedBy("mAppRestrictionsLock")
private static void writeApplicationRestrictionsLAr(String packageName,
- Bundle restrictions, int userId) {
+ Bundle restrictions, @UserIdInt int userId) {
AtomicFile restrictionsFile = new AtomicFile(
new File(Environment.getUserSystemDirectory(userId),
packageToRestrictionsFileName(packageName)));
@@ -3410,17 +3411,17 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public int getUserSerialNumber(int userHandle) {
+ public int getUserSerialNumber(@UserIdInt int userId) {
synchronized (mUsersLock) {
- final UserInfo userInfo = getUserInfoLU(userHandle);
+ final UserInfo userInfo = getUserInfoLU(userId);
return userInfo != null ? userInfo.serialNumber : -1;
}
}
@Override
- public boolean isUserNameSet(int userHandle) {
+ public boolean isUserNameSet(@UserIdInt int userId) {
synchronized (mUsersLock) {
- final UserInfo userInfo = getUserInfoLU(userHandle);
+ final UserInfo userInfo = getUserInfoLU(userId);
return userInfo != null && userInfo.name != null;
}
}
@@ -3438,21 +3439,21 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public long getUserCreationTime(int userHandle) {
+ public long getUserCreationTime(@UserIdInt int userId) {
int callingUserId = UserHandle.getCallingUserId();
UserInfo userInfo = null;
synchronized (mUsersLock) {
- if (callingUserId == userHandle) {
- userInfo = getUserInfoLU(userHandle);
+ if (callingUserId == userId) {
+ userInfo = getUserInfoLU(userId);
} else {
- UserInfo parent = getProfileParentLU(userHandle);
+ UserInfo parent = getProfileParentLU(userId);
if (parent != null && parent.id == callingUserId) {
- userInfo = getUserInfoLU(userHandle);
+ userInfo = getUserInfoLU(userId);
}
}
}
if (userInfo == null) {
- throw new SecurityException("userHandle can only be the calling user or a managed "
+ throw new SecurityException("userId can only be the calling user or a managed "
+ "profile associated with this user");
}
return userInfo.creationTime;
@@ -3485,7 +3486,7 @@ public class UserManagerService extends IUserManager.Stub {
* Called right before a user is started. This gives us a chance to prepare
* app storage and apply any user restrictions.
*/
- public void onBeforeStartUser(int userId) {
+ public void onBeforeStartUser(@UserIdInt int userId) {
UserInfo userInfo = getUserInfo(userId);
if (userInfo == null) {
return;
@@ -3600,7 +3601,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public void setSeedAccountData(int userId, String accountName, String accountType,
+ public void setSeedAccountData(@UserIdInt int userId, String accountName, String accountType,
PersistableBundle accountOptions, boolean persist) {
checkManageUsersPermission("Require MANAGE_USERS permission to set user seed data");
synchronized (mPackagesLock) {
@@ -3881,20 +3882,20 @@ public class UserManagerService extends IUserManager.Stub {
* @param userId
* @return whether the user has been initialized yet
*/
- boolean isUserInitialized(int userId) {
+ boolean isUserInitialized(@UserIdInt int userId) {
return mLocalService.isUserInitialized(userId);
}
private class LocalService extends UserManagerInternal {
@Override
- public void setDevicePolicyUserRestrictions(int userId, @Nullable Bundle restrictions,
- boolean isDeviceOwner, int cameraRestrictionScope) {
+ public void setDevicePolicyUserRestrictions(@UserIdInt int userId,
+ @Nullable Bundle restrictions, boolean isDeviceOwner, int cameraRestrictionScope) {
UserManagerService.this.setDevicePolicyUserRestrictionsInner(userId, restrictions,
isDeviceOwner, cameraRestrictionScope);
}
@Override
- public Bundle getBaseUserRestrictions(int userId) {
+ public Bundle getBaseUserRestrictions(@UserIdInt int userId) {
synchronized (mRestrictionsLock) {
return mBaseUserRestrictions.get(userId);
}
@@ -3902,7 +3903,7 @@ public class UserManagerService extends IUserManager.Stub {
@Override
public void setBaseUserRestrictionsByDpmsForMigration(
- int userId, Bundle baseRestrictions) {
+ @UserIdInt int userId, Bundle baseRestrictions) {
synchronized (mRestrictionsLock) {
if (updateRestrictionsIfNeededLR(
userId, new Bundle(baseRestrictions), mBaseUserRestrictions)) {
@@ -3921,7 +3922,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public boolean getUserRestriction(int userId, String key) {
+ public boolean getUserRestriction(@UserIdInt int userId, String key) {
return getUserRestrictions(userId).getBoolean(key);
}
@@ -3947,14 +3948,14 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public void setUserManaged(int userId, boolean isManaged) {
+ public void setUserManaged(@UserIdInt int userId, boolean isManaged) {
synchronized (mUsersLock) {
mIsUserManaged.put(userId, isManaged);
}
}
@Override
- public void setUserIcon(int userId, Bitmap bitmap) {
+ public void setUserIcon(@UserIdInt int userId, Bitmap bitmap) {
long ident = Binder.clearCallingIdentity();
try {
synchronized (mPackagesLock) {
@@ -4011,7 +4012,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public void onEphemeralUserStop(int userId) {
+ public void onEphemeralUserStop(@UserIdInt int userId) {
synchronized (mUsersLock) {
UserInfo userInfo = getUserInfoLU(userId);
if (userInfo != null && userInfo.isEphemeral()) {
@@ -4040,26 +4041,26 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public boolean removeUserEvenWhenDisallowed(int userId) {
+ public boolean removeUserEvenWhenDisallowed(@UserIdInt int userId) {
return removeUserUnchecked(userId);
}
@Override
- public boolean isUserRunning(int userId) {
+ public boolean isUserRunning(@UserIdInt int userId) {
synchronized (mUserStates) {
return mUserStates.get(userId, -1) >= 0;
}
}
@Override
- public void setUserState(int userId, int userState) {
+ public void setUserState(@UserIdInt int userId, int userState) {
synchronized (mUserStates) {
mUserStates.put(userId, userState);
}
}
@Override
- public void removeUserState(int userId) {
+ public void removeUserState(@UserIdInt int userId) {
synchronized (mUserStates) {
mUserStates.delete(userId);
}
@@ -4071,7 +4072,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public boolean isUserUnlockingOrUnlocked(int userId) {
+ public boolean isUserUnlockingOrUnlocked(@UserIdInt int userId) {
int state;
synchronized (mUserStates) {
state = mUserStates.get(userId, -1);
@@ -4085,7 +4086,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public boolean isUserUnlocked(int userId) {
+ public boolean isUserUnlocked(@UserIdInt int userId) {
int state;
synchronized (mUserStates) {
state = mUserStates.get(userId, -1);
@@ -4098,12 +4099,12 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public boolean isUserInitialized(int userId) {
+ public boolean isUserInitialized(@UserIdInt int userId) {
return (getUserInfo(userId).flags & UserInfo.FLAG_INITIALIZED) != 0;
}
@Override
- public boolean exists(int userId) {
+ public boolean exists(@UserIdInt int userId) {
return getUserInfoNoChecks(userId) != null;
}
@@ -4147,7 +4148,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public int getProfileParentId(int userId) {
+ public int getProfileParentId(@UserIdInt int userId) {
synchronized (mUsersLock) {
UserInfo profileParent = getProfileParentLU(userId);
if (profileParent == null) {
@@ -4165,7 +4166,7 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public boolean hasUserRestriction(String restrictionKey, int userId) {
+ public boolean hasUserRestriction(String restrictionKey, @UserIdInt int userId) {
if (!UserRestrictionsUtils.isValidRestriction(restrictionKey)) {
return false;
}
@@ -4274,7 +4275,7 @@ public class UserManagerService extends IUserManager.Stub {
* @param userId The parent user
* @return
*/
- boolean hasManagedProfile(int userId) {
+ boolean hasManagedProfile(@UserIdInt int userId) {
synchronized (mUsersLock) {
UserInfo userInfo = getUserInfoLU(userId);
final int userSize = mUsers.size();
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 83aa07d446e8..a9e3f046e425 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -57,6 +57,7 @@ import android.app.AppOpsManager;
import android.app.ApplicationPackageManager;
import android.app.IActivityManager;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.PermissionGroupInfoFlags;
import android.content.pm.PackageManager.PermissionInfoFlags;
@@ -3750,7 +3751,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
// Make sure all dynamic permissions have been assigned to a package,
// and make sure there are no dangling permissions.
boolean permissionSourcePackageChanged = updatePermissionSourcePackage(changingPkgName,
- changingPkg);
+ changingPkg, callback);
if (permissionTreesSourcePackageChanged | permissionSourcePackageChanged) {
// Permission ownership has changed. This e.g. changes which packages can get signature
@@ -3803,7 +3804,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
* @return {@code true} if a permission source package might have changed
*/
private boolean updatePermissionSourcePackage(@Nullable String packageName,
- @Nullable PackageParser.Package pkg) {
+ @Nullable PackageParser.Package pkg,
+ final @Nullable PermissionCallback callback) {
boolean changed = false;
Set<BasePermission> needsUpdate = null;
@@ -3819,6 +3821,45 @@ public class PermissionManagerService extends IPermissionManager.Stub {
&& (pkg == null || !hasPermission(pkg, bp.getName()))) {
Slog.i(TAG, "Removing permission " + bp.getName()
+ " that used to be declared by " + bp.getSourcePackageName());
+ if (bp.isRuntime()) {
+ final int[] userIds = mUserManagerInt.getUserIds();
+ final int numUserIds = userIds.length;
+ for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
+ final int userId = userIds[userIdNum];
+
+ mPackageManagerInt.forEachPackage((Package p) -> {
+ final String pName = p.packageName;
+ final ApplicationInfo appInfo =
+ mPackageManagerInt.getApplicationInfo(pName, 0,
+ Process.SYSTEM_UID, UserHandle.USER_SYSTEM);
+ if (appInfo != null
+ && appInfo.targetSdkVersion < Build.VERSION_CODES.M) {
+ return;
+ }
+
+ final String permissionName = bp.getName();
+ if (checkPermissionImpl(permissionName, pName, userId)
+ == PackageManager.PERMISSION_GRANTED) {
+ try {
+ revokeRuntimePermissionInternal(
+ permissionName,
+ pName,
+ false,
+ Process.SYSTEM_UID,
+ userId,
+ callback);
+ } catch (IllegalArgumentException e) {
+ Slog.e(TAG,
+ "Failed to revoke "
+ + permissionName
+ + " from "
+ + pName,
+ e);
+ }
+ }
+ });
+ }
+ }
changed = true;
it.remove();
}
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index a671e5f9a150..3147bc629ffa 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -568,6 +568,10 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
}
void onUnlockUser(int userId) {
+ // In order to ensure that no package begins running while a backup or restore is taking
+ // place, onUnlockUser must remain blocked until all pending backups and restores have
+ // completed.
+ CountDownLatch latch = new CountDownLatch(1);
getHandler().post(() -> {
final List<Rollback> rollbacks;
synchronized (mLock) {
@@ -580,7 +584,14 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
for (Rollback rollback : changed) {
saveRollback(rollback);
}
+ latch.countDown();
});
+
+ try {
+ latch.await();
+ } catch (InterruptedException ie) {
+ throw new IllegalStateException("RollbackManagerHandlerThread interrupted");
+ }
}
private void updateRollbackLifetimeDurationInMillis() {
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdater.java b/services/core/java/com/android/server/webkit/WebViewUpdater.java
index a460040d0a60..3b58af2a200f 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdater.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdater.java
@@ -87,19 +87,6 @@ class WebViewUpdater {
newPackage = findPreferredWebViewPackage();
if (mCurrentWebViewPackage != null) {
oldProviderName = mCurrentWebViewPackage.packageName;
- if (changedState == WebViewUpdateService.PACKAGE_CHANGED
- && newPackage.packageName.equals(oldProviderName)) {
- // If we don't change package name we should only rerun the
- // preparation phase if the current package has been replaced
- // (not if it has been enabled/disabled).
- return;
- }
- if (newPackage.packageName.equals(oldProviderName)
- && (newPackage.lastUpdateTime
- == mCurrentWebViewPackage.lastUpdateTime)) {
- // If the chosen package hasn't been updated, then early-out
- return;
- }
}
// Only trigger update actions if the updated package is the one
// that will be used, or the one that was in use before the
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index f5f6625c8728..b92625fe14af 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -33,6 +33,7 @@ import static android.app.WindowConfiguration.windowingModeToString;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
+import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
import static android.view.Display.INVALID_DISPLAY;
@@ -134,6 +135,7 @@ import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.SystemClock;
+import android.os.Trace;
import android.os.UserHandle;
import android.service.voice.IVoiceInteractionSession;
import android.util.ArraySet;
@@ -635,11 +637,15 @@ class ActivityStack extends ConfigurationContainer {
display.onStackWindowingModeChanged(this);
}
if (hasNewOverrideBounds) {
- // Note the resizeStack may enter onConfigurationChanged recursively, so we make a copy
- // of the temporary bounds (newBounds is mTmpRect) to avoid it being modified.
- mRootActivityContainer.resizeStack(this, new Rect(newBounds), null /* tempTaskBounds */,
- null /* tempTaskInsetBounds */, PRESERVE_WINDOWS,
- true /* allowResizeInDockedMode */, true /* deferResume */);
+ if (inSplitScreenPrimaryWindowingMode()) {
+ mStackSupervisor.resizeDockedStackLocked(new Rect(newBounds),
+ null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
+ null /* tempOtherTaskBounds */, null /* tempOtherTaskInsetBounds */,
+ PRESERVE_WINDOWS, true /* deferResume */);
+ } else {
+ resize(new Rect(newBounds), null /* tempTaskBounds */,
+ null /* tempTaskInsetBounds */, PRESERVE_WINDOWS, true /* deferResume */);
+ }
}
if (prevIsAlwaysOnTop != isAlwaysOnTop()) {
// Since always on top is only on when the stack is freeform or pinned, the state
@@ -818,7 +824,8 @@ class ActivityStack extends ConfigurationContainer {
}
if (!Objects.equals(getRequestedOverrideBounds(), mTmpRect2)) {
- resize(mTmpRect2, null /* tempTaskBounds */, null /* tempTaskInsetBounds */);
+ resize(mTmpRect2, null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
+ false /* preserveWindows */, true /* deferResume */);
}
} finally {
if (showRecents && !alreadyInSplitScreenMode && mDisplayId == DEFAULT_DISPLAY
@@ -2208,7 +2215,7 @@ class ActivityStack extends ConfigurationContainer {
* Returns true if this stack should be resized to match the bounds specified by
* {@link ActivityOptions#setLaunchBounds} when launching an activity into the stack.
*/
- boolean resizeStackWithLaunchBounds() {
+ boolean shouldResizeStackWithLaunchBounds() {
return inPinnedWindowingMode();
}
@@ -4344,31 +4351,42 @@ class ActivityStack extends ConfigurationContainer {
}
}
- // TODO: Figure-out a way to consolidate with resize() method below.
- void requestResize(Rect bounds) {
- mService.resizeStack(mStackId, bounds,
- true /* allowResizeInDockedMode */, false /* preserveWindows */,
- false /* animate */, -1 /* animationDuration */);
- }
-
// TODO: Can only be called from special methods in ActivityStackSupervisor.
// Need to consolidate those calls points into this resize method so anyone can call directly.
- void resize(Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds) {
+ void resize(Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds,
+ boolean preserveWindows, boolean deferResume) {
if (!updateBoundsAllowed(bounds)) {
return;
}
- // Update override configurations of all tasks in the stack.
- final Rect taskBounds = tempTaskBounds != null ? tempTaskBounds : bounds;
+ Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "stack.resize_" + mStackId);
+ mWindowManager.deferSurfaceLayout();
+ try {
+ // Update override configurations of all tasks in the stack.
+ final Rect taskBounds = tempTaskBounds != null ? tempTaskBounds : bounds;
+ for (int i = mTaskHistory.size() - 1; i >= 0; i--) {
+ final TaskRecord task = mTaskHistory.get(i);
+ if (task.isResizeable()) {
+ if (tempTaskInsetBounds != null && !tempTaskInsetBounds.isEmpty()) {
+ task.setDisplayedBounds(taskBounds);
+ task.setBounds(tempTaskInsetBounds);
+ } else {
+ task.setDisplayedBounds(null);
+ task.setBounds(taskBounds);
+ }
+ }
+ }
- for (int i = mTaskHistory.size() - 1; i >= 0; i--) {
- final TaskRecord task = mTaskHistory.get(i);
- if (task.isResizeable()) {
- task.updateOverrideConfiguration(taskBounds, tempTaskInsetBounds);
+ setBounds(bounds);
+
+ if (!deferResume) {
+ ensureVisibleActivitiesConfigurationLocked(
+ topRunningActivityLocked(), preserveWindows);
}
+ } finally {
+ mWindowManager.continueSurfaceLayout();
+ Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
-
- setBounds(bounds);
}
void onPipAnimationEndResize() {
@@ -4497,18 +4515,27 @@ class ActivityStack extends ConfigurationContainer {
* then skip running tasks that match those types.
*/
void getRunningTasks(List<TaskRecord> tasksOut, @ActivityType int ignoreActivityType,
- @WindowingMode int ignoreWindowingMode, int callingUid, boolean allowed) {
+ @WindowingMode int ignoreWindowingMode, int callingUid, boolean allowed,
+ boolean crossUser) {
boolean focusedStack = mRootActivityContainer.getTopDisplayFocusedStack() == this;
boolean topTask = true;
+ int userId = UserHandle.getUserId(callingUid);
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
final TaskRecord task = mTaskHistory.get(taskNdx);
if (task.getTopActivity() == null) {
// Skip if there are no activities in the task
continue;
}
- if (!allowed && !task.isActivityTypeHome() && task.effectiveUid != callingUid) {
- // Skip if the caller can't fetch this task
- continue;
+ if (task.effectiveUid != callingUid) {
+ if (task.userId != userId && !crossUser) {
+ // Skip if the caller does not have cross user permission
+ continue;
+ }
+ if (!allowed && !task.isActivityTypeHome()) {
+ // Skip if the caller isn't allowed to fetch this task, except for the home
+ // task which we always return.
+ continue;
+ }
}
if (ignoreActivityType != ACTIVITY_TYPE_UNDEFINED
&& task.getActivityType() == ignoreActivityType) {
@@ -4774,7 +4801,7 @@ class ActivityStack extends ConfigurationContainer {
if (!mStackSupervisor.getLaunchParamsController()
.layoutTask(task, info.windowLayout, activity, source, options)
&& !matchParentBounds() && task.isResizeable() && !isLockscreenShown) {
- task.updateOverrideConfiguration(getRequestedOverrideBounds());
+ task.setBounds(getRequestedOverrideBounds());
}
task.createTask(toTop, (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
return task;
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index a480fb8f110f..7a3f022d60bf 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -1398,7 +1398,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
boolean reparented = false;
if (task.isResizeable() && canUseActivityOptionsLaunchBounds(options)) {
final Rect bounds = options.getLaunchBounds();
- task.updateOverrideConfiguration(bounds);
+ task.setBounds(bounds);
ActivityStack stack =
mRootActivityContainer.getLaunchStack(null, options, task, ON_TOP);
@@ -1412,10 +1412,9 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
// task.reparent() should already placed the task on top,
// still need moveTaskToFrontLocked() below for any transition settings.
}
- if (stack.resizeStackWithLaunchBounds()) {
- mRootActivityContainer.resizeStack(stack, bounds, null /* tempTaskBounds */,
- null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS,
- true /* allowResizeInDockedMode */, !DEFER_RESUME);
+ if (stack.shouldResizeStackWithLaunchBounds()) {
+ stack.resize(bounds, null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
+ !PRESERVE_WINDOWS, !DEFER_RESUME);
} else {
// WM resizeTask must be done after the task is moved to the correct stack,
// because Task's setBounds() also updates dim layer's bounds, but that has
@@ -1636,7 +1635,8 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
// Don't allow re-entry while resizing. E.g. due to docked stack detaching.
mAllowDockedStackResize = false;
ActivityRecord r = stack.topRunningActivityLocked();
- stack.resize(dockedBounds, tempDockedTaskBounds, tempDockedTaskInsetBounds);
+ stack.resize(dockedBounds, tempDockedTaskBounds, tempDockedTaskInsetBounds,
+ !PRESERVE_WINDOWS, DEFER_RESUME);
// TODO: Checking for isAttached might not be needed as if the user passes in null
// dockedBounds then they want the docked stack to be dismissed.
@@ -1674,11 +1674,19 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
tempRect /* outStackBounds */,
otherTaskRect /* outTempTaskBounds */);
- mRootActivityContainer.resizeStack(current,
- !tempRect.isEmpty() ? tempRect : null,
+ if (tempRect.isEmpty()) {
+ // If this scenario is hit, it means something is not working right.
+ // Empty/null bounds implies fullscreen. In the event that this stack
+ // *should* be fullscreen, its mode should be set explicitly in a form
+ // of setWindowingMode so that other parts of the system are updated
+ // properly.
+ throw new IllegalArgumentException("Trying to set null bounds on a"
+ + " non-fullscreen stack");
+ }
+
+ current.resize(tempRect,
!otherTaskRect.isEmpty() ? otherTaskRect : tempOtherTaskBounds,
- tempOtherTaskInsetBounds, preserveWindows,
- true /* allowResizeInDockedMode */, deferResume);
+ tempOtherTaskInsetBounds, preserveWindows, deferResume);
}
}
if (!deferResume) {
@@ -1728,8 +1736,8 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
// transitioning it from fullscreen into a floating state.
stack.onPipAnimationEndResize();
}
- stack.resize(pinnedBounds, tempPinnedTaskBounds, insetBounds);
- stack.ensureVisibleActivitiesConfigurationLocked(r, false);
+ stack.resize(pinnedBounds, tempPinnedTaskBounds, insetBounds, !PRESERVE_WINDOWS,
+ !DEFER_RESUME);
} finally {
mWindowManager.continueSurfaceLayout();
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 5717e2fa02d2..641b00aeb70b 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2400,11 +2400,10 @@ class ActivityStarter {
}
final ActivityStack stack = task.getStack();
- if (stack != null && stack.resizeStackWithLaunchBounds()) {
- mService.resizeStack(
- stack.mStackId, bounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
+ if (stack != null && stack.inPinnedWindowingMode()) {
+ mService.animateResizePinnedStack(stack.mStackId, bounds, -1);
} else {
- task.updateOverrideConfiguration(bounds);
+ task.setBounds(bounds);
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index ee56c0902e78..d97f0f5041a4 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -19,6 +19,8 @@ package com.android.server.wm;
import static android.Manifest.permission.BIND_VOICE_INTERACTION;
import static android.Manifest.permission.CHANGE_CONFIGURATION;
import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
+import static android.Manifest.permission.INTERACT_ACROSS_USERS;
+import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
import static android.Manifest.permission.READ_FRAME_BUFFER;
@@ -2508,15 +2510,16 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@WindowConfiguration.ActivityType int ignoreActivityType,
@WindowConfiguration.WindowingMode int ignoreWindowingMode) {
final int callingUid = Binder.getCallingUid();
+ final int callingPid = Binder.getCallingPid();
+ final boolean crossUser = isCrossUserAllowed(callingPid, callingUid);
ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
synchronized (mGlobalLock) {
if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
- final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
- callingUid);
+ final boolean allowed = isGetTasksAllowed("getTasks", callingPid, callingUid);
mRootActivityContainer.getRunningTasks(maxNum, list, ignoreActivityType,
- ignoreWindowingMode, callingUid, allowed);
+ ignoreWindowingMode, callingUid, allowed, crossUser);
}
return list;
@@ -2582,35 +2585,23 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
@Override
- public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
- boolean preserveWindows, boolean animate, int animationDuration) {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
+ public void animateResizePinnedStack(int stackId, Rect destBounds, int animationDuration) {
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "animateResizePinnedStack()");
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
- if (animate) {
- final ActivityStack stack = mRootActivityContainer.getStack(stackId);
- if (stack == null) {
- Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
- return;
- }
- if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
- throw new IllegalArgumentException("Stack: " + stackId
- + " doesn't support animated resize.");
- }
- stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
- animationDuration, false /* fromFullscreen */);
- } else {
- final ActivityStack stack = mRootActivityContainer.getStack(stackId);
- if (stack == null) {
- Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
- return;
- }
- mRootActivityContainer.resizeStack(stack, destBounds,
- null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
- preserveWindows, allowResizeInDockedMode, !DEFER_RESUME);
+ final ActivityStack stack = mRootActivityContainer.getStack(stackId);
+ if (stack == null) {
+ Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
+ return;
+ }
+ if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
+ throw new IllegalArgumentException("Stack: " + stackId
+ + " doesn't support animated resize.");
}
+ stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
+ animationDuration, false /* fromFullscreen */);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -3546,6 +3537,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
return allowed;
}
+ boolean isCrossUserAllowed(int pid, int uid) {
+ return checkPermission(INTERACT_ACROSS_USERS, pid, uid) == PERMISSION_GRANTED
+ || checkPermission(INTERACT_ACROSS_USERS_FULL, pid, uid) == PERMISSION_GRANTED;
+ }
+
private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index aecbca391735..b502bd54bfc5 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -3551,7 +3551,8 @@ public class DisplayPolicy {
if (mScreenshotHelper != null) {
mScreenshotHelper.takeScreenshot(screenshotType,
mStatusBar != null && mStatusBar.isVisibleLw(),
- mNavigationBar != null && mNavigationBar.isVisibleLw(), mHandler);
+ mNavigationBar != null && mNavigationBar.isVisibleLw(),
+ mHandler, null /* completionConsumer */);
}
}
diff --git a/services/core/java/com/android/server/wm/LaunchParamsController.java b/services/core/java/com/android/server/wm/LaunchParamsController.java
index 59c02f736513..59df09be1ff5 100644
--- a/services/core/java/com/android/server/wm/LaunchParamsController.java
+++ b/services/core/java/com/android/server/wm/LaunchParamsController.java
@@ -152,7 +152,7 @@ class LaunchParamsController {
if (task.getStack().inFreeformWindowingMode()) {
// Only set bounds if it's in freeform mode.
- task.updateOverrideConfiguration(mTmpParams.mBounds);
+ task.setBounds(mTmpParams.mBounds);
return true;
}
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index eb5d096aa781..50b5902e17d4 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -27,12 +27,10 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
-import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY;
@@ -93,7 +91,6 @@ import android.os.FactoryTest;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
-import android.os.Trace;
import android.os.UserHandle;
import android.os.storage.StorageManager;
import android.provider.Settings;
@@ -881,48 +878,6 @@ class RootActivityContainer extends ConfigurationContainer
}
}
- void resizeStack(ActivityStack stack, Rect bounds, Rect tempTaskBounds,
- Rect tempTaskInsetBounds, boolean preserveWindows, boolean allowResizeInDockedMode,
- boolean deferResume) {
-
- if (stack.inSplitScreenPrimaryWindowingMode()) {
- mStackSupervisor.resizeDockedStackLocked(bounds, tempTaskBounds,
- tempTaskInsetBounds, null, null, preserveWindows, deferResume);
- return;
- }
-
- final boolean splitScreenActive = getDefaultDisplay().hasSplitScreenPrimaryStack();
- if (!allowResizeInDockedMode
- && !stack.getWindowConfiguration().tasksAreFloating() && splitScreenActive) {
- // If the docked stack exists, don't resize non-floating stacks independently of the
- // size computed from the docked stack size (otherwise they will be out of sync)
- return;
- }
-
- Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeStack_" + stack.mStackId);
- mWindowManager.deferSurfaceLayout();
- try {
- if (stack.affectedBySplitScreenResize()) {
- if (bounds == null && stack.inSplitScreenWindowingMode()) {
- // null bounds = fullscreen windowing mode...at least for now.
- stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
- } else if (splitScreenActive) {
- // If we are in split-screen mode and this stack support split-screen, then
- // it should be split-screen secondary mode. i.e. adjacent to the docked stack.
- stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
- }
- }
- stack.resize(bounds, tempTaskBounds, tempTaskInsetBounds);
- if (!deferResume) {
- stack.ensureVisibleActivitiesConfigurationLocked(
- stack.topRunningActivityLocked(), preserveWindows);
- }
- } finally {
- mWindowManager.continueSurfaceLayout();
- Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
- }
- }
-
/**
* Move stack with all its existing content to specified display.
* @param stackId Id of stack to move.
@@ -1014,9 +969,8 @@ class RootActivityContainer extends ConfigurationContainer
// Resize the pinned stack to match the current size of the task the activity we are
// going to be moving is currently contained in. We do this to have the right starting
// animation bounds for the pinned stack to the desired bounds the caller wants.
- resizeStack(stack, task.getRequestedOverrideBounds(), null /* tempTaskBounds */,
- null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS,
- true /* allowResizeInDockedMode */, !DEFER_RESUME);
+ stack.resize(task.getRequestedOverrideBounds(), null /* tempTaskBounds */,
+ null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS, !DEFER_RESUME);
if (task.mActivities.size() == 1) {
// Defer resume until below, and do not schedule PiP changes until we animate below
@@ -2260,9 +2214,9 @@ class RootActivityContainer extends ConfigurationContainer
void getRunningTasks(int maxNum, List<ActivityManager.RunningTaskInfo> list,
@WindowConfiguration.ActivityType int ignoreActivityType,
@WindowConfiguration.WindowingMode int ignoreWindowingMode, int callingUid,
- boolean allowed) {
+ boolean allowed, boolean crossUser) {
mStackSupervisor.getRunningTasks().getTasks(maxNum, list, ignoreActivityType,
- ignoreWindowingMode, mActivityDisplays, callingUid, allowed);
+ ignoreWindowingMode, mActivityDisplays, callingUid, allowed, crossUser);
}
void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
diff --git a/services/core/java/com/android/server/wm/RunningTasks.java b/services/core/java/com/android/server/wm/RunningTasks.java
index 3bf437d38bcc..22a9c32a830f 100644
--- a/services/core/java/com/android/server/wm/RunningTasks.java
+++ b/services/core/java/com/android/server/wm/RunningTasks.java
@@ -40,7 +40,7 @@ class RunningTasks {
void getTasks(int maxNum, List<RunningTaskInfo> list, @ActivityType int ignoreActivityType,
@WindowingMode int ignoreWindowingMode, ArrayList<ActivityDisplay> activityDisplays,
- int callingUid, boolean allowed) {
+ int callingUid, boolean allowed, boolean crossUser) {
// Return early if there are no tasks to fetch
if (maxNum <= 0) {
return;
@@ -55,7 +55,7 @@ class RunningTasks {
final ActivityStack stack = display.getChildAt(stackNdx);
mTmpStackTasks.clear();
stack.getRunningTasks(mTmpStackTasks, ignoreActivityType, ignoreWindowingMode,
- callingUid, allowed);
+ callingUid, allowed, crossUser);
mTmpSortedSet.addAll(mTmpStackTasks);
}
}
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index e25ca73e457d..d3f3981625d9 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -512,7 +512,7 @@ class TaskRecord extends ConfigurationContainer {
if (!getWindowConfiguration().persistTaskBounds()) {
// Reset current bounds for task whose bounds shouldn't be persisted so it uses
// default configuration the next time it launches.
- updateOverrideConfiguration(null);
+ setBounds(null);
}
mService.getTaskChangeNotificationController().notifyTaskRemoved(taskId);
}
@@ -565,7 +565,7 @@ class TaskRecord extends ConfigurationContainer {
// Task doesn't exist in window manager yet (e.g. was restored from recents).
// All we can do for now is update the bounds so it can be used when the task is
// added to window manager.
- updateOverrideConfiguration(bounds);
+ setBounds(bounds);
if (!inFreeformWindowingMode()) {
// re-restore the task so it can have the proper stack association.
mService.mStackSupervisor.restoreRecentTaskLocked(this, null, !ON_TOP);
@@ -584,7 +584,11 @@ class TaskRecord extends ConfigurationContainer {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + taskId);
- final boolean updatedConfig = updateOverrideConfiguration(bounds);
+ boolean updatedConfig = false;
+ mTmpConfig.setTo(getResolvedOverrideConfiguration());
+ if (setBounds(bounds) != BOUNDS_CHANGE_NONE) {
+ updatedConfig = !mTmpConfig.equals(getResolvedOverrideConfiguration());
+ }
// This variable holds information whether the configuration didn't change in a significant
// way and the activity was kept the way it was. If it's false, it means the activity
@@ -1803,15 +1807,6 @@ class TaskRecord extends ConfigurationContainer {
}
}
- /**
- * Update task's override configuration based on the bounds.
- * @param bounds The bounds of the task.
- * @return True if the override configuration was updated.
- */
- boolean updateOverrideConfiguration(Rect bounds) {
- return updateOverrideConfiguration(bounds, null /* insetBounds */);
- }
-
void setLastNonFullscreenBounds(Rect bounds) {
if (mLastNonFullscreenBounds == null) {
mLastNonFullscreenBounds = new Rect(bounds);
@@ -1821,32 +1816,6 @@ class TaskRecord extends ConfigurationContainer {
}
/**
- * Update task's override configuration based on the bounds.
- * @param bounds The bounds of the task.
- * @param insetBounds The bounds used to calculate the system insets, which is used here to
- * subtract the navigation bar/status bar size from the screen size reported
- * to the application. See {@link IActivityTaskManager#resizeDockedStack}.
- * @return True if the override configuration was updated.
- */
- boolean updateOverrideConfiguration(Rect bounds, @Nullable Rect insetBounds) {
- final boolean hasSetDisplayedBounds = (insetBounds != null && !insetBounds.isEmpty());
- if (hasSetDisplayedBounds) {
- setDisplayedBounds(bounds);
- } else {
- setDisplayedBounds(null);
- }
- // "steady" bounds do not include any temporary offsets from animation or interaction.
- Rect steadyBounds = hasSetDisplayedBounds ? insetBounds : bounds;
- if (equivalentRequestedOverrideBounds(steadyBounds)) {
- return false;
- }
-
- mTmpConfig.setTo(getResolvedOverrideConfiguration());
- setBounds(steadyBounds);
- return !mTmpConfig.equals(getResolvedOverrideConfiguration());
- }
-
- /**
* This should be called when an child activity changes state. This should only
* be called from
* {@link ActivityRecord#setState(ActivityState, String)} .
@@ -2297,7 +2266,7 @@ class TaskRecord extends ConfigurationContainer {
Rect updateOverrideConfigurationFromLaunchBounds() {
final Rect bounds = getLaunchBounds();
- updateOverrideConfiguration(bounds);
+ setBounds(bounds);
if (bounds != null && !bounds.isEmpty()) {
// TODO: Review if we actually want to do this - we are setting the launch bounds
// directly here.
@@ -2322,12 +2291,12 @@ class TaskRecord extends ConfigurationContainer {
return;
}
if (mLastNonFullscreenBounds != null) {
- updateOverrideConfiguration(mLastNonFullscreenBounds);
+ setBounds(mLastNonFullscreenBounds);
} else {
mService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
}
} else {
- updateOverrideConfiguration(inStack.getRequestedOverrideBounds());
+ setBounds(inStack.getRequestedOverrideBounds());
}
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 814bec671750..bef6a37a1ebe 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -859,7 +859,7 @@ public class TaskStack extends WindowContainer<Task> implements
// When the home stack is resizable, should always have the same stack and task bounds
if (isActivityTypeHome()) {
final Task homeTask = findHomeTask();
- if (homeTask != null && homeTask.isResizeable()) {
+ if (homeTask == null || homeTask.isResizeable()) {
// Calculate the home stack bounds when in docked mode and the home stack is
// resizeable.
getDisplayContent().mDividerControllerLocked
@@ -965,7 +965,7 @@ public class TaskStack extends WindowContainer<Task> implements
}
void resetDockedStackToMiddle() {
- if (inSplitScreenPrimaryWindowingMode()) {
+ if (!inSplitScreenPrimaryWindowingMode()) {
throw new IllegalStateException("Not a docked stack=" + this);
}
@@ -973,12 +973,12 @@ public class TaskStack extends WindowContainer<Task> implements
final Rect bounds = new Rect();
final Rect tempBounds = new Rect();
- TaskStack dockedStack = mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
- Rect dockedBounds =
- (dockedStack == null || dockedStack == this) ? null : dockedStack.getRawBounds();
- getStackDockedModeBoundsLocked(mDisplayContent.getConfiguration(), dockedBounds,
+ getStackDockedModeBoundsLocked(mDisplayContent.getConfiguration(), null /* dockedBounds */,
null /* currentTempTaskBounds */, bounds, tempBounds);
- mActivityStack.requestResize(bounds);
+ mActivityStack.mStackSupervisor.resizeDockedStackLocked(bounds, null /* tempTaskBounds */,
+ null /* tempTaskInsetBounds */, null /* tempOtherTaskBounds */,
+ null /* tempOtherTaskInsetBounds */, false /* preserveWindows */,
+ false /* deferResume */);
}
@Override
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 8c51452075b7..d7116d8bbd87 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -23,7 +23,6 @@ import static android.view.Display.INVALID_DISPLAY;
import static com.android.server.am.ActivityManagerService.MY_PID;
import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED;
import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING;
-import static com.android.server.wm.ActivityStack.ActivityState.INITIALIZING;
import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
@@ -556,14 +555,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
continue;
}
ActivityRecord topActivity = task.getTopActivity();
- if (topActivity == null) {
- continue;
- }
- // If an activity has just been started it will not yet be visible, but
- // is expected to be soon. We treat this as if it were already visible.
- // This ensures a subsequent activity can be started even before this one
- // becomes visible.
- if (topActivity.visible || topActivity.isState(INITIALIZING)) {
+ if (topActivity != null && topActivity.visible) {
return true;
}
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 8e679d44fe05..6dfbc36ce6f7 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1050,7 +1050,7 @@ class WindowStateAnimator {
// to prevent further updates until buffer latch.
// We also need to freeze the Surface geometry until a buffer
// comes in at the new size (normally position and crop are unfrozen).
- // setGeometryAppliesWithResizeInTransaction accomplishes this for us.
+ // deferTransactionUntil accomplishes this for us.
if (wasForceScaled && !mForceScaleUntilResize) {
mSurfaceController.deferTransactionUntil(mSurfaceController.mSurfaceControl,
mWin.getFrameNumber());
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 8cede6c52914..6d813d106345 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -245,10 +245,6 @@ class WindowSurfaceController {
}
}
- void setGeometryAppliesWithResizeInTransaction(boolean recoveringMemory) {
- mSurfaceControl.setGeometryAppliesWithResize();
- }
-
void setMatrixInTransaction(float dsdx, float dtdx, float dtdy, float dsdy,
boolean recoveringMemory) {
setMatrix(null, dsdx, dtdx, dtdy, dsdy, false);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/GlobalActionPerformerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/GlobalActionPerformerTest.java
index e72e4601bbe8..c73be6f100cd 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/GlobalActionPerformerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/GlobalActionPerformerTest.java
@@ -35,6 +35,8 @@ import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.function.Consumer;
+
/**
* Tests for GlobalActionPerformer
*/
@@ -84,6 +86,6 @@ public class GlobalActionPerformerTest {
AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT);
verify(mMockScreenshotHelper).takeScreenshot(
eq(android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN), anyBoolean(),
- anyBoolean(), any(Handler.class));
+ anyBoolean(), any(Handler.class), any());
}
}
diff --git a/services/tests/uiservicestests/AndroidManifest.xml b/services/tests/uiservicestests/AndroidManifest.xml
index 7453c489ecc8..180deb5c4dcc 100644
--- a/services/tests/uiservicestests/AndroidManifest.xml
+++ b/services/tests/uiservicestests/AndroidManifest.xml
@@ -31,6 +31,7 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.OBSERVE_ROLE_HOLDERS" />
<uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT"/>
+ <uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG" />
<application android:debuggable="true">
<uses-library android:name="android.test.runner" />
diff --git a/services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java b/services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java
index 14b71ec526a8..3c2d55058c3e 100644
--- a/services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java
+++ b/services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java
@@ -27,9 +27,11 @@ import androidx.test.InstrumentationRegistry;
import com.android.server.uri.UriGrantsManagerInternal;
+import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
public class UiServiceTestCase {
@@ -77,4 +79,9 @@ public class UiServiceTestCase {
when(mUgmInternal.checkGrantUriPermission(
anyInt(), anyString(), any(Uri.class), anyInt(), anyInt())).thenReturn(-1);
}
+
+ @After
+ public final void cleanUpMockito() {
+ Mockito.framework().clearInlineMocks();
+ }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index be638a9d9755..d11995a82229 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -62,6 +62,7 @@ import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
@@ -209,9 +210,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
private AudioManager mAudioManager;
@Mock
ActivityManager mActivityManager;
- NotificationManagerService.WorkerHandler mHandler;
@Mock
Resources mResources;
+ @Mock
+ RankingHandler mRankingHandler;
private NotificationChannel mTestNotificationChannel = new NotificationChannel(
TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT);
@@ -342,7 +344,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// Use this testable looper.
mTestableLooper = TestableLooper.get(this);
- mHandler = mService.new WorkerHandler(mTestableLooper.getLooper());
// MockPackageManager - default returns ApplicationInfo with matching calling UID
mContext.setMockPackageManager(mPackageManagerClient);
@@ -391,7 +392,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
when(mAssistants.isAdjustmentAllowed(anyString())).thenReturn(true);
- mService.init(mTestableLooper.getLooper(),
+ mService.init(mTestableLooper.getLooper(), mRankingHandler,
mPackageManager, mPackageManagerClient, mockLightsManager,
mListeners, mAssistants, mConditionProviders,
mCompanionMgr, mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager,
@@ -410,6 +411,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
PKG, new ParceledListSlice(Arrays.asList(mTestNotificationChannel)));
assertNotNull(mBinderService.getNotificationChannel(
PKG, mContext.getUserId(), PKG, TEST_CHANNEL_ID));
+ clearInvocations(mRankingHandler);
}
@After
@@ -461,7 +463,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
Notification.Builder nb = new Notification.Builder(mContext, "a")
.setContentTitle("foo")
.setSmallIcon(android.R.drawable.sym_def_app_icon);
- StatusBarNotification sbn = new StatusBarNotification(pkg, pkg, uid, "tag", uid, 0,
+ StatusBarNotification sbn = new StatusBarNotification(pkg, pkg, uid,
+ "tag" + System.currentTimeMillis(), uid, 0,
nb.build(), new UserHandle(userId), null, postTime);
return sbn;
}
@@ -482,7 +485,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
if (isBubble) {
nb.setBubbleMetadata(getBasicBubbleMetadataBuilder().build());
}
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, id, "tag", mUid, 0,
+
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, id,
+ "tag" + System.currentTimeMillis(), mUid, 0,
nb.build(), new UserHandle(mUid), null, 0);
return new NotificationRecord(mContext, sbn, channel);
}
@@ -510,7 +515,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
if (isBubble) {
nb.setBubbleMetadata(getBasicBubbleMetadataBuilder().build());
}
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
nb.build(), new UserHandle(mUid), null, 0);
return new NotificationRecord(mContext, sbn, channel);
}
@@ -588,7 +593,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
when(mActivityManager.getPackageImportance(nrBubble.sbn.getPackageName())).thenReturn(
IMPORTANCE_FOREGROUND);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nrBubble.sbn.getTag(),
nrBubble.sbn.getId(), nrBubble.sbn.getNotification(), nrBubble.sbn.getUserId());
waitForIdle();
@@ -600,7 +605,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// Plain notification without bubble metadata
NotificationRecord nrPlain = generateNotificationRecord(mTestNotificationChannel, 2,
"BUBBLE_GROUP", false /* isSummary */, false /* isBubble */);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nrPlain.sbn.getTag(),
nrPlain.sbn.getId(), nrPlain.sbn.getNotification(), nrPlain.sbn.getUserId());
waitForIdle();
@@ -613,7 +618,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
if (summaryAutoCancel) {
nrSummary.getNotification().flags |= FLAG_AUTO_CANCEL;
}
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nrSummary.sbn.getTag(),
nrSummary.sbn.getId(), nrSummary.sbn.getNotification(), nrSummary.sbn.getUserId());
waitForIdle();
@@ -757,7 +762,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mBinderService.createNotificationChannels(
PKG, new ParceledListSlice(Arrays.asList(channel)));
final StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testBlockedNotifications_blockedChannel",
sbn.getId(), sbn.getNotification(), sbn.getUserId());
waitForIdle();
assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
@@ -775,7 +781,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
sbn.getId(), sbn.getNotification(), sbn.getUserId());
waitForIdle();
assertEquals(1, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
@@ -804,7 +810,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
sbn.getId(), sbn.getNotification(), sbn.getUserId());
waitForIdle();
// The first time a foreground service notification is shown, we allow the channel
@@ -826,7 +832,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
sbn = generateNotificationRecord(channel).sbn;
sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testEnqueuedBlockedNotifications_userBlockedChannelForegroundService",
sbn.getId(), sbn.getNotification(), sbn.getUserId());
waitForIdle();
// The second time it is shown, we keep the user's preference.
@@ -840,7 +847,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testBlockedNotifications_blockedChannelGroup() throws Exception {
when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
mService.setPreferencesHelper(mPreferencesHelper);
- when(mPreferencesHelper.isGroupBlocked(anyString(), anyInt(), anyString())).thenReturn(true);
+ when(mPreferencesHelper.isGroupBlocked(anyString(), anyInt(), anyString())).
+ thenReturn(true);
NotificationChannel channel = new NotificationChannel("id", "name",
NotificationManager.IMPORTANCE_HIGH);
@@ -857,7 +865,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testEnqueuedBlockedNotifications_blockedApp",
sbn.getId(), sbn.getNotification(), sbn.getUserId());
waitForIdle();
assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
@@ -871,7 +880,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testEnqueuedBlockedNotifications_blockedAppForegroundService",
sbn.getId(), sbn.getNotification(), sbn.getUserId());
waitForIdle();
assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
@@ -893,7 +903,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final StatusBarNotification sbn =
generateNotificationRecord(mTestNotificationChannel, ++id, "", false).sbn;
sbn.getNotification().category = category;
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testEnqueuedRestrictedNotifications_asSystem",
sbn.getId(), sbn.getNotification(), sbn.getUserId());
}
waitForIdle();
@@ -917,7 +928,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final StatusBarNotification sbn =
generateNotificationRecord(mTestNotificationChannel, ++id, "", false).sbn;
sbn.getNotification().category = category;
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testEnqueuedRestrictedNotifications_notAutomotive",
sbn.getId(), sbn.getNotification(), sbn.getUserId());
}
waitForIdle();
@@ -940,7 +952,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
sbn.getNotification().category = category;
try {
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testEnqueuedRestrictedNotifications_badUser",
sbn.getId(), sbn.getNotification(), sbn.getUserId());
fail("Calls from non system apps should not allow use of restricted categories");
} catch (SecurityException e) {
@@ -977,7 +990,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
public void testEnqueueNotificationWithTag_PopulatesGetActiveNotifications() throws Exception {
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testEnqueueNotificationWithTag_PopulatesGetActiveNotifications", 0,
generateNotificationRecord(null).getNotification(), 0);
waitForIdle();
StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
@@ -987,9 +1001,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
public void testCancelNotificationImmediatelyAfterEnqueue() throws Exception {
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testCancelNotificationImmediatelyAfterEnqueue", 0,
generateNotificationRecord(null).getNotification(), 0);
- mBinderService.cancelNotificationWithTag(PKG, PKG, "tag", 0, 0);
+ mBinderService.cancelNotificationWithTag(PKG, PKG,
+ "testCancelNotificationImmediatelyAfterEnqueue", 0, 0);
waitForIdle();
StatusBarNotification[] notifs =
mBinderService.getActiveNotifications(PKG);
@@ -999,12 +1015,15 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
public void testCancelNotificationWhilePostedAndEnqueued() throws Exception {
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testCancelNotificationWhilePostedAndEnqueued", 0,
generateNotificationRecord(null).getNotification(), 0);
waitForIdle();
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testCancelNotificationWhilePostedAndEnqueued", 0,
generateNotificationRecord(null).getNotification(), 0);
- mBinderService.cancelNotificationWithTag(PKG, PKG, "tag", 0, 0);
+ mBinderService.cancelNotificationWithTag(PKG, PKG,
+ "testCancelNotificationWhilePostedAndEnqueued", 0, 0);
waitForIdle();
StatusBarNotification[] notifs =
mBinderService.getActiveNotifications(PKG);
@@ -1019,7 +1038,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testCancelNotificationsFromListenerImmediatelyAfterEnqueue() throws Exception {
NotificationRecord r = generateNotificationRecord(null);
final StatusBarNotification sbn = r.sbn;
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testCancelNotificationsFromListenerImmediatelyAfterEnqueue",
sbn.getId(), sbn.getNotification(), sbn.getUserId());
mBinderService.cancelNotificationsFromListener(null, null);
waitForIdle();
@@ -1032,7 +1052,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
public void testCancelAllNotificationsImmediatelyAfterEnqueue() throws Exception {
final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testCancelAllNotificationsImmediatelyAfterEnqueue",
sbn.getId(), sbn.getNotification(), sbn.getUserId());
mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
waitForIdle();
@@ -1047,7 +1068,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final NotificationRecord n = generateNotificationRecord(
mTestNotificationChannel, 1, "group", true);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testUserInitiatedClearAll_noLeak",
n.sbn.getId(), n.sbn.getNotification(), n.sbn.getUserId());
waitForIdle();
@@ -1070,9 +1092,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final NotificationRecord child = generateNotificationRecord(
mTestNotificationChannel, 2, "group1", false);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testCancelAllNotificationsCancelsChildren",
parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testCancelAllNotificationsCancelsChildren",
child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
waitForIdle();
@@ -1085,7 +1109,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testCancelAllNotificationsMultipleEnqueuedDoesNotCrash() throws Exception {
final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
for (int i = 0; i < 10; i++) {
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testCancelAllNotificationsMultipleEnqueuedDoesNotCrash",
sbn.getId(), sbn.getNotification(), sbn.getUserId());
}
mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
@@ -1104,17 +1129,20 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mTestNotificationChannel, 2, "group1", false);
// fully post parent notification
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testCancelGroupSummaryMultipleEnqueuedChildrenDoesNotCrash",
parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
waitForIdle();
// enqueue the child several times
for (int i = 0; i < 10; i++) {
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testCancelGroupSummaryMultipleEnqueuedChildrenDoesNotCrash",
child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
}
// make the parent a child, which will cancel the child notification
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testCancelGroupSummaryMultipleEnqueuedChildrenDoesNotCrash",
parentAsChild.sbn.getId(), parentAsChild.sbn.getNotification(),
parentAsChild.sbn.getUserId());
waitForIdle();
@@ -1126,7 +1154,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testCancelAllNotifications_IgnoreForegroundService() throws Exception {
final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testCancelAllNotifications_IgnoreForegroundService",
sbn.getId(), sbn.getNotification(), sbn.getUserId());
mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
waitForIdle();
@@ -1140,7 +1169,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testCancelAllNotifications_IgnoreOtherPackages() throws Exception {
final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testCancelAllNotifications_IgnoreOtherPackages",
sbn.getId(), sbn.getNotification(), sbn.getUserId());
mBinderService.cancelAllNotifications("other_pkg_name", sbn.getUserId());
waitForIdle();
@@ -1153,7 +1183,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
public void testCancelAllNotifications_NullPkgRemovesAll() throws Exception {
final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testCancelAllNotifications_NullPkgRemovesAll",
sbn.getId(), sbn.getNotification(), sbn.getUserId());
mBinderService.cancelAllNotifications(null, sbn.getUserId());
waitForIdle();
@@ -1166,7 +1197,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
public void testCancelAllNotifications_NullPkgIgnoresUserAllNotifications() throws Exception {
final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testCancelAllNotifications_NullPkgIgnoresUserAllNotifications",
sbn.getId(), sbn.getNotification(), UserHandle.USER_ALL);
// Null pkg is how we signal a user switch.
mBinderService.cancelAllNotifications(null, sbn.getUserId());
@@ -1181,7 +1213,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testAppInitiatedCancelAllNotifications_CancelsNoClearFlag() throws Exception {
final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
sbn.getNotification().flags |= Notification.FLAG_NO_CLEAR;
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testAppInitiatedCancelAllNotifications_CancelsNoClearFlag",
sbn.getId(), sbn.getNotification(), sbn.getUserId());
mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
waitForIdle();
@@ -1266,7 +1299,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
public void testRemoveForegroundServiceFlag_ImmediatelyAfterEnqueue() throws Exception {
- final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
+ Notification n =
+ new Notification.Builder(mContext, mTestNotificationChannel.getId())
+ .setSmallIcon(android.R.drawable.sym_def_app_icon)
+ .build();
+ StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, null, mUid, 0,
+ n, new UserHandle(mUid), null, 0);
sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
sbn.getId(), sbn.getNotification(), sbn.getUserId());
@@ -1283,12 +1321,13 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
sbn.getNotification().flags =
Notification.FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE;
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
sbn.getId(), sbn.getNotification(), sbn.getUserId());
sbn.getNotification().flags = Notification.FLAG_ONGOING_EVENT;
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
sbn.getId(), sbn.getNotification(), sbn.getUserId());
- mBinderService.cancelNotificationWithTag(PKG, PKG, "tag", sbn.getId(), sbn.getUserId());
+ mBinderService.cancelNotificationWithTag(PKG, PKG, sbn.getTag(), sbn.getId(),
+ sbn.getUserId());
waitForIdle();
assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
assertEquals(0, mService.getNotificationRecordCount());
@@ -1376,21 +1415,22 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// should not be returned
final NotificationRecord group2 = generateNotificationRecord(
mTestNotificationChannel, 2, "group2", true);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, "testFindGroupNotificationsLocked",
group2.sbn.getId(), group2.sbn.getNotification(), group2.sbn.getUserId());
waitForIdle();
// should not be returned
final NotificationRecord nonGroup = generateNotificationRecord(
mTestNotificationChannel, 3, null, false);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, "testFindGroupNotificationsLocked",
nonGroup.sbn.getId(), nonGroup.sbn.getNotification(), nonGroup.sbn.getUserId());
waitForIdle();
// same group, child, should be returned
final NotificationRecord group1Child = generateNotificationRecord(
mTestNotificationChannel, 4, "group1", false);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, null, group1Child.sbn.getId(),
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, "testFindGroupNotificationsLocked",
+ group1Child.sbn.getId(),
group1Child.sbn.getNotification(), group1Child.sbn.getUserId());
waitForIdle();
@@ -1447,7 +1487,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testAppInitiatedCancelAllNotifications_CancelsOnGoingFlag() throws Exception {
final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
sbn.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testAppInitiatedCancelAllNotifications_CancelsOnGoingFlag",
sbn.getId(), sbn.getNotification(), sbn.getUserId());
mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
waitForIdle();
@@ -1564,7 +1605,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
new NotificationChannel("foo", "foo", IMPORTANCE_HIGH));
Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo");
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, "testTvExtenderChannelOverride_onTv", 0,
generateNotificationRecord(null, tv).getNotification(), 0);
verify(mPreferencesHelper, times(1)).getNotificationChannel(
anyString(), anyInt(), eq("foo"), anyBoolean());
@@ -1579,8 +1620,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mTestNotificationChannel);
Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo");
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0,
- generateNotificationRecord(null, tv).getNotification(), 0);
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, "testTvExtenderChannelOverride_notOnTv",
+ 0, generateNotificationRecord(null, tv).getNotification(), 0);
verify(mPreferencesHelper, times(1)).getNotificationChannel(
anyString(), anyInt(), eq(mTestNotificationChannel.getId()), anyBoolean());
}
@@ -2220,7 +2261,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final NotificationRecord child = generateNotificationRecord(
mTestNotificationChannel, 2, "group", false);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, "testPostNonGroup_noUnsnoozing",
child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
waitForIdle();
@@ -2233,7 +2274,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final NotificationRecord record = generateNotificationRecord(
mTestNotificationChannel, 2, null, false);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, "testPostNonGroup_noUnsnoozing",
record.sbn.getId(), record.sbn.getNotification(), record.sbn.getUserId());
waitForIdle();
@@ -2245,7 +2286,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final NotificationRecord parent = generateNotificationRecord(
mTestNotificationChannel, 2, "group", true);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, "testPostGroupSummary_noUnsnoozing",
parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
waitForIdle();
@@ -2659,31 +2700,37 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
.setColorized(true)
.setFlag(Notification.FLAG_CAN_COLORIZE, true)
.setSmallIcon(android.R.drawable.sym_def_app_icon);
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+ "testNoFakeColorizedPermission", mUid, 0,
nb.build(), new UserHandle(mUid), null, 0);
NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
NotificationRecord posted = mService.findNotificationLocked(
- PKG, null, nr.sbn.getId(), nr.sbn.getUserId());
+ PKG, nr.sbn.getTag(), nr.sbn.getId(), nr.sbn.getUserId());
assertFalse(posted.getNotification().isColorized());
}
@Test
- public void testGetNotificationCountLocked() throws Exception {
+ public void testGetNotificationCountLocked() {
+ String sampleTagToExclude = null;
+ int sampleIdToExclude = 0;
for (int i = 0; i < 20; i++) {
NotificationRecord r =
generateNotificationRecord(mTestNotificationChannel, i, null, false);
mService.addEnqueuedNotification(r);
+
}
for (int i = 0; i < 20; i++) {
NotificationRecord r =
generateNotificationRecord(mTestNotificationChannel, i, null, false);
mService.addNotification(r);
+ sampleTagToExclude = r.sbn.getTag();
+ sampleIdToExclude = i;
}
// another package
@@ -2700,55 +2747,49 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mService.addNotification(otherPackage);
// Same notifications are enqueued as posted, everything counts b/c id and tag don't match
+ // anything that's currently enqueued or posted
int userId = new UserHandle(mUid).getIdentifier();
assertEquals(40,
mService.getNotificationCountLocked(PKG, userId, 0, null));
assertEquals(40,
mService.getNotificationCountLocked(PKG, userId, 0, "tag2"));
+
+ // return all for package "a" - "banana" tag isn't used
assertEquals(2,
mService.getNotificationCountLocked("a", userId, 0, "banana"));
// exclude a known notification - it's excluded from only the posted list, not enqueued
- assertEquals(39,
- mService.getNotificationCountLocked(PKG, userId, 0, "tag"));
+ assertEquals(39, mService.getNotificationCountLocked(
+ PKG, userId, sampleIdToExclude, sampleTagToExclude));
}
@Test
public void testAddAutogroup_requestsSort() throws Exception {
- RankingHandler rh = mock(RankingHandler.class);
- mService.setRankingHandler(rh);
-
final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
mService.addNotification(r);
mService.addAutogroupKeyLocked(r.getKey());
- verify(rh, times(1)).requestSort();
+ verify(mRankingHandler, times(1)).requestSort();
}
@Test
public void testRemoveAutogroup_requestsSort() throws Exception {
- RankingHandler rh = mock(RankingHandler.class);
- mService.setRankingHandler(rh);
-
final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
r.setOverrideGroupKey("TEST");
mService.addNotification(r);
mService.removeAutogroupKeyLocked(r.getKey());
- verify(rh, times(1)).requestSort();
+ verify(mRankingHandler, times(1)).requestSort();
}
@Test
public void testReaddAutogroup_noSort() throws Exception {
- RankingHandler rh = mock(RankingHandler.class);
- mService.setRankingHandler(rh);
-
final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
r.setOverrideGroupKey("TEST");
mService.addNotification(r);
mService.addAutogroupKeyLocked(r.getKey());
- verify(rh, never()).requestSort();
+ verify(mRankingHandler, never()).requestSort();
}
@Test
@@ -2922,7 +2963,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
.setFlag(FLAG_FOREGROUND_SERVICE, true)
.setPriority(Notification.PRIORITY_MIN);
- StatusBarNotification sbn = new StatusBarNotification(preOPkg, preOPkg, 9, "tag",
+ StatusBarNotification sbn = new StatusBarNotification(preOPkg, preOPkg, 9,
+ "testBumpFGImportance_noChannelChangePreOApp",
Binder.getCallingUid(), 0, nb.build(), new UserHandle(Binder.getCallingUid()), null, 0);
mBinderService.enqueueNotificationWithTag(sbn.getPackageName(), sbn.getOpPkg(),
@@ -2938,10 +2980,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
.setFlag(FLAG_FOREGROUND_SERVICE, true)
.setPriority(Notification.PRIORITY_MIN);
- sbn = new StatusBarNotification(preOPkg, preOPkg, 9, "tag", Binder.getCallingUid(),
+ sbn = new StatusBarNotification(preOPkg, preOPkg, 9,
+ "testBumpFGImportance_noChannelChangePreOApp", Binder.getCallingUid(),
0, nb.build(), new UserHandle(Binder.getCallingUid()), null, 0);
- mBinderService.enqueueNotificationWithTag(preOPkg, preOPkg, "tag",
+ mBinderService.enqueueNotificationWithTag(preOPkg, preOPkg,
+ "testBumpFGImportance_noChannelChangePreOApp",
sbn.getId(), sbn.getNotification(), sbn.getUserId());
waitForIdle();
assertEquals(IMPORTANCE_LOW,
@@ -3154,9 +3198,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testUserSentimentChangeTriggersUpdate() throws Exception {
final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
mService.addNotification(r);
- NotificationManagerService.WorkerHandler handler = mock(
- NotificationManagerService.WorkerHandler.class);
- mService.setHandler(handler);
when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
Bundle signals = new Bundle();
@@ -3168,16 +3209,13 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
waitForIdle();
- verify(handler, timeout(300).times(1)).scheduleSendRankingUpdate();
+ verify(mRankingHandler, timeout(300).times(1)).requestSort();
}
@Test
public void testTooLateAdjustmentTriggersUpdate() throws Exception {
final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
mService.addNotification(r);
- NotificationManagerService.WorkerHandler handler = mock(
- NotificationManagerService.WorkerHandler.class);
- mService.setHandler(handler);
when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
Bundle signals = new Bundle();
@@ -3189,16 +3227,13 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
waitForIdle();
- verify(handler, timeout(300).times(1)).scheduleSendRankingUpdate();
+ verify(mRankingHandler, times(1)).requestSort();
}
@Test
public void testEnqueuedAdjustmentAppliesAdjustments() throws Exception {
final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
mService.addEnqueuedNotification(r);
- NotificationManagerService.WorkerHandler handler = mock(
- NotificationManagerService.WorkerHandler.class);
- mService.setHandler(handler);
when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
Bundle signals = new Bundle();
@@ -3208,8 +3243,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
- assertEquals(USER_SENTIMENT_NEGATIVE,
- r.getUserSentiment());
+ assertEquals(USER_SENTIMENT_NEGATIVE, r.getUserSentiment());
}
@Test
@@ -4099,7 +4133,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
try {
- mInternalService.enqueueNotification(notReal, "android", 0, 0, "tag",
+ mInternalService.enqueueNotification(notReal, "android", 0, 0,
+ "testPostFromAndroidForNonExistentPackage",
sbn.getId(), sbn.getNotification(), sbn.getUserId());
fail("can't post notifications for nonexistent packages, even if you exist");
} catch (SecurityException e) {
@@ -4373,7 +4408,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
mService.addNotification(r);
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, r.sbn.getId(),
+ r.sbn.getTag(), mUid, 0,
new Notification.Builder(mContext, mTestNotificationChannel.getId()).build(),
new UserHandle(mUid), null, 0);
NotificationRecord update = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
@@ -4502,7 +4538,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
when(mActivityManager.getPackageImportance(nr.sbn.getPackageName())).thenReturn(
IMPORTANCE_FOREGROUND);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
@@ -4526,7 +4562,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
when(mActivityManager.getPackageImportance(nr.sbn.getPackageName())).thenReturn(
IMPORTANCE_FOREGROUND);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
@@ -4550,8 +4586,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
when(mActivityManager.getPackageImportance(nr.sbn.getPackageName())).thenReturn(
IMPORTANCE_FOREGROUND);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
- nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ nr.sbn.getTag(), nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
// yes allowed, yes foreground, yes bubble
@@ -4572,7 +4608,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
when(mActivityManager.getPackageImportance(nr.sbn.getPackageName())).thenReturn(
IMPORTANCE_VISIBLE);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
@@ -4593,7 +4629,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// Send notif when we're foreground
when(mActivityManager.getPackageImportance(nr1.sbn.getPackageName())).thenReturn(
IMPORTANCE_FOREGROUND);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nr1.sbn.getTag(),
nr1.sbn.getId(), nr1.sbn.getNotification(), nr1.sbn.getUserId());
waitForIdle();
@@ -4607,7 +4643,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
when(mActivityManager.getPackageImportance(nr2.sbn.getPackageName())).thenReturn(
IMPORTANCE_VISIBLE);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nr2.sbn.getTag(),
nr2.sbn.getId(), nr2.sbn.getNotification(), nr2.sbn.getUserId());
waitForIdle();
@@ -4633,7 +4669,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// Send notif when we're foreground
when(mActivityManager.getPackageImportance(nr1.sbn.getPackageName())).thenReturn(
IMPORTANCE_FOREGROUND);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nr1.sbn.getTag(),
nr1.sbn.getId(), nr1.sbn.getNotification(), nr1.sbn.getUserId());
waitForIdle();
@@ -4642,7 +4678,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
nr1.sbn.getKey()).getNotification().isBubbleNotification());
// Remove the bubble
- mBinderService.cancelNotificationWithTag(PKG, PKG, "tag", nr1.sbn.getId(),
+ mBinderService.cancelNotificationWithTag(PKG, PKG, nr1.sbn.getTag(), nr1.sbn.getId(),
nr1.sbn.getUserId());
waitForIdle();
@@ -4656,7 +4692,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
when(mActivityManager.getPackageImportance(nr2.sbn.getPackageName())).thenReturn(
IMPORTANCE_VISIBLE);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nr2.sbn.getTag(),
nr2.sbn.getId(), nr2.sbn.getNotification(), nr2.sbn.getUserId());
waitForIdle();
@@ -4702,11 +4738,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
.setActions(replyAction)
.setSmallIcon(android.R.drawable.sym_def_app_icon);
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0,
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+ "testFlagBubbleNotifs_flag_messaging", mUid, 0,
nb.build(), new UserHandle(mUid), null, 0);
NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
@@ -4735,13 +4772,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
.setBubbleMetadata(data)
.setSmallIcon(android.R.drawable.sym_def_app_icon);
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0,
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+ "testFlagBubbleNotifs_flag_phonecall", mUid, 0,
nb.build(), new UserHandle(mUid), null, 0);
// Make sure it has foreground service
sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
@@ -4774,7 +4812,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
nb.build(), new UserHandle(mUid), null, 0);
NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
@@ -4798,13 +4836,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
.setBubbleMetadata(data)
.setSmallIcon(android.R.drawable.sym_def_app_icon);
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0,
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+ "testFlagBubbleNotifs_noFlag_phonecall_noPerson", mUid, 0,
nb.build(), new UserHandle(mUid), null, 0);
// Make sure it has foreground service
sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
@@ -4832,13 +4871,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
.setBubbleMetadata(data)
.setSmallIcon(android.R.drawable.sym_def_app_icon);
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0,
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+ "testFlagBubbleNotifs_noFlag_phonecall_noCategory", mUid, 0,
nb.build(), new UserHandle(mUid), null, 0);
// Make sure it has foreground service
sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
@@ -4872,12 +4912,13 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
)
.setSmallIcon(android.R.drawable.sym_def_app_icon);
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0,
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+ "testFlagBubbleNotifs_noFlag_messaging_appNotAllowed", mUid, 0,
nb.build(), new UserHandle(mUid), null, 0);
NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
// Post the notification
- mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
@@ -4895,7 +4936,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel);
// Post the notification
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
@@ -4929,12 +4970,13 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
)
.setSmallIcon(android.R.drawable.sym_def_app_icon);
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0,
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+ "testFlagBubbleNotifs_noFlag_messaging_channelNotAllowed", mUid, 0,
nb.build(), new UserHandle(mUid), null, 0);
NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
// Post the notification
- mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
@@ -4963,13 +5005,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
.setBubbleMetadata(data)
.setSmallIcon(android.R.drawable.sym_def_app_icon);
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0,
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+ "testFlagBubbleNotifs_noFlag_phonecall_notAllowed", mUid, 0,
nb.build(), new UserHandle(mUid), null, 0);
// Make sure it has foreground service
sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
@@ -4998,13 +5041,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
.setBubbleMetadata(data)
.setSmallIcon(android.R.drawable.sym_def_app_icon);
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0,
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+ "testFlagBubbleNotifs_noFlag_phonecall_channelNotAllowed", mUid, 0,
nb.build(), new UserHandle(mUid), null, 0);
// Make sure it has foreground service
sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
@@ -5033,7 +5077,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
nrBubble.sbn.getNotification().flags |= FLAG_BUBBLE;
// Post the notification
- mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testAppCancelNotifications_cancelsBubbles",
nrBubble.sbn.getId(), nrBubble.sbn.getNotification(), nrBubble.sbn.getUserId());
waitForIdle();
@@ -5041,7 +5086,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
assertEquals(1, notifs.length);
assertEquals(1, mService.getNotificationRecordCount());
- mBinderService.cancelNotificationWithTag(PKG, PKG, null, nrBubble.sbn.getId(),
+ mBinderService.cancelNotificationWithTag(PKG, PKG,
+ "testAppCancelNotifications_cancelsBubbles", nrBubble.sbn.getId(),
nrBubble.sbn.getUserId());
waitForIdle();
@@ -5196,7 +5242,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
when(mActivityManager.getPackageImportance(nr.sbn.getPackageName())).thenReturn(
IMPORTANCE_FOREGROUND);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
@@ -5226,7 +5272,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// Plain notification that has bubble metadata
NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel,
null /* tvExtender */, true /* isBubble */);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
@@ -5260,7 +5306,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// Notif that is not a bubble
NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel,
null /* tvExtender */, true /* isBubble */);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
@@ -5290,7 +5336,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// Plain notification that has bubble metadata
NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel,
null /* tvExtender */, true /* isBubble */);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.sbn.getTag(),
nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
index f37ff1177fe9..7f9f489c509a 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
@@ -129,7 +129,7 @@ public class RoleObserverTest extends UiServiceTestCase {
mRoleObserver = mService.new RoleObserver(mRoleManager, mPm, mExecutor);
try {
- mService.init(mock(Looper.class),
+ mService.init(mock(Looper.class), mock(RankingHandler.class),
mock(IPackageManager.class), mock(PackageManager.class),
mock(LightsManager.class),
mock(NotificationListeners.class), mock(NotificationAssistants.class),
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index d2af18e5f10b..34cc0c742005 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -147,8 +147,8 @@ public class ActivityStarterTests extends ActivityTestsBase {
assertThat((Object) task2.getStack()).isInstanceOf(ActivityStack.class);
mStarter.updateBounds(task2, bounds);
- verify(mService, times(1)).resizeStack(eq(task2.getStack().mStackId),
- eq(bounds), anyBoolean(), anyBoolean(), anyBoolean(), anyInt());
+ verify(mService, times(1)).animateResizePinnedStack(eq(task2.getStack().mStackId),
+ eq(bounds), anyInt());
// In the case of no animation, the stack and task bounds should be set immediately.
if (!ANIMATE) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index fb4e330f06ed..55011fb0aa04 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -1031,7 +1031,7 @@ public class RecentTasksTest extends ActivityTestsBase {
assertSecurityException(expectCallable,
() -> mService.moveTopActivityToPinnedStack(INVALID_STACK_ID, new Rect()));
assertSecurityException(expectCallable,
- () -> mService.resizeStack(INVALID_STACK_ID, new Rect(), true, true, true, 0));
+ () -> mService.animateResizePinnedStack(INVALID_STACK_ID, new Rect(), -1));
assertSecurityException(expectCallable,
() -> mService.resizeDockedStack(new Rect(), new Rect(), new Rect(), new Rect(),
new Rect()));
@@ -1289,10 +1289,10 @@ public class RecentTasksTest extends ActivityTestsBase {
@Override
void getTasks(int maxNum, List<RunningTaskInfo> list, int ignoreActivityType,
int ignoreWindowingMode, ArrayList<ActivityDisplay> activityDisplays,
- int callingUid, boolean allowed) {
+ int callingUid, boolean allowed, boolean crossUser) {
mLastAllowed = allowed;
super.getTasks(maxNum, list, ignoreActivityType, ignoreWindowingMode, activityDisplays,
- callingUid, allowed);
+ callingUid, allowed, crossUser);
}
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
index dc964806b7a9..cdd4c2424421 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
@@ -77,7 +77,7 @@ public class RunningTasksTest extends ActivityTestsBase {
final int numFetchTasks = 5;
ArrayList<RunningTaskInfo> tasks = new ArrayList<>();
mRunningTasks.getTasks(5, tasks, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED,
- displays, -1 /* callingUid */, true /* allowed */);
+ displays, -1 /* callingUid */, true /* allowed */, true /*crossUser */);
assertThat(tasks).hasSize(numFetchTasks);
for (int i = 0; i < numFetchTasks; i++) {
assertEquals(numTasks - i - 1, tasks.get(i).id);
@@ -87,7 +87,7 @@ public class RunningTasksTest extends ActivityTestsBase {
// and does not crash
tasks.clear();
mRunningTasks.getTasks(100, tasks, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED,
- displays, -1 /* callingUid */, true /* allowed */);
+ displays, -1 /* callingUid */, true /* allowed */, true /* crossUser */);
assertThat(tasks).hasSize(numTasks);
for (int i = 0; i < numTasks; i++) {
assertEquals(numTasks - i - 1, tasks.get(i).id);
diff --git a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
index 83dd69a24295..8d2a79b6b5db 100644
--- a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
+++ b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
@@ -185,11 +185,6 @@ public class StubTransaction extends SurfaceControl.Transaction {
}
@Override
- public SurfaceControl.Transaction setGeometryAppliesWithResize(SurfaceControl sc) {
- return this;
- }
-
- @Override
public SurfaceControl.Transaction setSecure(SurfaceControl sc, boolean isSecure) {
return this;
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index fc464a1f4393..090623e2f767 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -121,7 +121,7 @@ public class UsageStatsService extends SystemService implements
private static final long TEN_SECONDS = 10 * 1000;
private static final long TWENTY_MINUTES = 20 * 60 * 1000;
private static final long FLUSH_INTERVAL = COMPRESS_TIME ? TEN_SECONDS : TWENTY_MINUTES;
- private static final long TIME_CHANGE_THRESHOLD_MILLIS = 2 * 1000; // Two seconds.
+ static final long TIME_CHANGE_THRESHOLD_MILLIS = 2 * 1000; // Two seconds.
private static final boolean ENABLE_KERNEL_UPDATES = true;
private static final File KERNEL_COUNTER_FILE = new File("/proc/uid_procstat/set");
@@ -156,8 +156,6 @@ public class UsageStatsService extends SystemService implements
private final SparseArray<UserUsageStatsService> mUserState = new SparseArray<>();
private final SparseBooleanArray mUserUnlockedStates = new SparseBooleanArray();
private final SparseIntArray mUidToKernelCounter = new SparseIntArray();
- long mRealTimeSnapshot;
- long mSystemTimeSnapshot;
int mUsageSource;
/** Manages the standby state of apps. */
@@ -253,9 +251,6 @@ public class UsageStatsService extends SystemService implements
getContext().registerReceiverAsUser(new UserActionsReceiver(), UserHandle.ALL, filter,
null, mHandler);
- mRealTimeSnapshot = SystemClock.elapsedRealtime();
- mSystemTimeSnapshot = System.currentTimeMillis();
-
publishLocalService(UsageStatsManagerInternal.class, new LocalService());
publishBinderService(Context.USAGE_STATS_SERVICE, new BinderService());
}
@@ -345,7 +340,7 @@ public class UsageStatsService extends SystemService implements
mUserUnlockedStates.put(userId, true);
final UserUsageStatsService userService = getUserDataAndInitializeIfNeededLocked(
userId, System.currentTimeMillis());
- userService.userUnlocked(checkAndGetTimeLocked());
+ userService.userUnlocked(System.currentTimeMillis());
// Process all the pending reported events
while (pendingEvents.peek() != null) {
reportEvent(pendingEvents.poll(), userId);
@@ -569,37 +564,6 @@ public class UsageStatsService extends SystemService implements
}
/**
- * This should be the only way to get the time from the system.
- */
- private long checkAndGetTimeLocked() {
- final long actualSystemTime = System.currentTimeMillis();
- final long actualRealtime = SystemClock.elapsedRealtime();
- final long expectedSystemTime = (actualRealtime - mRealTimeSnapshot) + mSystemTimeSnapshot;
- final long diffSystemTime = actualSystemTime - expectedSystemTime;
- if (Math.abs(diffSystemTime) > TIME_CHANGE_THRESHOLD_MILLIS
- && ENABLE_TIME_CHANGE_CORRECTION) {
- // The time has changed.
- Slog.i(TAG, "Time changed in UsageStats by " + (diffSystemTime / 1000) + " seconds");
- final int userCount = mUserState.size();
- for (int i = 0; i < userCount; i++) {
- final UserUsageStatsService service = mUserState.valueAt(i);
- service.onTimeChanged(expectedSystemTime, actualSystemTime);
- }
- mRealTimeSnapshot = actualRealtime;
- mSystemTimeSnapshot = actualSystemTime;
- }
- return actualSystemTime;
- }
-
- /**
- * Assuming the event's timestamp is measured in milliseconds since boot,
- * convert it to a system wall time.
- */
- private void convertToSystemTimeLocked(Event event) {
- event.mTimeStamp = Math.max(0, event.mTimeStamp - mRealTimeSnapshot) + mSystemTimeSnapshot;
- }
-
- /**
* Called by the Binder stub
*/
void shutdown() {
@@ -718,9 +682,8 @@ public class UsageStatsService extends SystemService implements
return;
}
- final long timeNow = checkAndGetTimeLocked();
+ final long timeNow = System.currentTimeMillis();
final long elapsedRealtime = SystemClock.elapsedRealtime();
- convertToSystemTimeLocked(event);
if (event.mPackage != null
&& mPackageManagerInternal.isPackageEphemeral(userId, event.mPackage)) {
@@ -876,13 +839,8 @@ public class UsageStatsService extends SystemService implements
return null;
}
- final long timeNow = checkAndGetTimeLocked();
- if (!validRange(timeNow, beginTime, endTime)) {
- return null;
- }
-
final UserUsageStatsService service =
- getUserDataAndInitializeIfNeededLocked(userId, timeNow);
+ getUserDataAndInitializeIfNeededLocked(userId, System.currentTimeMillis());
List<UsageStats> list = service.queryUsageStats(bucketType, beginTime, endTime);
if (list == null) {
return null;
@@ -913,13 +871,8 @@ public class UsageStatsService extends SystemService implements
return null;
}
- final long timeNow = checkAndGetTimeLocked();
- if (!validRange(timeNow, beginTime, endTime)) {
- return null;
- }
-
final UserUsageStatsService service =
- getUserDataAndInitializeIfNeededLocked(userId, timeNow);
+ getUserDataAndInitializeIfNeededLocked(userId, System.currentTimeMillis());
return service.queryConfigurationStats(bucketType, beginTime, endTime);
}
}
@@ -935,13 +888,8 @@ public class UsageStatsService extends SystemService implements
return null;
}
- final long timeNow = checkAndGetTimeLocked();
- if (!validRange(timeNow, beginTime, endTime)) {
- return null;
- }
-
final UserUsageStatsService service =
- getUserDataAndInitializeIfNeededLocked(userId, timeNow);
+ getUserDataAndInitializeIfNeededLocked(userId, System.currentTimeMillis());
return service.queryEventStats(bucketType, beginTime, endTime);
}
}
@@ -957,13 +905,8 @@ public class UsageStatsService extends SystemService implements
return null;
}
- final long timeNow = checkAndGetTimeLocked();
- if (!validRange(timeNow, beginTime, endTime)) {
- return null;
- }
-
final UserUsageStatsService service =
- getUserDataAndInitializeIfNeededLocked(userId, timeNow);
+ getUserDataAndInitializeIfNeededLocked(userId, System.currentTimeMillis());
return service.queryEvents(beginTime, endTime, shouldObfuscateInstantApps);
}
}
@@ -979,21 +922,12 @@ public class UsageStatsService extends SystemService implements
return null;
}
- final long timeNow = checkAndGetTimeLocked();
- if (!validRange(timeNow, beginTime, endTime)) {
- return null;
- }
-
final UserUsageStatsService service =
- getUserDataAndInitializeIfNeededLocked(userId, timeNow);
+ getUserDataAndInitializeIfNeededLocked(userId, System.currentTimeMillis());
return service.queryEventsForPackage(beginTime, endTime, packageName, includeTaskRoot);
}
}
- private static boolean validRange(long currentTime, long beginTime, long endTime) {
- return beginTime <= currentTime && beginTime < endTime;
- }
-
private String buildFullToken(String packageName, String token) {
final StringBuilder sb = new StringBuilder(packageName.length() + token.length() + 1);
sb.append(packageName);
@@ -2050,8 +1984,8 @@ public class UsageStatsService extends SystemService implements
// Check to ensure that only user 0's data is b/r for now
if (user == UserHandle.USER_SYSTEM) {
- final UserUsageStatsService userStats =
- getUserDataAndInitializeIfNeededLocked(user, checkAndGetTimeLocked());
+ final UserUsageStatsService userStats = getUserDataAndInitializeIfNeededLocked(
+ user, System.currentTimeMillis());
return userStats.getBackupPayload(key);
} else {
return null;
@@ -2068,8 +2002,8 @@ public class UsageStatsService extends SystemService implements
}
if (user == UserHandle.USER_SYSTEM) {
- final UserUsageStatsService userStats =
- getUserDataAndInitializeIfNeededLocked(user, checkAndGetTimeLocked());
+ final UserUsageStatsService userStats = getUserDataAndInitializeIfNeededLocked(
+ user, System.currentTimeMillis());
userStats.applyRestoredPayload(key, payload);
}
}
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index 6fbd88227f9b..1560b9e708e3 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -76,6 +76,8 @@ class UserUsageStatsService {
private final String mLogPrefix;
private String mLastBackgroundedPackage;
private final int mUserId;
+ private long mRealTimeSnapshot;
+ private long mSystemTimeSnapshot;
private static final long[] INTERVAL_LENGTH = new long[] {
UnixCalendar.DAY_IN_MILLIS, UnixCalendar.WEEK_IN_MILLIS,
@@ -101,6 +103,8 @@ class UserUsageStatsService {
mListener = listener;
mLogPrefix = "User[" + Integer.toString(userId) + "] ";
mUserId = userId;
+ mRealTimeSnapshot = SystemClock.elapsedRealtime();
+ mSystemTimeSnapshot = System.currentTimeMillis();
}
void init(final long currentTimeMillis) {
@@ -165,12 +169,41 @@ class UserUsageStatsService {
persistActiveStats();
}
- void onTimeChanged(long oldTime, long newTime) {
+ private void onTimeChanged(long oldTime, long newTime) {
persistActiveStats();
mDatabase.onTimeChanged(newTime - oldTime);
loadActiveStats(newTime);
}
+ /**
+ * This should be the only way to get the time from the system.
+ */
+ private long checkAndGetTimeLocked() {
+ final long actualSystemTime = System.currentTimeMillis();
+ if (!UsageStatsService.ENABLE_TIME_CHANGE_CORRECTION) {
+ return actualSystemTime;
+ }
+ final long actualRealtime = SystemClock.elapsedRealtime();
+ final long expectedSystemTime = (actualRealtime - mRealTimeSnapshot) + mSystemTimeSnapshot;
+ final long diffSystemTime = actualSystemTime - expectedSystemTime;
+ if (Math.abs(diffSystemTime) > UsageStatsService.TIME_CHANGE_THRESHOLD_MILLIS) {
+ // The time has changed.
+ Slog.i(TAG, mLogPrefix + "Time changed in by " + (diffSystemTime / 1000) + " seconds");
+ onTimeChanged(expectedSystemTime, actualSystemTime);
+ mRealTimeSnapshot = actualRealtime;
+ mSystemTimeSnapshot = actualSystemTime;
+ }
+ return actualSystemTime;
+ }
+
+ /**
+ * Assuming the event's timestamp is measured in milliseconds since boot,
+ * convert it to a system wall time.
+ */
+ private void convertToSystemTimeLocked(Event event) {
+ event.mTimeStamp = Math.max(0, event.mTimeStamp - mRealTimeSnapshot) + mSystemTimeSnapshot;
+ }
+
void reportEvent(Event event) {
if (DEBUG) {
Slog.d(TAG, mLogPrefix + "Got usage event for " + event.mPackage
@@ -178,6 +211,9 @@ class UserUsageStatsService {
+ eventToString(event.mEventType));
}
+ checkAndGetTimeLocked();
+ convertToSystemTimeLocked(event);
+
if (event.mTimeStamp >= mDailyExpiryDate.getTimeInMillis()) {
// Need to rollover
rolloverStats(event.mTimeStamp);
@@ -298,6 +334,10 @@ class UserUsageStatsService {
}
};
+ private static boolean validRange(long currentTime, long beginTime, long endTime) {
+ return beginTime <= currentTime && beginTime < endTime;
+ }
+
/**
* Generic query method that selects the appropriate IntervalStats for the specified time range
* and bucket, then calls the {@link com.android.server.usage.UsageStatsDatabase.StatCombiner}
@@ -370,19 +410,31 @@ class UserUsageStatsService {
}
List<UsageStats> queryUsageStats(int bucketType, long beginTime, long endTime) {
+ if (!validRange(checkAndGetTimeLocked(), beginTime, endTime)) {
+ return null;
+ }
return queryStats(bucketType, beginTime, endTime, sUsageStatsCombiner);
}
List<ConfigurationStats> queryConfigurationStats(int bucketType, long beginTime, long endTime) {
+ if (!validRange(checkAndGetTimeLocked(), beginTime, endTime)) {
+ return null;
+ }
return queryStats(bucketType, beginTime, endTime, sConfigStatsCombiner);
}
List<EventStats> queryEventStats(int bucketType, long beginTime, long endTime) {
+ if (!validRange(checkAndGetTimeLocked(), beginTime, endTime)) {
+ return null;
+ }
return queryStats(bucketType, beginTime, endTime, sEventStatsCombiner);
}
UsageEvents queryEvents(final long beginTime, final long endTime,
boolean obfuscateInstantApps) {
+ if (!validRange(checkAndGetTimeLocked(), beginTime, endTime)) {
+ return null;
+ }
final ArraySet<String> names = new ArraySet<>();
List<Event> results = queryStats(INTERVAL_DAILY,
beginTime, endTime, new StatCombiner<Event>() {
@@ -428,6 +480,9 @@ class UserUsageStatsService {
UsageEvents queryEventsForPackage(final long beginTime, final long endTime,
final String packageName, boolean includeTaskRoot) {
+ if (!validRange(checkAndGetTimeLocked(), beginTime, endTime)) {
+ return null;
+ }
final ArraySet<String> names = new ArraySet<>();
names.add(packageName);
final List<Event> results = queryStats(INTERVAL_DAILY,
@@ -1030,10 +1085,12 @@ class UserUsageStatsService {
}
byte[] getBackupPayload(String key){
+ checkAndGetTimeLocked();
return mDatabase.getBackupPayload(key);
}
void applyRestoredPayload(String key, byte[] payload){
+ checkAndGetTimeLocked();
mDatabase.applyRestoredPayload(key, payload);
}
}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java
index de2dd101acfd..3f2d8c8ef47c 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java
@@ -41,6 +41,8 @@ public final class UsbConfigDescriptor extends UsbDescriptor {
// D4..0 Reserved, set to 0.
private int mMaxPower; // 8:1 Maximum Power Consumption in 2mA units
+ private boolean mBlockAudio; // leave it off for now. We be replace with a "Developer Option"
+
private ArrayList<UsbInterfaceDescriptor> mInterfaceDescriptors =
new ArrayList<UsbInterfaceDescriptor>();
@@ -77,21 +79,35 @@ public final class UsbConfigDescriptor extends UsbDescriptor {
mInterfaceDescriptors.add(interfaceDesc);
}
+ private boolean isAudioInterface(UsbInterfaceDescriptor descriptor) {
+ return descriptor.getUsbClass() == UsbDescriptor.CLASSID_AUDIO
+ && descriptor.getUsbSubclass() == UsbDescriptor.AUDIO_AUDIOSTREAMING;
+ }
+
UsbConfiguration toAndroid(UsbDescriptorParser parser) {
if (UsbDescriptorParser.DEBUG) {
Log.d(TAG, " toAndroid()");
}
+
+ // NOTE - This code running in the server process.
+ //TODO (pmclean@) - remove this
+// int pid = android.os.Process.myPid();
+// int uid = android.os.Process.myUid();
+// Log.d(TAG, " ---- pid:" + pid + " uid:" + uid);
+
String name = parser.getDescriptorString(mConfigIndex);
UsbConfiguration config = new
UsbConfiguration(mConfigValue, name, mAttribs, mMaxPower);
- UsbInterface[] interfaces = new UsbInterface[mInterfaceDescriptors.size()];
- if (UsbDescriptorParser.DEBUG) {
- Log.d(TAG, " " + mInterfaceDescriptors.size() + " interfaces.");
- }
- for (int index = 0; index < mInterfaceDescriptors.size(); index++) {
- interfaces[index] = mInterfaceDescriptors.get(index).toAndroid(parser);
+
+ ArrayList<UsbInterface> filteredInterfaces = new ArrayList<UsbInterface>();
+ for (UsbInterfaceDescriptor descriptor : mInterfaceDescriptors) {
+ if (!mBlockAudio || !isAudioInterface(descriptor)) {
+ filteredInterfaces.add(descriptor.toAndroid(parser));
+ }
}
- config.setInterfaces(interfaces);
+ UsbInterface[] interfaceArray = new UsbInterface[0];
+ interfaceArray = filteredInterfaces.toArray(interfaceArray);
+ config.setInterfaces(interfaceArray);
return config;
}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
index 4f62d5a5c967..6ffbd43a7b1a 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
@@ -26,7 +26,7 @@ import java.util.ArrayList;
*/
public final class UsbDescriptorParser {
private static final String TAG = "UsbDescriptorParser";
- public static final boolean DEBUG = false;
+ public static final boolean DEBUG = true;
private final String mDeviceAddr;
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java
index 5eb0a2f75ded..4d0cfea98630 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java
@@ -31,7 +31,7 @@ public class UsbEndpointDescriptor extends UsbDescriptor {
public static final int MASK_ENDPOINT_ADDRESS = 0b000000000001111;
public static final int MASK_ENDPOINT_DIRECTION = (byte) 0b0000000010000000;
public static final int DIRECTION_OUTPUT = 0x0000;
- public static final int DIRECTION_INPUT = (byte) 0x0080;
+ public static final int DIRECTION_INPUT = 0x0080;
public static final int MASK_ATTRIBS_TRANSTYPE = 0b00000011;
public static final int TRANSTYPE_CONTROL = 0x00;
@@ -85,7 +85,7 @@ public class UsbEndpointDescriptor extends UsbDescriptor {
}
public int getEndpointAddress() {
- return mEndpointAddress;
+ return mEndpointAddress & MASK_ENDPOINT_ADDRESS;
}
public int getAttributes() {
@@ -108,6 +108,10 @@ public class UsbEndpointDescriptor extends UsbDescriptor {
return mSyncAddress;
}
+ public int getDirection() {
+ return mEndpointAddress & UsbEndpointDescriptor.MASK_ENDPOINT_DIRECTION;
+ }
+
/* package */ UsbEndpoint toAndroid(UsbDescriptorParser parser) {
if (UsbDescriptorParser.DEBUG) {
Log.d(TAG, "toAndroid() type:"
@@ -137,11 +141,9 @@ public class UsbEndpointDescriptor extends UsbDescriptor {
canvas.openList();
- int address = getEndpointAddress();
canvas.writeListItem("Address: "
- + ReportCanvas.getHexString(address & UsbEndpointDescriptor.MASK_ENDPOINT_ADDRESS)
- + ((address & UsbEndpointDescriptor.MASK_ENDPOINT_DIRECTION)
- == UsbEndpointDescriptor.DIRECTION_OUTPUT ? " [out]" : " [in]"));
+ + ReportCanvas.getHexString(getEndpointAddress())
+ + (getDirection() == UsbEndpointDescriptor.DIRECTION_OUTPUT ? " [out]" : " [in]"));
int attributes = getAttributes();
canvas.openListItem();
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java
index 1dc6069bbb0a..64dbd971cc67 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java
@@ -31,7 +31,6 @@ import java.util.ArrayList;
*/
public class UsbInterfaceDescriptor extends UsbDescriptor {
private static final String TAG = "UsbInterfaceDescriptor";
-
protected int mInterfaceNumber; // 2:1 Number of Interface
protected byte mAlternateSetting; // 3:1 Value used to select alternative setting
protected byte mNumEndpoints; // 4:1 Number of Endpoints used for this interface
@@ -73,6 +72,19 @@ public class UsbInterfaceDescriptor extends UsbDescriptor {
return mNumEndpoints;
}
+ /**
+ * @param index Index of desired UsbEndpointDescriptor.
+ * @return the UsbEndpointDescriptor descriptor at the specified index, or
+ * null if an invalid index.
+ */
+ public UsbEndpointDescriptor getEndpointDescriptor(int index) {
+ if (index < 0 || index >= mEndpointDescriptors.size()) {
+ return null;
+ }
+
+ return mEndpointDescriptors.get(index);
+ }
+
public int getUsbClass() {
return mUsbClass;
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index f16dec6fb670..0ff92739f8b6 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -194,7 +194,7 @@ final class VoiceInteractionSessionConnection implements ServiceConnection,
if (!mFullyBound) {
mFullyBound = mContext.bindServiceAsUser(mBindIntent, mFullConnection,
Context.BIND_AUTO_CREATE | Context.BIND_TREAT_LIKE_ACTIVITY
- | Context.BIND_FOREGROUND_SERVICE
+ | Context.BIND_SCHEDULE_LIKE_TOP_APP
| Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS,
new UserHandle(mUser));
}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java b/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java
index 31bd34199784..902da4c0f72e 100644
--- a/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java
+++ b/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java
@@ -275,7 +275,8 @@ public class IorapForwardingService extends SystemService {
Log.e(TAG, "connectToRemoteAndConfigure - null iorap remote. check for Log.wtf?");
return false;
}
- invokeRemote( () -> mIorapRemote.setTaskListener(new RemoteTaskListener()) );
+ invokeRemote(mIorapRemote,
+ (IIorap remote) -> remote.setTaskListener(new RemoteTaskListener()) );
registerInProcessListenersLocked();
return true;
@@ -323,8 +324,9 @@ public class IorapForwardingService extends SystemService {
mSequenceId, intent));
}
- invokeRemote(() ->
- mIorapRemote.onAppLaunchEvent(RequestId.nextValueForSequence(),
+ invokeRemote(mIorapRemote,
+ (IIorap remote) ->
+ remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
new AppLaunchEvent.IntentStarted(mSequenceId, intent))
);
}
@@ -335,8 +337,9 @@ public class IorapForwardingService extends SystemService {
Log.v(TAG, String.format("AppLaunchObserver#onIntentFailed(%d)", mSequenceId));
}
- invokeRemote(() ->
- mIorapRemote.onAppLaunchEvent(RequestId.nextValueForSequence(),
+ invokeRemote(mIorapRemote,
+ (IIorap remote) ->
+ remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
new AppLaunchEvent.IntentFailed(mSequenceId))
);
}
@@ -349,8 +352,9 @@ public class IorapForwardingService extends SystemService {
mSequenceId, activity, temperature));
}
- invokeRemote(() ->
- mIorapRemote.onAppLaunchEvent(RequestId.nextValueForSequence(),
+ invokeRemote(mIorapRemote,
+ (IIorap remote) ->
+ remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
new AppLaunchEvent.ActivityLaunched(mSequenceId, activity, temperature))
);
}
@@ -362,8 +366,9 @@ public class IorapForwardingService extends SystemService {
mSequenceId, activity));
}
- invokeRemote(() ->
- mIorapRemote.onAppLaunchEvent(RequestId.nextValueForSequence(),
+ invokeRemote(mIorapRemote,
+ (IIorap remote) ->
+ remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
new AppLaunchEvent.ActivityLaunchCancelled(mSequenceId,
activity)));
}
@@ -375,8 +380,9 @@ public class IorapForwardingService extends SystemService {
mSequenceId, activity));
}
- invokeRemote(() ->
- mIorapRemote.onAppLaunchEvent(RequestId.nextValueForSequence(),
+ invokeRemote(mIorapRemote,
+ (IIorap remote) ->
+ remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
new AppLaunchEvent.ActivityLaunchFinished(mSequenceId, activity))
);
}
@@ -501,8 +507,8 @@ public class IorapForwardingService extends SystemService {
mRunningJobs.put(request, params);
}
- if (!invokeRemote( () ->
- mIorapRemote.onJobScheduledEvent(request,
+ if (!invokeRemote(mIorapRemote, (IIorap remote) ->
+ remote.onJobScheduledEvent(request,
JobScheduledEvent.createIdleMaintenance(
JobScheduledEvent.TYPE_START_JOB,
params))
@@ -539,8 +545,8 @@ public class IorapForwardingService extends SystemService {
// Notify iorapd to stop (abort) the job.
if (wasTracking) {
- invokeRemote(() ->
- mIorapRemote.onJobScheduledEvent(RequestId.nextValueForSequence(),
+ invokeRemote(mIorapRemote, (IIorap remote) ->
+ remote.onJobScheduledEvent(RequestId.nextValueForSequence(),
JobScheduledEvent.createIdleMaintenance(
JobScheduledEvent.TYPE_STOP_JOB,
params))
@@ -632,12 +638,17 @@ public class IorapForwardingService extends SystemService {
/** Allow passing lambdas to #invokeRemote */
private interface RemoteRunnable {
// TODO: run(RequestId) ?
- void run() throws RemoteException;
+ void run(IIorap iorap) throws RemoteException;
}
- private static boolean invokeRemote(RemoteRunnable r) {
+ // Always pass in the iorap directly here to avoid data race.
+ private static boolean invokeRemote(IIorap iorap, RemoteRunnable r) {
+ if (iorap == null) {
+ Log.w(TAG, "IIorap went to null in this thread, drop invokeRemote.");
+ return false;
+ }
try {
- r.run();
+ r.run(iorap);
return true;
} catch (RemoteException e) {
// This could be a logic error (remote side returning error), which we need to fix.
diff --git a/startop/view_compiler/dex_builder_test/Android.bp b/startop/view_compiler/dex_builder_test/Android.bp
index 1214538e8f0d..f783aa68fe92 100644
--- a/startop/view_compiler/dex_builder_test/Android.bp
+++ b/startop/view_compiler/dex_builder_test/Android.bp
@@ -37,15 +37,21 @@ genrule {
android_test {
name: "dex-builder-test",
srcs: [
+ "src/android/startop/test/ApkLayoutCompilerTest.java",
"src/android/startop/test/DexBuilderTest.java",
"src/android/startop/test/LayoutCompilerTest.java",
"src/android/startop/test/TestClass.java",
],
sdk_version: "current",
- data: [":generate_dex_testcases", ":generate_compiled_layout1", ":generate_compiled_layout2"],
+ data: [
+ ":generate_dex_testcases",
+ ":generate_compiled_layout1",
+ ":generate_compiled_layout2",
+ ],
static_libs: [
- "androidx.test.rules",
- "guava",
+ "androidx.test.core",
+ "androidx.test.runner",
+ "junit",
],
manifest: "AndroidManifest.xml",
resource_dirs: ["res"],
diff --git a/startop/view_compiler/dex_builder_test/src/android/startop/test/ApkLayoutCompilerTest.java b/startop/view_compiler/dex_builder_test/src/android/startop/test/ApkLayoutCompilerTest.java
new file mode 100644
index 000000000000..230e8df1e687
--- /dev/null
+++ b/startop/view_compiler/dex_builder_test/src/android/startop/test/ApkLayoutCompilerTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.startop.test;
+
+import android.content.Context;
+import androidx.test.InstrumentationRegistry;
+import android.view.View;
+import dalvik.system.PathClassLoader;
+import java.lang.reflect.Method;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class ApkLayoutCompilerTest {
+ static ClassLoader loadDexFile() throws Exception {
+ Context context = InstrumentationRegistry.getTargetContext();
+ return new PathClassLoader(context.getCodeCacheDir() + "/compiled_view.dex",
+ ClassLoader.getSystemClassLoader());
+ }
+
+ @BeforeClass
+ public static void setup() throws Exception {
+ // ensure PackageManager has compiled the layouts.
+ Process pm = Runtime.getRuntime().exec("pm compile --compile-layouts android.startop.test");
+ pm.waitFor();
+ }
+
+ @Test
+ public void loadAndInflateLayout1() throws Exception {
+ ClassLoader dex_file = loadDexFile();
+ Class compiled_view = dex_file.loadClass("android.startop.test.CompiledView");
+ Method layout1 = compiled_view.getMethod("layout1", Context.class, int.class);
+ Context context = InstrumentationRegistry.getTargetContext();
+ layout1.invoke(null, context, R.layout.layout1);
+ }
+
+ @Test
+ public void loadAndInflateLayout2() throws Exception {
+ ClassLoader dex_file = loadDexFile();
+ Class compiled_view = dex_file.loadClass("android.startop.test.CompiledView");
+ Method layout2 = compiled_view.getMethod("layout2", Context.class, int.class);
+ Context context = InstrumentationRegistry.getTargetContext();
+ layout2.invoke(null, context, R.layout.layout2);
+ }
+}
diff --git a/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java b/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
index d1fe58800bbf..6af01f6f3292 100644
--- a/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
+++ b/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
@@ -14,8 +14,11 @@
package android.startop.test;
+import android.content.Context;
+import androidx.test.InstrumentationRegistry;
import dalvik.system.PathClassLoader;
-
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import org.junit.Assert;
import org.junit.Test;
diff --git a/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java b/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java
index 3dfb20c2e524..b0cf91d5fb97 100644
--- a/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java
+++ b/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java
@@ -15,11 +15,11 @@
package android.startop.test;
import android.content.Context;
-
import androidx.test.InstrumentationRegistry;
-
+import android.view.View;
import dalvik.system.PathClassLoader;
-
+import java.lang.reflect.Method;
+import org.junit.Assert;
import org.junit.Test;
import java.lang.reflect.Method;
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index c1b8479a7f56..67b252e52db9 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -3962,6 +3962,13 @@ public final class Telephony {
public static final Uri CONTENT_URI = Uri.parse("content://cellbroadcasts");
/**
+ * The id of the subscription which received this cell broadcast message.
+ * <P>Type: INTEGER</P>
+ * @hide
+ */
+ public static final String SUB_ID = "sub_id";
+
+ /**
* Message geographical scope. Valid values are:
* <ul>
* <li>{@link android.telephony.SmsCbMessage#GEOGRAPHICAL_SCOPE_CELL_WIDE}. meaning the
@@ -4183,6 +4190,18 @@ public final class Telephony {
public static final String GEOMETRIES = "geometries";
/**
+ * Geo-Fencing Maximum Wait Time in second. The range of the time is [0, 255]. A device
+ * shall allow to determine its position meeting operator policy. If the device is unable to
+ * determine its position meeting operator policy within the GeoFencing Maximum Wait Time,
+ * it shall present the alert to the user and discontinue further positioning determination
+ * for the alert.
+ *
+ * <P>Type: INTEGER</P>
+ * @hide
+ */
+ public static final String MAXIMUM_WAIT_TIME = "maximum_wait_time";
+
+ /**
* Query columns for instantiating {@link android.telephony.CellBroadcastMessage} objects.
* @hide
*/
@@ -4235,7 +4254,8 @@ public final class Telephony {
CMAS_CERTAINTY,
RECEIVED_TIME,
MESSAGE_BROADCASTED,
- GEOMETRIES
+ GEOMETRIES,
+ MAXIMUM_WAIT_TIME
};
}
diff --git a/telephony/java/android/telephony/SmsCbMessage.java b/telephony/java/android/telephony/SmsCbMessage.java
index 77231d107c6a..c078764cfa24 100644
--- a/telephony/java/android/telephony/SmsCbMessage.java
+++ b/telephony/java/android/telephony/SmsCbMessage.java
@@ -139,6 +139,12 @@ public final class SmsCbMessage implements Parcelable {
@Retention(RetentionPolicy.SOURCE)
public @interface MessagePriority {}
+ /**
+ * ATIS-0700041 Section 5.2.8 WAC Geo-Fencing Maximum Wait Time Table 12.
+ * @hide
+ */
+ public static final int MAXIMUM_WAIT_TIME_NOT_SET = 255;
+
/** Format of this message (for interpretation of service category values). */
private final int mMessageFormat;
@@ -187,6 +193,14 @@ public final class SmsCbMessage implements Parcelable {
@Nullable
private final SmsCbCmasInfo mCmasWarningInfo;
+ /**
+ * Geo-Fencing Maximum Wait Time in second, a device shall allow to determine its position
+ * meeting operator policy. If the device is unable to determine its position meeting operator
+ * policy within the GeoFencing Maximum Wait Time, it shall present the alert to the user and
+ * discontinue further positioning determination for the alert.
+ */
+ private final int mMaximumWaitTimeSec;
+
/** UNIX timestamp of when the message was received. */
private final long mReceivedTimeMillis;
@@ -202,8 +216,8 @@ public final class SmsCbMessage implements Parcelable {
@Nullable SmsCbCmasInfo cmasWarningInfo) {
this(messageFormat, geographicalScope, serialNumber, location, serviceCategory, language,
- body, priority, etwsWarningInfo, cmasWarningInfo, null /* geometries */,
- System.currentTimeMillis());
+ body, priority, etwsWarningInfo, cmasWarningInfo, 0 /* maximumWaitingTime */,
+ null /* geometries */, System.currentTimeMillis());
}
/**
@@ -213,7 +227,7 @@ public final class SmsCbMessage implements Parcelable {
public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber,
SmsCbLocation location, int serviceCategory, String language, String body,
int priority, SmsCbEtwsInfo etwsWarningInfo, SmsCbCmasInfo cmasWarningInfo,
- List<Geometry> geometries, long receivedTimeMillis) {
+ int maximumWaitTimeSec, List<Geometry> geometries, long receivedTimeMillis) {
mMessageFormat = messageFormat;
mGeographicalScope = geographicalScope;
mSerialNumber = serialNumber;
@@ -226,6 +240,7 @@ public final class SmsCbMessage implements Parcelable {
mCmasWarningInfo = cmasWarningInfo;
mReceivedTimeMillis = receivedTimeMillis;
mGeometries = geometries;
+ mMaximumWaitTimeSec = maximumWaitTimeSec;
}
/**
@@ -262,6 +277,7 @@ public final class SmsCbMessage implements Parcelable {
mReceivedTimeMillis = in.readLong();
String geoStr = in.readString();
mGeometries = geoStr != null ? CbGeoUtils.parseGeometriesFromString(geoStr) : null;
+ mMaximumWaitTimeSec = in.readInt();
}
/**
@@ -295,6 +311,7 @@ public final class SmsCbMessage implements Parcelable {
dest.writeLong(mReceivedTimeMillis);
dest.writeString(
mGeometries != null ? CbGeoUtils.encodeGeometriesToString(mGeometries) : null);
+ dest.writeInt(mMaximumWaitTimeSec);
}
@NonNull
@@ -389,6 +406,15 @@ public final class SmsCbMessage implements Parcelable {
}
/**
+ * Get the Geo-Fencing Maximum Wait Time.
+ * @return the time in second.
+ * @hide
+ */
+ public int getMaximumWaitingTime() {
+ return mMaximumWaitTimeSec;
+ }
+
+ /**
* Get the time when this message was received.
* @return the time in millisecond
*/
@@ -475,6 +501,7 @@ public final class SmsCbMessage implements Parcelable {
+ ", priority=" + mPriority
+ (mEtwsWarningInfo != null ? (", " + mEtwsWarningInfo.toString()) : "")
+ (mCmasWarningInfo != null ? (", " + mCmasWarningInfo.toString()) : "")
+ + ", maximumWaitingTime = " + mMaximumWaitTimeSec
+ ", geo=" + (mGeometries != null
? CbGeoUtils.encodeGeometriesToString(mGeometries) : "null")
+ '}';
@@ -535,6 +562,8 @@ public final class SmsCbMessage implements Parcelable {
cv.put(CellBroadcasts.GEOMETRIES, (String) null);
}
+ cv.put(CellBroadcasts.MAXIMUM_WAIT_TIME, mMaximumWaitTimeSec);
+
return cv;
}
@@ -644,17 +673,21 @@ public final class SmsCbMessage implements Parcelable {
List<Geometry> geometries =
geoStr != null ? CbGeoUtils.parseGeometriesFromString(geoStr) : null;
- long receivedTimeSec = cursor.getLong(
+ long receivedTimeMillis = cursor.getLong(
cursor.getColumnIndexOrThrow(CellBroadcasts.RECEIVED_TIME));
+ int maximumWaitTimeSec = cursor.getInt(
+ cursor.getColumnIndexOrThrow(CellBroadcasts.MAXIMUM_WAIT_TIME));
+
return new SmsCbMessage(format, geoScope, serialNum, location, category,
- language, body, priority, etwsInfo, cmasInfo, geometries, receivedTimeSec);
+ language, body, priority, etwsInfo, cmasInfo, maximumWaitTimeSec, geometries,
+ receivedTimeMillis);
}
/**
* @return {@code True} if this message needs geo-fencing check.
*/
public boolean needGeoFencingCheck() {
- return mGeometries != null;
+ return mMaximumWaitTimeSec > 0 && mGeometries != null;
}
}
diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java
index 3a9979d78a55..356288047e15 100644
--- a/telephony/java/android/telephony/ims/feature/ImsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java
@@ -201,15 +201,20 @@ public abstract class ImsFeature {
}
/**
- * Contains the capabilities defined and supported by an ImsFeature in the form of a bit mask.
- * <p>
- * Typically this class is not used directly, but rather extended in subclasses of
+ * Contains the IMS capabilities defined and supported by an ImsFeature in the form of a
+ * bit-mask.
+ *
+ * @deprecated This class is not used directly, but rather extended in subclasses of
* {@link ImsFeature} to provide service specific capabilities.
+ * @see MmTelFeature.MmTelCapabilities
* @hide
*/
- @SystemApi
+ // Not Actually deprecated, but we need to remove it from the @SystemApi surface.
+ @Deprecated
+ @SystemApi // SystemApi only because it was leaked through type usage in a previous release.
public static class Capabilities {
/** @deprecated Use getters and accessors instead. */
+ // Not actually deprecated, but we need to remove it from the @SystemApi surface eventually.
protected int mCapabilities = 0;
/**
diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
index 20c191da0550..ceb470491dc5 100644
--- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
@@ -242,8 +242,8 @@ public class MmTelFeature extends ImsFeature {
* @param capabilities The capabilities that are supported for MmTel in the form of a
* bitfield.
*/
- public MmTelCapabilities(int capabilities) {
- mCapabilities = capabilities;
+ public MmTelCapabilities(@MmTelCapability int capabilities) {
+ super(capabilities);
}
@IntDef(flag = true,
diff --git a/telephony/java/com/android/internal/telephony/CbGeoUtils.java b/telephony/java/com/android/internal/telephony/CbGeoUtils.java
index 73dd822903f5..0b73252a1e1b 100644
--- a/telephony/java/com/android/internal/telephony/CbGeoUtils.java
+++ b/telephony/java/com/android/internal/telephony/CbGeoUtils.java
@@ -299,7 +299,8 @@ public class CbGeoUtils {
* @return the encoded string.
*/
@NonNull
- public static String encodeGeometriesToString(@NonNull List<Geometry> geometries) {
+ public static String encodeGeometriesToString(List<Geometry> geometries) {
+ if (geometries == null || geometries.isEmpty()) return "";
return geometries.stream()
.map(geometry -> encodeGeometryToString(geometry))
.filter(encodedStr -> !TextUtils.isEmpty(encodedStr))
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
index dca4e6b13b90..6eea118787a7 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
@@ -104,7 +104,7 @@ public class GsmSmsCbMessage {
header.getSerialNumber(), location, header.getServiceCategory(), null,
getEtwsPrimaryMessage(context, header.getEtwsInfo().getWarningType()),
SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, header.getEtwsInfo(),
- header.getCmasInfo(), null /* geometries */, receivedTimeMillis);
+ header.getCmasInfo(), 0, null /* geometries */, receivedTimeMillis);
} else if (header.isUmtsFormat()) {
// UMTS format has only 1 PDU
byte[] pdu = pdus[0];
@@ -120,9 +120,13 @@ public class GsmSmsCbMessage {
// Has Warning Area Coordinates information
List<Geometry> geometries = null;
+ int maximumWaitingTimeSec = 255;
if (pdu.length > wacDataOffset) {
try {
- geometries = parseWarningAreaCoordinates(pdu, wacDataOffset);
+ Pair<Integer, List<Geometry>> wac = parseWarningAreaCoordinates(pdu,
+ wacDataOffset);
+ maximumWaitingTimeSec = wac.first;
+ geometries = wac.second;
} catch (Exception ex) {
// Catch the exception here, the message will be considered as having no WAC
// information which means the message will be broadcasted directly.
@@ -133,7 +137,8 @@ public class GsmSmsCbMessage {
return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP,
header.getGeographicalScope(), header.getSerialNumber(), location,
header.getServiceCategory(), language, body, priority,
- header.getEtwsInfo(), header.getCmasInfo(), geometries, receivedTimeMillis);
+ header.getEtwsInfo(), header.getCmasInfo(), maximumWaitingTimeSec, geometries,
+ receivedTimeMillis);
} else {
String language = null;
StringBuilder sb = new StringBuilder();
@@ -148,7 +153,7 @@ public class GsmSmsCbMessage {
return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP,
header.getGeographicalScope(), header.getSerialNumber(), location,
header.getServiceCategory(), language, sb.toString(), priority,
- header.getEtwsInfo(), header.getCmasInfo(), null /* geometries */,
+ header.getEtwsInfo(), header.getCmasInfo(), 0, null /* geometries */,
receivedTimeMillis);
}
}
@@ -197,7 +202,17 @@ public class GsmSmsCbMessage {
}
}
- private static List<Geometry> parseWarningAreaCoordinates(byte[] pdu, int wacOffset) {
+ /**
+ * Parse the broadcast area and maximum wait time from the Warning Area Coordinates TLV.
+ *
+ * @param pdu Warning Area Coordinates TLV.
+ * @param wacOffset the offset of Warning Area Coordinates TLV.
+ * @return a pair with the first element is maximum wait time and the second is the broadcast
+ * area. The default value of the maximum wait time is 255 which means use the device default
+ * value.
+ */
+ private static Pair<Integer, List<Geometry>> parseWarningAreaCoordinates(
+ byte[] pdu, int wacOffset) {
// little-endian
int wacDataLength = (pdu[wacOffset + 1] << 8) | pdu[wacOffset];
int offset = wacOffset + 2;
@@ -209,6 +224,8 @@ public class GsmSmsCbMessage {
BitStreamReader bitReader = new BitStreamReader(pdu, offset);
+ int maximumWaitTimeSec = SmsCbMessage.MAXIMUM_WAIT_TIME_NOT_SET;
+
List<Geometry> geo = new ArrayList<>();
int remainedBytes = wacDataLength;
while (remainedBytes > 0) {
@@ -220,8 +237,7 @@ public class GsmSmsCbMessage {
switch (type) {
case CbGeoUtils.GEO_FENCING_MAXIMUM_WAIT_TIME:
- // TODO: handle the maximum wait time in cell broadcast provider.
- int maximumWaitTimeSec = bitReader.read(8);
+ maximumWaitTimeSec = bitReader.read(8);
break;
case CbGeoUtils.GEOMETRY_TYPE_POLYGON:
List<LatLng> latLngs = new ArrayList<>();
@@ -247,7 +263,7 @@ public class GsmSmsCbMessage {
throw new IllegalArgumentException("Unsupported geoType = " + type);
}
}
- return geo;
+ return new Pair(maximumWaitTimeSec, geo);
}
/**
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index 4c5abf9fc6a6..2d867f9d754f 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -20,7 +20,6 @@ import static android.service.watchdog.ExplicitHealthCheckService.PackageConfig;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -65,8 +64,6 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
-// TODO: Write test without using PackageWatchdog#getPackages. Just rely on
-// behavior of observers receiving crash notifications or not to determine if it's registered
// TODO: Use Truth in tests.
/**
* Test PackageWatchdog.
@@ -115,76 +112,109 @@ public class PackageWatchdogTest {
dropShellPermissions();
}
- /**
- * Test registration, unregistration, package expiry and duration reduction
- */
@Test
- public void testRegistration() throws Exception {
+ public void testRegistration_singleObserver() {
+ PackageWatchdog watchdog = createWatchdog();
+ TestObserver observer = new TestObserver(OBSERVER_NAME_1);
+
+ watchdog.startObservingHealth(observer, Arrays.asList(APP_A), SHORT_DURATION);
+ raiseFatalFailure(watchdog, Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
+ mTestLooper.dispatchAll();
+
+ // The failed packages should be the same as the registered ones to ensure registration is
+ // done successfully
+ assertEquals(1, observer.mHealthCheckFailedPackages.size());
+ assertTrue(observer.mHealthCheckFailedPackages.contains(APP_A));
+ }
+
+ @Test
+ public void testRegistration_multiObservers() {
PackageWatchdog watchdog = createWatchdog();
TestObserver observer1 = new TestObserver(OBSERVER_NAME_1);
TestObserver observer2 = new TestObserver(OBSERVER_NAME_2);
- TestObserver observer3 = new TestObserver(OBSERVER_NAME_3);
- // Start observing for observer1 which will be unregistered
watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION);
- // Start observing for observer2 which will expire
watchdog.startObservingHealth(observer2, Arrays.asList(APP_A, APP_B), SHORT_DURATION);
- // Start observing for observer3 which will have expiry duration reduced
- watchdog.startObservingHealth(observer3, Arrays.asList(APP_A), LONG_DURATION);
-
- // Verify packages observed at start
- // 1
- assertEquals(1, watchdog.getPackages(observer1).size());
- assertTrue(watchdog.getPackages(observer1).contains(APP_A));
- // 2
- assertEquals(2, watchdog.getPackages(observer2).size());
- assertTrue(watchdog.getPackages(observer2).contains(APP_A));
- assertTrue(watchdog.getPackages(observer2).contains(APP_B));
- // 3
- assertEquals(1, watchdog.getPackages(observer3).size());
- assertTrue(watchdog.getPackages(observer3).contains(APP_A));
-
- // Then unregister observer1
- watchdog.unregisterHealthObserver(observer1);
-
- // Verify observer2 and observer3 left
- // 1
- assertNull(watchdog.getPackages(observer1));
- // 2
- assertEquals(2, watchdog.getPackages(observer2).size());
- assertTrue(watchdog.getPackages(observer2).contains(APP_A));
- assertTrue(watchdog.getPackages(observer2).contains(APP_B));
- // 3
- assertEquals(1, watchdog.getPackages(observer3).size());
- assertTrue(watchdog.getPackages(observer3).contains(APP_A));
-
- // Then advance time a little and run messages in Handlers so observer2 expires
+ raiseFatalFailure(watchdog, Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE),
+ new VersionedPackage(APP_B, VERSION_CODE)));
+ mTestLooper.dispatchAll();
+
+ // The failed packages should be the same as the registered ones to ensure registration is
+ // done successfully
+ assertEquals(1, observer1.mHealthCheckFailedPackages.size());
+ assertEquals(2, observer2.mHealthCheckFailedPackages.size());
+ assertTrue(observer1.mHealthCheckFailedPackages.contains(APP_A));
+ assertTrue(observer2.mHealthCheckFailedPackages.contains(APP_A));
+ assertTrue(observer2.mHealthCheckFailedPackages.contains(APP_B));
+ }
+
+ @Test
+ public void testUnregistration_singleObserver() {
+ PackageWatchdog watchdog = createWatchdog();
+ TestObserver observer = new TestObserver(OBSERVER_NAME_1);
+
+ watchdog.startObservingHealth(observer, Arrays.asList(APP_A), SHORT_DURATION);
+ watchdog.unregisterHealthObserver(observer);
+ raiseFatalFailure(watchdog, Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
+ mTestLooper.dispatchAll();
+
+ // We should have no failed packages to ensure unregistration is done successfully
+ assertEquals(0, observer.mHealthCheckFailedPackages.size());
+ }
+
+ @Test
+ public void testUnregistration_multiObservers() {
+ PackageWatchdog watchdog = createWatchdog();
+ TestObserver observer1 = new TestObserver(OBSERVER_NAME_1);
+ TestObserver observer2 = new TestObserver(OBSERVER_NAME_2);
+
+ watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION);
+ watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), SHORT_DURATION);
+ watchdog.unregisterHealthObserver(observer2);
+ raiseFatalFailure(watchdog, Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
+ mTestLooper.dispatchAll();
+
+ // observer1 should receive failed packages as intended.
+ assertEquals(1, observer1.mHealthCheckFailedPackages.size());
+ // observer2 should have no failed packages to ensure unregistration is done successfully
+ assertEquals(0, observer2.mHealthCheckFailedPackages.size());
+ }
+
+ @Test
+ public void testExpiration_singleObserver() {
+ PackageWatchdog watchdog = createWatchdog();
+ TestObserver observer = new TestObserver(OBSERVER_NAME_1);
+
+ watchdog.startObservingHealth(observer, Arrays.asList(APP_A), SHORT_DURATION);
moveTimeForwardAndDispatch(SHORT_DURATION);
+ raiseFatalFailure(watchdog, Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
+ mTestLooper.dispatchAll();
- // Verify observer3 left with reduced expiry duration
- // 1
- assertNull(watchdog.getPackages(observer1));
- // 2
- assertNull(watchdog.getPackages(observer2));
- // 3
- assertEquals(1, watchdog.getPackages(observer3).size());
- assertTrue(watchdog.getPackages(observer3).contains(APP_A));
-
- // Then advance time some more and run messages in Handlers so observer3 expires
- moveTimeForwardAndDispatch(LONG_DURATION);
-
- // Verify observer3 expired
- // 1
- assertNull(watchdog.getPackages(observer1));
- // 2
- assertNull(watchdog.getPackages(observer2));
- // 3
- assertNull(watchdog.getPackages(observer3));
+ // We should have no failed packages for the fatal failure is raised after expiration
+ assertEquals(0, observer.mHealthCheckFailedPackages.size());
+ }
+
+ @Test
+ public void testExpiration_multiObservers() {
+ PackageWatchdog watchdog = createWatchdog();
+ TestObserver observer1 = new TestObserver(OBSERVER_NAME_1);
+ TestObserver observer2 = new TestObserver(OBSERVER_NAME_2);
+
+ watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION);
+ watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), LONG_DURATION);
+ moveTimeForwardAndDispatch(SHORT_DURATION);
+ raiseFatalFailure(watchdog, Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
+ mTestLooper.dispatchAll();
+
+ // We should have no failed packages for the fatal failure is raised after expiration
+ assertEquals(0, observer1.mHealthCheckFailedPackages.size());
+ // We should have failed packages since observer2 hasn't expired
+ assertEquals(1, observer2.mHealthCheckFailedPackages.size());
}
/** Observing already observed package extends the observation time. */
@Test
- public void testObserveAlreadyObservedPackage() throws Exception {
+ public void testObserveAlreadyObservedPackage() {
PackageWatchdog watchdog = createWatchdog();
TestObserver observer = new TestObserver(OBSERVER_NAME_1);
@@ -200,56 +230,43 @@ public class PackageWatchdogTest {
// Then advance time such that it should have expired were it not for the second observation
moveTimeForwardAndDispatch((SHORT_DURATION / 2) + 1);
- // Verify that APP_A not expired since second observation extended the time
- assertEquals(1, watchdog.getPackages(observer).size());
- assertTrue(watchdog.getPackages(observer).contains(APP_A));
+ raiseFatalFailure(watchdog, Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
+ mTestLooper.dispatchAll();
+
+ // Verify that we receive failed packages as expected for APP_A not expired
+ assertEquals(1, observer.mHealthCheckFailedPackages.size());
+ assertTrue(observer.mHealthCheckFailedPackages.contains(APP_A));
}
/**
* Test package observers are persisted and loaded on startup
*/
@Test
- public void testPersistence() throws Exception {
+ public void testPersistence() {
PackageWatchdog watchdog1 = createWatchdog();
TestObserver observer1 = new TestObserver(OBSERVER_NAME_1);
TestObserver observer2 = new TestObserver(OBSERVER_NAME_2);
watchdog1.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION);
watchdog1.startObservingHealth(observer2, Arrays.asList(APP_A, APP_B), SHORT_DURATION);
-
- // Verify 2 observers are registered and saved internally
- // 1
- assertEquals(1, watchdog1.getPackages(observer1).size());
- assertTrue(watchdog1.getPackages(observer1).contains(APP_A));
- // 2
- assertEquals(2, watchdog1.getPackages(observer2).size());
- assertTrue(watchdog1.getPackages(observer2).contains(APP_A));
- assertTrue(watchdog1.getPackages(observer2).contains(APP_B));
-
// Then advance time and run IO Handler so file is saved
mTestLooper.dispatchAll();
-
// Then start a new watchdog
PackageWatchdog watchdog2 = createWatchdog();
-
- // Verify the new watchdog loads observers on startup but nothing registered
- assertEquals(0, watchdog2.getPackages(observer1).size());
- assertEquals(0, watchdog2.getPackages(observer2).size());
- // Verify random observer not saved returns null
- assertNull(watchdog2.getPackages(new TestObserver(OBSERVER_NAME_3)));
-
- // Then register observer1
+ // Then resume observer1 and observer2
watchdog2.registerHealthObserver(observer1);
watchdog2.registerHealthObserver(observer2);
+ raiseFatalFailure(watchdog2, Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE),
+ new VersionedPackage(APP_B, VERSION_CODE)));
+ mTestLooper.dispatchAll();
- // Verify 2 observers are registered after reload
- // 1
- assertEquals(1, watchdog1.getPackages(observer1).size());
- assertTrue(watchdog1.getPackages(observer1).contains(APP_A));
- // 2
- assertEquals(2, watchdog1.getPackages(observer2).size());
- assertTrue(watchdog1.getPackages(observer2).contains(APP_A));
- assertTrue(watchdog1.getPackages(observer2).contains(APP_B));
+ // We should receive failed packages as expected to ensure observers are persisted and
+ // resumed correctly
+ assertEquals(1, observer1.mHealthCheckFailedPackages.size());
+ assertEquals(2, observer2.mHealthCheckFailedPackages.size());
+ assertTrue(observer1.mHealthCheckFailedPackages.contains(APP_A));
+ assertTrue(observer1.mHealthCheckFailedPackages.contains(APP_A));
+ assertTrue(observer2.mHealthCheckFailedPackages.contains(APP_B));
}
/**
@@ -273,8 +290,8 @@ public class PackageWatchdogTest {
mTestLooper.dispatchAll();
// Verify that observers are not notified
- assertEquals(0, observer1.mFailedPackages.size());
- assertEquals(0, observer2.mFailedPackages.size());
+ assertEquals(0, observer1.mMitigatedPackages.size());
+ assertEquals(0, observer2.mMitigatedPackages.size());
}
/**
@@ -292,16 +309,14 @@ public class PackageWatchdogTest {
watchdog.startObservingHealth(observer1, Arrays.asList(APP_B), SHORT_DURATION);
// Then fail APP_C (not observed) above the threshold
- for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_C, VERSION_CODE)));
- }
+ raiseFatalFailure(watchdog, Arrays.asList(new VersionedPackage(APP_C, VERSION_CODE)));
// Run handler so package failures are dispatched to observers
mTestLooper.dispatchAll();
// Verify that observers are not notified
- assertEquals(0, observer1.mFailedPackages.size());
- assertEquals(0, observer2.mFailedPackages.size());
+ assertEquals(0, observer1.mMitigatedPackages.size());
+ assertEquals(0, observer2.mMitigatedPackages.size());
}
/**
@@ -326,16 +341,14 @@ public class PackageWatchdogTest {
watchdog.startObservingHealth(observer, Arrays.asList(APP_A), SHORT_DURATION);
// Then fail APP_A (different version) above the threshold
- for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
- watchdog.onPackageFailure(Arrays.asList(
- new VersionedPackage(APP_A, differentVersionCode)));
- }
+ raiseFatalFailure(watchdog,
+ Arrays.asList(new VersionedPackage(APP_A, differentVersionCode)));
// Run handler so package failures are dispatched to observers
mTestLooper.dispatchAll();
// Verify that observers are not notified
- assertEquals(0, observer.mFailedPackages.size());
+ assertEquals(0, observer.mMitigatedPackages.size());
}
@@ -365,21 +378,19 @@ public class PackageWatchdogTest {
SHORT_DURATION);
// Then fail all apps above the threshold
- for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE),
- new VersionedPackage(APP_B, VERSION_CODE),
- new VersionedPackage(APP_C, VERSION_CODE),
- new VersionedPackage(APP_D, VERSION_CODE)));
- }
+ raiseFatalFailure(watchdog, Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE),
+ new VersionedPackage(APP_B, VERSION_CODE),
+ new VersionedPackage(APP_C, VERSION_CODE),
+ new VersionedPackage(APP_D, VERSION_CODE)));
// Run handler so package failures are dispatched to observers
mTestLooper.dispatchAll();
// Verify least impact observers are notifed of package failures
- List<String> observerNonePackages = observerNone.mFailedPackages;
- List<String> observerHighPackages = observerHigh.mFailedPackages;
- List<String> observerMidPackages = observerMid.mFailedPackages;
- List<String> observerLowPackages = observerLow.mFailedPackages;
+ List<String> observerNonePackages = observerNone.mMitigatedPackages;
+ List<String> observerHighPackages = observerHigh.mMitigatedPackages;
+ List<String> observerMidPackages = observerMid.mMitigatedPackages;
+ List<String> observerLowPackages = observerLow.mMitigatedPackages;
// APP_D failure observed by only observerNone is not caught cos its impact is none
assertEquals(0, observerNonePackages.size());
@@ -418,66 +429,58 @@ public class PackageWatchdogTest {
watchdog.startObservingHealth(observerSecond, Arrays.asList(APP_A), LONG_DURATION);
// Then fail APP_A above the threshold
- for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
- }
+ raiseFatalFailure(watchdog, Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
// Run handler so package failures are dispatched to observers
mTestLooper.dispatchAll();
// Verify only observerFirst is notifed
- assertEquals(1, observerFirst.mFailedPackages.size());
- assertEquals(APP_A, observerFirst.mFailedPackages.get(0));
- assertEquals(0, observerSecond.mFailedPackages.size());
+ assertEquals(1, observerFirst.mMitigatedPackages.size());
+ assertEquals(APP_A, observerFirst.mMitigatedPackages.get(0));
+ assertEquals(0, observerSecond.mMitigatedPackages.size());
// After observerFirst handles failure, next action it has is high impact
observerFirst.mImpact = PackageHealthObserverImpact.USER_IMPACT_HIGH;
- observerFirst.mFailedPackages.clear();
- observerSecond.mFailedPackages.clear();
+ observerFirst.mMitigatedPackages.clear();
+ observerSecond.mMitigatedPackages.clear();
// Then fail APP_A again above the threshold
- for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
- }
+ raiseFatalFailure(watchdog, Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
// Run handler so package failures are dispatched to observers
mTestLooper.dispatchAll();
// Verify only observerSecond is notifed cos it has least impact
- assertEquals(1, observerSecond.mFailedPackages.size());
- assertEquals(APP_A, observerSecond.mFailedPackages.get(0));
- assertEquals(0, observerFirst.mFailedPackages.size());
+ assertEquals(1, observerSecond.mMitigatedPackages.size());
+ assertEquals(APP_A, observerSecond.mMitigatedPackages.get(0));
+ assertEquals(0, observerFirst.mMitigatedPackages.size());
// After observerSecond handles failure, it has no further actions
observerSecond.mImpact = PackageHealthObserverImpact.USER_IMPACT_NONE;
- observerFirst.mFailedPackages.clear();
- observerSecond.mFailedPackages.clear();
+ observerFirst.mMitigatedPackages.clear();
+ observerSecond.mMitigatedPackages.clear();
// Then fail APP_A again above the threshold
- for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
- }
+ raiseFatalFailure(watchdog, Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
// Run handler so package failures are dispatched to observers
mTestLooper.dispatchAll();
// Verify only observerFirst is notifed cos it has the only action
- assertEquals(1, observerFirst.mFailedPackages.size());
- assertEquals(APP_A, observerFirst.mFailedPackages.get(0));
- assertEquals(0, observerSecond.mFailedPackages.size());
+ assertEquals(1, observerFirst.mMitigatedPackages.size());
+ assertEquals(APP_A, observerFirst.mMitigatedPackages.get(0));
+ assertEquals(0, observerSecond.mMitigatedPackages.size());
// After observerFirst handles failure, it too has no further actions
observerFirst.mImpact = PackageHealthObserverImpact.USER_IMPACT_NONE;
- observerFirst.mFailedPackages.clear();
- observerSecond.mFailedPackages.clear();
+ observerFirst.mMitigatedPackages.clear();
+ observerSecond.mMitigatedPackages.clear();
// Then fail APP_A again above the threshold
- for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
- }
+ raiseFatalFailure(watchdog, Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
// Run handler so package failures are dispatched to observers
mTestLooper.dispatchAll();
// Verify no observer is notified cos no actions left
- assertEquals(0, observerFirst.mFailedPackages.size());
- assertEquals(0, observerSecond.mFailedPackages.size());
+ assertEquals(0, observerFirst.mMitigatedPackages.size());
+ assertEquals(0, observerSecond.mMitigatedPackages.size());
}
/**
@@ -496,17 +499,15 @@ public class PackageWatchdogTest {
watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION);
// Then fail APP_A above the threshold
- for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
- }
+ raiseFatalFailure(watchdog, Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
// Run handler so package failures are dispatched to observers
mTestLooper.dispatchAll();
// Verify only one observer is notifed
- assertEquals(1, observer1.mFailedPackages.size());
- assertEquals(APP_A, observer1.mFailedPackages.get(0));
- assertEquals(0, observer2.mFailedPackages.size());
+ assertEquals(1, observer1.mMitigatedPackages.size());
+ assertEquals(APP_A, observer1.mMitigatedPackages.get(0));
+ assertEquals(0, observer2.mMitigatedPackages.size());
}
/**
@@ -555,15 +556,15 @@ public class PackageWatchdogTest {
assertEquals(0, controller.getRequestedPackages().size());
// Verify observer1 is not notified
- assertEquals(0, observer1.mFailedPackages.size());
+ assertEquals(0, observer1.mMitigatedPackages.size());
// Verify observer2 is notifed because health checks for APP_B never passed
- assertEquals(1, observer2.mFailedPackages.size());
- assertEquals(APP_B, observer2.mFailedPackages.get(0));
+ assertEquals(1, observer2.mMitigatedPackages.size());
+ assertEquals(APP_B, observer2.mMitigatedPackages.get(0));
// Verify observer3 is notifed because health checks for APP_A did not pass before expiry
- assertEquals(1, observer3.mFailedPackages.size());
- assertEquals(APP_A, observer3.mFailedPackages.get(0));
+ assertEquals(1, observer3.mMitigatedPackages.size());
+ assertEquals(APP_A, observer3.mMitigatedPackages.get(0));
}
/**
@@ -607,7 +608,7 @@ public class PackageWatchdogTest {
moveTimeForwardAndDispatch(SHORT_DURATION);
// Verify APP_A is not failed (APP_B) is not expired yet
- assertEquals(0, observer.mFailedPackages.size());
+ assertEquals(0, observer.mMitigatedPackages.size());
// Re-enable explicit health checks
setExplicitHealthCheckEnabled(true);
@@ -635,8 +636,8 @@ public class PackageWatchdogTest {
moveTimeForwardAndDispatch(SHORT_DURATION);
// Verify only APP_C is failed because explicit health checks was not supported for APP_A
- assertEquals(1, observer.mFailedPackages.size());
- assertEquals(APP_C, observer.mFailedPackages.get(0));
+ assertEquals(1, observer.mMitigatedPackages.size());
+ assertEquals(APP_C, observer.mMitigatedPackages.get(0));
}
/**
@@ -660,17 +661,17 @@ public class PackageWatchdogTest {
moveTimeForwardAndDispatch(SHORT_DURATION);
// Verify that health check is failed
- assertEquals(1, observer.mFailedPackages.size());
- assertEquals(APP_A, observer.mFailedPackages.get(0));
+ assertEquals(1, observer.mMitigatedPackages.size());
+ assertEquals(APP_A, observer.mMitigatedPackages.get(0));
// Then clear failed packages and start observing a random package so requests are synced
// and PackageWatchdog#onSupportedPackages is called and APP_A has a chance to fail again
// this time due to package expiry.
- observer.mFailedPackages.clear();
+ observer.mMitigatedPackages.clear();
watchdog.startObservingHealth(observer, Arrays.asList(APP_B), LONG_DURATION);
// Verify that health check failure is not notified again
- assertTrue(observer.mFailedPackages.isEmpty());
+ assertTrue(observer.mMitigatedPackages.isEmpty());
}
/** Tests {@link MonitoredPackage} health check state transitions. */
@@ -734,8 +735,8 @@ public class PackageWatchdogTest {
mTestLooper.dispatchAll();
// Verify the NetworkStack observer is notified
- assertEquals(1, observer.mFailedPackages.size());
- assertEquals(APP_A, observer.mFailedPackages.get(0));
+ assertEquals(1, observer.mMitigatedPackages.size());
+ assertEquals(APP_A, observer.mMitigatedPackages.get(0));
}
private void adoptShellPermissions(String... permissions) {
@@ -770,6 +771,13 @@ public class PackageWatchdogTest {
mTestLooper.dispatchAll();
}
+ /** Trigger package failures above the threshold. */
+ private void raiseFatalFailure(PackageWatchdog watchdog, List<VersionedPackage> packages) {
+ for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
+ watchdog.onPackageFailure(packages);
+ }
+ }
+
private PackageWatchdog createWatchdog() {
return createWatchdog(new TestController(), true /* withPackagesReady */);
}
@@ -799,7 +807,8 @@ public class PackageWatchdogTest {
private static class TestObserver implements PackageHealthObserver {
private final String mName;
private int mImpact;
- final List<String> mFailedPackages = new ArrayList<>();
+ final List<String> mHealthCheckFailedPackages = new ArrayList<>();
+ final List<String> mMitigatedPackages = new ArrayList<>();
TestObserver(String name) {
mName = name;
@@ -812,11 +821,12 @@ public class PackageWatchdogTest {
}
public int onHealthCheckFailed(VersionedPackage versionedPackage) {
+ mHealthCheckFailedPackages.add(versionedPackage.getPackageName());
return mImpact;
}
public boolean execute(VersionedPackage versionedPackage) {
- mFailedPackages.add(versionedPackage.getPackageName());
+ mMitigatedPackages.add(versionedPackage.getPackageName());
return true;
}
diff --git a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
index b2e5a62849e7..bc98f06ebc56 100644
--- a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
+++ b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
@@ -28,6 +28,8 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.concurrent.TimeUnit;
+
/**
* Runs the staged rollback tests.
*/
@@ -99,9 +101,15 @@ public class StagedRollbackTest extends BaseHostJUnit4Test {
// crash system_server enough times to trigger a rollback
crashProcess("system_server", NATIVE_CRASHES_THRESHOLD);
- // Rollback should be committed automatically now
- // Give time for rollback to be committed
- assertTrue(getDevice().waitForDeviceNotAvailable(60000));
+ // Rollback should be committed automatically now.
+ // Give time for rollback to be committed. This could take a while,
+ // because we need all of the following to happen:
+ // 1. system_server comes back up and boot completes.
+ // 2. Rollback health observer detects updatable crashing signal.
+ // 3. Staged rollback session becomes ready.
+ // 4. Device actually reboots.
+ // So we give a generous timeout here.
+ assertTrue(getDevice().waitForDeviceNotAvailable(TimeUnit.MINUTES.toMillis(5)));
getDevice().waitForDeviceAvailable();
// verify rollback committed
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index 9d4b837ce2d1..f8c20111d79b 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -15,6 +15,7 @@
*/
package android.net.wifi;
+import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
@@ -23,6 +24,8 @@ import android.security.Credentials;
import android.text.TextUtils;
import android.util.Log;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
@@ -111,6 +114,48 @@ public class WifiEnterpriseConfig implements Parcelable {
/** @hide */
public static final String CA_CERT_ALIAS_DELIMITER = " ";
+ /**
+ * Do not use OCSP stapling (TLS certificate status extension)
+ * @hide
+ */
+ public static final int OCSP_NONE = 0;
+
+ /**
+ * Try to use OCSP stapling, but not require response
+ * @hide
+ */
+ public static final int OCSP_REQUEST_CERT_STATUS = 1;
+
+ /**
+ * Require valid OCSP stapling response
+ * @hide
+ */
+ public static final int OCSP_REQUIRE_CERT_STATUS = 2;
+
+ /**
+ * Require valid OCSP stapling response for all not-trusted certificates in the server
+ * certificate chain
+ * @hide
+ */
+ public static final int OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS = 3;
+
+ /** @hide */
+ @IntDef(prefix = {"OCSP_"}, value = {
+ OCSP_NONE,
+ OCSP_REQUEST_CERT_STATUS,
+ OCSP_REQUIRE_CERT_STATUS,
+ OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Ocsp {
+ }
+
+ /**
+ * Whether to use/require OCSP (Online Certificate Status Protocol) to check server certificate.
+ * @hide
+ */
+ private @Ocsp int mOcsp = OCSP_NONE;
+
// Fields to copy verbatim from wpa_supplicant.
private static final String[] SUPPLICANT_CONFIG_KEYS = new String[] {
IDENTITY_KEY,
@@ -185,6 +230,7 @@ public class WifiEnterpriseConfig implements Parcelable {
mPhase2Method = source.mPhase2Method;
mIsAppInstalledDeviceKeyAndCert = source.mIsAppInstalledDeviceKeyAndCert;
mIsAppInstalledCaCert = source.mIsAppInstalledCaCert;
+ mOcsp = source.mOcsp;
}
/**
@@ -230,6 +276,7 @@ public class WifiEnterpriseConfig implements Parcelable {
ParcelUtil.writeCertificates(dest, mClientCertificateChain);
dest.writeBoolean(mIsAppInstalledDeviceKeyAndCert);
dest.writeBoolean(mIsAppInstalledCaCert);
+ dest.writeInt(mOcsp);
}
public static final @android.annotation.NonNull Creator<WifiEnterpriseConfig> CREATOR =
@@ -251,6 +298,7 @@ public class WifiEnterpriseConfig implements Parcelable {
enterpriseConfig.mClientCertificateChain = ParcelUtil.readCertificates(in);
enterpriseConfig.mIsAppInstalledDeviceKeyAndCert = in.readBoolean();
enterpriseConfig.mIsAppInstalledCaCert = in.readBoolean();
+ enterpriseConfig.mOcsp = in.readInt();
return enterpriseConfig;
}
@@ -1141,6 +1189,7 @@ public class WifiEnterpriseConfig implements Parcelable {
if (mPhase2Method > 0 && mPhase2Method < Phase2.strings.length) {
sb.append("phase2_method: ").append(Phase2.strings[mPhase2Method]).append("\n");
}
+ sb.append(" ocsp: ").append(mOcsp).append("\n");
return sb.toString();
}
@@ -1190,4 +1239,28 @@ public class WifiEnterpriseConfig implements Parcelable {
public boolean isAppInstalledCaCert() {
return mIsAppInstalledCaCert;
}
+
+ /**
+ * Set the ocsp type.
+ * @param ocsp is one {@link ##OCSP_NONE}, {@link #OCSP_REQUEST_CERT_STATUS},
+ * {@link #OCSP_REQUIRE_CERT_STATUS} or
+ * {@link #OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS}
+ * @hide
+ */
+ public void setOcsp(@Ocsp int ocsp) {
+ if (ocsp >= OCSP_NONE && ocsp <= OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS) {
+ mOcsp = ocsp;
+ } else {
+ throw new IllegalArgumentException("Invalid OCSP type.");
+ }
+ }
+
+ /**
+ * Get the ocsp type.
+ * @return ocsp type
+ * @hide
+ */
+ public @Ocsp int getOcsp() {
+ return mOcsp;
+ }
}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 6bf7bfb9b4a1..a37de00ce7de 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -52,12 +52,14 @@ import android.os.Messenger;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.WorkSource;
+import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
import com.android.server.net.NetworkPinner;
@@ -1821,6 +1823,7 @@ public class WifiManager {
try {
IWifiManager iWifiManager = getIWifiManager();
if (iWifiManager == null) {
+ if (config == null) return;
throw new RemoteException("Wifi service is not running");
}
if (!iWifiManager.addOrUpdatePasspointConfiguration(
@@ -1849,6 +1852,7 @@ public class WifiManager {
try {
IWifiManager iWifiManager = getIWifiManager();
if (iWifiManager == null) {
+ if (TextUtils.isEmpty(fqdn)) return;
throw new RemoteException("Wifi service is not running");
}
if (!iWifiManager.removePasspointConfiguration(
@@ -1899,6 +1903,7 @@ public class WifiManager {
try {
IWifiManager iWifiManager = getIWifiManager();
if (iWifiManager == null) {
+ if (bssid == 0L || TextUtils.isEmpty(fileName)) return;
throw new RemoteException("Wifi service is not running");
}
iWifiManager.queryPasspointIcon(bssid, fileName);
@@ -1928,6 +1933,8 @@ public class WifiManager {
* @param holdoff hold off time in milliseconds
* @param ess set if the hold off pertains to an ESS rather than a BSS
* @hide
+ *
+ * TODO (140167680): This needs to be removed, the implementation is empty!
*/
public void deauthenticateNetwork(long holdoff, boolean ess) {
try {
@@ -2504,6 +2511,7 @@ public class WifiManager {
try {
IWifiManager iWifiManager = getIWifiManager();
if (iWifiManager == null) {
+ if (TextUtils.isEmpty(country)) return;
throw new RemoteException("Wifi service is not running");
}
iWifiManager.setCountryCode(country);
@@ -2692,6 +2700,7 @@ public class WifiManager {
try {
IWifiManager iWifiManager = getIWifiManager();
if (iWifiManager == null) {
+ if (TextUtils.isEmpty(ifaceName) || mode == IFACE_IP_MODE_UNSPECIFIED) return;
throw new RemoteException("Wifi service is not running");
}
iWifiManager.updateInterfaceIpState(ifaceName, mode);
@@ -3044,6 +3053,7 @@ public class WifiManager {
try {
IWifiManager iWifiManager = getIWifiManager();
if (iWifiManager == null) {
+ if (remoteIPAddress == null || !enable) return;
throw new RemoteException("Wifi service is not running");
}
iWifiManager.enableTdls(remoteIPAddress.getHostAddress(), enable);
@@ -3062,6 +3072,7 @@ public class WifiManager {
try {
IWifiManager iWifiManager = getIWifiManager();
if (iWifiManager == null) {
+ if (TextUtils.isEmpty(remoteMacAddress) || !enable) return;
throw new RemoteException("Wifi service is not running");
}
iWifiManager.enableTdlsWithMacAddress(remoteMacAddress, enable);
@@ -3956,7 +3967,7 @@ public class WifiManager {
android.Manifest.permission.NETWORK_STACK
})
public void disableEphemeralNetwork(String SSID) {
- if (SSID == null) throw new IllegalArgumentException("SSID cannot be null");
+ if (TextUtils.isEmpty(SSID)) throw new IllegalArgumentException("SSID cannot be null");
try {
IWifiManager iWifiManager = getIWifiManager();
if (iWifiManager == null) {
@@ -4495,6 +4506,7 @@ public class WifiManager {
try {
IWifiManager iWifiManager = getIWifiManager();
if (iWifiManager == null) {
+ if (verbose == 0) return;
throw new RemoteException("Wifi service is not running");
}
iWifiManager.enableVerboseLogging(verbose);
@@ -4581,6 +4593,7 @@ public class WifiManager {
try {
IWifiManager iWifiManager = getIWifiManager();
if (iWifiManager == null) {
+ if (enabled) return;
throw new RemoteException("Wifi service is not running");
}
iWifiManager.enableWifiConnectivityManager(enabled);
@@ -4611,6 +4624,7 @@ public class WifiManager {
try {
IWifiManager iWifiManager = getIWifiManager();
if (iWifiManager == null) {
+ if (ArrayUtils.isEmpty(data)) return;
throw new RemoteException("Wifi service is not running");
}
iWifiManager.restoreBackupData(data);
@@ -4631,6 +4645,7 @@ public class WifiManager {
try {
IWifiManager iWifiManager = getIWifiManager();
if (iWifiManager == null) {
+ if (ArrayUtils.isEmpty(supplicantData) && ArrayUtils.isEmpty(ipConfigData)) return;
throw new RemoteException("Wifi service is not running");
}
iWifiManager.restoreSupplicantBackupData(supplicantData, ipConfigData);
@@ -4937,6 +4952,7 @@ public class WifiManager {
try {
IWifiManager iWifiManager = getIWifiManager();
if (iWifiManager == null) {
+ if (state == DEVICE_MOBILITY_STATE_UNKNOWN) return;
throw new RemoteException("Wifi service is not running");
}
iWifiManager.setDeviceMobilityState(state);
diff --git a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java b/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
index beed6666f28f..d8db4ceb6e9c 100644
--- a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
@@ -23,6 +23,7 @@ import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import android.net.wifi.WifiEnterpriseConfig.Eap;
import android.net.wifi.WifiEnterpriseConfig.Phase2;
@@ -343,11 +344,13 @@ public class WifiEnterpriseConfigTest {
enterpriseConfig.setPassword("*");
enterpriseConfig.setEapMethod(Eap.TTLS);
enterpriseConfig.setPhase2Method(Phase2.GTC);
+ enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS);
mEnterpriseConfig = new WifiEnterpriseConfig();
mEnterpriseConfig.copyFromExternal(enterpriseConfig, "*");
assertEquals("TTLS", getSupplicantEapMethod());
assertEquals("\"autheap=GTC\"", getSupplicantPhase2Method());
assertNotEquals("*", mEnterpriseConfig.getPassword());
+ assertEquals(enterpriseConfig.getOcsp(), mEnterpriseConfig.getOcsp());
}
/** Verfies that parceling a WifiEnterpriseConfig preseves method information. */
@@ -487,4 +490,35 @@ public class WifiEnterpriseConfigTest {
assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
assertTrue(mEnterpriseConfig.isAppInstalledCaCert());
}
+
+ /** Verifies that OCSP value is set correctly. */
+ @Test
+ public void testOcspSetGet() throws Exception {
+ WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
+
+ enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_NONE);
+ assertEquals(WifiEnterpriseConfig.OCSP_NONE, enterpriseConfig.getOcsp());
+
+ enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS);
+ assertEquals(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS, enterpriseConfig.getOcsp());
+
+ enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS);
+ assertEquals(WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS, enterpriseConfig.getOcsp());
+
+ enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS);
+ assertEquals(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS,
+ enterpriseConfig.getOcsp());
+ }
+
+ /** Verifies that an exception is thrown when invalid OCSP is set. */
+ @Test
+ public void testInvalidOcspValue() {
+ WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
+ try {
+ enterpriseConfig.setOcsp(-1);
+ fail("Should raise an IllegalArgumentException here.");
+ } catch (IllegalArgumentException e) {
+ // expected exception.
+ }
+ }
}