Merge "Fix long screenshots actions for work profile." into tm-qpr-dev
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
intent.setDataAndType(uri, "image/png");
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
|
||||
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());
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user