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

Commit 43b8ccaa authored by Coco Duan's avatar Coco Duan Committed by Android (Google) Code Review
Browse files

Merge "Turn off glanceable hub touch handling on dream if disabled" into main

parents a3c870d1 0906c162
Loading
Loading
Loading
Loading
+39 −1
Original line number Diff line number Diff line
@@ -18,15 +18,20 @@ package com.android.systemui.dreams.touch;

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

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.view.GestureDetector;
import android.view.MotionEvent;

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

import com.android.systemui.SysuiTestCase;
import com.android.systemui.kosmos.KosmosJavaAdapter;
import com.android.systemui.shared.system.InputChannelCompat;
import com.android.systemui.statusbar.phone.CentralSurfaces;

@@ -39,28 +44,60 @@ import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;

import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;

@SmallTest
@RunWith(AndroidJUnit4.class)
public class CommunalTouchHandlerTest extends SysuiTestCase {
    private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);

    @Mock
    CentralSurfaces mCentralSurfaces;
    @Mock
    DreamTouchHandler.TouchSession mTouchSession;
    CommunalTouchHandler mTouchHandler;
    @Mock
    Lifecycle mLifecycle;

    private static final int INITIATION_WIDTH = 20;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        AtomicReference reference = new AtomicReference<>(null);
        when(mLifecycle.getInternalScopeRef()).thenReturn(reference);
        when(mLifecycle.getCurrentState()).thenReturn(Lifecycle.State.CREATED);
        mTouchHandler = new CommunalTouchHandler(
                Optional.of(mCentralSurfaces),
                INITIATION_WIDTH);
                INITIATION_WIDTH,
                mKosmos.getCommunalInteractor(),
                mLifecycle
                );
    }

    @Test
    public void communalTouchHandler_disabledByDefault() {
        assertThat(mTouchHandler.isEnabled()).isFalse();
    }

    @Test
    public void communalTouchHandler_disabled_whenCommunalUnavailable() {
        mTouchHandler.mIsCommunalAvailableCallback.accept(false);
        assertThat(mTouchHandler.isEnabled()).isFalse();

        mTouchHandler.onSessionStart(mTouchSession);
        verify(mTouchSession, never()).registerGestureListener(any());
    }

    @Test
    public void communalTouchHandler_enabled_whenCommunalAvailable() {
        mTouchHandler.mIsCommunalAvailableCallback.accept(true);
        assertThat(mTouchHandler.isEnabled()).isTrue();
    }

    @Test
    public void testEventPropagation() {
        mTouchHandler.mIsCommunalAvailableCallback.accept(true);
        final MotionEvent motionEvent = Mockito.mock(MotionEvent.class);

        final ArgumentCaptor<InputChannelCompat.InputEventListener>
@@ -75,6 +112,7 @@ public class CommunalTouchHandlerTest extends SysuiTestCase {

    @Test
    public void testTouchPilferingOnScroll() {
        mTouchHandler.mIsCommunalAvailableCallback.accept(true);
        final MotionEvent motionEvent1 = Mockito.mock(MotionEvent.class);
        final MotionEvent motionEvent2 = Mockito.mock(MotionEvent.class);

+39 −1
Original line number Diff line number Diff line
@@ -17,15 +17,21 @@
package com.android.systemui.dreams.touch;

import static com.android.systemui.dreams.touch.dagger.ShadeModule.COMMUNAL_GESTURE_INITIATION_WIDTH;
import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;

import android.graphics.Rect;
import android.graphics.Region;
import android.view.GestureDetector;
import android.view.MotionEvent;

import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.Lifecycle;

import com.android.systemui.communal.domain.interactor.CommunalInteractor;
import com.android.systemui.statusbar.phone.CentralSurfaces;

import java.util.Optional;
import java.util.function.Consumer;

import javax.inject.Inject;
import javax.inject.Named;
@@ -34,17 +40,49 @@ import javax.inject.Named;
public class CommunalTouchHandler implements DreamTouchHandler {
    private final int mInitiationWidth;
    private final Optional<CentralSurfaces> mCentralSurfaces;
    private final Lifecycle mLifecycle;
    private final CommunalInteractor mCommunalInteractor;
    private Boolean mIsEnabled = false;

    @VisibleForTesting
    final Consumer<Boolean> mIsCommunalAvailableCallback =
            isAvailable -> {
                setIsEnabled(isAvailable);
            };

    @Inject
    public CommunalTouchHandler(
            Optional<CentralSurfaces> centralSurfaces,
            @Named(COMMUNAL_GESTURE_INITIATION_WIDTH) int initiationWidth) {
            @Named(COMMUNAL_GESTURE_INITIATION_WIDTH) int initiationWidth,
            CommunalInteractor communalInteractor,
            Lifecycle lifecycle) {
        mInitiationWidth = initiationWidth;
        mCentralSurfaces = centralSurfaces;
        mLifecycle = lifecycle;
        mCommunalInteractor = communalInteractor;

        collectFlow(
                mLifecycle,
                mCommunalInteractor.isCommunalAvailable(),
                mIsCommunalAvailableCallback
        );
    }

    @Override
    public Boolean isEnabled() {
        return mIsEnabled;
    }

    @Override
    public void setIsEnabled(Boolean enabled) {
        mIsEnabled = enabled;
    }

    @Override
    public void onSessionStart(TouchSession session) {
        if (!mIsEnabled) {
            return;
        }
        mCentralSurfaces.ifPresent(surfaces -> handleSessionStart(surfaces, session));
    }

+3 −0
Original line number Diff line number Diff line
@@ -292,6 +292,9 @@ public class DreamOverlayTouchMonitor {
                        new HashMap<>();

                for (DreamTouchHandler handler : mHandlers) {
                            if (!handler.isEnabled()) {
                                continue;
                            }
                    final Rect maxBounds = mDisplayHelper.getMaxBounds(ev.getDisplayId(),
                            TYPE_APPLICATION_OVERLAY);

+14 −0
Original line number Diff line number Diff line
@@ -85,6 +85,20 @@ public interface DreamTouchHandler {
        Rect getBounds();
    }

    /**
     * Returns whether the handler is enabled to handle touch on dream.
     * @return isEnabled state. By default it's true.
     */
    default Boolean isEnabled() {
        return true;
    }

    /**
     * Sets whether to enable the handler to handle touch on dream.
     * @param enabled new value to be set whether to enable the handler.
     */
    default void setIsEnabled(Boolean enabled){}

    /**
     * Returns the region the touch handler is interested in. By default, no region is specified,
     * indicating the entire screen should be considered.
+18 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.util.kotlin

import android.view.View
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.coroutineScope
import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -76,6 +77,23 @@ fun <T> collectFlow(
    }
}

/**
 * Collect information for the given [flow], calling [consumer] for each emitted event. Defaults to
 * [LifeCycle.State.CREATED] which is mapped over from the equivalent definition for collecting the
 * flow on a view.
 */
@JvmOverloads
fun <T> collectFlow(
    lifecycle: Lifecycle,
    flow: Flow<T>,
    consumer: Consumer<T>,
    state: Lifecycle.State = Lifecycle.State.CREATED,
) {
    lifecycle.coroutineScope.launch {
        lifecycle.repeatOnLifecycle(state) { flow.collect { consumer.accept(it) } }
    }
}

fun <A, B, R> combineFlows(flow1: Flow<A>, flow2: Flow<B>, bifunction: (A, B) -> R): Flow<R> {
    return combine(flow1, flow2, bifunction)
}
Loading