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

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

Merge "Exclude CommunalSurfaceView tap region from keyguard."

parents c0445999 a4ffa0ac
Loading
Loading
Loading
Loading
+14 −1
Original line number Original line Diff line number Diff line
@@ -27,6 +27,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.KeyguardVisibilityHelper;
import com.android.keyguard.KeyguardVisibilityHelper;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -121,6 +122,11 @@ public class CommunalHostViewController extends ViewController<CommunalHostView>


                    setState(STATE_DOZING, isDozing);
                    setState(STATE_DOZING, isDozing);
                }
                }

                @Override
                public void onStateChanged(int newState) {
                    updateCommunalViewOccluded();
                }
            };
            };


    @Inject
    @Inject
@@ -195,6 +201,8 @@ public class CommunalHostViewController extends ViewController<CommunalHostView>
        if (existingState != mState) {
        if (existingState != mState) {
            showSource();
            showSource();
        }
        }

        updateCommunalViewOccluded();
    }
    }


    private String describeState(@State int stateFlag) {
    private String describeState(@State int stateFlag) {
@@ -308,7 +316,12 @@ public class CommunalHostViewController extends ViewController<CommunalHostView>
    }
    }


    private void updateCommunalViewOccluded() {
    private void updateCommunalViewOccluded() {
        final boolean bouncerShowing = (mState & STATE_BOUNCER_SHOWING) == STATE_BOUNCER_SHOWING;
        final int statusBarState = mStatusBarStateController.getState();
        final boolean shadeExpanded = statusBarState == StatusBarState.SHADE
                || statusBarState == StatusBarState.SHADE_LOCKED;

        mCommunalStateController.setCommunalViewOccluded(
        mCommunalStateController.setCommunalViewOccluded(
                mQsExpansion > 0.0f || mShadeExpansion > 0.0f);
                bouncerShowing || shadeExpanded || mQsExpansion > 0.0f || mShadeExpansion > 0.0f);
    }
    }
}
}
+23 −7
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.communal.service;
package com.android.systemui.communal.service;


import android.content.Context;
import android.content.Context;
import android.content.res.Resources;
import android.os.IBinder;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.RemoteException;
import android.util.Log;
import android.util.Log;
@@ -30,6 +31,7 @@ import com.android.systemui.communal.CommunalStateController;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.shared.communal.ICommunalSource;
import com.android.systemui.shared.communal.ICommunalSource;
import com.android.systemui.shared.communal.ICommunalSurfaceCallback;
import com.android.systemui.shared.communal.ICommunalSurfaceCallback;
import com.android.systemui.statusbar.NotificationShadeWindowController;


import com.google.android.collect.Lists;
import com.google.android.collect.Lists;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListenableFuture;
@@ -47,23 +49,32 @@ import javax.inject.Inject;
 */
 */
public class CommunalSourceImpl implements CommunalSource {
public class CommunalSourceImpl implements CommunalSource {
    private static final String TAG = "CommunalSourceImpl";
    private static final String TAG = "CommunalSourceImpl";
    private static final boolean DEBUG = false;
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
    private final ICommunalSource mSourceProxy;
    private final ICommunalSource mSourceProxy;
    private final Resources mResources;
    private final Executor mMainExecutor;
    private final Executor mMainExecutor;
    private final NotificationShadeWindowController mNotificationShadeWindowController;
    private final CommunalStateController mCommunalStateController;
    private final CommunalStateController mCommunalStateController;


    static class Factory {
    static class Factory {
        private final Executor mExecutor;
        private final Executor mExecutor;
        private final Resources mResources;
        private final CommunalStateController mCommunalStateController;
        private final CommunalStateController mCommunalStateController;
        private final NotificationShadeWindowController mNotificationShadeWindowController;


        @Inject
        @Inject
        Factory(@Main Executor executor, CommunalStateController communalStateController) {
        Factory(@Main Executor executor, @Main Resources resources,
                NotificationShadeWindowController notificationShadeWindowController,
                CommunalStateController communalStateController) {
            mExecutor = executor;
            mExecutor = executor;
            mResources = resources;
            mNotificationShadeWindowController = notificationShadeWindowController;
            mCommunalStateController = communalStateController;
            mCommunalStateController = communalStateController;
        }
        }


