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

Commit d7bd0f13 authored by Bryce Lee's avatar Bryce Lee
Browse files

Add dream overlay state callback.

This changelist adds a callback for when the dream overlay active state changes.

Bug: 216726588
Test: atest DreamOverlayStateControllerTest
Change-Id: I0ec2d06d548b28c7952f7eed4c71c5dd61851756
parent ee1f9361
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -88,16 +88,20 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
                }
                }
            };
            };


    private DreamOverlayStateController mStateController;

    @Inject
    @Inject
    public DreamOverlayService(
    public DreamOverlayService(
            Context context,
            Context context,
            @Main Executor executor,
            @Main Executor executor,
            DreamOverlayComponent.Factory dreamOverlayComponentFactory,
            DreamOverlayComponent.Factory dreamOverlayComponentFactory,
            DreamOverlayStateController stateController,
            KeyguardUpdateMonitor keyguardUpdateMonitor) {
            KeyguardUpdateMonitor keyguardUpdateMonitor) {
        mContext = context;
        mContext = context;
        mExecutor = executor;
        mExecutor = executor;
        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
        mKeyguardUpdateMonitor.registerCallback(mKeyguardCallback);
        mKeyguardUpdateMonitor.registerCallback(mKeyguardCallback);
        mStateController = stateController;


        final DreamOverlayComponent component =
        final DreamOverlayComponent component =
                dreamOverlayComponentFactory.create(mViewModelStore, mHost);
                dreamOverlayComponentFactory.create(mViewModelStore, mHost);
@@ -118,6 +122,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
        setCurrentState(Lifecycle.State.DESTROYED);
        setCurrentState(Lifecycle.State.DESTROYED);
        final WindowManager windowManager = mContext.getSystemService(WindowManager.class);
        final WindowManager windowManager = mContext.getSystemService(WindowManager.class);
        windowManager.removeView(mWindow.getDecorView());
        windowManager.removeView(mWindow.getDecorView());
        mStateController.setOverlayActive(false);
        super.onDestroy();
        super.onDestroy();
    }
    }


@@ -127,6 +132,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
        mExecutor.execute(() -> {
        mExecutor.execute(() -> {
            addOverlayWindowLocked(layoutParams);
            addOverlayWindowLocked(layoutParams);
            setCurrentState(Lifecycle.State.RESUMED);
            setCurrentState(Lifecycle.State.RESUMED);
            mStateController.setOverlayActive(true);
        });
        });
    }
    }


+63 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@


package com.android.systemui.dreams;
package com.android.systemui.dreams;


import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.NonNull;


import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
@@ -30,6 +32,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.HashSet;
import java.util.Objects;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.concurrent.Executor;
import java.util.function.Consumer;


import javax.inject.Inject;
import javax.inject.Inject;


@@ -41,6 +44,16 @@ import javax.inject.Inject;
@SysUISingleton
@SysUISingleton
public class DreamOverlayStateController implements
public class DreamOverlayStateController implements
        CallbackController<DreamOverlayStateController.Callback> {
        CallbackController<DreamOverlayStateController.Callback> {
    private static final String TAG = "DreamOverlayStateCtlr";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    public static final int STATE_DREAM_OVERLAY_ACTIVE = 1 << 0;

    private static final int OP_CLEAR_STATE = 1;
    private static final int OP_SET_STATE = 2;

    private int mState;

    /**
    /**
     * Callback for dream overlay events.
     * Callback for dream overlay events.
     */
     */
@@ -50,6 +63,12 @@ public class DreamOverlayStateController implements
         */
         */
        default void onComplicationsChanged() {
        default void onComplicationsChanged() {
        }
        }

        /**
         * Called when the dream overlay state changes.
         */
        default void onStateChanged() {
        }
    }
    }


    private final Executor mExecutor;
    private final Executor mExecutor;
