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

Commit 4233b5b6 authored by Jordan Demeulenaere's avatar Jordan Demeulenaere
Browse files

Animate the screen recording dialog (1/2)

This CL animates the screen recording dialog when opened from its QS
tile.

See b/202257558#comment3 and #comment4 for before/after videos.

Bug: 202257558
Test: Manual
Test: atest ScreenRecordTileTest
Test: atest RecordingControllerTest
Change-Id: I49cff0381c85ef870fea03b62bfe8d9c5fb0a110
parent 3b6f9fd2
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -356,10 +356,6 @@
                  android:exported="false"
                  android:finishOnTaskLaunch="true" />

        <activity android:name=".screenrecord.ScreenRecordDialog"
            android:theme="@style/ScreenRecord"
            android:showForAllUsers="true"
            android:excludeFromRecents="true" />
        <service android:name=".screenrecord.RecordingService" />

        <receiver android:name=".SysuiRestartReceiver"
+1 −2
Original line number Diff line number Diff line
@@ -17,8 +17,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:background="@drawable/rounded_bg_full">
    android:orientation="vertical">

    <!-- Scrollview is necessary to fit everything in landscape layout -->
    <ScrollView
+0 −7
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import com.android.systemui.ForegroundServicesDialog;
import com.android.systemui.keyguard.WorkLockActivity;
import com.android.systemui.people.PeopleSpaceActivity;
import com.android.systemui.people.widget.LaunchConversationActivity;
import com.android.systemui.screenrecord.ScreenRecordDialog;
import com.android.systemui.screenshot.LongScreenshotActivity;
import com.android.systemui.sensorprivacy.SensorUseStartedActivity;
import com.android.systemui.sensorprivacy.television.TvUnblockSensorActivity;
@@ -67,12 +66,6 @@ public abstract class DefaultActivityBinder {
    @ClassKey(BrightnessDialog.class)
    public abstract Activity bindBrightnessDialog(BrightnessDialog activity);

    /** Inject into ScreenRecordDialog */
    @Binds
    @IntoMap
    @ClassKey(ScreenRecordDialog.class)
    public abstract Activity bindScreenRecordDialog(ScreenRecordDialog activity);

    /** Inject into UsbDebuggingActivity. */
    @Binds
    @IntoMap
+39 −11
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import androidx.annotation.Nullable;

import com.android.internal.logging.MetricsLogger;
import com.android.systemui.R;
import com.android.systemui.animation.DialogLaunchAnimator;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
@@ -39,7 +40,9 @@ import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.screenrecord.RecordingController;
import com.android.systemui.screenrecord.ScreenRecordDialog;
import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
import com.android.systemui.statusbar.policy.KeyguardStateController;

import javax.inject.Inject;

@@ -49,10 +52,13 @@ import javax.inject.Inject;
public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState>
        implements RecordingController.RecordingStateChangeCallback {
    private static final String TAG = "ScreenRecordTile";
    private RecordingController mController;
    private KeyguardDismissUtil mKeyguardDismissUtil;
    private final RecordingController mController;
    private final KeyguardDismissUtil mKeyguardDismissUtil;
    private final KeyguardStateController mKeyguardStateController;
    private final Callback mCallback = new Callback();
    private final DialogLaunchAnimator mDialogLaunchAnimator;

    private long mMillisUntilFinished = 0;
    private Callback mCallback = new Callback();

    @Inject
    public ScreenRecordTile(
@@ -65,13 +71,17 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState>
            ActivityStarter activityStarter,
            QSLogger qsLogger,
            RecordingController controller,
            KeyguardDismissUtil keyguardDismissUtil
            KeyguardDismissUtil keyguardDismissUtil,
            KeyguardStateController keyguardStateController,
            DialogLaunchAnimator dialogLaunchAnimator
    ) {
        super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
                statusBarStateController, activityStarter, qsLogger);
        mController = controller;
        mController.observe(this, mCallback);
        mKeyguardDismissUtil = keyguardDismissUtil;
        mKeyguardStateController = keyguardStateController;
        mDialogLaunchAnimator = dialogLaunchAnimator;
    }

    @Override
@@ -89,7 +99,7 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState>
        } else if (mController.isRecording()) {
            stopRecording();
        } else {
            mUiHandler.post(() -> showPrompt());
            mUiHandler.post(() -> showPrompt(view));
        }
        refreshState();
    }
