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

Commit f9ea202f authored by Nick Chameyev's avatar Nick Chameyev
Browse files

[Partial Screensharing] Add a temporary entrypoint in SysUI screen recorder

Adds a button that allows to start app selection flow in
SystemUI screen recorder dialog (see screenshot in the bug).

This button is needed for teamfood testing of partial
screensharing and will be shown only when the feature flag
is enabled.

It will be removed when redesigned dialog with a dropdown
will be implemented.

Bug: 239422418
Test: turn on feature flag and start partial screen recording
Test: atest com.android.systemui.screenrecord.ScreenRecordDialogTest
Change-Id: I9caa913ef52eeb2203dca32e94e0b10d71fc4b83
parent bbb51619
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -148,6 +148,20 @@
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"/>

                <!-- Temporary entrypoint for the partial screensharing used for teamfooding -->
                <!-- TODO(b/236838395) remove this and use redesigned dialog -->
                <TextView
                    android:id="@+id/button_app"
                    android:visibility="gone"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="0"
                    android:layout_gravity="end"
                    android:layout_marginEnd="8dp"
                    android:text="App"
                    style="@style/Widget.Dialog.Button.BorderButton" />

                <TextView
                    android:id="@+id/button_start"
                    android:layout_width="wrap_content"
+34 −8
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.media.projection.MediaProjectionManager.EXTRA_MEDIA_PROJECTION
import android.os.Binder
import android.os.Bundle
import android.os.IBinder
import android.os.ResultReceiver
import android.view.View
import com.android.internal.app.ChooserActivity
import com.android.internal.app.chooser.NotSelectableTargetInfo
@@ -103,6 +104,19 @@ class MediaProjectionAppSelectorActivity @Inject constructor(
    }

    private fun onTargetActivityLaunched(launchToken: IBinder) {
        if (intent.hasExtra(EXTRA_CAPTURE_REGION_RESULT_RECEIVER)) {
            // The client requested to return the result in the result receiver instead of
            // activity result, let's send the media projection to the result receiver
            val resultReceiver = intent
                .getParcelableExtra(EXTRA_CAPTURE_REGION_RESULT_RECEIVER,
                    ResultReceiver::class.java) as ResultReceiver
            val captureRegion = MediaProjectionCaptureTarget(launchToken)
            val data = Bundle().apply {
                putParcelable(KEY_CAPTURE_TARGET, captureRegion)
            }
            resultReceiver.send(RESULT_OK, data)
        } else {
            // Return the media projection instance as activity result
            val mediaProjectionBinder = intent.getIBinderExtra(EXTRA_MEDIA_PROJECTION)
            val projection = IMediaProjection.Stub.asInterface(mediaProjectionBinder)

@@ -112,8 +126,20 @@ class MediaProjectionAppSelectorActivity @Inject constructor(
            intent.putExtra(EXTRA_MEDIA_PROJECTION, projection.asBinder())
            setResult(RESULT_OK, intent)
            setForceSendResultForMediaProjection()
        }

        finish()
    }

    override fun shouldGetOnlyDefaultActivities() = false

    companion object {
        /**
         * When EXTRA_CAPTURE_REGION_RESULT_RECEIVER is passed as intent extra
         * the activity will send the [CaptureRegion] to the result receiver
         * instead of returning media projection instance through activity result.
         */
        const val EXTRA_CAPTURE_REGION_RESULT_RECEIVER = "capture_region_result_receiver"
        const val KEY_CAPTURE_TARGET = "capture_region"
    }
}
+49 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.media

import android.os.IBinder
import android.os.Parcel
import android.os.Parcelable

/**
 * Class that represents an area that should be captured.
 * Currently it has only a launch cookie that represents a task but
 * we potentially could add more identifiers e.g. for a pair of tasks.
 */
data class MediaProjectionCaptureTarget(
    val launchCookie: IBinder?
): Parcelable {

    constructor(parcel: Parcel) : this(parcel.readStrongBinder())

    override fun writeToParcel(dest: Parcel, flags: Int) {
        dest.writeStrongBinder(launchCookie)
    }

    override fun describeContents(): Int = 0

    companion object CREATOR : Parcelable.Creator<MediaProjectionCaptureTarget> {
        override fun createFromParcel(parcel: Parcel): MediaProjectionCaptureTarget {
            return MediaProjectionCaptureTarget(parcel)
        }

        override fun newArray(size: Int): Array<MediaProjectionCaptureTarget?> {
            return arrayOfNulls(size)
        }
    }
}
+6 −2
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import com.android.systemui.animation.DialogCuj;
import com.android.systemui.animation.DialogLaunchAnimator;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.QSTile;
@@ -61,6 +62,7 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState>
    private final KeyguardStateController mKeyguardStateController;
    private final Callback mCallback = new Callback();
    private final DialogLaunchAnimator mDialogLaunchAnimator;
    private final FeatureFlags mFlags;

    private long mMillisUntilFinished = 0;

@@ -71,6 +73,7 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState>
            @Main Handler mainHandler,
            FalsingManager falsingManager,
            MetricsLogger metricsLogger,
            FeatureFlags flags,
            StatusBarStateController statusBarStateController,
            ActivityStarter activityStarter,
            QSLogger qsLogger,
@@ -83,6 +86,7 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState>
                statusBarStateController, activityStarter, qsLogger);
        mController = controller;
        mController.observe(this, mCallback);
        mFlags = flags;
        mKeyguardDismissUtil = keyguardDismissUtil;
        mKeyguardStateController = keyguardStateController;
        mDialogLaunchAnimator = dialogLaunchAnimator;
@@ -164,8 +168,8 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState>
            mDialogLaunchAnimator.disableAllCurrentDialogsExitAnimations();
            getHost().collapsePanels();
        };
        ScreenRecordDialog dialog = mController.createScreenRecordDialog(mContext,
                onStartRecordingClicked);
        ScreenRecordDialog dialog = mController.createScreenRecordDialog(mContext, mFlags,
                mDialogLaunchAnimator, mActivityStarter, onStartRecordingClicked);

        ActivityStarter.OnDismissAction dismissAction = () -> {
            if (shouldAnimateFromView) {
+7 −2
Original line number Diff line number Diff line
@@ -29,8 +29,11 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.animation.DialogLaunchAnimator;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.settings.UserContextProvider;
import com.android.systemui.statusbar.policy.CallbackController;

@@ -94,9 +97,11 @@ public class RecordingController
    }

    /** Create a dialog to show screen recording options to the user. */
    public ScreenRecordDialog createScreenRecordDialog(Context context,
    public ScreenRecordDialog createScreenRecordDialog(Context context, FeatureFlags flags,
            DialogLaunchAnimator dialogLaunchAnimator, ActivityStarter activityStarter,
            @Nullable Runnable onStartRecordingClicked) {
        return new ScreenRecordDialog(context, this, mUserContextProvider, onStartRecordingClicked);
        return new ScreenRecordDialog(context, this, activityStarter, mUserContextProvider,
                flags, dialogLaunchAnimator, onStartRecordingClicked);
    }

    /**
Loading