Merge "Fix transitions in the background when launching something in TaskView" into sc-dev

This commit is contained in:
Mady Mellor
2021-05-20 22:55:00 +00:00
committed by Android (Google) Code Review
9 changed files with 92 additions and 15 deletions

View File

@@ -118,15 +118,15 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback,
*
* @param shortcut the shortcut used to launch the activity.
* @param options options for the activity.
* @param sourceBounds the rect containing the source bounds of the clicked icon to open
* this shortcut.
* @param launchBounds the bounds (window size and position) that the activity should be
* launched in, in pixels and in screen coordinates.
*/
public void startShortcutActivity(@NonNull ShortcutInfo shortcut,
@NonNull ActivityOptions options, @Nullable Rect sourceBounds) {
prepareActivityOptions(options);
@NonNull ActivityOptions options, @Nullable Rect launchBounds) {
prepareActivityOptions(options, launchBounds);
LauncherApps service = mContext.getSystemService(LauncherApps.class);
try {
service.startShortcut(shortcut, sourceBounds, options.toBundle());
service.startShortcut(shortcut, null /* sourceBounds */, options.toBundle());
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -138,10 +138,12 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback,
* @param pendingIntent Intent used to launch an activity.
* @param fillInIntent Additional Intent data, see {@link Intent#fillIn Intent.fillIn()}
* @param options options for the activity.
* @param launchBounds the bounds (window size and position) that the activity should be
* launched in, in pixels and in screen coordinates.
*/
public void startActivity(@NonNull PendingIntent pendingIntent, @Nullable Intent fillInIntent,
@NonNull ActivityOptions options) {
prepareActivityOptions(options);
@NonNull ActivityOptions options, @Nullable Rect launchBounds) {
prepareActivityOptions(options, launchBounds);
try {
pendingIntent.send(mContext, 0 /* code */, fillInIntent,
null /* onFinished */, null /* handler */, null /* requiredPermission */,
@@ -151,11 +153,12 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback,
}
}
private void prepareActivityOptions(ActivityOptions options) {
private void prepareActivityOptions(ActivityOptions options, Rect launchBounds) {
final Binder launchCookie = new Binder();
mShellExecutor.execute(() -> {
mTaskOrganizer.setPendingLaunchCookieListener(launchCookie, this);
});
options.setLaunchBounds(launchBounds);
options.setLaunchCookie(launchCookie);
options.setLaunchWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
options.setRemoveWithTaskOrganizer(true);

View File

@@ -153,6 +153,9 @@ public class BubbleExpandedView extends LinearLayout {
ActivityOptions options = ActivityOptions.makeCustomAnimation(getContext(),
0 /* enterResId */, 0 /* exitResId */);
Rect launchBounds = new Rect();
mTaskView.getBoundsOnScreen(launchBounds);
// TODO: I notice inconsistencies in lifecycle
// Post to keep the lifecycle normal
post(() -> {
@@ -166,7 +169,7 @@ public class BubbleExpandedView extends LinearLayout {
if (!mIsOverflow && mBubble.hasMetadataShortcutId()) {
options.setApplyActivityFlagsForBubbles(true);
mTaskView.startShortcutActivity(mBubble.getShortcutInfo(),
options, null /* sourceBounds */);
options, launchBounds);
} else {
Intent fillInIntent = new Intent();
// Apply flags to make behaviour match documentLaunchMode=always.
@@ -175,7 +178,8 @@ public class BubbleExpandedView extends LinearLayout {
if (mBubble != null) {
mBubble.setIntentActive();
}
mTaskView.startActivity(mPendingIntent, fillInIntent, options);
mTaskView.startActivity(mPendingIntent, fillInIntent, options,
launchBounds);
}
} catch (RuntimeException e) {
// If there's a runtime exception here then there's something

View File

@@ -36,6 +36,7 @@ import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.PendingIntent;
import android.content.Context;
import android.graphics.Rect;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.SurfaceControl;
@@ -125,7 +126,7 @@ public class TaskViewTest extends ShellTestCase {
@Test
public void testStartActivity() {
ActivityOptions options = ActivityOptions.makeBasic();
mTaskView.startActivity(mock(PendingIntent.class), null, options);
mTaskView.startActivity(mock(PendingIntent.class), null, options, new Rect(0, 0, 100, 100));
verify(mOrganizer).setPendingLaunchCookieListener(any(), eq(mTaskView));
assertThat(options.getLaunchWindowingMode()).isEqualTo(WINDOWING_MODE_MULTI_WINDOW);

View File

@@ -1333,6 +1333,7 @@
<dimen name="controls_setup_title">22sp</dimen>
<dimen name="controls_setup_subtitle">14sp</dimen>
<dimen name="controls_setup_vertical_padding">52dp</dimen>
<dimen name="controls_detail_dialog_header_height">52dp</dimen>
<!-- Home Controls activity view detail panel-->
<dimen name="controls_activity_view_top_offset">100dp</dimen>

View File

@@ -24,6 +24,7 @@ import android.app.PendingIntent
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.graphics.Rect
import android.view.View
import android.view.ViewGroup
import android.view.WindowInsets
@@ -83,8 +84,9 @@ class DetailDialog(
taskView.startActivity(
PendingIntent.getActivity(context, 0, launchIntent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE),
null,
options
null /* fillInIntent */,
options,
getTaskViewBounds()
)
}
@@ -159,6 +161,23 @@ class DetailDialog(
taskView.setListener(cvh.uiExecutor, stateCallback)
}
fun getTaskViewBounds(): Rect {
val wm = context.getSystemService(WindowManager::class.java)
val windowMetrics = wm.getCurrentWindowMetrics()
val rect = windowMetrics.bounds
val metricInsets = windowMetrics.windowInsets
val insets = metricInsets.getInsetsIgnoringVisibility(Type.systemBars()
or Type.displayCutout())
val headerHeight = context.resources.getDimensionPixelSize(
R.dimen.controls_detail_dialog_header_height)
val finalRect = Rect(rect.left - insets.left /* left */,
rect.top + insets.top + headerHeight /* top */,
rect.right - insets.right /* right */,
rect.bottom - insets.bottom /* bottom */)
return finalRect
}
override fun dismiss() {
if (!isShowing()) return
taskView.release()

View File

@@ -160,8 +160,7 @@ class LaunchParamsController {
return false;
}
if (task.getRootTask().inFreeformWindowingMode()) {
// Only set bounds if it's in freeform mode.
if (task.getRootTask().inMultiWindowMode()) {
task.setBounds(mTmpParams.mBounds);
return true;
}

View File

@@ -18,6 +18,7 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
@@ -195,6 +196,11 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
} else {
if (DEBUG) appendLog("empty-window-layout");
}
} else if (launchMode == WINDOWING_MODE_MULTI_WINDOW
&& options != null && options.getLaunchBounds() != null) {
outParams.mBounds.set(options.getLaunchBounds());
hasInitialBounds = true;
if (DEBUG) appendLog("multiwindow-activity-options-bounds=" + outParams.mBounds);
}
// STEP 2.2: Check if previous modifier or the controller (referred as "callers" below) has

View File

@@ -18,6 +18,7 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.view.Display.INVALID_DISPLAY;
@@ -371,6 +372,29 @@ public class LaunchParamsControllerTests extends WindowTestsBase {
assertEquals(expected, task.getRequestedOverrideBounds());
}
/**
* Ensures that {@link LaunchParamsModifier} requests specifying bounds during
* layout are honored if window is in multiwindow mode.
*/
@Test
public void testLayoutTaskBoundsChangeMultiWindow() {
final Rect expected = new Rect(10, 20, 30, 40);
final LaunchParams params = new LaunchParams();
params.mWindowingMode = WINDOWING_MODE_MULTI_WINDOW;
params.mBounds.set(expected);
final InstrumentedPositioner positioner = new InstrumentedPositioner(RESULT_DONE, params);
final Task task = new TaskBuilder(mAtm.mTaskSupervisor).build();
mController.registerModifier(positioner);
assertNotEquals(expected, task.getBounds());
mController.layoutTask(task, null /* windowLayout */);
assertEquals(expected, task.getRequestedOverrideBounds());
}
/**
* Ensures that {@link LaunchParamsModifier} requests specifying bounds during
* layout are set to last non-fullscreen bounds.

View File

@@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
@@ -926,6 +927,25 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
assertEquals(expected, mResult.mBounds);
}
@Test
public void testKeepsBoundsForMultiWindowModeInOptions() {
final TestDisplayContent freeformDisplay = createNewDisplayContent(
WINDOWING_MODE_FULLSCREEN);
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
final Rect expected = new Rect(0, 0, 100, 100);
options.setLaunchBounds(expected);
mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea();
assertEquals(RESULT_CONTINUE,
new CalculateRequestBuilder().setOptions(options).calculate());
assertEquals(expected, mResult.mBounds);
}
@Test
public void testRespectsLaunchBoundsWithFreeformSourceOnFullscreenDisplay() {
final TestDisplayContent fullscreenDisplay = createNewDisplayContent(