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

Commit 789872fb authored by Matt Casey's avatar Matt Casey
Browse files

Fix long screenshots actions for work profile.

Use the ActionIntentExecutor for edit/share there as well.

Logic changes are flagged (everything outside of that is just parameter
passing).

Shared element transition from work profile long screenshots -> markup
wasn't working, so I've omitted it for now.

Bug: 231957192
Test: Manual testing with and without the flag, work and personal
profile long screenshots.

Change-Id: I6d035bfd1838900f8004dbb5bc8f9ae5411e960d
parent ad23a83c
Loading
Loading
Loading
Loading
+15 −17
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ import android.view.WindowManagerGlobal
import com.android.internal.infra.ServiceConnector
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import javax.inject.Inject
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineDispatcher
@@ -45,7 +45,7 @@ class ActionIntentExecutor
@Inject
constructor(
    @Application private val applicationScope: CoroutineScope,
    @Background private val bgDispatcher: CoroutineDispatcher,
    @Main private val mainDispatcher: CoroutineDispatcher,
    private val context: Context,
) {
    /**
@@ -70,11 +70,10 @@ constructor(
        userId: Int,
        overrideTransition: Boolean,
    ) {
        withContext(bgDispatcher) {
        dismissKeyguard()

        if (userId == UserHandle.myUserId()) {
                context.startActivity(intent, bundle)
            withContext(mainDispatcher) { context.startActivity(intent, bundle) }
        } else {
            launchCrossProfileIntent(userId, intent, bundle)
        }
@@ -89,7 +88,6 @@ constructor(
            }
        }
    }
    }

    private val proxyConnector: ServiceConnector<IScreenshotProxy> =
        ServiceConnector.Impl(
+58 −29
Original line number Diff line number Diff line
@@ -46,6 +46,8 @@ import com.android.internal.logging.UiEventLogger;
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.screenshot.ScrollCaptureController.LongScreenshot;

import com.google.common.util.concurrent.ListenableFuture;
@@ -67,6 +69,7 @@ public class LongScreenshotActivity extends Activity {
    private static final String TAG = LogConfig.logTag(LongScreenshotActivity.class);

    public static final String EXTRA_CAPTURE_RESPONSE = "capture-response";
    public static final String EXTRA_SCREENSHOT_USER_HANDLE = "screenshot-userhandle";
    private static final String KEY_SAVED_IMAGE_PATH = "saved-image-path";

    private final UiEventLogger mUiEventLogger;
@@ -74,6 +77,8 @@ public class LongScreenshotActivity extends Activity {
    private final Executor mBackgroundExecutor;
    private final ImageExporter mImageExporter;
    private final LongScreenshotData mLongScreenshotHolder;
    private final ActionIntentExecutor mActionExecutor;
    private final FeatureFlags mFeatureFlags;

    private ImageView mPreview;
    private ImageView mTransitionView;
@@ -85,6 +90,7 @@ public class LongScreenshotActivity extends Activity {
    private CropView mCropView;
    private MagnifierView mMagnifierView;
    private ScrollCaptureResponse mScrollCaptureResponse;
    private UserHandle mScreenshotUserHandle;
    private File mSavedImagePath;

    private ListenableFuture<File> mCacheSaveFuture;
@@ -103,12 +109,15 @@ public class LongScreenshotActivity extends Activity {
    @Inject
    public LongScreenshotActivity(UiEventLogger uiEventLogger, ImageExporter imageExporter,
            @Main Executor mainExecutor, @Background Executor bgExecutor,
            LongScreenshotData longScreenshotHolder) {
            LongScreenshotData longScreenshotHolder, ActionIntentExecutor actionExecutor,
            FeatureFlags featureFlags) {
        mUiEventLogger = uiEventLogger;
        mUiExecutor = mainExecutor;
        mBackgroundExecutor = bgExecutor;
        mImageExporter = imageExporter;
        mLongScreenshotHolder = longScreenshotHolder;
        mActionExecutor = actionExecutor;
        mFeatureFlags = featureFlags;
    }


@@ -139,6 +148,11 @@ public class LongScreenshotActivity extends Activity {

        Intent intent = getIntent();
        mScrollCaptureResponse = intent.getParcelableExtra(EXTRA_CAPTURE_RESPONSE);
        mScreenshotUserHandle = intent.getParcelableExtra(EXTRA_SCREENSHOT_USER_HANDLE,
                UserHandle.class);
        if (mScreenshotUserHandle == null) {
            mScreenshotUserHandle = Process.myUserHandle();
        }

        if (savedInstanceState != null) {
            String savedImagePath = savedInstanceState.getString(KEY_SAVED_IMAGE_PATH);
@@ -318,6 +332,14 @@ public class LongScreenshotActivity extends Activity {
    }

    private void doEdit(Uri uri) {
        if (mFeatureFlags.isEnabled(Flags.SCREENSHOT_WORK_PROFILE_POLICY) && mScreenshotUserHandle
                != Process.myUserHandle()) {
            // TODO: Fix transition for work profile. Omitting it in the meantime.
            mActionExecutor.launchIntentAsync(
                    ActionIntentCreator.INSTANCE.createEditIntent(uri, this),
                    null,
                    mScreenshotUserHandle.getIdentifier(), false);
        } else {
            String editorPackage = getString(R.string.config_screenshotEditor);
            Intent intent = new Intent(Intent.ACTION_EDIT);
            if (!TextUtils.isEmpty(editorPackage)) {
@@ -337,8 +359,14 @@ public class LongScreenshotActivity extends Activity {
                    ActivityOptions.makeSceneTransitionAnimation(this, mTransitionView,
                            ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME).toBundle());
        }
    }

    private void doShare(Uri uri) {
        if (mFeatureFlags.isEnabled(Flags.SCREENSHOT_WORK_PROFILE_POLICY)) {
            Intent shareIntent = ActionIntentCreator.INSTANCE.createShareIntent(uri, null);
            mActionExecutor.launchIntentAsync(shareIntent, null,
                    mScreenshotUserHandle.getIdentifier(), false);
        } else {
            Intent intent = new Intent(Intent.ACTION_SEND);
            intent.setType("image/png");
            intent.putExtra(Intent.EXTRA_STREAM, uri);
@@ -349,6 +377,7 @@ public class LongScreenshotActivity extends Activity {

            startActivityAsUser(sharingChooserIntent, UserHandle.CURRENT);
        }
    }

    private void onClicked(View v) {
        int id = v.getId();
@@ -389,8 +418,8 @@ public class LongScreenshotActivity extends Activity {
        mOutputBitmap = renderBitmap(drawable, bounds);
        ListenableFuture<ImageExporter.Result> exportFuture = mImageExporter.export(
                mBackgroundExecutor, UUID.randomUUID(), mOutputBitmap, ZonedDateTime.now(),
                // TODO: Owner must match the owner of the captured window.
                Process.myUserHandle());
                mFeatureFlags.isEnabled(Flags.SCREENSHOT_WORK_PROFILE_POLICY)
                        ? mScreenshotUserHandle : Process.myUserHandle());
        exportFuture.addListener(() -> onExportCompleted(action, exportFuture), mUiExecutor);
    }

+13 −10
Original line number Diff line number Diff line
@@ -587,7 +587,7 @@ public class ScreenshotController {
        // Wait until this window is attached to request because it is
        // the reference used to locate the target window (below).
        withWindowAttached(() -> {
            requestScrollCapture();
            requestScrollCapture(owner);
            mWindow.peekDecorView().getViewRootImpl().setActivityConfigCallback(
                    new ViewRootImpl.ActivityConfigCallback() {
                        @Override
@@ -599,11 +599,11 @@ public class ScreenshotController {
                                mScreenshotView.hideScrollChip();
                                // Delay scroll capture eval a bit to allow the underlying activity
                                // to set up in the new orientation.
                                mScreenshotHandler.postDelayed(
                                        ScreenshotController.this::requestScrollCapture, 150);
                                mScreenshotHandler.postDelayed(() -> {
                                    requestScrollCapture(owner);
                                }, 150);
                                mScreenshotView.updateInsets(
                                        mWindowManager.getCurrentWindowMetrics()
                                                .getWindowInsets());
                                        mWindowManager.getCurrentWindowMetrics().getWindowInsets());
                                // Screenshot animation calculations won't be valid anymore,
                                // so just end
                                if (mScreenshotAnimation != null
@@ -651,7 +651,7 @@ public class ScreenshotController {
        mScreenshotHandler.cancelTimeout(); // restarted after animation
    }

    private void requestScrollCapture() {
    private void requestScrollCapture(UserHandle owner) {
        if (!allowLongScreenshots()) {
            Log.d(TAG, "Long screenshots not supported on this device");
            return;
@@ -664,10 +664,11 @@ public class ScreenshotController {
                mScrollCaptureClient.request(DEFAULT_DISPLAY);
        mLastScrollCaptureRequest = future;
        mLastScrollCaptureRequest.addListener(() ->
                onScrollCaptureResponseReady(future), mMainExecutor);
                onScrollCaptureResponseReady(future, owner), mMainExecutor);
    }

    private void onScrollCaptureResponseReady(Future<ScrollCaptureResponse> responseFuture) {
    private void onScrollCaptureResponseReady(Future<ScrollCaptureResponse> responseFuture,
            UserHandle owner) {
        try {
            if (mLastScrollCaptureResponse != null) {
                mLastScrollCaptureResponse.close();
@@ -697,7 +698,7 @@ public class ScreenshotController {
                mScreenshotView.prepareScrollingTransition(response, mScreenBitmap, newScreenshot,
                        mScreenshotTakenInPortrait);
                // delay starting scroll capture to make sure the scrim is up before the app moves
                mScreenshotView.post(() -> runBatchScrollCapture(response));
                mScreenshotView.post(() -> runBatchScrollCapture(response, owner));
            });
        } catch (InterruptedException | ExecutionException e) {
            Log.e(TAG, "requestScrollCapture failed", e);
@@ -706,7 +707,7 @@ public class ScreenshotController {

    ListenableFuture<ScrollCaptureController.LongScreenshot> mLongScreenshotFuture;

    private void runBatchScrollCapture(ScrollCaptureResponse response) {
    private void runBatchScrollCapture(ScrollCaptureResponse response, UserHandle owner) {
        // Clear the reference to prevent close() in dismissScreenshot
        mLastScrollCaptureResponse = null;

@@ -740,6 +741,8 @@ public class ScreenshotController {
                                    longScreenshot));

            final Intent intent = new Intent(mContext, LongScreenshotActivity.class);
            intent.putExtra(LongScreenshotActivity.EXTRA_SCREENSHOT_USER_HANDLE,
                    owner);
            intent.setFlags(
                    Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);