@@ -136,15 +146,33 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState>
        return mContext.getString(R.string.quick_settings_screen_record_label);
    }

    private void showPrompt() {
        // Close QS, otherwise the dialog appears beneath it
    private void showPrompt(@Nullable View view) {
        // We animate from the touched view only if we are not on the keyguard, given that if we
        // are we will dismiss it which will also collapse the shade.
        boolean shouldAnimateFromView = view != null && !mKeyguardStateController.isShowing();

        // Create the recording dialog that will collapse the shade only if we start the recording.
        Runnable onStartRecordingClicked = () -> {
            // We dismiss the shade. Since starting the recording will also dismiss the dialog, we
            // disable the exit animation which looks weird when it happens at the same time as the
            // shade collapsing.
            mDialogLaunchAnimator.disableAllCurrentDialogsExitAnimations();
            getHost().collapsePanels();
        Intent intent = mController.getPromptIntent();
        };
        ScreenRecordDialog dialog = mController.createScreenRecordDialog(mContext,
                onStartRecordingClicked);

        ActivityStarter.OnDismissAction dismissAction = () -> {
            mHost.getUserContext().startActivity(intent);
            if (shouldAnimateFromView) {
                mDialogLaunchAnimator.showFromView(dialog, view);
            } else {
                dialog.show();
            }
            return false;
        };
        mKeyguardDismissUtil.executeWhenUnlocked(dismissAction, false, false);

        mKeyguardDismissUtil.executeWhenUnlocked(dismissAction, false /* requiresShadeOpen */,
                true /* afterKeyguardDone */);
    }

    private void cancelCountdown() {
+10 −15
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.systemui.screenrecord;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -27,10 +26,12 @@ import android.os.UserHandle;
import android.util.Log;

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

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.settings.UserContextProvider;
import com.android.systemui.statusbar.policy.CallbackController;

import java.util.concurrent.CopyOnWriteArrayList;
@@ -44,15 +45,13 @@ import javax.inject.Inject;
public class RecordingController
        implements CallbackController<RecordingController.RecordingStateChangeCallback> {
    private static final String TAG = "RecordingController";
    private static final String SYSUI_PACKAGE = "com.android.systemui";
    private static final String SYSUI_SCREENRECORD_LAUNCHER =
            "com.android.systemui.screenrecord.ScreenRecordDialog";

    private boolean mIsStarting;
    private boolean mIsRecording;
    private PendingIntent mStopIntent;
    private CountDownTimer mCountDownTimer = null;
    private BroadcastDispatcher mBroadcastDispatcher;
    private UserContextProvider mUserContextProvider;

    protected static final String INTENT_UPDATE_STATE =
            "com.android.systemui.screenrecord.UPDATE_STATE";
@@ -88,20 +87,16 @@ public class RecordingController
     * Create a new RecordingController
     */
    @Inject
    public RecordingController(BroadcastDispatcher broadcastDispatcher) {
    public RecordingController(BroadcastDispatcher broadcastDispatcher,
            UserContextProvider userContextProvider) {
        mBroadcastDispatcher = broadcastDispatcher;
        mUserContextProvider = userContextProvider;
    }

    /**
     * Get an intent to show screen recording options to the user.
     */
    public Intent getPromptIntent() {
        final ComponentName launcherComponent = new ComponentName(SYSUI_PACKAGE,
                SYSUI_SCREENRECORD_LAUNCHER);
        final Intent intent = new Intent();
        intent.setComponent(launcherComponent);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        return intent;
    /** Create a dialog to show screen recording options to the user. */
    public ScreenRecordDialog createScreenRecordDialog(Context context,
            @Nullable Runnable onStartRecordingClicked) {
        return new ScreenRecordDialog(context, this, mUserContextProvider, onStartRecordingClicked);
    }

    /**
Loading