Loading packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt +15 −17 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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, ) { /** Loading @@ -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) } Loading @@ -89,7 +88,6 @@ constructor( } } } } private val proxyConnector: ServiceConnector<IScreenshotProxy> = ServiceConnector.Impl( Loading packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java +58 −29 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; } Loading Loading @@ -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); Loading Loading @@ -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)) { Loading @@ -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); Loading @@ -349,6 +377,7 @@ public class LongScreenshotActivity extends Activity { startActivityAsUser(sharingChooserIntent, UserHandle.CURRENT); } } private void onClicked(View v) { int id = v.getId(); Loading Loading @@ -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); } Loading packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +13 −10 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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); Loading @@ -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; Loading Loading @@ -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); Loading Loading
packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt +15 −17 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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, ) { /** Loading @@ -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) } Loading @@ -89,7 +88,6 @@ constructor( } } } } private val proxyConnector: ServiceConnector<IScreenshotProxy> = ServiceConnector.Impl( Loading
packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java +58 −29 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; } Loading Loading @@ -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); Loading Loading @@ -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)) { Loading @@ -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); Loading @@ -349,6 +377,7 @@ public class LongScreenshotActivity extends Activity { startActivityAsUser(sharingChooserIntent, UserHandle.CURRENT); } } private void onClicked(View v) { int id = v.getId(); Loading Loading @@ -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); } Loading
packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +13 −10 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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); Loading @@ -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; Loading Loading @@ -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); Loading