Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3f712f3a authored by Bryce Lee's avatar Bryce Lee Committed by Android (Google) Code Review
Browse files

Merge "Make Condition#start a suspend function." into main

parents fe47d228 6d85344a
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.keyguard.keyguardUpdateMonitor
import com.android.systemui.SysuiTestCase
import com.android.systemui.condition.testStart
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP
import com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE
@@ -67,7 +68,7 @@ class DeviceInactiveConditionTest : SysuiTestCase() {
    fun asleep_conditionTrue() =
        kosmos.runTest {
            // Condition is false to start.
            underTest.start()
            testStart(underTest)
            assertThat(underTest.isConditionMet).isFalse()

            // Condition is true when device goes to sleep.
@@ -79,7 +80,7 @@ class DeviceInactiveConditionTest : SysuiTestCase() {
    fun dozingAndAsleep_conditionFalse() =
        kosmos.runTest {
            // Condition is true when device is asleep.
            underTest.start()
            testStart(underTest)
            sleep()
            assertThat(underTest.isConditionMet).isTrue()

+0 −92
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.dreams.conditions;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;

import com.android.systemui.SysuiTestCase;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.assist.AssistManager.VisualQueryAttentionListener;
import com.android.systemui.shared.condition.Condition;

import kotlinx.coroutines.CoroutineScope;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

@SmallTest
@RunWith(AndroidJUnit4.class)
@android.platform.test.annotations.EnabledOnRavenwood
public class AssistantAttentionConditionTest extends SysuiTestCase {
    @Mock
    Condition.Callback mCallback;
    @Mock
    AssistManager mAssistManager;
    @Mock
    CoroutineScope mScope;

    private AssistantAttentionCondition mAssistantAttentionCondition;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);

        mAssistantAttentionCondition = new AssistantAttentionCondition(mScope, mAssistManager);
        // Adding a callback also starts the condition.
        mAssistantAttentionCondition.addCallback(mCallback);
    }

    @Test
    public void testEnableVisualQueryDetection() {
        verify(mAssistManager).addVisualQueryAttentionListener(
                any(VisualQueryAttentionListener.class));
    }

    @Test
    public void testDisableVisualQueryDetection() {
        mAssistantAttentionCondition.stop();
        verify(mAssistManager).removeVisualQueryAttentionListener(
                any(VisualQueryAttentionListener.class));
    }

    @Test
    public void testAttentionChangedTriggersCondition() {
        final ArgumentCaptor<VisualQueryAttentionListener> argumentCaptor =
                ArgumentCaptor.forClass(VisualQueryAttentionListener.class);
        verify(mAssistManager).addVisualQueryAttentionListener(argumentCaptor.capture());

        argumentCaptor.getValue().onAttentionGained();
        assertThat(mAssistantAttentionCondition.isConditionMet()).isTrue();

        argumentCaptor.getValue().onAttentionLost();
        assertThat(mAssistantAttentionCondition.isConditionMet()).isFalse();

        verify(mCallback, times(2)).onConditionChanged(eq(mAssistantAttentionCondition));
    }
}
+85 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.dreams.conditions

import android.platform.test.annotations.EnabledOnRavenwood
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.assist.AssistManager
import com.android.systemui.assist.AssistManager.VisualQueryAttentionListener
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
import com.android.systemui.shared.condition.Condition
import com.google.common.truth.Truth
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.any
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.eq

@SmallTest
@RunWith(AndroidJUnit4::class)
@EnabledOnRavenwood
class AssistantAttentionConditionTest : SysuiTestCase() {
    private val kosmos = Kosmos()

    @Mock private lateinit var callback: Condition.Callback

    @Mock private lateinit var assistManager: AssistManager

    private lateinit var underTest: AssistantAttentionCondition

    @Before
    fun setup() {
        MockitoAnnotations.initMocks(this)

        underTest = AssistantAttentionCondition(kosmos.testScope, assistManager)
        // Adding a callback also starts the condition.
        underTest.addCallback(callback)
    }

    @Test
    fun testEnableVisualQueryDetection() =
        kosmos.runTest { Mockito.verify(assistManager).addVisualQueryAttentionListener(any()) }

    @Test
    fun testDisableVisualQueryDetection() =
        kosmos.runTest {
            underTest.stop()
            Mockito.verify(assistManager).removeVisualQueryAttentionListener(any())
        }

    @Test
    fun testAttentionChangedTriggersCondition() =
        kosmos.runTest {
            val argumentCaptor = argumentCaptor<VisualQueryAttentionListener>()
            Mockito.verify(assistManager).addVisualQueryAttentionListener(argumentCaptor.capture())

            argumentCaptor.lastValue.onAttentionGained()
            Truth.assertThat(underTest.isConditionMet).isTrue()

            argumentCaptor.lastValue.onAttentionLost()
            Truth.assertThat(underTest.isConditionMet).isFalse()

            Mockito.verify(callback, Mockito.times(2)).onConditionChanged(eq(underTest))
        }
}
+0 −118
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.dreams.conditions;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.DreamManager;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;

import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.shared.condition.Condition;

import kotlinx.coroutines.CoroutineScope;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

@SmallTest
@RunWith(AndroidJUnit4.class)
@android.platform.test.annotations.EnabledOnRavenwood
public class DreamConditionTest extends SysuiTestCase {
    @Mock
    Condition.Callback mCallback;

    @Mock
    DreamManager mDreamManager;

    @Mock
    KeyguardUpdateMonitor mKeyguardUpdateMonitor;

    @Mock
    CoroutineScope mScope;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
    }

    /**
     * Ensure a dreaming state immediately triggers the condition.
     */
    @Test
    public void testInitialDreamingState() {
        when(mDreamManager.isDreaming()).thenReturn(true);
        final DreamCondition condition = new DreamCondition(mScope, mDreamManager,
                mKeyguardUpdateMonitor);
        condition.addCallback(mCallback);

        verify(mCallback).onConditionChanged(eq(condition));
        assertThat(condition.isConditionMet()).isTrue();
    }

    /**
     * Ensure a non-dreaming state does not trigger the condition.
     */
    @Test
    public void testInitialNonDreamingState() {
        when(mDreamManager.isDreaming()).thenReturn(false);
        final DreamCondition condition = new DreamCondition(mScope, mDreamManager,
                mKeyguardUpdateMonitor);
        condition.addCallback(mCallback);

        verify(mCallback, never()).onConditionChanged(eq(condition));
        assertThat(condition.isConditionMet()).isFalse();
    }

    /**
     * Ensure that changing dream state triggers condition.
     */
    @Test
    public void testChange() {
        final ArgumentCaptor<KeyguardUpdateMonitorCallback> callbackCaptor =
                ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class);
        when(mDreamManager.isDreaming()).thenReturn(true);
        final DreamCondition condition = new DreamCondition(mScope, mDreamManager,
                mKeyguardUpdateMonitor);
        condition.addCallback(mCallback);
        verify(mKeyguardUpdateMonitor).registerCallback(callbackCaptor.capture());

        clearInvocations(mCallback);
        callbackCaptor.getValue().onDreamingStateChanged(false);
        verify(mCallback).onConditionChanged(eq(condition));
        assertThat(condition.isConditionMet()).isFalse();

        clearInvocations(mCallback);
        callbackCaptor.getValue().onDreamingStateChanged(true);
        verify(mCallback).onConditionChanged(eq(condition));
        assertThat(condition.isConditionMet()).isTrue();
    }
}
+106 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.dreams.conditions

