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

Commit 12ced892 authored by Miranda Kephart's avatar Miranda Kephart Committed by Matt Casey
Browse files

Move dismissal logic into the ScreenshotViewProxy

Simplify the communication between ScreenshotController and
ScreenshotView by handling dismissal requests within the ViewProxy.

Bug: 329659738
Flag: NONE
Test: manual, atest
Change-Id: I1909004a4c698cf4261891ae1cede10993850a6b
Merged-In: I1909004a4c698cf4261891ae1cede10993850a6b
parent 51059540
Loading
Loading
Loading
Loading
+73 −40
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.util.Log
import android.view.Display
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.ScrollCaptureResponse
import android.view.View
@@ -34,12 +35,15 @@ import android.window.OnBackInvokedDispatcher
import com.android.internal.logging.UiEventLogger
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.res.R
import com.android.systemui.screenshot.LogConfig.DEBUG_DISMISS
import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_DISMISSED_OTHER

/**
 * Legacy implementation of screenshot view methods. Just proxies the calls down into the original
 * ScreenshotView.
 */
class LegacyScreenshotViewProxy(context: Context) : ScreenshotViewProxy {
class LegacyScreenshotViewProxy(context: Context, private val logger: UiEventLogger) :
    ScreenshotViewProxy {
    override val view: ScreenshotView =
        LayoutInflater.from(context).inflate(R.layout.screenshot, null) as ScreenshotView
    override val screenshotPreview: View
@@ -52,13 +56,6 @@ class LegacyScreenshotViewProxy(context: Context) : ScreenshotViewProxy {
        set(value) {
            view.setDefaultTimeoutMillis(value)
        }
    override var onBackInvokedCallback: OnBackInvokedCallback = OnBackInvokedCallback {
        Log.wtf(TAG, "OnBackInvoked called before being set!")
    }
    override var onKeyListener: View.OnKeyListener? = null
        set(value) {
            view.setOnKeyListener(value)
        }
    override var flags: FeatureFlags? = null
        set(value) {
            view.setFlags(value)
@@ -67,10 +64,6 @@ class LegacyScreenshotViewProxy(context: Context) : ScreenshotViewProxy {
        set(value) {
            view.setPackageName(value)
        }
    override var logger: UiEventLogger? = null
        set(value) {
            view.setUiEventLogger(value)
        }
    override var callbacks: ScreenshotView.ScreenshotViewCallback? = null
        set(value) {
            view.setCallbacks(value)
@@ -88,31 +81,9 @@ class LegacyScreenshotViewProxy(context: Context) : ScreenshotViewProxy {
        get() = view.isPendingSharedTransition

    init {

        view.addOnAttachStateChangeListener(
            object : View.OnAttachStateChangeListener {
                override fun onViewAttachedToWindow(view: View) {
                    if (LogConfig.DEBUG_INPUT) {
                        Log.d(TAG, "Registering Predictive Back callback")
                    }
                    view
                        .findOnBackInvokedDispatcher()
                        ?.registerOnBackInvokedCallback(
                            OnBackInvokedDispatcher.PRIORITY_DEFAULT,
                            onBackInvokedCallback
                        )
                }

                override fun onViewDetachedFromWindow(view: View) {
                    if (LogConfig.DEBUG_INPUT) {
                        Log.d(TAG, "Unregistering Predictive Back callback")
                    }
                    view
                        .findOnBackInvokedDispatcher()
                        ?.unregisterOnBackInvokedCallback(onBackInvokedCallback)
                }
            }
        )
        view.setUiEventLogger(logger)
        addPredictiveBackListener { requestDismissal(SCREENSHOT_DISMISSED_OTHER) }
        setOnKeyListener { requestDismissal(SCREENSHOT_DISMISSED_OTHER) }
        if (LogConfig.DEBUG_WINDOW) {
            Log.d(TAG, "adding OnComputeInternalInsetsListener")
        }
@@ -135,7 +106,20 @@ class LegacyScreenshotViewProxy(context: Context) : ScreenshotViewProxy {
    override fun setChipIntents(imageData: ScreenshotController.SavedImageData) =
        view.setChipIntents(imageData)

    override fun animateDismissal() = view.animateDismissal()
    override fun requestDismissal(event: ScreenshotEvent) {
        if (DEBUG_DISMISS) {
            Log.d(TAG, "screenshot dismissal requested")
        }
        // If we're already animating out, don't restart the animation
        if (view.isDismissing) {
            if (DEBUG_DISMISS) {
                Log.v(TAG, "Already dismissing, ignoring duplicate command $event")
            }
            return
        }
        logger.log(event, 0, packageName)
        view.animateDismissal()
    }

    override fun showScrollChip(packageName: String, onClick: Runnable) =
        view.showScrollChip(packageName, onClick)
@@ -177,9 +161,58 @@ class LegacyScreenshotViewProxy(context: Context) : ScreenshotViewProxy {
        view.post(runnable)
    }

    private fun addPredictiveBackListener(onDismissRequested: (ScreenshotEvent) -> Unit) {
        val onBackInvokedCallback = OnBackInvokedCallback {
            if (LogConfig.DEBUG_INPUT) {
                Log.d(TAG, "Predictive Back callback dispatched")
            }
            onDismissRequested.invoke(ScreenshotEvent.SCREENSHOT_DISMISSED_OTHER)
        }
        view.addOnAttachStateChangeListener(
            object : View.OnAttachStateChangeListener {
                override fun onViewAttachedToWindow(v: View) {
                    if (LogConfig.DEBUG_INPUT) {
                        Log.d(TAG, "Registering Predictive Back callback")
                    }
                    view
                        .findOnBackInvokedDispatcher()
                        ?.registerOnBackInvokedCallback(
                            OnBackInvokedDispatcher.PRIORITY_DEFAULT,
                            onBackInvokedCallback
                        )
                }

                override fun onViewDetachedFromWindow(view: View) {
                    if (LogConfig.DEBUG_INPUT) {
                        Log.d(TAG, "Unregistering Predictive Back callback")
                    }
                    view
                        .findOnBackInvokedDispatcher()
                        ?.unregisterOnBackInvokedCallback(onBackInvokedCallback)
                }
            }
        )
    }
    private fun setOnKeyListener(onDismissRequested: (ScreenshotEvent) -> Unit) {
        view.setOnKeyListener(
            object : View.OnKeyListener {
                override fun onKey(view: View, keyCode: Int, event: KeyEvent): Boolean {
                    if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE) {
                        if (LogConfig.DEBUG_INPUT) {
                            Log.d(TAG, "onKeyEvent: $keyCode")
                        }
                        onDismissRequested.invoke(ScreenshotEvent.SCREENSHOT_DISMISSED_OTHER)
                        return true
                    }
                    return false
                }
            }
        )
    }

    class Factory : ScreenshotViewProxy.Factory {
        override fun getProxy(context: Context): ScreenshotViewProxy {
            return LegacyScreenshotViewProxy(context)
        override fun getProxy(context: Context, logger: UiEventLogger): ScreenshotViewProxy {
            return LegacyScreenshotViewProxy(context, logger)
        }
    }

+14 −47
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;

import static com.android.systemui.screenshot.LogConfig.DEBUG_ANIM;
import static com.android.systemui.screenshot.LogConfig.DEBUG_CALLBACK;
import static com.android.systemui.screenshot.LogConfig.DEBUG_DISMISS;
import static com.android.systemui.screenshot.LogConfig.DEBUG_INPUT;
import static com.android.systemui.screenshot.LogConfig.DEBUG_UI;
import static com.android.systemui.screenshot.LogConfig.DEBUG_WINDOW;
@@ -64,7 +63,6 @@ import android.util.Pair;
import android.view.Display;
import android.view.IRemoteAnimationFinishedCallback;
import android.view.IRemoteAnimationRunner;
import android.view.KeyEvent;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationTarget;
import android.view.ScrollCaptureResponse;
@@ -333,12 +331,7 @@ public class ScreenshotController {

        mScreenshotHandler = timeoutHandler;
        mScreenshotHandler.setDefaultTimeoutMillis(SCREENSHOT_CORNER_DEFAULT_TIMEOUT_MILLIS);
        mScreenshotHandler.setOnTimeoutRunnable(() -> {
            if (DEBUG_UI) {
                Log.d(TAG, "Corner timeout hit");
            }
            dismissScreenshot(SCREENSHOT_INTERACTION_TIMEOUT);
        });


        mDisplayId = displayId;
        mDisplayManager = requireNonNull(context.getSystemService(DisplayManager.class));
@@ -351,7 +344,14 @@ public class ScreenshotController {
        mMessageContainerController = messageContainerController;
        mAssistContentRequester = assistContentRequester;

        mViewProxy = viewProxyFactory.getProxy(mContext);
        mViewProxy = viewProxyFactory.getProxy(mContext, mUiEventLogger);

        mScreenshotHandler.setOnTimeoutRunnable(() -> {
            if (DEBUG_UI) {
                Log.d(TAG, "Corner timeout hit");
            }
            mViewProxy.requestDismissal(SCREENSHOT_INTERACTION_TIMEOUT);
        });

        mAccessibilityManager = AccessibilityManager.getInstance(mContext);

@@ -376,7 +376,7 @@ public class ScreenshotController {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (ClipboardOverlayController.COPY_OVERLAY_ACTION.equals(intent.getAction())) {
                    dismissScreenshot(SCREENSHOT_DISMISSED_OTHER);
                    mViewProxy.requestDismissal(SCREENSHOT_DISMISSED_OTHER);
                }
            }
        };
@@ -525,22 +525,11 @@ public class ScreenshotController {
    }

    /**
     * Clears current screenshot
     * Requests the view to dismiss the current screenshot (may be ignored, if screenshot is already
     * being dismissed)
     */
    void dismissScreenshot(ScreenshotEvent event) {
        if (DEBUG_DISMISS) {
            Log.d(TAG, "dismissScreenshot");
        }
        // If we're already animating out, don't restart the animation
        if (mViewProxy.isDismissing()) {
            if (DEBUG_DISMISS) {
                Log.v(TAG, "Already dismissing, ignoring duplicate command");
            }
            return;
        }
        mUiEventLogger.log(event, 0, mPackageName);
        mScreenshotHandler.cancelTimeout();
        mViewProxy.animateDismissal();
    void requestDismissal(ScreenshotEvent event) {
        mViewProxy.requestDismissal(event);
    }

    boolean isPendingSharedTransition() {
@@ -572,10 +561,6 @@ public class ScreenshotController {
        mScreenshotSoundController.releaseScreenshotSoundAsync();
    }

    private void respondToKeyDismissal() {
        dismissScreenshot(SCREENSHOT_DISMISSED_OTHER);
    }

    /**
     * Update resources on configuration change. Reinflate for theme/color changes.
     */
@@ -585,13 +570,6 @@ public class ScreenshotController {
        }

        mMessageContainerController.setView(mViewProxy.getView());
        mViewProxy.setLogger(mUiEventLogger);
        mViewProxy.setOnBackInvokedCallback(() -> {
            if (DEBUG_INPUT) {
                Log.d(TAG, "Predictive Back callback dispatched");
            }
            respondToKeyDismissal();
        });
        mViewProxy.setCallbacks(new ScreenshotView.ScreenshotViewCallback() {
            @Override
            public void onUserInteraction() {
@@ -622,17 +600,6 @@ public class ScreenshotController {
        mViewProxy.setDefaultDisplay(mDisplayId);
        mViewProxy.setDefaultTimeoutMillis(mScreenshotHandler.getDefaultTimeoutMillis());

        mViewProxy.setOnKeyListener((v, keyCode, event) -> {
            if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE) {
                if (DEBUG_INPUT) {
                    Log.d(TAG, "onKeyEvent: " + keyCode);
                }
                respondToKeyDismissal();
                return true;
            }
            return false;
        });

        if (DEBUG_WINDOW) {
            Log.d(TAG, "setContentView: " + mViewProxy.getView());
        }
+2 −7
Original line number Diff line number Diff line
@@ -24,11 +24,9 @@ import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.view.ScrollCaptureResponse
import android.view.View
import android.view.View.OnKeyListener
import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.view.WindowInsets
import android.window.OnBackInvokedCallback
import com.android.internal.logging.UiEventLogger
import com.android.systemui.flags.FeatureFlags

@@ -39,11 +37,8 @@ interface ScreenshotViewProxy {

    var defaultDisplay: Int
    var defaultTimeoutMillis: Long
    var onBackInvokedCallback: OnBackInvokedCallback
    var onKeyListener: OnKeyListener?
    var flags: FeatureFlags?
    var packageName: String
    var logger: UiEventLogger?
    var callbacks: ScreenshotView.ScreenshotViewCallback?
    var screenshot: ScreenshotData?

@@ -58,7 +53,7 @@ interface ScreenshotViewProxy {
    fun createScreenshotDropInAnimation(screenRect: Rect, showFlash: Boolean): Animator
    fun addQuickShareChip(quickShareAction: Notification.Action)
    fun setChipIntents(imageData: ScreenshotController.SavedImageData)
    fun animateDismissal()
    fun requestDismissal(event: ScreenshotEvent)

    fun showScrollChip(packageName: String, onClick: Runnable)
    fun hideScrollChip()
@@ -82,6 +77,6 @@ interface ScreenshotViewProxy {
    fun post(runnable: Runnable)

    interface Factory {
        fun getProxy(context: Context): ScreenshotViewProxy
        fun getProxy(context: Context, logger: UiEventLogger): ScreenshotViewProxy
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -136,7 +136,7 @@ constructor(
    fun onCloseSystemDialogsReceived() {
        screenshotControllers.forEach { (_, screenshotController) ->
            if (!screenshotController.isPendingSharedTransition) {
                screenshotController.dismissScreenshot(ScreenshotEvent.SCREENSHOT_DISMISSED_OTHER)
                screenshotController.requestDismissal(ScreenshotEvent.SCREENSHOT_DISMISSED_OTHER)
            }
        }
    }
+2 −2
Original line number Diff line number Diff line
@@ -53,9 +53,9 @@ import android.widget.Toast;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.util.ScreenshotRequest;
import com.android.systemui.res.R;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.res.R;

import java.util.concurrent.Executor;
import java.util.function.Consumer;
@@ -89,7 +89,7 @@ public class TakeScreenshotService extends Service {
                    // TODO(b/295143676): move receiver inside executor when the flag is enabled.
                    mTakeScreenshotExecutor.get().onCloseSystemDialogsReceived();
                } else if (!mScreenshot.isPendingSharedTransition()) {
                    mScreenshot.dismissScreenshot(SCREENSHOT_DISMISSED_OTHER);
                    mScreenshot.requestDismissal(SCREENSHOT_DISMISSED_OTHER);
                }
            }
        }
Loading