@@ -92,6 +111,14 @@ public class DreamOverlayStateController implements
        return Collections.unmodifiableCollection(mComplications);
        return Collections.unmodifiableCollection(mComplications);
    }
    }


    private void notifyCallbacks(Consumer<Callback> callbackConsumer) {
        mExecutor.execute(() -> {
            for (Callback callback : mCallbacks) {
                callbackConsumer.accept(callback);
            }
        });
    }

    @Override
    @Override
    public void addCallback(@NonNull Callback callback) {
    public void addCallback(@NonNull Callback callback) {
        mExecutor.execute(() -> {
        mExecutor.execute(() -> {
@@ -117,4 +144,40 @@ public class DreamOverlayStateController implements
            mCallbacks.remove(callback);
            mCallbacks.remove(callback);
        });
        });
    }
    }

    /**
     * Returns whether the overlay is active.
     * @return {@code true} if overlay is active, {@code false} otherwise.
     */
    public boolean isOverlayActive() {
        return containsState(STATE_DREAM_OVERLAY_ACTIVE);
    }

    private boolean containsState(int state) {
        return (mState & state) != 0;
    }

    private void modifyState(int op, int state) {
        final int existingState = mState;
        switch (op) {
            case OP_CLEAR_STATE:
                mState &= ~state;
                break;
            case OP_SET_STATE:
                mState |= state;
                break;
        }

        if (existingState != mState) {
            notifyCallbacks(callback -> callback.onStateChanged());
        }
    }

    /**
     * Sets whether the overlay is active.
     * @param active {@code true} if overlay is active, {@code false} otherwise.
     */
    public void setOverlayActive(boolean active) {
        modifyState(active ? OP_SET_STATE : OP_CLEAR_STATE, STATE_DREAM_OVERLAY_ACTIVE);
    }
}
}
+4 −0
Original line number Original line Diff line number Diff line
@@ -91,6 +91,9 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
    @Mock
    @Mock
    DreamOverlayTouchMonitor mDreamOverlayTouchMonitor;
    DreamOverlayTouchMonitor mDreamOverlayTouchMonitor;


    @Mock
    DreamOverlayStateController mStateController;



    DreamOverlayService mService;
    DreamOverlayService mService;


@@ -115,6 +118,7 @@ public class DreamOverlayServiceTest extends SysuiTestCase {


        mService = new DreamOverlayService(mContext, mMainExecutor,
        mService = new DreamOverlayService(mContext, mMainExecutor,
                mDreamOverlayComponentFactory,
                mDreamOverlayComponentFactory,
                mStateController,
                mKeyguardUpdateMonitor);
                mKeyguardUpdateMonitor);
        final IBinder proxy = mService.onBind(new Intent());
        final IBinder proxy = mService.onBind(new Intent());
        final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy);
        final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy);
+27 −1
Original line number Original line Diff line number Diff line
@@ -16,9 +16,12 @@


package com.android.systemui.dreams;
package com.android.systemui.dreams;


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

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verify;


@@ -35,6 +38,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoAnnotations;


import java.util.Collection;
import java.util.Collection;
@@ -56,7 +60,29 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
    }
    }


    @Test
    @Test
    public void testCallback() throws Exception {
    public void testStateChange() {
        final DreamOverlayStateController stateController = new DreamOverlayStateController(
                mExecutor);
        stateController.addCallback(mCallback);
        stateController.setOverlayActive(true);
        mExecutor.runAllReady();

        verify(mCallback).onStateChanged();
        assertThat(stateController.isOverlayActive()).isTrue();

        Mockito.clearInvocations(mCallback);
        stateController.setOverlayActive(true);
        mExecutor.runAllReady();
        verify(mCallback, never()).onStateChanged();

        stateController.setOverlayActive(false);
        mExecutor.runAllReady();
        verify(mCallback).onStateChanged();
        assertThat(stateController.isOverlayActive()).isFalse();
    }

    @Test
    public void testCallback() {
        final DreamOverlayStateController stateController = new DreamOverlayStateController(
        final DreamOverlayStateController stateController = new DreamOverlayStateController(
                mExecutor);
                mExecutor);
        stateController.addCallback(mCallback);
        stateController.addCallback(mCallback);