diff options
3 files changed, 86 insertions, 56 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt index 5961635a0dba..01e32b7ada5f 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt @@ -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,23 +70,21 @@ constructor( userId: Int, overrideTransition: Boolean, ) { - withContext(bgDispatcher) { - dismissKeyguard() + dismissKeyguard() - if (userId == UserHandle.myUserId()) { - context.startActivity(intent, bundle) - } else { - launchCrossProfileIntent(userId, intent, bundle) - } + if (userId == UserHandle.myUserId()) { + withContext(mainDispatcher) { context.startActivity(intent, bundle) } + } else { + launchCrossProfileIntent(userId, intent, bundle) + } - if (overrideTransition) { - val runner = RemoteAnimationAdapter(SCREENSHOT_REMOTE_RUNNER, 0, 0) - try { - WindowManagerGlobal.getWindowManagerService() - .overridePendingAppTransitionRemote(runner, Display.DEFAULT_DISPLAY) - } catch (e: Exception) { - Log.e(TAG, "Error overriding screenshot app transition", e) - } + if (overrideTransition) { + val runner = RemoteAnimationAdapter(SCREENSHOT_REMOTE_RUNNER, 0, 0) + try { + WindowManagerGlobal.getWindowManagerService() + .overridePendingAppTransitionRemote(runner, Display.DEFAULT_DISPLAY) + } catch (e: Exception) { + Log.e(TAG, "Error overriding screenshot app transition", e) } } } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java index 8bf956b86683..5450db98af52 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java @@ -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,36 +332,51 @@ public class LongScreenshotActivity extends Activity { } private void doEdit(Uri uri) { - String editorPackage = getString(R.string.config_screenshotEditor); - Intent intent = new Intent(Intent.ACTION_EDIT); - if (!TextUtils.isEmpty(editorPackage)) { - intent.setComponent(ComponentName.unflattenFromString(editorPackage)); + 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)) { + intent.setComponent(ComponentName.unflattenFromString(editorPackage)); + } + intent.setDataAndType(uri, "image/png"); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION + | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + + mTransitionView.setImageBitmap(mOutputBitmap); + mTransitionView.setVisibility(View.VISIBLE); + mTransitionView.setTransitionName( + ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME); + // TODO: listen for transition completing instead of finishing onStop + mTransitionStarted = true; + startActivity(intent, + ActivityOptions.makeSceneTransitionAnimation(this, mTransitionView, + ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME).toBundle()); } - intent.setDataAndType(uri, "image/png"); - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION - | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); - - mTransitionView.setImageBitmap(mOutputBitmap); - mTransitionView.setVisibility(View.VISIBLE); - mTransitionView.setTransitionName( - ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME); - // TODO: listen for transition completing instead of finishing onStop - mTransitionStarted = true; - startActivity(intent, - ActivityOptions.makeSceneTransitionAnimation(this, mTransitionView, - ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME).toBundle()); } private void doShare(Uri uri) { - Intent intent = new Intent(Intent.ACTION_SEND); - intent.setType("image/png"); - intent.putExtra(Intent.EXTRA_STREAM, uri); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK - | Intent.FLAG_GRANT_READ_URI_PERMISSION); - Intent sharingChooserIntent = Intent.createChooser(intent, null) - .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - - startActivityAsUser(sharingChooserIntent, UserHandle.CURRENT); + 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); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK + | Intent.FLAG_GRANT_READ_URI_PERMISSION); + Intent sharingChooserIntent = Intent.createChooser(intent, null) + .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + + startActivityAsUser(sharingChooserIntent, UserHandle.CURRENT); + } } private void onClicked(View v) { @@ -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); } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java index d395bd33241d..d94c8277b82c 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java @@ -591,7 +591,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 @@ -603,11 +603,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 @@ -655,7 +655,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; @@ -668,10 +668,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(); @@ -701,7 +702,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); @@ -710,7 +711,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; @@ -744,6 +745,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); |