        public CommunalSource create(ICommunalSource source) {
        public CommunalSource create(ICommunalSource source) {
            return new CommunalSourceImpl(mExecutor, mCommunalStateController, source);
            return new CommunalSourceImpl(mExecutor, mResources, mCommunalStateController,
                    mNotificationShadeWindowController, source);
        }
        }
    }
    }


@@ -75,10 +86,14 @@ public class CommunalSourceImpl implements CommunalSource {
    // A list of {@link Callback} that have registered to receive updates.
    // A list of {@link Callback} that have registered to receive updates.
    private final ArrayList<WeakReference<Callback>> mCallbacks = Lists.newArrayList();
    private final ArrayList<WeakReference<Callback>> mCallbacks = Lists.newArrayList();


    public CommunalSourceImpl(Executor mainExecutor,
    public CommunalSourceImpl(Executor mainExecutor, Resources resources,
            CommunalStateController communalStateController, ICommunalSource sourceProxy) {
            CommunalStateController communalStateController,
            NotificationShadeWindowController notificationShadeWindowController,
            ICommunalSource sourceProxy) {
        mMainExecutor = mainExecutor;
        mMainExecutor = mainExecutor;
        mCommunalStateController = communalStateController;
        mCommunalStateController = communalStateController;
        mNotificationShadeWindowController = notificationShadeWindowController;
        mResources = resources;
        mSourceProxy = sourceProxy;
        mSourceProxy = sourceProxy;


        try {
        try {
@@ -120,8 +135,9 @@ public class CommunalSourceImpl implements CommunalSource {
                CallbackToFutureAdapter.getFuture(completer -> {
                CallbackToFutureAdapter.getFuture(completer -> {
                    final SurfaceView view = new SurfaceView(context);
                    final SurfaceView view = new SurfaceView(context);
                    completer.set(new CommunalViewResult(view,
                    completer.set(new CommunalViewResult(view,
                            new CommunalSurfaceViewController(view, mMainExecutor,
                            new CommunalSurfaceViewController(view, mResources, mMainExecutor,
                                    mCommunalStateController, this)));
                                    mCommunalStateController, mNotificationShadeWindowController,
                                    this)));
                    return "CommunalSourceImpl::requestCommunalSurface::getCommunalSurface";
                    return "CommunalSourceImpl::requestCommunalSurface::getCommunalSurface";
                });
                });


+65 −2
Original line number Original line Diff line number Diff line
@@ -17,14 +17,21 @@
package com.android.systemui.communal.service;
package com.android.systemui.communal.service;


import android.annotation.IntDef;
import android.annotation.IntDef;
import android.content.res.Resources;
import android.graphics.Region;
import android.util.Log;
import android.util.Log;
import android.view.IWindow;
import android.view.SurfaceControlViewHost;
import android.view.SurfaceControlViewHost;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceView;
import android.view.View;


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


import com.android.systemui.R;
import com.android.systemui.communal.CommunalStateController;
import com.android.systemui.communal.CommunalStateController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.util.Utils;
import com.android.systemui.util.ViewController;
import com.android.systemui.util.ViewController;


import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListenableFuture;
@@ -40,7 +47,10 @@ public class CommunalSurfaceViewController extends ViewController<SurfaceView> {
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
    private final Executor mMainExecutor;
    private final Executor mMainExecutor;
    private final CommunalStateController mCommunalStateController;
    private final CommunalStateController mCommunalStateController;
    private final NotificationShadeWindowController mNotificationShadeWindowController;
    private final CommunalSourceImpl mSource;
    private final CommunalSourceImpl mSource;
    private final Resources mResources;
    private final Region mSurfaceViewTouchableRegion;


    @IntDef({STATE_SURFACE_CREATED, STATE_SURFACE_VIEW_ATTACHED})
    @IntDef({STATE_SURFACE_CREATED, STATE_SURFACE_VIEW_ATTACHED})
    private @interface State {}
    private @interface State {}
@@ -73,18 +83,51 @@ public class CommunalSurfaceViewController extends ViewController<SurfaceView> {
        }
        }
    };
    };


    protected CommunalSurfaceViewController(SurfaceView view, Executor executor,
    private final View.OnLayoutChangeListener mOnLayoutChangeListener =
            CommunalStateController communalStateController, CommunalSourceImpl source) {
            new View.OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
                int oldTop, int oldRight, int oldBottom) {
            // The margin for the status bar and keyguard indication are excluded from the tap
            // exclusion to preserve vertical swipes in this region.
            final int topMargin = mResources.getDimensionPixelSize(
                    Utils.shouldUseSplitNotificationShade(mResources)
                            ? R.dimen.split_shade_header_height
                            : R.dimen.notification_panel_margin_top);
            final int bottomMargin = mResources.getDimensionPixelSize(
                    R.dimen.keyguard_indication_bottom_padding);

            mSurfaceViewTouchableRegion.set(left, top + topMargin, right, bottom - bottomMargin);
            updateTouchExclusion();
        }
    };

    private CommunalStateController.Callback mCommunalStateCallback =
            new CommunalStateController.Callback() {
        @Override
        public void onCommunalViewOccludedChanged() {
            updateTouchExclusion();
        }
    };

    protected CommunalSurfaceViewController(SurfaceView view, Resources resources,
            Executor executor, CommunalStateController communalStateController,
            NotificationShadeWindowController notificationShadeWindowController,
            CommunalSourceImpl source) {
        super(view);
        super(view);
        mCommunalStateController = communalStateController;
        mCommunalStateController = communalStateController;
        mSource = source;
        mSource = source;
        mResources = resources;
        mMainExecutor = executor;
        mMainExecutor = executor;
        mNotificationShadeWindowController = notificationShadeWindowController;
        mSurfaceViewTouchableRegion = new Region();
    }
    }


    @Override
    @Override
    public void init() {
    public void init() {
        super.init();
        super.init();
        mView.getHolder().addCallback(mSurfaceHolderCallback);
        mView.getHolder().addCallback(mSurfaceHolderCallback);
        mView.addOnLayoutChangeListener(mOnLayoutChangeListener);
    }
    }


    private void setState(@State int state, boolean enabled) {
    private void setState(@State int state, boolean enabled) {
@@ -106,6 +149,24 @@ public class CommunalSurfaceViewController extends ViewController<SurfaceView> {
        mCurrentState = newState;
        mCurrentState = newState;


        showSurface(newState == STATE_CAN_SHOW_SURFACE);
        showSurface(newState == STATE_CAN_SHOW_SURFACE);

        updateTouchExclusion();
    }

    private void updateTouchExclusion() {
        final IWindow window = IWindow.Stub.asInterface(mView.getWindowToken());
        final boolean excludeTouches = (mCurrentState & STATE_SURFACE_VIEW_ATTACHED) != 0
                && !mCommunalStateController.getCommunalViewOccluded();
        if (excludeTouches) {
            mNotificationShadeWindowController.setTouchExclusionRegion(mSurfaceViewTouchableRegion);
        } else {
            final Region emptyRegion = Region.obtain();
            mNotificationShadeWindowController.setTouchExclusionRegion(emptyRegion);
            emptyRegion.recycle();
        }
        // TODO(b/197036940): This is no longer necessary once the surface view is not on top of the
        // z-order.
        mView.setZOrderOnTop(excludeTouches);
    }
    }


    private void showSurface(boolean show) {
    private void showSurface(boolean show) {
@@ -163,10 +224,12 @@ public class CommunalSurfaceViewController extends ViewController<SurfaceView> {
    @Override
    @Override
    protected void onViewAttached() {
    protected void onViewAttached() {
        setState(STATE_SURFACE_VIEW_ATTACHED, true);
        setState(STATE_SURFACE_VIEW_ATTACHED, true);
        mCommunalStateController.addCallback(mCommunalStateCallback);
    }
    }


    @Override
    @Override
    protected void onViewDetached() {
    protected void onViewDetached() {
        mCommunalStateController.removeCallback(mCommunalStateCallback);
        setState(STATE_SURFACE_VIEW_ATTACHED, false);
        setState(STATE_SURFACE_VIEW_ATTACHED, false);
    }
    }
}
}
+4 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.systemui.statusbar;
package com.android.systemui.statusbar;


import android.graphics.Region;
import android.view.ViewGroup;
import android.view.ViewGroup;


import androidx.annotation.Nullable;
import androidx.annotation.Nullable;
@@ -158,6 +159,9 @@ public interface NotificationShadeWindowController extends RemoteInputController
    /** Sets the state of whether the notification shade is touchable or not. */
    /** Sets the state of whether the notification shade is touchable or not. */
    default void setNotTouchable(boolean notTouchable) {}
    default void setNotTouchable(boolean notTouchable) {}


    /** Sets the region where touch is excluded from the parent window. */
    default void setTouchExclusionRegion(Region region) {}

    /** Sets a {@link OtherwisedCollapsedListener}. */
    /** Sets a {@link OtherwisedCollapsedListener}. */
    default void setStateListener(OtherwisedCollapsedListener listener) {}
    default void setStateListener(OtherwisedCollapsedListener listener) {}


+17 −0
Original line number Original line Diff line number Diff line
@@ -27,16 +27,20 @@ import android.app.IActivityManager;
import android.content.Context;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.ActivityInfo;
import android.graphics.PixelFormat;
import android.graphics.PixelFormat;
import android.graphics.Region;
import android.os.Binder;
import android.os.Binder;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.Trace;
import android.os.Trace;
import android.util.Log;
import android.util.Log;
import android.view.Display;
import android.view.Display;
import android.view.Gravity;
import android.view.Gravity;
import android.view.IWindow;
import android.view.IWindowSession;
import android.view.View;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManagerGlobal;


import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.Dumpable;
import com.android.systemui.Dumpable;
@@ -506,6 +510,19 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
        }
        }
    }
    }


    @Override
    public void setTouchExclusionRegion(Region region) {
        try {
            final IWindowSession session = WindowManagerGlobal.getWindowSession();
            session.updateTapExcludeRegion(
                    IWindow.Stub.asInterface(getNotificationShadeView().getWindowToken()),
                    region);
        } catch (RemoteException e) {
            Log.e(TAG, "could not update the tap exclusion region:" + e);
        }
    }


    @Override
    @Override
    public void setKeyguardShowing(boolean showing) {
    public void setKeyguardShowing(boolean showing) {
        mCurrentState.mKeyguardShowing = showing;
        mCurrentState.mKeyguardShowing = showing;
Loading