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

Commit 56e41925 authored by Miranda Kephart's avatar Miranda Kephart Committed by Matt Casey
Browse files

Move more code into ScreenshotViewProxy

- viewTreeObserver (only used to postpone the startAnimation call until
  after the view has loaded in onPreDraw)
- setDefaultTimeout (this can't be anything other than the
  SCREENSHOT_CORNER_DEFAULT_TIMEOUT_MILLIS)

Bug: 329659738
Test: manual, atest
Flag: NONE
Change-Id: I520affe2b957fc064598f295cfec341f60318c8c
Merged-In: I520affe2b957fc064598f295cfec341f60318c8c
parent 12ced892
Loading
Loading
Loading
Loading
+30 −16
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import android.app.Notification
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.util.Log
import android.view.Display
import android.view.KeyEvent
@@ -32,6 +31,7 @@ import android.view.ViewTreeObserver
import android.view.WindowInsets
import android.window.OnBackInvokedCallback
import android.window.OnBackInvokedDispatcher
import androidx.appcompat.content.res.AppCompatResources
import com.android.internal.logging.UiEventLogger
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.res.R
@@ -42,20 +42,15 @@ import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_DISMISSED_OTHE
 * Legacy implementation of screenshot view methods. Just proxies the calls down into the original
 * ScreenshotView.
 */