import android.app.DreamManager
import android.platform.test.annotations.EnabledOnRavenwood
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.systemui.SysuiTestCase
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.runCurrent
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
import com.android.systemui.shared.condition.Condition
import com.google.common.truth.Truth
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.eq
import org.mockito.kotlin.whenever

@SmallTest
@RunWith(AndroidJUnit4::class)
@EnabledOnRavenwood
class DreamConditionTest : SysuiTestCase() {
    private val kosmos = Kosmos()

    @Mock private lateinit var callback: Condition.Callback

    @Mock private lateinit var dreamManager: DreamManager

    @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor

    @Before
    fun setup() {
        MockitoAnnotations.initMocks(this)
    }

    /** Ensure a dreaming state immediately triggers the condition. */
    @Test
    fun testInitialDreamingState() =
        kosmos.runTest {
            whenever(dreamManager.isDreaming).thenReturn(true)
            val condition = DreamCondition(testScope, dreamManager, keyguardUpdateMonitor)
            condition.addCallback(callback)
            runCurrent()

            Mockito.verify(callback).onConditionChanged(eq(condition))
            Truth.assertThat(condition.isConditionMet).isTrue()
        }

    /** Ensure a non-dreaming state does not trigger the condition. */
    @Test
    fun testInitialNonDreamingState() =
        kosmos.runTest {
            whenever(dreamManager.isDreaming).thenReturn(false)
            val condition = DreamCondition(testScope, dreamManager, keyguardUpdateMonitor)
            condition.addCallback(callback)

            Mockito.verify(callback, Mockito.never()).onConditionChanged(eq(condition))
            Truth.assertThat(condition.isConditionMet).isFalse()
        }

    /** Ensure that changing dream state triggers condition. */
    @Test
    fun testChange() =
        kosmos.runTest {
            val callbackCaptor = argumentCaptor<KeyguardUpdateMonitorCallback>()
            whenever(dreamManager.isDreaming).thenReturn(true)
            val condition = DreamCondition(testScope, dreamManager, keyguardUpdateMonitor)
            condition.addCallback(callback)
            runCurrent()
            Mockito.verify(keyguardUpdateMonitor).registerCallback(callbackCaptor.capture())

            Mockito.clearInvocations(callback)
            callbackCaptor.lastValue.onDreamingStateChanged(false)
            runCurrent()
            Mockito.verify(callback).onConditionChanged(eq(condition))
            Truth.assertThat(condition.isConditionMet).isFalse()

            Mockito.clearInvocations(callback)
            callbackCaptor.lastValue.onDreamingStateChanged(true)
            runCurrent()
            Mockito.verify(callback).onConditionChanged(eq(condition))
            Truth.assertThat(condition.isConditionMet).isTrue()
        }
}
Loading