diff options
49 files changed, 469 insertions, 184 deletions
diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl index 70c25ea3ab1c..740f5932f902 100644 --- a/core/java/android/app/trust/ITrustManager.aidl +++ b/core/java/android/app/trust/ITrustManager.aidl @@ -41,4 +41,5 @@ interface ITrustManager { void unlockedByBiometricForUser(int userId, in BiometricSourceType source); void clearAllBiometricRecognized(in BiometricSourceType target, int unlockedUser); boolean isActiveUnlockRunning(int userId); + boolean isInSignificantPlace(); } diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java index 23b2ea4dc537..88d4d691cd97 100644 --- a/core/java/android/app/trust/TrustManager.java +++ b/core/java/android/app/trust/TrustManager.java @@ -299,6 +299,20 @@ public class TrustManager { } } + /** + * Returns true if the device is currently in a significant place, and false in all other + * circumstances. + * + * @hide + */ + public boolean isInSignificantPlace() { + try { + return mService.isInSignificantPlace(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + private final Handler mHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java index 1eb466cb10a3..e3780edcd7da 100644 --- a/core/java/android/database/sqlite/SQLiteDatabase.java +++ b/core/java/android/database/sqlite/SQLiteDatabase.java @@ -683,7 +683,9 @@ public final class SQLiteDatabase extends SQLiteClosable { * <p> * Read-only transactions may run concurrently with other read-only transactions, and if the * database is in WAL mode, they may also run concurrently with IMMEDIATE or EXCLUSIVE - * transactions. + * transactions. The {@code temp} schema may be modified during a read-only transaction; + * if the transaction is {@link #setTransactionSuccessful}, modifications to temp tables may + * be visible to some subsequent transactions. * <p> * Transactions can be nested. However, the behavior of the transaction is not altered by * nested transactions. A nested transaction may be any of the three transaction types but if diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig index ee5e533364ff..fe7eab7abeda 100644 --- a/core/java/android/security/flags.aconfig +++ b/core/java/android/security/flags.aconfig @@ -81,6 +81,13 @@ flag { } flag { + name: "significant_places" + namespace: "biometrics" + description: "Enabled significant place monitoring" + bug: "337870680" +} + +flag { name: "report_primary_auth_attempts" namespace: "biometrics" description: "Report primary auth attempts from LockSettingsService" diff --git a/core/jni/android_database_SQLiteConnection.cpp b/core/jni/android_database_SQLiteConnection.cpp index 6f1c76385120..99a7e433d330 100644 --- a/core/jni/android_database_SQLiteConnection.cpp +++ b/core/jni/android_database_SQLiteConnection.cpp @@ -436,7 +436,7 @@ static jboolean nativeUpdatesTempOnly(JNIEnv* env, jclass, int result = SQLITE_OK; if (connection->tableQuery == nullptr) { static char const* sql = - "SELECT COUNT(*) FROM tables_used(?) WHERE schema != 'temp' AND wr != 0"; + "SELECT NULL FROM tables_used(?) WHERE schema != 'temp' AND wr != 0"; result = sqlite3_prepare_v2(connection->db, sql, -1, &connection->tableQuery, nullptr); if (result != SQLITE_OK) { ALOGE("failed to compile query table: %s", @@ -455,17 +455,14 @@ static jboolean nativeUpdatesTempOnly(JNIEnv* env, jclass, return false; } result = sqlite3_step(query); - if (result != SQLITE_ROW) { + // Make sure the query is no longer bound to the statement SQL string. + sqlite3_clear_bindings(query); + + if (result != SQLITE_ROW && result != SQLITE_DONE) { ALOGE("tables query error: %d/%s", result, sqlite3_errstr(result)); - // Make sure the query is no longer bound to the statement. - sqlite3_clear_bindings(query); return false; } - - int count = sqlite3_column_int(query, 0); - // Make sure the query is no longer bound to the statement SQL string. - sqlite3_clear_bindings(query); - return count == 0; + return result == SQLITE_DONE; } static jint nativeGetColumnCount(JNIEnv* env, jclass clazz, jlong connectionPtr, diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index b885e03bc098..a0807ca580a2 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -72,6 +72,9 @@ <!-- The default margin used in immersive mode to capture the start of a swipe gesture from the edge of the screen to show the system bars. --> <dimen name="system_gestures_start_threshold">24dp</dimen> + <!-- The minimum swipe gesture distance for showing the system bars when in immersive mode. This + swipe must be within the specified system_gestures_start_threshold area. --> + <dimen name="system_gestures_distance_threshold">24dp</dimen> <!-- Height of the bottom navigation bar frame; this is different than navigation_bar_height where that is the height reported to all the other windows to resize themselves around the diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 7e2c111719e5..4ae6c5e7cc3d 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1804,6 +1804,7 @@ <java-symbol type="dimen" name="taskbar_frame_height" /> <java-symbol type="dimen" name="status_bar_height" /> <java-symbol type="dimen" name="display_cutout_touchable_region_size" /> + <java-symbol type="dimen" name="system_gestures_distance_threshold" /> <java-symbol type="dimen" name="system_gestures_start_threshold" /> <java-symbol type="dimen" name="quick_qs_offset_height" /> <java-symbol type="drawable" name="ic_jog_dial_sound_off" /> diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig index 163c8493e4d9..780a099350d0 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -964,6 +964,9 @@ flag { namespace: "systemui" description: "Only dismiss media notifications when the control was removed by the user." bug: "335875159" + metadata { + purpose: PURPOSE_BUGFIX + } } flag { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt index d88260f0760a..303548131788 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt @@ -16,90 +16,93 @@ package com.android.systemui.bouncer.domain.interactor +import android.platform.test.annotations.DisableFlags +import android.platform.test.annotations.EnableFlags import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.keyguard.KeyguardUpdateMonitor +import com.android.keyguard.keyguardUpdateMonitor import com.android.systemui.Flags import com.android.systemui.SysuiTestCase -import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository -import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository -import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepositoryImpl -import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFingerprintAuthInteractor +import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository +import com.android.systemui.authentication.domain.interactor.authenticationInteractor +import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository +import com.android.systemui.bouncer.data.repository.keyguardBouncerRepository +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor -import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository -import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor -import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor -import com.android.systemui.log.table.TableLogBuffer -import com.android.systemui.plugins.statusbar.StatusBarStateController -import com.android.systemui.statusbar.policy.KeyguardStateController -import com.android.systemui.util.mockito.whenever -import com.android.systemui.util.time.FakeSystemClock -import com.android.systemui.util.time.SystemClock -import dagger.Lazy -import kotlinx.coroutines.test.TestScope +import com.android.systemui.flags.DisableSceneContainer +import com.android.systemui.flags.EnableSceneContainer +import com.android.systemui.keyguard.data.repository.biometricSettingsRepository +import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository +import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.kosmos.testScope +import com.android.systemui.scene.domain.interactor.sceneInteractor +import com.android.systemui.scene.shared.model.Scenes +import com.android.systemui.statusbar.policy.keyguardStateController +import com.android.systemui.testKosmos +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.test.runTest import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.Mockito.mock -import org.mockito.MockitoAnnotations +import org.mockito.kotlin.whenever @SmallTest @RunWith(AndroidJUnit4::class) class AlternateBouncerInteractorTest : SysuiTestCase() { + private val kosmos = testKosmos() + private lateinit var underTest: AlternateBouncerInteractor - private lateinit var bouncerRepository: KeyguardBouncerRepository - private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository - private lateinit var fingerprintPropertyRepository: FakeFingerprintPropertyRepository - @Mock private lateinit var statusBarStateController: StatusBarStateController - @Mock private lateinit var keyguardStateController: KeyguardStateController - @Mock private lateinit var systemClock: SystemClock - @Mock private lateinit var bouncerLogger: TableLogBuffer - @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor @Before fun setup() { - MockitoAnnotations.initMocks(this) - bouncerRepository = - KeyguardBouncerRepositoryImpl( - FakeSystemClock(), - TestScope().backgroundScope, - bouncerLogger, - ) - biometricSettingsRepository = FakeBiometricSettingsRepository() - fingerprintPropertyRepository = FakeFingerprintPropertyRepository() - - mSetFlagsRule.disableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR) - initializeUnderTest() - } - - private fun initializeUnderTest() { - // Set any feature flags before creating the alternateBouncerInteractor - underTest = - AlternateBouncerInteractor( - statusBarStateController, - keyguardStateController, - bouncerRepository, - fingerprintPropertyRepository, - biometricSettingsRepository, - systemClock, - keyguardUpdateMonitor, - Lazy { mock(DeviceEntryFingerprintAuthInteractor::class.java) }, - Lazy { mock(KeyguardInteractor::class.java) }, - Lazy { mock(KeyguardTransitionInteractor::class.java) }, - TestScope().backgroundScope, - ) + underTest = kosmos.alternateBouncerInteractor } @Test(expected = IllegalStateException::class) + @EnableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR) fun enableUdfpsRefactor_deprecatedShowMethod_throwsIllegalStateException() { - mSetFlagsRule.enableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR) underTest.show() } @Test + @DisableSceneContainer + fun canShowAlternateBouncer_false_dueToTransitionState() = + kosmos.testScope.runTest { + givenAlternateBouncerSupported() + val canShowAlternateBouncer by collectLastValue(underTest.canShowAlternateBouncer) + kosmos.fakeKeyguardTransitionRepository.sendTransitionStep( + from = KeyguardState.AOD, + to = KeyguardState.GONE, + validateStep = false, + ) + assertFalse(canShowAlternateBouncer!!) + } + + @Test + @EnableSceneContainer + fun canShowAlternateBouncer_false_dueToTransitionState_scene_container() = + kosmos.testScope.runTest { + givenAlternateBouncerSupported() + val canShowAlternateBouncer by collectLastValue(underTest.canShowAlternateBouncer) + val isDeviceUnlocked by + collectLastValue( + kosmos.deviceUnlockedInteractor.deviceUnlockStatus.map { it.isUnlocked } + ) + assertThat(isDeviceUnlocked).isFalse() + + kosmos.authenticationInteractor.authenticate(FakeAuthenticationRepository.DEFAULT_PIN) + assertThat(isDeviceUnlocked).isTrue() + kosmos.sceneInteractor.changeScene(Scenes.Gone, "") + + assertThat(canShowAlternateBouncer).isFalse() + } + + @Test + @DisableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR) fun canShowAlternateBouncerForFingerprint_givenCanShow() { givenCanShowAlternateBouncer() assertTrue(underTest.canShowAlternateBouncerForFingerprint()) @@ -108,7 +111,7 @@ class AlternateBouncerInteractorTest : SysuiTestCase() { @Test fun canShowAlternateBouncerForFingerprint_alternateBouncerUIUnavailable() { givenCanShowAlternateBouncer() - bouncerRepository.setAlternateBouncerUIAvailable(false) + kosmos.keyguardBouncerRepository.setAlternateBouncerUIAvailable(false) assertFalse(underTest.canShowAlternateBouncerForFingerprint()) } @@ -116,7 +119,7 @@ class AlternateBouncerInteractorTest : SysuiTestCase() { @Test fun canShowAlternateBouncerForFingerprint_ifFingerprintIsNotUsuallyAllowed() { givenCanShowAlternateBouncer() - biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false) + kosmos.biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false) assertFalse(underTest.canShowAlternateBouncerForFingerprint()) } @@ -124,7 +127,7 @@ class AlternateBouncerInteractorTest : SysuiTestCase() { @Test fun canShowAlternateBouncerForFingerprint_strongBiometricNotAllowed() { givenCanShowAlternateBouncer() - biometricSettingsRepository.setIsFingerprintAuthCurrentlyAllowed(false) + kosmos.biometricSettingsRepository.setIsFingerprintAuthCurrentlyAllowed(false) assertFalse(underTest.canShowAlternateBouncerForFingerprint()) } @@ -132,23 +135,24 @@ class AlternateBouncerInteractorTest : SysuiTestCase() { @Test fun canShowAlternateBouncerForFingerprint_fingerprintLockedOut() { givenCanShowAlternateBouncer() - whenever(keyguardUpdateMonitor.isFingerprintLockedOut).thenReturn(true) + whenever(kosmos.keyguardUpdateMonitor.isFingerprintLockedOut).thenReturn(true) assertFalse(underTest.canShowAlternateBouncerForFingerprint()) } @Test + @DisableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR) fun show_whenCanShow() { givenCanShowAlternateBouncer() assertTrue(underTest.show()) - assertTrue(bouncerRepository.alternateBouncerVisible.value) + assertTrue(kosmos.keyguardBouncerRepository.alternateBouncerVisible.value) } @Test fun canShowAlternateBouncerForFingerprint_butCanDismissLockScreen() { givenCanShowAlternateBouncer() - whenever(keyguardStateController.isUnlocked).thenReturn(true) + whenever(kosmos.keyguardStateController.isUnlocked).thenReturn(true) assertFalse(underTest.canShowAlternateBouncerForFingerprint()) } @@ -156,82 +160,86 @@ class AlternateBouncerInteractorTest : SysuiTestCase() { @Test fun canShowAlternateBouncerForFingerprint_primaryBouncerShowing() { givenCanShowAlternateBouncer() - bouncerRepository.setPrimaryShow(true) + kosmos.keyguardBouncerRepository.setPrimaryShow(true) assertFalse(underTest.canShowAlternateBouncerForFingerprint()) } @Test + @DisableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR) fun show_whenCannotShow() { givenCannotShowAlternateBouncer() assertFalse(underTest.show()) - assertFalse(bouncerRepository.alternateBouncerVisible.value) + assertFalse(kosmos.keyguardBouncerRepository.alternateBouncerVisible.value) } @Test fun hide_wasPreviouslyShowing() { - bouncerRepository.setAlternateVisible(true) + kosmos.keyguardBouncerRepository.setAlternateVisible(true) assertTrue(underTest.hide()) - assertFalse(bouncerRepository.alternateBouncerVisible.value) + assertFalse(kosmos.keyguardBouncerRepository.alternateBouncerVisible.value) } @Test fun hide_wasNotPreviouslyShowing() { - bouncerRepository.setAlternateVisible(false) + kosmos.keyguardBouncerRepository.setAlternateVisible(false) assertFalse(underTest.hide()) - assertFalse(bouncerRepository.alternateBouncerVisible.value) + assertFalse(kosmos.keyguardBouncerRepository.alternateBouncerVisible.value) } @Test + @EnableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR) fun canShowAlternateBouncerForFingerprint_rearFps() { - mSetFlagsRule.enableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR) - initializeUnderTest() givenCanShowAlternateBouncer() - fingerprintPropertyRepository.supportsRearFps() // does not support alternate bouncer + kosmos.fingerprintPropertyRepository.supportsRearFps() // does not support alternate bouncer assertFalse(underTest.canShowAlternateBouncerForFingerprint()) } @Test + @DisableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR) fun alternateBouncerUiAvailable_fromMultipleSources() { - initializeUnderTest() - assertFalse(bouncerRepository.alternateBouncerUIAvailable.value) + assertFalse(kosmos.keyguardBouncerRepository.alternateBouncerUIAvailable.value) // GIVEN there are two different sources indicating the alternate bouncer is available underTest.setAlternateBouncerUIAvailable(true, "source1") underTest.setAlternateBouncerUIAvailable(true, "source2") - assertTrue(bouncerRepository.alternateBouncerUIAvailable.value) + assertTrue(kosmos.keyguardBouncerRepository.alternateBouncerUIAvailable.value) // WHEN one of the sources no longer says the UI is available underTest.setAlternateBouncerUIAvailable(false, "source1") // THEN alternate bouncer UI is still available (from the other source) - assertTrue(bouncerRepository.alternateBouncerUIAvailable.value) + assertTrue(kosmos.keyguardBouncerRepository.alternateBouncerUIAvailable.value) // WHEN all sources say the UI is not available underTest.setAlternateBouncerUIAvailable(false, "source2") // THEN alternate boucer UI is not available - assertFalse(bouncerRepository.alternateBouncerUIAvailable.value) + assertFalse(kosmos.keyguardBouncerRepository.alternateBouncerUIAvailable.value) } - private fun givenCanShowAlternateBouncer() { + private fun givenAlternateBouncerSupported() { if (DeviceEntryUdfpsRefactor.isEnabled) { - fingerprintPropertyRepository.supportsUdfps() + kosmos.fingerprintPropertyRepository.supportsUdfps() } else { - bouncerRepository.setAlternateBouncerUIAvailable(true) + kosmos.keyguardBouncerRepository.setAlternateBouncerUIAvailable(true) } - bouncerRepository.setPrimaryShow(false) - biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true) - biometricSettingsRepository.setIsFingerprintAuthCurrentlyAllowed(true) - whenever(keyguardUpdateMonitor.isFingerprintLockedOut).thenReturn(false) - whenever(keyguardStateController.isUnlocked).thenReturn(false) + } + + private fun givenCanShowAlternateBouncer() { + givenAlternateBouncerSupported() + kosmos.keyguardBouncerRepository.setPrimaryShow(false) + kosmos.biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true) + kosmos.biometricSettingsRepository.setIsFingerprintAuthCurrentlyAllowed(true) + whenever(kosmos.keyguardUpdateMonitor.isFingerprintLockedOut).thenReturn(false) + whenever(kosmos.keyguardStateController.isUnlocked).thenReturn(false) } private fun givenCannotShowAlternateBouncer() { - biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false) + kosmos.biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false) } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModelTest.kt new file mode 100644 index 000000000000..460a1fc44e67 --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModelTest.kt @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2024 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.keyguard.ui.viewmodel + +import android.graphics.Color +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.biometrics.data.repository.fakeFingerprintPropertyRepository +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository +import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository +import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.kosmos.testScope +import com.android.systemui.testKosmos +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runTest +import org.junit.Test +import org.junit.runner.RunWith + +@ExperimentalCoroutinesApi +@SmallTest +@RunWith(AndroidJUnit4::class) +class DeviceEntryForegroundViewModelTest : SysuiTestCase() { + private val kosmos = testKosmos() + private val testScope = kosmos.testScope + private val underTest: DeviceEntryForegroundViewModel = + kosmos.deviceEntryForegroundIconViewModel + + @Test + fun aodIconColorWhite() = + testScope.runTest { + val viewModel by collectLastValue(underTest.viewModel) + + givenUdfpsEnrolledAndEnabled() + kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.AOD, + testScope = testScope, + ) + + assertThat(viewModel?.useAodVariant).isEqualTo(true) + assertThat(viewModel?.tint).isEqualTo(Color.WHITE) + } + + private fun givenUdfpsEnrolledAndEnabled() { + kosmos.fakeFingerprintPropertyRepository.supportsUdfps() + kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt index e0334a060ee2..1d11dfbc48a8 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt @@ -28,6 +28,9 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.plugins.statusbar.StatusBarStateController +import com.android.systemui.scene.domain.interactor.SceneInteractor +import com.android.systemui.scene.shared.flag.SceneContainerFlag +import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.kotlin.BooleanFlowOperators.anyOf import com.android.systemui.util.time.SystemClock @@ -60,6 +63,7 @@ constructor( private val deviceEntryFingerprintAuthInteractor: Lazy<DeviceEntryFingerprintAuthInteractor>, private val keyguardInteractor: Lazy<KeyguardInteractor>, keyguardTransitionInteractor: Lazy<KeyguardTransitionInteractor>, + sceneInteractor: Lazy<SceneInteractor>, @Application scope: CoroutineScope, ) { var receivedDownTouch = false @@ -96,30 +100,42 @@ constructor( alternateBouncerSupported .flatMapLatest { alternateBouncerSupported -> if (alternateBouncerSupported) { - keyguardTransitionInteractor.get().currentKeyguardState.flatMapLatest { - currentKeyguardState -> - if (currentKeyguardState == KeyguardState.GONE) { - flowOf(false) - } else { - combine( - deviceEntryFingerprintAuthInteractor - .get() - .isFingerprintAuthCurrentlyAllowed, - keyguardInteractor.get().isKeyguardDismissible, - bouncerRepository.primaryBouncerShow, - isDozingOrAod + combine( + keyguardTransitionInteractor.get().currentKeyguardState, + if (SceneContainerFlag.isEnabled) { + sceneInteractor.get().currentScene + } else { + flowOf(Scenes.Lockscreen) + }, + ::Pair + ) + .flatMapLatest { (currentKeyguardState, transitionState) -> + if (currentKeyguardState == KeyguardState.GONE) { + flowOf(false) + } else if ( + SceneContainerFlag.isEnabled && transitionState == Scenes.Gone ) { - fingerprintAllowed, - keyguardDismissible, - primaryBouncerShowing, - dozing -> - fingerprintAllowed && - !keyguardDismissible && - !primaryBouncerShowing && - !dozing + flowOf(false) + } else { + combine( + deviceEntryFingerprintAuthInteractor + .get() + .isFingerprintAuthCurrentlyAllowed, + keyguardInteractor.get().isKeyguardDismissible, + bouncerRepository.primaryBouncerShow, + isDozingOrAod + ) { + fingerprintAllowed, + keyguardDismissible, + primaryBouncerShowing, + dozing -> + fingerprintAllowed && + !keyguardDismissible && + !primaryBouncerShowing && + !dozing + } } } - } } else { flowOf(false) } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index 9cdba5853959..956c0f51cda0 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -77,6 +77,7 @@ import com.android.internal.policy.IKeyguardStateCallback; import com.android.keyguard.mediator.ScreenOnCoordinator; import com.android.systemui.SystemUIApplication; import com.android.systemui.dagger.qualifiers.Application; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.keyguard.ui.binder.KeyguardSurfaceBehindParamsApplier; import com.android.systemui.keyguard.ui.binder.KeyguardSurfaceBehindViewBinder; @@ -101,6 +102,7 @@ import kotlinx.coroutines.CoroutineScope; import java.util.ArrayList; import java.util.Map; import java.util.WeakHashMap; +import java.util.concurrent.Executor; import javax.inject.Inject; @@ -116,6 +118,7 @@ public class KeyguardService extends Service { private final DisplayTracker mDisplayTracker; private final PowerInteractor mPowerInteractor; private final Lazy<SceneInteractor> mSceneInteractorLazy; + private final Executor mMainExecutor; private static RemoteAnimationTarget[] wrap(TransitionInfo info, boolean wallpapers, SurfaceControl.Transaction t, ArrayMap<SurfaceControl, SurfaceControl> leashMap, @@ -331,7 +334,8 @@ public class KeyguardService extends Service { FeatureFlags featureFlags, PowerInteractor powerInteractor, WindowManagerOcclusionManager windowManagerOcclusionManager, - Lazy<SceneInteractor> sceneInteractorLazy) { + Lazy<SceneInteractor> sceneInteractorLazy, + @Main Executor mainExecutor) { super(); mKeyguardViewMediator = keyguardViewMediator; mKeyguardLifecyclesDispatcher = keyguardLifecyclesDispatcher; @@ -341,6 +345,7 @@ public class KeyguardService extends Service { mFlags = featureFlags; mPowerInteractor = powerInteractor; mSceneInteractorLazy = sceneInteractorLazy; + mMainExecutor = mainExecutor; if (KeyguardWmStateRefactor.isEnabled()) { WindowManagerLockscreenVisibilityViewBinder.bind( @@ -619,8 +624,8 @@ public class KeyguardService extends Service { mKeyguardViewMediator.showDismissibleKeyguard(); if (SceneContainerFlag.isEnabled() && mFoldGracePeriodProvider.get().isEnabled()) { - mSceneInteractorLazy.get().changeScene( - Scenes.Lockscreen, "KeyguardService.showDismissibleKeyguard"); + mMainExecutor.execute(() -> mSceneInteractorLazy.get().changeScene( + Scenes.Lockscreen, "KeyguardService.showDismissibleKeyguard")); } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/DeviceEntryIconView.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/DeviceEntryIconView.kt index 200d30c66305..7a2e61049ea7 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/DeviceEntryIconView.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/DeviceEntryIconView.kt @@ -88,6 +88,12 @@ constructor( } } + /** + * Setups different icon states. + * - All lottie views will require a LottieOnCompositionLoadedListener to update + * LottieProperties (like color) of the view. + * - Drawable properties can be updated using ImageView properties like imageTintList. + */ private fun setupIconStates() { // Lockscreen States // LOCK diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt index 0aa6d129f247..0f1f5c1f1cb5 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt @@ -64,13 +64,6 @@ constructor( } } - private val color: Flow<Int> = - deviceEntryIconViewModel.useBackgroundProtection.flatMapLatest { useBgProtection -> - configurationInteractor.onAnyConfigurationChange - .map { getColor(useBgProtection) } - .onStart { emit(getColor(useBgProtection)) } - } - // While dozing, the display can show the AOD UI; show the AOD udfps when dozing private val useAodIconVariant: Flow<Boolean> = deviceEntryUdfpsInteractor.isUdfpsEnrolledAndEnabled.flatMapLatest { udfspEnrolled -> @@ -81,6 +74,22 @@ constructor( } } + private val color: Flow<Int> = + useAodIconVariant + .flatMapLatest { useAodVariant -> + if (useAodVariant) { + flowOf(android.graphics.Color.WHITE) + } else { + deviceEntryIconViewModel.useBackgroundProtection.flatMapLatest { useBgProtection + -> + configurationInteractor.onAnyConfigurationChange + .map { getColor(useBgProtection) } + .onStart { emit(getColor(useBgProtection)) } + } + } + } + .distinctUntilChanged() + private val padding: Flow<Int> = deviceEntryUdfpsInteractor.isUdfpsSupported.flatMapLatest { udfpsSupported -> if (udfpsSupported) { diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt index 3ac070a28b2b..1b5fa345ebb4 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt @@ -22,8 +22,13 @@ import android.app.Notification import android.content.Context import android.graphics.Bitmap import android.graphics.Rect +import android.graphics.Region +import android.os.Looper +import android.view.Choreographer +import android.view.InputEvent import android.view.KeyEvent import android.view.LayoutInflater +import android.view.MotionEvent import android.view.ScrollCaptureResponse import android.view.View import android.view.ViewTreeObserver @@ -48,6 +53,8 @@ import com.android.systemui.screenshot.ui.ScreenshotShelfView import com.android.systemui.screenshot.ui.binder.ScreenshotShelfViewBinder import com.android.systemui.screenshot.ui.viewmodel.AnimationState import com.android.systemui.screenshot.ui.viewmodel.ScreenshotViewModel +import com.android.systemui.shared.system.InputChannelCompat +import com.android.systemui.shared.system.InputMonitorCompat import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -91,6 +98,8 @@ constructor( override var isPendingSharedTransition = false private val animationController = ScreenshotAnimationController(view, viewModel) + private var inputMonitor: InputMonitorCompat? = null + private var inputEventReceiver: InputChannelCompat.InputEventReceiver? = null init { shelfViewBinder.bind( @@ -106,20 +115,25 @@ constructor( setOnKeyListener { requestDismissal(SCREENSHOT_DISMISSED_OTHER) } debugLog(DEBUG_WINDOW) { "adding OnComputeInternalInsetsListener" } view.viewTreeObserver.addOnComputeInternalInsetsListener { info -> - val touchableRegion = - view.getTouchRegion( - windowManager.currentWindowMetrics.windowInsets.getInsets( - WindowInsets.Type.systemGestures() - ) - ) info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION) - info.touchableRegion.set(touchableRegion) + info.touchableRegion.set(getTouchRegion()) } screenshotPreview = view.screenshotPreview thumbnailObserver.setViews( view.blurredScreenshotPreview, view.requireViewById(R.id.screenshot_preview_border) ) + view.addOnAttachStateChangeListener( + object : View.OnAttachStateChangeListener { + override fun onViewAttachedToWindow(v: View) { + startInputListening() + } + + override fun onViewDetachedFromWindow(v: View) { + stopInputListening() + } + } + ) } override fun reset() { @@ -236,7 +250,12 @@ constructor( callbacks?.onUserInteraction() // reset the timeout } - override fun stopInputListening() {} + override fun stopInputListening() { + inputMonitor?.dispose() + inputMonitor = null + inputEventReceiver?.dispose() + inputEventReceiver = null + } override fun requestFocus() { view.requestFocus() @@ -303,6 +322,32 @@ constructor( ) } + private fun startInputListening() { + stopInputListening() + inputMonitor = + InputMonitorCompat("Screenshot", displayId).also { + inputEventReceiver = + it.getInputReceiver(Looper.getMainLooper(), Choreographer.getInstance()) { + ev: InputEvent? -> + if ( + ev is MotionEvent && + ev.actionMasked == MotionEvent.ACTION_DOWN && + !getTouchRegion().contains(ev.rawX.toInt(), ev.rawY.toInt()) + ) { + callbacks?.onTouchOutside() + } + } + } + } + + private fun getTouchRegion(): Region { + return view.getTouchRegion( + windowManager.currentWindowMetrics.windowInsets.getInsets( + WindowInsets.Type.systemGestures() + ) + ) + } + @AssistedFactory interface Factory : ScreenshotViewProxy.Factory { override fun getProxy(context: Context, displayId: Int): ScreenshotShelfViewProxy diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/GesturePointerEventListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/GesturePointerEventListener.kt index 8505c5ff32e0..0d5ade7ab49c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/GesturePointerEventListener.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/GesturePointerEventListener.kt @@ -98,10 +98,10 @@ constructor(context: Context, gestureDetector: GesturePointerEventDetector) : Co return } val r = mContext.resources - val defaultThreshold = r.getDimensionPixelSize(R.dimen.system_gestures_start_threshold) - mSwipeStartThreshold[defaultThreshold, defaultThreshold, defaultThreshold] = - defaultThreshold - mSwipeDistanceThreshold = defaultThreshold + val startThreshold = r.getDimensionPixelSize(R.dimen.system_gestures_start_threshold) + mSwipeStartThreshold[startThreshold, startThreshold, startThreshold] = startThreshold + mSwipeDistanceThreshold = + r.getDimensionPixelSize(R.dimen.system_gestures_distance_threshold) val display = DisplayManagerGlobal.getInstance().getRealDisplay(mContext.displayId) val displayCutout = display.cutout if (displayCutout != null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeUpGestureHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeUpGestureHandler.kt index 2fd0a5324d15..0ece88dcd184 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeUpGestureHandler.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeUpGestureHandler.kt @@ -46,7 +46,7 @@ abstract class SwipeUpGestureHandler( private var monitoringCurrentTouch: Boolean = false private var swipeDistanceThreshold: Int = context.resources.getDimensionPixelSize( - com.android.internal.R.dimen.system_gestures_start_threshold + com.android.internal.R.dimen.system_gestures_distance_threshold ) override fun onInputEvent(ev: InputEvent) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt index 472d0458b77a..8be1e7a2b3f1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt @@ -115,6 +115,7 @@ class DeviceEntrySideFpsOverlayInteractorTest : SysuiTestCase() { { mock(DeviceEntryFingerprintAuthInteractor::class.java) }, { mock(KeyguardInteractor::class.java) }, { mock(KeyguardTransitionInteractor::class.java) }, + { kosmos.sceneInteractor }, testScope.backgroundScope, ) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorKosmos.kt index 070a3697df68..f75cdd4d3bbc 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorKosmos.kt @@ -26,15 +26,15 @@ import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInterac import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.plugins.statusbar.statusBarStateController -import com.android.systemui.statusbar.policy.KeyguardStateControllerImpl -import com.android.systemui.util.mockito.mock +import com.android.systemui.scene.domain.interactor.sceneInteractor +import com.android.systemui.statusbar.policy.keyguardStateController import com.android.systemui.util.time.systemClock -var Kosmos.alternateBouncerInteractor by +val Kosmos.alternateBouncerInteractor: AlternateBouncerInteractor by Kosmos.Fixture { AlternateBouncerInteractor( statusBarStateController = statusBarStateController, - keyguardStateController = mock<KeyguardStateControllerImpl>(), + keyguardStateController = keyguardStateController, bouncerRepository = keyguardBouncerRepository, fingerprintPropertyRepository = fingerprintPropertyRepository, biometricSettingsRepository = biometricSettingsRepository, @@ -44,5 +44,6 @@ var Kosmos.alternateBouncerInteractor by keyguardInteractor = { keyguardInteractor }, keyguardTransitionInteractor = { keyguardTransitionInteractor }, scope = testScope.backgroundScope, + sceneInteractor = { sceneInteractor }, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorFactory.kt index 7eef704c1622..be8048e774f6 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorFactory.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorFactory.kt @@ -36,6 +36,7 @@ import com.android.systemui.keyguard.data.repository.FakeTrustRepository import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.power.data.repository.FakePowerRepository import com.android.systemui.power.domain.interactor.PowerInteractorFactory +import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.user.data.repository.FakeUserRepository import com.android.systemui.user.domain.interactor.SelectedUserInteractor @@ -89,6 +90,7 @@ object KeyguardDismissInteractorFactory { { mock(DeviceEntryFingerprintAuthInteractor::class.java) }, { mock(KeyguardInteractor::class.java) }, { mock(KeyguardTransitionInteractor::class.java) }, + { mock(SceneInteractor::class.java) }, testScope.backgroundScope, ) val powerInteractorWithDeps = diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/KeyguardStateControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/KeyguardStateControllerKosmos.kt index 0e909c498a2b..f19ac1e5a58d 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/KeyguardStateControllerKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/KeyguardStateControllerKosmos.kt @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.policy import com.android.systemui.kosmos.Kosmos -import com.android.systemui.util.mockito.mock +import org.mockito.Mockito.mock -var Kosmos.keyguardStateController by Kosmos.Fixture { mock<KeyguardStateController>() } +var Kosmos.keyguardStateController: KeyguardStateController by + Kosmos.Fixture { mock(KeyguardStateController::class.java) } diff --git a/services/autofill/java/com/android/server/autofill/SaveEventLogger.java b/services/autofill/java/com/android/server/autofill/SaveEventLogger.java index b7f12adc90d4..c41a8cd78693 100644 --- a/services/autofill/java/com/android/server/autofill/SaveEventLogger.java +++ b/services/autofill/java/com/android/server/autofill/SaveEventLogger.java @@ -23,6 +23,7 @@ import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SAVE_EVENT_RE import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_NONE; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_NO_SAVE_INFO; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_NO_VALUE_CHANGED; +import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_SCREEN_HAS_CREDMAN_FIELD; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_SESSION_DESTROYED; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_UNKNOWN; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_WITH_DELAY_SAVE_FLAG; @@ -112,6 +113,8 @@ public class SaveEventLogger { AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_SESSION_DESTROYED; public static final int NO_SAVE_REASON_WITH_DONT_SAVE_ON_FINISH_FLAG = AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_WITH_DONT_SAVE_ON_FINISH_FLAG; + public static final int NO_SAVE_REASON_SCREEN_HAS_CREDMAN_FIELD = + AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_SCREEN_HAS_CREDMAN_FIELD; public static final long UNINITIATED_TIMESTAMP = Long.MIN_VALUE; diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index a8b123518db3..c46464b7cac8 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -89,6 +89,7 @@ import static com.android.server.autofill.SaveEventLogger.NO_SAVE_REASON_HAS_EMP import static com.android.server.autofill.SaveEventLogger.NO_SAVE_REASON_NONE; import static com.android.server.autofill.SaveEventLogger.NO_SAVE_REASON_NO_SAVE_INFO; import static com.android.server.autofill.SaveEventLogger.NO_SAVE_REASON_NO_VALUE_CHANGED; +import static com.android.server.autofill.SaveEventLogger.NO_SAVE_REASON_SCREEN_HAS_CREDMAN_FIELD; import static com.android.server.autofill.SaveEventLogger.NO_SAVE_REASON_SESSION_DESTROYED; import static com.android.server.autofill.SaveEventLogger.NO_SAVE_REASON_WITH_DELAY_SAVE_FLAG; import static com.android.server.autofill.SaveEventLogger.NO_SAVE_REASON_WITH_DONT_SAVE_ON_FINISH_FLAG; @@ -3673,6 +3674,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState Slog.v(TAG, "Call to Session#showSaveLocked() rejected - " + "there is credman field in screen"); } + mSaveEventLogger.maybeSetSaveUiNotShownReason(NO_SAVE_REASON_SCREEN_HAS_CREDMAN_FIELD); + mSaveEventLogger.logAndEndEvent(); return new SaveResult(/* logSaveShown= */ false, /* removeSession= */ true, Event.NO_SAVE_UI_REASON_NONE); } diff --git a/services/core/java/com/android/server/display/ExternalDisplayPolicy.java b/services/core/java/com/android/server/display/ExternalDisplayPolicy.java index b24caf4ced76..44c8d1cfee36 100644 --- a/services/core/java/com/android/server/display/ExternalDisplayPolicy.java +++ b/services/core/java/com/android/server/display/ExternalDisplayPolicy.java @@ -136,6 +136,9 @@ class ExternalDisplayPolicy { handleExternalDisplayConnectedLocked(logicalDisplay); } } + if (!mDisplayIdsWaitingForBootCompletion.isEmpty()) { + mLogicalDisplayMapper.updateLogicalDisplaysLocked(); + } mDisplayIdsWaitingForBootCompletion.clear(); } @@ -222,7 +225,7 @@ class ExternalDisplayPolicy { } else { // As external display is enabled by default, need to disable it now. // TODO(b/292196201) Remove when the display can be disabled before DPC is created. - mLogicalDisplayMapper.setDisplayEnabledLocked(logicalDisplay, false); + mLogicalDisplayMapper.setEnabledLocked(logicalDisplay, false); } if (!isExternalDisplayAllowed()) { diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java index 01485cb3a4d1..e645e98c215c 100644 --- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java +++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java @@ -1195,7 +1195,6 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { return display; } - @VisibleForTesting void setEnabledLocked(LogicalDisplay display, boolean isEnabled) { final int displayId = display.getDisplayIdLocked(); final DisplayInfo info = display.getDisplayInfoLocked(); diff --git a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java index f992a2399c61..88da6fb94754 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java @@ -100,6 +100,9 @@ public class HdmiCecNetwork { // Map from port ID to HdmiDeviceInfo. private UnmodifiableSparseArray<HdmiDeviceInfo> mPortDeviceMap; + // Cached physical address. + private int mPhysicalAddress = Constants.INVALID_PHYSICAL_ADDRESS; + HdmiCecNetwork(HdmiControlService hdmiControlService, HdmiCecController hdmiCecController, HdmiMhlControllerStub hdmiMhlController) { @@ -431,6 +434,8 @@ public class HdmiCecNetwork { // each port. Return empty array if CEC HAL didn't provide the info. if (mHdmiCecController != null) { cecPortInfo = mHdmiCecController.getPortInfos(); + // Invalid cached physical address. + mPhysicalAddress = Constants.INVALID_PHYSICAL_ADDRESS; } if (cecPortInfo == null) { return; @@ -856,7 +861,10 @@ public class HdmiCecNetwork { } public int getPhysicalAddress() { - return mHdmiCecController.getPhysicalAddress(); + if (mPhysicalAddress == Constants.INVALID_PHYSICAL_ADDRESS) { + mPhysicalAddress = mHdmiCecController.getPhysicalAddress(); + } + return mPhysicalAddress; } @ServiceThreadOnly diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index cca73b5eabf0..dbd1e65e8b0f 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -1567,7 +1567,7 @@ public class HdmiControlService extends SystemService { * Returns physical address of the device. */ int getPhysicalAddress() { - return mCecController.getPhysicalAddress(); + return mHdmiCecNetwork.getPhysicalAddress(); } /** diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index f62c76e1505a..e00e81371853 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -29,6 +29,7 @@ import android.app.AlarmManager.OnAlarmListener; import android.app.admin.DevicePolicyManager; import android.app.trust.ITrustListener; import android.app.trust.ITrustManager; +import android.app.trust.TrustManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -47,6 +48,8 @@ import android.hardware.biometrics.BiometricSourceType; import android.hardware.biometrics.SensorProperties; import android.hardware.face.FaceManager; import android.hardware.fingerprint.FingerprintManager; +import android.hardware.location.ISignificantPlaceProvider; +import android.hardware.location.ISignificantPlaceProviderManager; import android.os.Binder; import android.os.Build; import android.os.Bundle; @@ -83,6 +86,8 @@ import com.android.internal.infra.AndroidFuture; import com.android.internal.util.DumpUtils; import com.android.internal.widget.LockPatternUtils; import com.android.server.SystemService; +import com.android.server.servicewatcher.CurrentUserServiceSupplier; +import com.android.server.servicewatcher.ServiceWatcher; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -248,6 +253,9 @@ public class TrustManagerService extends SystemService { private boolean mTrustAgentsCanRun = false; private int mCurrentUser = UserHandle.USER_SYSTEM; + private ServiceWatcher mSignificantPlaceServiceWatcher; + private volatile boolean mIsInSignificantPlace = false; + /** * A class for providing dependencies to {@link TrustManagerService} in both production and test * cases. @@ -310,6 +318,38 @@ public class TrustManagerService extends SystemService { mTrustAgentsCanRun = true; refreshAgentList(UserHandle.USER_ALL); refreshDeviceLockedForUser(UserHandle.USER_ALL); + + if (android.security.Flags.significantPlaces()) { + mSignificantPlaceServiceWatcher = ServiceWatcher.create(mContext, TAG, + CurrentUserServiceSupplier.create( + mContext, + TrustManager.ACTION_BIND_SIGNIFICANT_PLACE_PROVIDER, + null, + null, + null), + new ServiceWatcher.ServiceListener<>() { + @Override + public void onBind(IBinder binder, + CurrentUserServiceSupplier.BoundServiceInfo service) + throws RemoteException { + ISignificantPlaceProvider.Stub.asInterface(binder) + .setSignificantPlaceProviderManager( + new ISignificantPlaceProviderManager.Stub() { + @Override + public void setInSignificantPlace( + boolean inSignificantPlace) { + mIsInSignificantPlace = inSignificantPlace; + } + }); + } + + @Override + public void onUnbind() { + mIsInSignificantPlace = false; + } + }); + mSignificantPlaceServiceWatcher.register(); + } } else if (phase == SystemService.PHASE_BOOT_COMPLETED) { maybeEnableFactoryTrustAgents(UserHandle.USER_SYSTEM); } @@ -1651,6 +1691,11 @@ public class TrustManagerService extends SystemService { } } + @Override + public boolean isInSignificantPlace() { + return mIsInSignificantPlace; + } + private void enforceReportPermission() { mContext.enforceCallingOrSelfPermission( Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events"); @@ -1680,6 +1725,9 @@ public class TrustManagerService extends SystemService { for (UserInfo user : userInfos) { dumpUser(fout, user, user.id == mCurrentUser); } + if (mSignificantPlaceServiceWatcher != null) { + mSignificantPlaceServiceWatcher.dump(fout); + } } }, 1500); } diff --git a/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java b/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java index 100735784fb1..b7944d3b8234 100644 --- a/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java +++ b/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java @@ -107,11 +107,12 @@ class SystemGesturesPointerEventListener implements PointerEventListener { void onConfigurationChanged() { final Resources r = mContext.getResources(); - final int defaultThreshold = r.getDimensionPixelSize( + final int startThreshold = r.getDimensionPixelSize( com.android.internal.R.dimen.system_gestures_start_threshold); - mSwipeStartThreshold.set(defaultThreshold, defaultThreshold, defaultThreshold, - defaultThreshold); - mSwipeDistanceThreshold = defaultThreshold; + mSwipeStartThreshold.set(startThreshold, startThreshold, startThreshold, + startThreshold); + mSwipeDistanceThreshold = r.getDimensionPixelSize( + com.android.internal.R.dimen.system_gestures_distance_threshold); final Display display = DisplayManagerGlobal.getInstance() .getRealDisplay(Display.DEFAULT_DISPLAY); diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java index 8844e6cc3a2c..d0eb83aa986b 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java @@ -2513,9 +2513,8 @@ public class DisplayManagerServiceTest { LogicalDisplay display = logicalDisplayMapper.getDisplayLocked(displayDevice, /* includeDisabled= */ true); assertThat(display.isEnabledLocked()).isFalse(); - // TODO(b/332711269) make sure only one DISPLAY_GROUP_EVENT_ADDED sent. assertThat(callback.receivedEvents()).containsExactly(DISPLAY_GROUP_EVENT_ADDED, - DISPLAY_GROUP_EVENT_ADDED, EVENT_DISPLAY_CONNECTED).inOrder(); + EVENT_DISPLAY_CONNECTED).inOrder(); } @Test @@ -3359,8 +3358,11 @@ public class DisplayManagerServiceTest { } displayDeviceInfo.address = new TestUtils.TestDisplayAddress(); displayDevice.setDisplayDeviceInfo(displayDeviceInfo); - displayManager.getDisplayDeviceRepository() - .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED); + + displayManager.getDisplayHandler().runWithScissors(() -> { + displayManager.getDisplayDeviceRepository() + .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED); + }, 0 /* now */); return displayDevice; } diff --git a/services/tests/displayservicetests/src/com/android/server/display/ExternalDisplayPolicyTest.java b/services/tests/displayservicetests/src/com/android/server/display/ExternalDisplayPolicyTest.java index ea08be4f1be4..82acaf86988d 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/ExternalDisplayPolicyTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/ExternalDisplayPolicyTest.java @@ -317,7 +317,7 @@ public class ExternalDisplayPolicyTest { mDisplayEventCaptor.capture()); assertThat(mLogicalDisplayCaptor.getValue()).isEqualTo(mMockedLogicalDisplay); assertThat(mDisplayEventCaptor.getValue()).isEqualTo(EVENT_DISPLAY_CONNECTED); - verify(mMockedLogicalDisplayMapper).setDisplayEnabledLocked(eq(mMockedLogicalDisplay), + verify(mMockedLogicalDisplayMapper).setEnabledLocked(eq(mMockedLogicalDisplay), eq(false)); clearInvocations(mMockedLogicalDisplayMapper); clearInvocations(mMockedLogicalDisplay); diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java index c1ae85252ffc..6d863015231c 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java @@ -86,6 +86,8 @@ public class ActiveSourceActionTest { mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(mContextSpy)); mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper()); mNativeWrapper = new FakeNativeWrapper(); + mPhysicalAddress = 0x2000; + mNativeWrapper.setPhysicalAddress(mPhysicalAddress); HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper( this.mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter()); mHdmiControlService.setCecController(hdmiCecController); @@ -94,8 +96,6 @@ public class ActiveSourceActionTest { mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY); mPowerManager = new FakePowerManagerWrapper(mContextSpy); mHdmiControlService.setPowerManager(mPowerManager); - mPhysicalAddress = 0x2000; - mNativeWrapper.setPhysicalAddress(mPhysicalAddress); mTestLooper.dispatchAll(); } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java index e669e7c019d6..2296911a4e7e 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java @@ -104,6 +104,8 @@ public class DevicePowerStatusActionTest { mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(mContextSpy)); mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper()); mNativeWrapper = new FakeNativeWrapper(); + mPhysicalAddress = 0x2000; + mNativeWrapper.setPhysicalAddress(mPhysicalAddress); HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper( this.mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter()); mHdmiControlService.setCecController(hdmiCecController); @@ -112,8 +114,6 @@ public class DevicePowerStatusActionTest { mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY); mPowerManager = new FakePowerManagerWrapper(mContextSpy); mHdmiControlService.setPowerManager(mPowerManager); - mPhysicalAddress = 0x2000; - mNativeWrapper.setPhysicalAddress(mPhysicalAddress); mTestLooper.dispatchAll(); mPlaybackDevice = mHdmiControlService.playback(); mDevicePowerStatusAction = DevicePowerStatusAction.create(mPlaybackDevice, ADDR_TV, diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java index 29d20a64e439..47cfa4218435 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java @@ -137,6 +137,7 @@ public class DeviceSelectActionFromPlaybackTest { mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context)); mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper()); mNativeWrapper = new FakeNativeWrapper(); + mNativeWrapper.setPhysicalAddress(0x0000); mHdmiCecController = HdmiCecController.createWithNativeWrapper( mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter()); mHdmiControlService.setCecController(mHdmiCecController); @@ -150,7 +151,7 @@ public class DeviceSelectActionFromPlaybackTest { mHdmiControlService.initService(); mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY); - mNativeWrapper.setPhysicalAddress(0x0000); + mPowerManager = new FakePowerManagerWrapper(context); mHdmiControlService.setPowerManager(mPowerManager); mTestLooper.dispatchAll(); diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java index d32b75bc57da..eb4a628e14e5 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java @@ -146,6 +146,7 @@ public class DeviceSelectActionFromTvTest { mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context)); mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper()); mNativeWrapper = new FakeNativeWrapper(); + mNativeWrapper.setPhysicalAddress(0x0000); mHdmiCecController = HdmiCecController.createWithNativeWrapper( mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter()); mHdmiControlService.setCecController(mHdmiCecController); @@ -168,7 +169,6 @@ public class DeviceSelectActionFromTvTest { mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY); mPowerManager = new FakePowerManagerWrapper(context); mHdmiControlService.setPowerManager(mPowerManager); - mNativeWrapper.setPhysicalAddress(0x0000); mTestLooper.dispatchAll(); mNativeWrapper.clearResultMessages(); mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_PLAYBACK_1); diff --git a/services/tests/servicestests/src/com/android/server/hdmi/FakeNativeWrapper.java b/services/tests/servicestests/src/com/android/server/hdmi/FakeNativeWrapper.java index cb19029d246e..bfe435c2b30b 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/FakeNativeWrapper.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/FakeNativeWrapper.java @@ -62,6 +62,7 @@ final class FakeNativeWrapper implements NativeWrapper { private HdmiCecController.HdmiCecCallback mCallback = null; private int mCecVersion = HdmiControlManager.HDMI_CEC_VERSION_2_0; private boolean mIsCecControlEnabled = true; + private boolean mGetPhysicalAddressCalled = false; @Override public String nativeInit() { @@ -96,6 +97,7 @@ final class FakeNativeWrapper implements NativeWrapper { @Override public int nativeGetPhysicalAddress() { + mGetPhysicalAddressCalled = true; return mMyPhysicalAddress; } @@ -161,6 +163,10 @@ final class FakeNativeWrapper implements NativeWrapper { return mIsCecControlEnabled; } + public boolean getPhysicalAddressCalled() { + return mGetPhysicalAddressCalled; + } + public void setCecVersion(@HdmiControlManager.HdmiCecVersion int cecVersion) { mCecVersion = cecVersion; } @@ -200,6 +206,10 @@ final class FakeNativeWrapper implements NativeWrapper { mResultMessages.clear(); } + public void clearGetPhysicalAddressCallHistory() { + mGetPhysicalAddressCalled = false; + } + public void setPollAddressResponse(int logicalAddress, int response) { mPollAddressResponse[logicalAddress] = response; } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java index 5502de8f46e9..02441648a589 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java @@ -472,6 +472,7 @@ public class HdmiCecLocalDeviceAudioSystemTest { HdmiCecMessage message = HdmiCecMessageBuilder.buildRequestArcInitiation(ADDR_TV, ADDR_AUDIO_SYSTEM); mNativeWrapper.setPhysicalAddress(0x1100); + mHdmiControlService.onHotplug(0x1100, true); assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcInitiate(message)) .isEqualTo(Constants.ABORT_NOT_IN_CORRECT_MODE); @@ -482,6 +483,8 @@ public class HdmiCecLocalDeviceAudioSystemTest { HdmiCecMessage message = HdmiCecMessageBuilder.buildRequestArcInitiation(ADDR_TV, ADDR_AUDIO_SYSTEM); mNativeWrapper.setPhysicalAddress(0x1000); + mHdmiControlService.onHotplug(0x1000, true); + mHdmiCecLocalDeviceAudioSystem.removeAction(ArcInitiationActionFromAvr.class); assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcInitiate(message)) diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java index 8df7d548e21e..95a7f4b6c80f 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java @@ -167,6 +167,7 @@ public class HdmiCecLocalDevicePlaybackTest { } }; mHdmiCecLocalDevicePlayback.init(); + mPlaybackPhysicalAddress = 0x2000; HdmiPortInfo[] hdmiPortInfos = new HdmiPortInfo[1]; hdmiPortInfos[0] = new HdmiPortInfo.Builder(1, HdmiPortInfo.PORT_OUTPUT, 0x0000) @@ -176,13 +177,12 @@ public class HdmiCecLocalDevicePlaybackTest { .build(); mNativeWrapper.setPortInfo(hdmiPortInfos); mNativeWrapper.setPortConnectionStatus(1, true); + mNativeWrapper.setPhysicalAddress(mPlaybackPhysicalAddress); mHdmiControlService.initService(); mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY); mPowerManager = new FakePowerManagerWrapper(context); mHdmiControlService.setPowerManager(mPowerManager); mHdmiControlService.setPowerManagerInternal(mPowerManagerInternal); - mPlaybackPhysicalAddress = 0x2000; - mNativeWrapper.setPhysicalAddress(mPlaybackPhysicalAddress); mTestLooper.dispatchAll(); mLocalDevices.add(mHdmiCecLocalDevicePlayback); mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV); @@ -416,6 +416,7 @@ public class HdmiCecLocalDevicePlaybackTest { int newPlaybackPhysicalAddress = 0x2100; int switchPhysicalAddress = 0x2000; mNativeWrapper.setPhysicalAddress(newPlaybackPhysicalAddress); + mHdmiControlService.onHotplug(newPlaybackPhysicalAddress, true); mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue( diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java index 192be2a4200b..004c6c68781c 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java @@ -181,6 +181,7 @@ public class HdmiCecLocalDeviceTest { mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context)); mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper()); mNativeWrapper = new FakeNativeWrapper(); + mNativeWrapper.setPhysicalAddress(0x2000); mHdmiCecController = HdmiCecController.createWithNativeWrapper( mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter()); mHdmiControlService.setCecController(mHdmiCecController); @@ -199,7 +200,6 @@ public class HdmiCecLocalDeviceTest { mHdmiControlService.initService(); mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY); mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); - mNativeWrapper.setPhysicalAddress(0x2000); mTestLooper.dispatchAll(); mNativeWrapper.clearResultMessages(); } @@ -237,6 +237,7 @@ public class HdmiCecLocalDeviceTest { @Test public void handleGivePhysicalAddress_success() { mNativeWrapper.setPhysicalAddress(0x0); + mHdmiControlService.onHotplug(0x0, true); HdmiCecMessage expectedMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(ADDR_TV, 0, DEVICE_TV); @Constants.HandleMessageResult @@ -252,6 +253,7 @@ public class HdmiCecLocalDeviceTest { @Test public void handleGivePhysicalAddress_failure() { mNativeWrapper.setPhysicalAddress(Constants.INVALID_PHYSICAL_ADDRESS); + mHdmiControlService.onHotplug(Constants.INVALID_PHYSICAL_ADDRESS, true); HdmiCecMessage expectedMessage = HdmiCecMessageBuilder.buildFeatureAbortCommand( ADDR_TV, diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java index b50684bb7a25..2a4b79730851 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java @@ -221,13 +221,13 @@ public class HdmiCecLocalDeviceTvTest { .setEarcSupported(true) .build(); mNativeWrapper.setPortInfo(hdmiPortInfos); + mTvPhysicalAddress = 0x0000; + mNativeWrapper.setPhysicalAddress(mTvPhysicalAddress); mHdmiControlService.initService(); mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY); mPowerManager = new FakePowerManagerWrapper(context); mHdmiControlService.setPowerManager(mPowerManager); - mTvPhysicalAddress = 0x0000; mEarcBlocksArc = false; - mNativeWrapper.setPhysicalAddress(mTvPhysicalAddress); mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_DISABLED); mTestLooper.dispatchAll(); mHdmiCecLocalDeviceTv = mHdmiControlService.tv(); diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java index 1ad9ce02daa3..10f4308cbcfb 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java @@ -660,4 +660,18 @@ public class HdmiCecNetworkTest { assertThat(mHdmiCecNetwork.getLocalDeviceList().get(0)).isInstanceOf( HdmiCecLocalDeviceTv.class); } + + @Test + public void portInfoInitiated_getPhysicalAddressCalled_readsFromHalOnFirstCallOnly() { + mNativeWrapper.clearGetPhysicalAddressCallHistory(); + mNativeWrapper.setPhysicalAddress(0x0000); + mHdmiCecNetwork.initPortInfo(); + + assertThat(mHdmiCecNetwork.getPhysicalAddress()).isEqualTo(0x0000); + assertThat(mNativeWrapper.getPhysicalAddressCalled()).isTrue(); + + mNativeWrapper.clearGetPhysicalAddressCallHistory(); + assertThat(mHdmiCecNetwork.getPhysicalAddress()).isEqualTo(0x0000); + assertThat(mNativeWrapper.getPhysicalAddressCalled()).isFalse(); + } } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java index 9412ee0d4ac7..3361e7f359e2 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java @@ -115,12 +115,12 @@ public class HdmiCecPowerStatusControllerTest { .build(); mNativeWrapper.setPortInfo(hdmiPortInfos); mNativeWrapper.setPortConnectionStatus(1, true); + mNativeWrapper.setPhysicalAddress(0x2000); mHdmiControlService.initService(); mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY); mPowerManager = new FakePowerManagerWrapper(contextSpy); mHdmiControlService.setPowerManager(mPowerManager); mHdmiControlService.getHdmiCecNetwork().initPortInfo(); - mNativeWrapper.setPhysicalAddress(0x2000); mTestLooper.dispatchAll(); mHdmiCecLocalDevicePlayback = mHdmiControlService.playback(); mHdmiCecPowerStatusController = new HdmiCecPowerStatusController(mHdmiControlService); diff --git a/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java index 298ff460c9eb..2f4a6604441f 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java @@ -118,6 +118,8 @@ public class OneTouchPlayActionTest { mHdmiControlService.setHdmiCecConfig(mHdmiCecConfig); setHdmiControlEnabled(hdmiControlEnabled); mNativeWrapper = new FakeNativeWrapper(); + mPhysicalAddress = 0x2000; + mNativeWrapper.setPhysicalAddress(mPhysicalAddress); mHdmiCecController = HdmiCecController.createWithNativeWrapper( this.mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter()); mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper()); @@ -127,8 +129,6 @@ public class OneTouchPlayActionTest { mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY); mPowerManager = new FakePowerManagerWrapper(mContextSpy); mHdmiControlService.setPowerManager(mPowerManager); - mPhysicalAddress = 0x2000; - mNativeWrapper.setPhysicalAddress(mPhysicalAddress); mTestLooper.dispatchAll(); mNativeWrapper.clearResultMessages(); } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java index 1d4a72fc30e2..974f64dbd84f 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java @@ -111,12 +111,12 @@ public class PowerStatusMonitorActionTest { .setArcSupported(false) .build(); mNativeWrapper.setPortInfo(hdmiPortInfo); + mPhysicalAddress = 0x0000; + mNativeWrapper.setPhysicalAddress(mPhysicalAddress); mHdmiControlService.initService(); mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY); mPowerManager = new FakePowerManagerWrapper(mContextSpy); mHdmiControlService.setPowerManager(mPowerManager); - mPhysicalAddress = 0x0000; - mNativeWrapper.setPhysicalAddress(mPhysicalAddress); mTestLooper.dispatchAll(); mTvDevice = mHdmiControlService.tv(); mNativeWrapper.clearResultMessages(); diff --git a/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java index cafe1e7dc197..f8e465c4c36f 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java @@ -128,6 +128,7 @@ public class RequestSadActionTest { mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context)); mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper()); mNativeWrapper = new FakeNativeWrapper(); + mNativeWrapper.setPhysicalAddress(0x0000); mHdmiCecController = HdmiCecController.createWithNativeWrapper( mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter()); mHdmiControlService.setCecController(mHdmiCecController); @@ -136,7 +137,6 @@ public class RequestSadActionTest { mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY); mPowerManager = new FakePowerManagerWrapper(context); mHdmiControlService.setPowerManager(mPowerManager); - mNativeWrapper.setPhysicalAddress(0x0000); mTestLooper.dispatchAll(); mHdmiCecLocalDeviceTv = mHdmiControlService.tv(); mTvLogicalAddress = mHdmiCecLocalDeviceTv.getDeviceInfo().getLogicalAddress(); diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ResendCecCommandActionPlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ResendCecCommandActionPlaybackTest.java index 864a182e8d0d..67a3f2a64d32 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/ResendCecCommandActionPlaybackTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/ResendCecCommandActionPlaybackTest.java @@ -87,6 +87,8 @@ public class ResendCecCommandActionPlaybackTest { mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context)); mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper()); mNativeWrapper = new FakeNativeWrapper(); + mPhysicalAddress = 0x2000; + mNativeWrapper.setPhysicalAddress(mPhysicalAddress); HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper( this.mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter()); mHdmiControlService.setCecController(hdmiCecController); @@ -95,8 +97,6 @@ public class ResendCecCommandActionPlaybackTest { mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY); mPowerManager = new FakePowerManagerWrapper(context); mHdmiControlService.setPowerManager(mPowerManager); - mPhysicalAddress = 0x2000; - mNativeWrapper.setPhysicalAddress(mPhysicalAddress); mTestLooper.dispatchAll(); mPlaybackDevice = mHdmiControlService.playback(); diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ResendCecCommandActionTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ResendCecCommandActionTvTest.java index 06709cdd6ac4..047a04c60176 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/ResendCecCommandActionTvTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/ResendCecCommandActionTvTest.java @@ -89,6 +89,8 @@ public class ResendCecCommandActionTvTest { mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context)); mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper()); mNativeWrapper = new FakeNativeWrapper(); + mPhysicalAddress = 0x0000; + mNativeWrapper.setPhysicalAddress(mPhysicalAddress); HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper( this.mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter()); mHdmiControlService.setCecController(hdmiCecController); @@ -97,8 +99,6 @@ public class ResendCecCommandActionTvTest { mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY); mPowerManager = new FakePowerManagerWrapper(context); mHdmiControlService.setPowerManager(mPowerManager); - mPhysicalAddress = 0x0000; - mNativeWrapper.setPhysicalAddress(mPhysicalAddress); mTestLooper.dispatchAll(); mTvDevice = mHdmiControlService.tv(); diff --git a/services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java index 5163e29b86f1..1019db46482d 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java @@ -188,6 +188,7 @@ public class RoutingControlActionTest { mHdmiControlService.setIoLooper(mMyLooper); mNativeWrapper = new FakeNativeWrapper(); + mNativeWrapper.setPhysicalAddress(0x0000); mHdmiCecController = HdmiCecController.createWithNativeWrapper( mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter()); mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper()); @@ -205,7 +206,6 @@ public class RoutingControlActionTest { mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY); mPowerManager = new FakePowerManagerWrapper(context); mHdmiControlService.setPowerManager(mPowerManager); - mNativeWrapper.setPhysicalAddress(0x0000); mTestLooper.dispatchAll(); mHdmiCecLocalDeviceTv = mHdmiControlService.tv(); mNativeWrapper.clearResultMessages(); diff --git a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java index 4dcc6a400c1e..effea5abcecb 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java @@ -92,6 +92,8 @@ public class SystemAudioAutoInitiationActionTest { mHdmiControlService.setIoLooper(myLooper); mNativeWrapper = new FakeNativeWrapper(); + mPhysicalAddress = 0x0000; + mNativeWrapper.setPhysicalAddress(mPhysicalAddress); HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper( mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter()); mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper()); @@ -115,8 +117,6 @@ public class SystemAudioAutoInitiationActionTest { mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY); mPowerManager = new FakePowerManagerWrapper(mContextSpy); mHdmiControlService.setPowerManager(mPowerManager); - mPhysicalAddress = 0x0000; - mNativeWrapper.setPhysicalAddress(mPhysicalAddress); mTestLooper.dispatchAll(); mHdmiCecLocalDeviceTv = mHdmiControlService.tv(); mPhysicalAddress = mHdmiCecLocalDeviceTv.getDeviceInfo().getLogicalAddress(); |