class LegacyScreenshotViewProxy(context: Context, private val logger: UiEventLogger) :
class LegacyScreenshotViewProxy(private val 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

    override var defaultDisplay: Int = Display.DEFAULT_DISPLAY
        set(value) {
            view.setDefaultDisplay(value)
        }
    override var defaultTimeoutMillis: Long = 6000
        set(value) {
            view.setDefaultTimeoutMillis(value)
        }
    override var flags: FeatureFlags? = null
        set(value) {
            view.setFlags(value)
@@ -70,7 +65,16 @@ class LegacyScreenshotViewProxy(context: Context, private val logger: UiEventLog
        }
    override var screenshot: ScreenshotData? = null
        set(value) {
            view.setScreenshot(value)
            field = value
            value?.let {
                val badgeBg =
                    AppCompatResources.getDrawable(context, R.drawable.overlay_badge_background)
                val user = it.userHandle
                if (badgeBg != null && user != null) {
                    view.badgeScreenshot(context.packageManager.getUserBadgedIcon(badgeBg, user))
                }
                view.setScreenshot(it)
            }
        }

    override val isAttachedToWindow
@@ -95,8 +99,6 @@ class LegacyScreenshotViewProxy(context: Context, private val logger: UiEventLog
    override fun updateInsets(insets: WindowInsets) = view.updateInsets(insets)
    override fun updateOrientation(insets: WindowInsets) = view.updateOrientation(insets)

    override fun badgeScreenshot(userBadgedIcon: Drawable) = view.badgeScreenshot(userBadgedIcon)

    override fun createScreenshotDropInAnimation(screenRect: Rect, showFlash: Boolean): Animator =
        view.createScreenshotDropInAnimation(screenRect, showFlash)

@@ -130,14 +132,17 @@ class LegacyScreenshotViewProxy(context: Context, private val logger: UiEventLog
        response: ScrollCaptureResponse,
        screenBitmap: Bitmap,
        newScreenshot: Bitmap,
        screenshotTakenInPortrait: Boolean
    ) =
        screenshotTakenInPortrait: Boolean,
        onTransitionPrepared: Runnable,
    ) {
        view.prepareScrollingTransition(
            response,
            screenBitmap,
            newScreenshot,
            screenshotTakenInPortrait
        )
        view.post { onTransitionPrepared.run() }
    }

    override fun startLongScreenshotTransition(
        transitionDestination: Rect,
@@ -155,10 +160,19 @@ class LegacyScreenshotViewProxy(context: Context, private val logger: UiEventLog

    override fun announceForAccessibility(string: String) = view.announceForAccessibility(string)

    override fun getViewTreeObserver(): ViewTreeObserver = view.viewTreeObserver

    override fun post(runnable: Runnable) {
        view.post(runnable)
    override fun prepareEntranceAnimation(runnable: Runnable) {
        view.viewTreeObserver.addOnPreDrawListener(
            object : ViewTreeObserver.OnPreDrawListener {
                override fun onPreDraw(): Boolean {
                    if (LogConfig.DEBUG_WINDOW) {
                        Log.d(TAG, "onPreDraw: startAnimation")
                    }
                    view.viewTreeObserver.removeOnPreDrawListener(this)
                    runnable.run()
                    return true
                }
            }
        )
    }

    private fun addPredictiveBackListener(onDismissRequested: (ScreenshotEvent) -> Unit) {
+15 −29
Original line number Diff line number Diff line
@@ -228,7 +228,7 @@ public class ScreenshotController {
    // From WizardManagerHelper.java
    private static final String SETTINGS_SECURE_USER_SETUP_COMPLETE = "user_setup_complete";

    private static final int SCREENSHOT_CORNER_DEFAULT_TIMEOUT_MILLIS = 6000;
    static final int SCREENSHOT_CORNER_DEFAULT_TIMEOUT_MILLIS = 6000;

    private final WindowContext mContext;
    private final FeatureFlags mFlags;
@@ -460,7 +460,7 @@ public class ScreenshotController {

        attachWindow();

        boolean showFlash = true;
        boolean showFlash;
        if (screenshot.getType() == WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE) {
            if (screenshot.getScreenBounds() != null
                    && aspectRatiosMatch(screenshot.getBitmap(), screenshot.getInsets(),
@@ -472,15 +472,14 @@ public class ScreenshotController {
                screenshot.setScreenBounds(new Rect(0, 0, screenshot.getBitmap().getWidth(),
                        screenshot.getBitmap().getHeight()));
            }
        } else {
            showFlash = true;
        }

        prepareAnimation(screenshot.getScreenBounds(), showFlash, () -> {
            mMessageContainerController.onScreenshotTaken(screenshot);
        });
        mViewProxy.prepareEntranceAnimation(
                () -> startAnimation(screenshot.getScreenBounds(), showFlash,
                        () -> mMessageContainerController.onScreenshotTaken(screenshot)));

        mViewProxy.badgeScreenshot(mContext.getPackageManager().getUserBadgedIcon(
                mContext.getDrawable(R.drawable.overlay_badge_background),
                screenshot.getUserHandle()));
        mViewProxy.setScreenshot(screenshot);

        // ignore system bar insets for the purpose of window layout
@@ -598,7 +597,6 @@ public class ScreenshotController {
        });
        mViewProxy.setFlags(mFlags);
        mViewProxy.setDefaultDisplay(mDisplayId);
        mViewProxy.setDefaultTimeoutMillis(mScreenshotHandler.getDefaultTimeoutMillis());

        if (DEBUG_WINDOW) {
            Log.d(TAG, "setContentView: " + mViewProxy.getView());
@@ -606,22 +604,6 @@ public class ScreenshotController {
        setContentView(mViewProxy.getView());
    }

    private void prepareAnimation(Rect screenRect, boolean showFlash,
            Runnable onAnimationComplete) {
        mViewProxy.getViewTreeObserver().addOnPreDrawListener(
                new ViewTreeObserver.OnPreDrawListener() {
                    @Override
                    public boolean onPreDraw() {
                        if (DEBUG_WINDOW) {
                            Log.d(TAG, "onPreDraw: startAnimation");
                        }
                        mViewProxy.getViewTreeObserver().removeOnPreDrawListener(this);
                        startAnimation(screenRect, showFlash, onAnimationComplete);
                        return true;
                    }
                });
    }

    private void enqueueScrollCaptureRequest(UserHandle owner) {
        // Wait until this window is attached to request because it is
        // the reference used to locate the target window (below).
@@ -706,10 +688,14 @@ public class ScreenshotController {
                Bitmap newScreenshot = mImageCapture.captureDisplay(mDisplayId,
                        new Rect(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels));

                mViewProxy.prepareScrollingTransition(response, mScreenBitmap, newScreenshot,
                        mScreenshotTakenInPortrait);
                // delay starting scroll capture to make sure the scrim is up before the app moves
                mViewProxy.post(() -> runBatchScrollCapture(response, owner));
                if (newScreenshot != null) {
                    // delay starting scroll capture to make sure scrim is up before the app moves
                    mViewProxy.prepareScrollingTransition(
                            response, mScreenBitmap, newScreenshot, mScreenshotTakenInPortrait,
                            () -> runBatchScrollCapture(response, owner));
                } else {
                    Log.wtf(TAG, "failed to capture current screenshot for scroll transition");
                }
            });
        } catch (InterruptedException | ExecutionException e) {
            Log.e(TAG, "requestScrollCapture failed", e);
+4 −7
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static com.android.systemui.screenshot.LogConfig.DEBUG_SCROLL;
import static com.android.systemui.screenshot.LogConfig.DEBUG_UI;
import static com.android.systemui.screenshot.LogConfig.DEBUG_WINDOW;
import static com.android.systemui.screenshot.LogConfig.logTag;
import static com.android.systemui.screenshot.ScreenshotController.SCREENSHOT_CORNER_DEFAULT_TIMEOUT_MILLIS;

import static java.util.Objects.requireNonNull;

@@ -33,6 +34,7 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.BroadcastOptions;
import android.app.Notification;
@@ -168,7 +170,6 @@ public class ScreenshotView extends FrameLayout implements
    private ScreenshotData mScreenshotData;

    private final InteractionJankMonitor mInteractionJankMonitor;
    private long mDefaultTimeoutOfTimeoutHandler;
    private FeatureFlags mFlags;
    private final Bundle mInteractiveBroadcastOption;

@@ -244,10 +245,6 @@ public class ScreenshotView extends FrameLayout implements
        return InteractionJankMonitor.getInstance();
    }

    void setDefaultTimeoutMillis(long timeout) {
        mDefaultTimeoutOfTimeoutHandler = timeout;
    }

    public void hideScrollChip() {
        mScrollChip.setVisibility(View.GONE);
    }
@@ -755,7 +752,7 @@ public class ScreenshotView extends FrameLayout implements
                        InteractionJankMonitor.Configuration.Builder.withView(
                                        CUJ_TAKE_SCREENSHOT, mScreenshotStatic)
                                .setTag("Actions")
                                .setTimeout(mDefaultTimeoutOfTimeoutHandler);
                                .setTimeout(SCREENSHOT_CORNER_DEFAULT_TIMEOUT_MILLIS);
                mInteractionJankMonitor.begin(builder);
            }
        });
@@ -781,7 +778,7 @@ public class ScreenshotView extends FrameLayout implements
        return animator;
    }

    void badgeScreenshot(Drawable badge) {
    void badgeScreenshot(@Nullable Drawable badge) {
        mScreenshotBadge.setImageDrawable(badge);
        mScreenshotBadge.setVisibility(badge != null ? View.VISIBLE : View.GONE);
    }
+3 −7
Original line number Diff line number Diff line
@@ -21,11 +21,9 @@ import android.app.Notification
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.view.ScrollCaptureResponse
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.view.WindowInsets
import com.android.internal.logging.UiEventLogger
import com.android.systemui.flags.FeatureFlags
@@ -36,7 +34,6 @@ interface ScreenshotViewProxy {
    val screenshotPreview: View

    var defaultDisplay: Int
    var defaultTimeoutMillis: Long
    var flags: FeatureFlags?
    var packageName: String
    var callbacks: ScreenshotView.ScreenshotViewCallback?
@@ -49,7 +46,6 @@ interface ScreenshotViewProxy {
    fun reset()
    fun updateInsets(insets: WindowInsets)
    fun updateOrientation(insets: WindowInsets)
    fun badgeScreenshot(userBadgedIcon: Drawable)
    fun createScreenshotDropInAnimation(screenRect: Rect, showFlash: Boolean): Animator
    fun addQuickShareChip(quickShareAction: Notification.Action)
    fun setChipIntents(imageData: ScreenshotController.SavedImageData)
@@ -61,7 +57,8 @@ interface ScreenshotViewProxy {
        response: ScrollCaptureResponse,
        screenBitmap: Bitmap,
        newScreenshot: Bitmap,
        screenshotTakenInPortrait: Boolean
        screenshotTakenInPortrait: Boolean,
        onTransitionPrepared: Runnable,
    )
    fun startLongScreenshotTransition(
        transitionDestination: Rect,
@@ -73,8 +70,7 @@ interface ScreenshotViewProxy {
    fun stopInputListening()
    fun requestFocus()
    fun announceForAccessibility(string: String)
    fun getViewTreeObserver(): ViewTreeObserver
    fun post(runnable: Runnable)
    fun prepareEntranceAnimation(runnable: Runnable)

    interface Factory {
        fun getProxy(context: Context, logger: UiEventLogger): ScreenshotViewProxy
+1 −1
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ public class TimeoutHandler extends Handler {
    private final Context mContext;

    private Runnable mOnTimeout;
    private int mDefaultTimeout = DEFAULT_TIMEOUT_MILLIS;
    int mDefaultTimeout = DEFAULT_TIMEOUT_MILLIS;

    @Inject
    public TimeoutHandler(Context context) {