Merge "Address TaskFragmentOrganizer style comments" into tm-qpr-dev
This commit is contained in:
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package android.window;
|
package android.window;
|
||||||
|
|
||||||
import static android.window.TaskFragmentTransaction.TYPE_ACTIVITY_REPARENT_TO_TASK;
|
import static android.window.TaskFragmentTransaction.TYPE_ACTIVITY_REPARENTED_TO_TASK;
|
||||||
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_APPEARED;
|
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_APPEARED;
|
||||||
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_ERROR;
|
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_ERROR;
|
||||||
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_INFO_CHANGED;
|
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_INFO_CHANGED;
|
||||||
@@ -238,7 +238,7 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
|
|||||||
* {@link WindowContainerTransaction} if needed.
|
* {@link WindowContainerTransaction} if needed.
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public void onActivityReparentToTask(int taskId, @NonNull Intent activityIntent,
|
public void onActivityReparentedToTask(int taskId, @NonNull Intent activityIntent,
|
||||||
@NonNull IBinder activityToken) {}
|
@NonNull IBinder activityToken) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -298,8 +298,8 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
|
|||||||
errorBundle.getSerializable(KEY_ERROR_CALLBACK_EXCEPTION,
|
errorBundle.getSerializable(KEY_ERROR_CALLBACK_EXCEPTION,
|
||||||
java.lang.Throwable.class));
|
java.lang.Throwable.class));
|
||||||
break;
|
break;
|
||||||
case TYPE_ACTIVITY_REPARENT_TO_TASK:
|
case TYPE_ACTIVITY_REPARENTED_TO_TASK:
|
||||||
onActivityReparentToTask(
|
onActivityReparentedToTask(
|
||||||
change.getTaskId(),
|
change.getTaskId(),
|
||||||
change.getActivityIntent(),
|
change.getActivityIntent(),
|
||||||
change.getActivityToken());
|
change.getActivityToken());
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ public final class TaskFragmentTransaction implements Parcelable {
|
|||||||
* then exits Picture-in-picture, it will be reparented back to its original Task. In this case,
|
* then exits Picture-in-picture, it will be reparented back to its original Task. In this case,
|
||||||
* we need to notify the organizer so that it can check if the Activity matches any split rule.
|
* we need to notify the organizer so that it can check if the Activity matches any split rule.
|
||||||
*/
|
*/
|
||||||
public static final int TYPE_ACTIVITY_REPARENT_TO_TASK = 6;
|
public static final int TYPE_ACTIVITY_REPARENTED_TO_TASK = 6;
|
||||||
|
|
||||||
@IntDef(prefix = { "TYPE_" }, value = {
|
@IntDef(prefix = { "TYPE_" }, value = {
|
||||||
TYPE_TASK_FRAGMENT_APPEARED,
|
TYPE_TASK_FRAGMENT_APPEARED,
|
||||||
@@ -130,7 +130,7 @@ public final class TaskFragmentTransaction implements Parcelable {
|
|||||||
TYPE_TASK_FRAGMENT_VANISHED,
|
TYPE_TASK_FRAGMENT_VANISHED,
|
||||||
TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED,
|
TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED,
|
||||||
TYPE_TASK_FRAGMENT_ERROR,
|
TYPE_TASK_FRAGMENT_ERROR,
|
||||||
TYPE_ACTIVITY_REPARENT_TO_TASK
|
TYPE_ACTIVITY_REPARENTED_TO_TASK
|
||||||
})
|
})
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@interface ChangeType {}
|
@interface ChangeType {}
|
||||||
@@ -247,7 +247,7 @@ public final class TaskFragmentTransaction implements Parcelable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Intent of the activity that is reparented to the Task for
|
* Intent of the activity that is reparented to the Task for
|
||||||
* {@link #TYPE_ACTIVITY_REPARENT_TO_TASK}.
|
* {@link #TYPE_ACTIVITY_REPARENTED_TO_TASK}.
|
||||||
*/
|
*/
|
||||||
public Change setActivityIntent(@NonNull Intent intent) {
|
public Change setActivityIntent(@NonNull Intent intent) {
|
||||||
mActivityIntent = requireNonNull(intent);
|
mActivityIntent = requireNonNull(intent);
|
||||||
@@ -255,7 +255,7 @@ public final class TaskFragmentTransaction implements Parcelable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Token of the reparent activity for {@link #TYPE_ACTIVITY_REPARENT_TO_TASK}.
|
* Token of the reparent activity for {@link #TYPE_ACTIVITY_REPARENTED_TO_TASK}.
|
||||||
* If the activity belongs to the same process as the organizer, this will be the actual
|
* If the activity belongs to the same process as the organizer, this will be the actual
|
||||||
* activity token; if the activity belongs to a different process, the server will generate
|
* activity token; if the activity belongs to a different process, the server will generate
|
||||||
* a temporary token that the organizer can use to reparent the activity through
|
* a temporary token that the organizer can use to reparent the activity through
|
||||||
|
|||||||
@@ -51,8 +51,11 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
final Map<IBinder, TaskFragmentInfo> mFragmentInfos = new ArrayMap<>();
|
final Map<IBinder, TaskFragmentInfo> mFragmentInfos = new ArrayMap<>();
|
||||||
|
|
||||||
|
@NonNull
|
||||||
private final TaskFragmentCallback mCallback;
|
private final TaskFragmentCallback mCallback;
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
@Nullable
|
||||||
TaskFragmentAnimationController mAnimationController;
|
TaskFragmentAnimationController mAnimationController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,7 +66,7 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
|||||||
void onTaskFragmentInfoChanged(@NonNull TaskFragmentInfo taskFragmentInfo);
|
void onTaskFragmentInfoChanged(@NonNull TaskFragmentInfo taskFragmentInfo);
|
||||||
void onTaskFragmentVanished(@NonNull TaskFragmentInfo taskFragmentInfo);
|
void onTaskFragmentVanished(@NonNull TaskFragmentInfo taskFragmentInfo);
|
||||||
void onTaskFragmentParentInfoChanged(int taskId, @NonNull Configuration parentConfig);
|
void onTaskFragmentParentInfoChanged(int taskId, @NonNull Configuration parentConfig);
|
||||||
void onActivityReparentToTask(int taskId, @NonNull Intent activityIntent,
|
void onActivityReparentedToTask(int taskId, @NonNull Intent activityIntent,
|
||||||
@NonNull IBinder activityToken);
|
@NonNull IBinder activityToken);
|
||||||
void onTaskFragmentError(@Nullable TaskFragmentInfo taskFragmentInfo, int opType);
|
void onTaskFragmentError(@Nullable TaskFragmentInfo taskFragmentInfo, int opType);
|
||||||
}
|
}
|
||||||
@@ -72,7 +75,8 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
|||||||
* @param executor callbacks from WM Core are posted on this executor. It should be tied to the
|
* @param executor callbacks from WM Core are posted on this executor. It should be tied to the
|
||||||
* UI thread that all other calls into methods of this class are also on.
|
* UI thread that all other calls into methods of this class are also on.
|
||||||
*/
|
*/
|
||||||
JetpackTaskFragmentOrganizer(@NonNull Executor executor, TaskFragmentCallback callback) {
|
JetpackTaskFragmentOrganizer(@NonNull Executor executor,
|
||||||
|
@NonNull TaskFragmentCallback callback) {
|
||||||
super(executor);
|
super(executor);
|
||||||
mCallback = callback;
|
mCallback = callback;
|
||||||
}
|
}
|
||||||
@@ -147,7 +151,8 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
|||||||
* @param wct WindowContainerTransaction in which the task fragment should be resized.
|
* @param wct WindowContainerTransaction in which the task fragment should be resized.
|
||||||
* @param fragmentToken token of an existing TaskFragment.
|
* @param fragmentToken token of an existing TaskFragment.
|
||||||
*/
|
*/
|
||||||
void expandTaskFragment(WindowContainerTransaction wct, IBinder fragmentToken) {
|
void expandTaskFragment(@NonNull WindowContainerTransaction wct,
|
||||||
|
@NonNull IBinder fragmentToken) {
|
||||||
resizeTaskFragment(wct, fragmentToken, new Rect());
|
resizeTaskFragment(wct, fragmentToken, new Rect());
|
||||||
setAdjacentTaskFragments(wct, fragmentToken, null /* secondary */, null /* splitRule */);
|
setAdjacentTaskFragments(wct, fragmentToken, null /* secondary */, null /* splitRule */);
|
||||||
updateWindowingMode(wct, fragmentToken, WINDOWING_MODE_UNDEFINED);
|
updateWindowingMode(wct, fragmentToken, WINDOWING_MODE_UNDEFINED);
|
||||||
@@ -157,7 +162,7 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
|||||||
* Expands an existing TaskFragment to fill parent.
|
* Expands an existing TaskFragment to fill parent.
|
||||||
* @param fragmentToken token of an existing TaskFragment.
|
* @param fragmentToken token of an existing TaskFragment.
|
||||||
*/
|
*/
|
||||||
void expandTaskFragment(IBinder fragmentToken) {
|
void expandTaskFragment(@NonNull IBinder fragmentToken) {
|
||||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||||
expandTaskFragment(wct, fragmentToken);
|
expandTaskFragment(wct, fragmentToken);
|
||||||
applyTransaction(wct);
|
applyTransaction(wct);
|
||||||
@@ -168,7 +173,7 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
|||||||
* @param fragmentToken token to create new TaskFragment with.
|
* @param fragmentToken token to create new TaskFragment with.
|
||||||
* @param activity activity to move to the fill-parent TaskFragment.
|
* @param activity activity to move to the fill-parent TaskFragment.
|
||||||
*/
|
*/
|
||||||
void expandActivity(IBinder fragmentToken, Activity activity) {
|
void expandActivity(@NonNull IBinder fragmentToken, @NonNull Activity activity) {
|
||||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||||
createTaskFragmentAndReparentActivity(
|
createTaskFragmentAndReparentActivity(
|
||||||
wct, fragmentToken, activity.getActivityToken(), new Rect(),
|
wct, fragmentToken, activity.getActivityToken(), new Rect(),
|
||||||
@@ -180,8 +185,8 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
|||||||
* @param ownerToken The token of the activity that creates this task fragment. It does not
|
* @param ownerToken The token of the activity that creates this task fragment. It does not
|
||||||
* have to be a child of this task fragment, but must belong to the same task.
|
* have to be a child of this task fragment, but must belong to the same task.
|
||||||
*/
|
*/
|
||||||
void createTaskFragment(WindowContainerTransaction wct, IBinder fragmentToken,
|
void createTaskFragment(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken,
|
||||||
IBinder ownerToken, @NonNull Rect bounds, @WindowingMode int windowingMode) {
|
@NonNull IBinder ownerToken, @NonNull Rect bounds, @WindowingMode int windowingMode) {
|
||||||
final TaskFragmentCreationParams fragmentOptions =
|
final TaskFragmentCreationParams fragmentOptions =
|
||||||
createFragmentOptions(fragmentToken, ownerToken, bounds, windowingMode);
|
createFragmentOptions(fragmentToken, ownerToken, bounds, windowingMode);
|
||||||
wct.createTaskFragment(fragmentOptions);
|
wct.createTaskFragment(fragmentOptions);
|
||||||
@@ -191,9 +196,9 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
|||||||
* @param ownerToken The token of the activity that creates this task fragment. It does not
|
* @param ownerToken The token of the activity that creates this task fragment. It does not
|
||||||
* have to be a child of this task fragment, but must belong to the same task.
|
* have to be a child of this task fragment, but must belong to the same task.
|
||||||
*/
|
*/
|
||||||
private void createTaskFragmentAndReparentActivity(
|
private void createTaskFragmentAndReparentActivity(@NonNull WindowContainerTransaction wct,
|
||||||
WindowContainerTransaction wct, IBinder fragmentToken, IBinder ownerToken,
|
@NonNull IBinder fragmentToken, @NonNull IBinder ownerToken, @NonNull Rect bounds,
|
||||||
@NonNull Rect bounds, @WindowingMode int windowingMode, Activity activity) {
|
@WindowingMode int windowingMode, @NonNull Activity activity) {
|
||||||
createTaskFragment(wct, fragmentToken, ownerToken, bounds, windowingMode);
|
createTaskFragment(wct, fragmentToken, ownerToken, bounds, windowingMode);
|
||||||
wct.reparentActivityToTaskFragment(fragmentToken, activity.getActivityToken());
|
wct.reparentActivityToTaskFragment(fragmentToken, activity.getActivityToken());
|
||||||
}
|
}
|
||||||
@@ -202,9 +207,9 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
|||||||
* @param ownerToken The token of the activity that creates this task fragment. It does not
|
* @param ownerToken The token of the activity that creates this task fragment. It does not
|
||||||
* have to be a child of this task fragment, but must belong to the same task.
|
* have to be a child of this task fragment, but must belong to the same task.
|
||||||
*/
|
*/
|
||||||
private void createTaskFragmentAndStartActivity(
|
private void createTaskFragmentAndStartActivity(@NonNull WindowContainerTransaction wct,
|
||||||
WindowContainerTransaction wct, IBinder fragmentToken, IBinder ownerToken,
|
@NonNull IBinder fragmentToken, @NonNull IBinder ownerToken, @NonNull Rect bounds,
|
||||||
@NonNull Rect bounds, @WindowingMode int windowingMode, Intent activityIntent,
|
@WindowingMode int windowingMode, @NonNull Intent activityIntent,
|
||||||
@Nullable Bundle activityOptions) {
|
@Nullable Bundle activityOptions) {
|
||||||
createTaskFragment(wct, fragmentToken, ownerToken, bounds, windowingMode);
|
createTaskFragment(wct, fragmentToken, ownerToken, bounds, windowingMode);
|
||||||
wct.startActivityInTaskFragment(fragmentToken, ownerToken, activityIntent, activityOptions);
|
wct.startActivityInTaskFragment(fragmentToken, ownerToken, activityIntent, activityOptions);
|
||||||
@@ -225,8 +230,8 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
|||||||
wct.setAdjacentTaskFragments(primary, secondary, adjacentParams);
|
wct.setAdjacentTaskFragments(primary, secondary, adjacentParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskFragmentCreationParams createFragmentOptions(IBinder fragmentToken, IBinder ownerToken,
|
TaskFragmentCreationParams createFragmentOptions(@NonNull IBinder fragmentToken,
|
||||||
Rect bounds, @WindowingMode int windowingMode) {
|
@NonNull IBinder ownerToken, @NonNull Rect bounds, @WindowingMode int windowingMode) {
|
||||||
if (mFragmentInfos.containsKey(fragmentToken)) {
|
if (mFragmentInfos.containsKey(fragmentToken)) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"There is an existing TaskFragment with fragmentToken=" + fragmentToken);
|
"There is an existing TaskFragment with fragmentToken=" + fragmentToken);
|
||||||
@@ -241,7 +246,7 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
void resizeTaskFragment(WindowContainerTransaction wct, IBinder fragmentToken,
|
void resizeTaskFragment(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken,
|
||||||
@Nullable Rect bounds) {
|
@Nullable Rect bounds) {
|
||||||
if (!mFragmentInfos.containsKey(fragmentToken)) {
|
if (!mFragmentInfos.containsKey(fragmentToken)) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
@@ -253,8 +258,8 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
|||||||
wct.setBounds(mFragmentInfos.get(fragmentToken).getToken(), bounds);
|
wct.setBounds(mFragmentInfos.get(fragmentToken).getToken(), bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateWindowingMode(WindowContainerTransaction wct, IBinder fragmentToken,
|
void updateWindowingMode(@NonNull WindowContainerTransaction wct,
|
||||||
@WindowingMode int windowingMode) {
|
@NonNull IBinder fragmentToken, @WindowingMode int windowingMode) {
|
||||||
if (!mFragmentInfos.containsKey(fragmentToken)) {
|
if (!mFragmentInfos.containsKey(fragmentToken)) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Can't find an existing TaskFragment with fragmentToken=" + fragmentToken);
|
"Can't find an existing TaskFragment with fragmentToken=" + fragmentToken);
|
||||||
@@ -262,7 +267,8 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
|||||||
wct.setWindowingMode(mFragmentInfos.get(fragmentToken).getToken(), windowingMode);
|
wct.setWindowingMode(mFragmentInfos.get(fragmentToken).getToken(), windowingMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void deleteTaskFragment(WindowContainerTransaction wct, IBinder fragmentToken) {
|
void deleteTaskFragment(@NonNull WindowContainerTransaction wct,
|
||||||
|
@NonNull IBinder fragmentToken) {
|
||||||
if (!mFragmentInfos.containsKey(fragmentToken)) {
|
if (!mFragmentInfos.containsKey(fragmentToken)) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Can't find an existing TaskFragment with fragmentToken=" + fragmentToken);
|
"Can't find an existing TaskFragment with fragmentToken=" + fragmentToken);
|
||||||
@@ -274,44 +280,31 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
|||||||
public void onTaskFragmentAppeared(@NonNull TaskFragmentInfo taskFragmentInfo) {
|
public void onTaskFragmentAppeared(@NonNull TaskFragmentInfo taskFragmentInfo) {
|
||||||
final IBinder fragmentToken = taskFragmentInfo.getFragmentToken();
|
final IBinder fragmentToken = taskFragmentInfo.getFragmentToken();
|
||||||
mFragmentInfos.put(fragmentToken, taskFragmentInfo);
|
mFragmentInfos.put(fragmentToken, taskFragmentInfo);
|
||||||
|
mCallback.onTaskFragmentAppeared(taskFragmentInfo);
|
||||||
if (mCallback != null) {
|
|
||||||
mCallback.onTaskFragmentAppeared(taskFragmentInfo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTaskFragmentInfoChanged(@NonNull TaskFragmentInfo taskFragmentInfo) {
|
public void onTaskFragmentInfoChanged(@NonNull TaskFragmentInfo taskFragmentInfo) {
|
||||||
final IBinder fragmentToken = taskFragmentInfo.getFragmentToken();
|
final IBinder fragmentToken = taskFragmentInfo.getFragmentToken();
|
||||||
mFragmentInfos.put(fragmentToken, taskFragmentInfo);
|
mFragmentInfos.put(fragmentToken, taskFragmentInfo);
|
||||||
|
mCallback.onTaskFragmentInfoChanged(taskFragmentInfo);
|
||||||
if (mCallback != null) {
|
|
||||||
mCallback.onTaskFragmentInfoChanged(taskFragmentInfo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTaskFragmentVanished(@NonNull TaskFragmentInfo taskFragmentInfo) {
|
public void onTaskFragmentVanished(@NonNull TaskFragmentInfo taskFragmentInfo) {
|
||||||
mFragmentInfos.remove(taskFragmentInfo.getFragmentToken());
|
mFragmentInfos.remove(taskFragmentInfo.getFragmentToken());
|
||||||
|
mCallback.onTaskFragmentVanished(taskFragmentInfo);
|
||||||
if (mCallback != null) {
|
|
||||||
mCallback.onTaskFragmentVanished(taskFragmentInfo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTaskFragmentParentInfoChanged(int taskId, @NonNull Configuration parentConfig) {
|
public void onTaskFragmentParentInfoChanged(int taskId, @NonNull Configuration parentConfig) {
|
||||||
if (mCallback != null) {
|
mCallback.onTaskFragmentParentInfoChanged(taskId, parentConfig);
|
||||||
mCallback.onTaskFragmentParentInfoChanged(taskId, parentConfig);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityReparentToTask(int taskId, @NonNull Intent activityIntent,
|
public void onActivityReparentedToTask(int taskId, @NonNull Intent activityIntent,
|
||||||
@NonNull IBinder activityToken) {
|
@NonNull IBinder activityToken) {
|
||||||
if (mCallback != null) {
|
mCallback.onActivityReparentedToTask(taskId, activityIntent, activityToken);
|
||||||
mCallback.onActivityReparentToTask(taskId, activityIntent, activityToken);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -322,9 +315,6 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
|
|||||||
final IBinder fragmentToken = taskFragmentInfo.getFragmentToken();
|
final IBinder fragmentToken = taskFragmentInfo.getFragmentToken();
|
||||||
mFragmentInfos.put(fragmentToken, taskFragmentInfo);
|
mFragmentInfos.put(fragmentToken, taskFragmentInfo);
|
||||||
}
|
}
|
||||||
|
mCallback.onTaskFragmentError(taskFragmentInfo, opType);
|
||||||
if (mCallback != null) {
|
|
||||||
mCallback.onTaskFragmentError(taskFragmentInfo, opType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,17 +16,21 @@
|
|||||||
|
|
||||||
package androidx.window.extensions.embedding;
|
package androidx.window.extensions.embedding;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.util.Size;
|
import android.util.Size;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client-side descriptor of a split that holds two containers.
|
* Client-side descriptor of a split that holds two containers.
|
||||||
*/
|
*/
|
||||||
class SplitContainer {
|
class SplitContainer {
|
||||||
|
@NonNull
|
||||||
private final TaskFragmentContainer mPrimaryContainer;
|
private final TaskFragmentContainer mPrimaryContainer;
|
||||||
|
@NonNull
|
||||||
private final TaskFragmentContainer mSecondaryContainer;
|
private final TaskFragmentContainer mSecondaryContainer;
|
||||||
|
@NonNull
|
||||||
private final SplitRule mSplitRule;
|
private final SplitRule mSplitRule;
|
||||||
|
|
||||||
SplitContainer(@NonNull TaskFragmentContainer primaryContainer,
|
SplitContainer(@NonNull TaskFragmentContainer primaryContainer,
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityReparentToTask(int taskId, @NonNull Intent activityIntent,
|
public void onActivityReparentedToTask(int taskId, @NonNull Intent activityIntent,
|
||||||
@NonNull IBinder activityToken) {
|
@NonNull IBinder activityToken) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
// If the activity belongs to the current app process, we treat it as a new activity
|
// If the activity belongs to the current app process, we treat it as a new activity
|
||||||
@@ -1523,7 +1523,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
private final class LifecycleCallbacks extends EmptyLifecycleCallbacksAdapter {
|
private final class LifecycleCallbacks extends EmptyLifecycleCallbacksAdapter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityPreCreated(Activity activity, Bundle savedInstanceState) {
|
public void onActivityPreCreated(@NonNull Activity activity,
|
||||||
|
@Nullable Bundle savedInstanceState) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
final IBinder activityToken = activity.getActivityToken();
|
final IBinder activityToken = activity.getActivityToken();
|
||||||
final IBinder initialTaskFragmentToken = getInitialTaskFragmentToken(activity);
|
final IBinder initialTaskFragmentToken = getInitialTaskFragmentToken(activity);
|
||||||
@@ -1552,7 +1553,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityPostCreated(Activity activity, Bundle savedInstanceState) {
|
public void onActivityPostCreated(@NonNull Activity activity,
|
||||||
|
@Nullable Bundle savedInstanceState) {
|
||||||
// Calling after Activity#onCreate is complete to allow the app launch something
|
// Calling after Activity#onCreate is complete to allow the app launch something
|
||||||
// first. In case of a configured placeholder activity we want to make sure
|
// first. In case of a configured placeholder activity we want to make sure
|
||||||
// that we don't launch it if an activity itself already requested something to be
|
// that we don't launch it if an activity itself already requested something to be
|
||||||
@@ -1563,14 +1565,14 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityConfigurationChanged(Activity activity) {
|
public void onActivityConfigurationChanged(@NonNull Activity activity) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
SplitController.this.onActivityConfigurationChanged(activity);
|
SplitController.this.onActivityConfigurationChanged(activity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityPostDestroyed(Activity activity) {
|
public void onActivityPostDestroyed(@NonNull Activity activity) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
SplitController.this.onActivityDestroyed(activity);
|
SplitController.this.onActivityDestroyed(activity);
|
||||||
}
|
}
|
||||||
@@ -1582,7 +1584,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
private final Handler mHandler = new Handler(Looper.getMainLooper());
|
private final Handler mHandler = new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Runnable r) {
|
public void execute(@NonNull Runnable r) {
|
||||||
mHandler.post(r);
|
mHandler.post(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1662,7 +1664,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
* If the two rules have the same presentation, we can reuse the same {@link SplitContainer} if
|
* If the two rules have the same presentation, we can reuse the same {@link SplitContainer} if
|
||||||
* there is any.
|
* there is any.
|
||||||
*/
|
*/
|
||||||
private static boolean canReuseContainer(SplitRule rule1, SplitRule rule2) {
|
private static boolean canReuseContainer(@NonNull SplitRule rule1, @NonNull SplitRule rule2) {
|
||||||
if (!isContainerReusableRule(rule1) || !isContainerReusableRule(rule2)) {
|
if (!isContainerReusableRule(rule1) || !isContainerReusableRule(rule2)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1670,7 +1672,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Whether the two rules have the same presentation. */
|
/** Whether the two rules have the same presentation. */
|
||||||
private static boolean haveSamePresentation(SplitPairRule rule1, SplitPairRule rule2) {
|
private static boolean haveSamePresentation(@NonNull SplitPairRule rule1,
|
||||||
|
@NonNull SplitPairRule rule2) {
|
||||||
// TODO(b/231655482): add util method to do the comparison in SplitPairRule.
|
// TODO(b/231655482): add util method to do the comparison in SplitPairRule.
|
||||||
return rule1.getSplitRatio() == rule2.getSplitRatio()
|
return rule1.getSplitRatio() == rule2.getSplitRatio()
|
||||||
&& rule1.getLayoutDirection() == rule2.getLayoutDirection()
|
&& rule1.getLayoutDirection() == rule2.getLayoutDirection()
|
||||||
@@ -1684,7 +1687,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
|||||||
* Whether it is ok for other rule to reuse the {@link TaskFragmentContainer} of the given
|
* Whether it is ok for other rule to reuse the {@link TaskFragmentContainer} of the given
|
||||||
* rule.
|
* rule.
|
||||||
*/
|
*/
|
||||||
private static boolean isContainerReusableRule(SplitRule rule) {
|
private static boolean isContainerReusableRule(@NonNull SplitRule rule) {
|
||||||
// We don't expect to reuse the placeholder rule.
|
// We don't expect to reuse the placeholder rule.
|
||||||
if (!(rule instanceof SplitPairRule)) {
|
if (!(rule instanceof SplitPairRule)) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
|||||||
|
|
||||||
private final SplitController mController;
|
private final SplitController mController;
|
||||||
|
|
||||||
SplitPresenter(@NonNull Executor executor, SplitController controller) {
|
SplitPresenter(@NonNull Executor executor, @NonNull SplitController controller) {
|
||||||
super(executor, controller);
|
super(executor, controller);
|
||||||
mController = controller;
|
mController = controller;
|
||||||
registerOrganizer();
|
registerOrganizer();
|
||||||
@@ -502,14 +502,14 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
static Pair<Size, Size> getActivitiesMinDimensionsPair(Activity primaryActivity,
|
static Pair<Size, Size> getActivitiesMinDimensionsPair(@NonNull Activity primaryActivity,
|
||||||
Activity secondaryActivity) {
|
@NonNull Activity secondaryActivity) {
|
||||||
return new Pair<>(getMinDimensions(primaryActivity), getMinDimensions(secondaryActivity));
|
return new Pair<>(getMinDimensions(primaryActivity), getMinDimensions(secondaryActivity));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
static Pair<Size, Size> getActivityIntentMinDimensionsPair(Activity primaryActivity,
|
static Pair<Size, Size> getActivityIntentMinDimensionsPair(@NonNull Activity primaryActivity,
|
||||||
Intent secondaryIntent) {
|
@NonNull Intent secondaryIntent) {
|
||||||
return new Pair<>(getMinDimensions(primaryActivity), getMinDimensions(secondaryIntent));
|
return new Pair<>(getMinDimensions(primaryActivity), getMinDimensions(secondaryIntent));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
|
|||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
|
||||||
import android.annotation.Nullable;
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.WindowConfiguration;
|
import android.app.WindowConfiguration;
|
||||||
import android.app.WindowConfiguration.WindowingMode;
|
import android.app.WindowConfiguration.WindowingMode;
|
||||||
@@ -31,6 +29,9 @@ import android.os.IBinder;
|
|||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
import android.window.TaskFragmentInfo;
|
import android.window.TaskFragmentInfo;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ import android.view.RemoteAnimationAdapter;
|
|||||||
import android.view.RemoteAnimationDefinition;
|
import android.view.RemoteAnimationDefinition;
|
||||||
import android.window.TaskFragmentOrganizer;
|
import android.window.TaskFragmentOrganizer;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
|
||||||
/** Controls the TaskFragment remote animations. */
|
/** Controls the TaskFragment remote animations. */
|
||||||
@@ -45,7 +47,7 @@ class TaskFragmentAnimationController {
|
|||||||
/** Task Ids that we have registered for remote animation. */
|
/** Task Ids that we have registered for remote animation. */
|
||||||
private final ArraySet<Integer> mRegisterTasks = new ArraySet<>();
|
private final ArraySet<Integer> mRegisterTasks = new ArraySet<>();
|
||||||
|
|
||||||
TaskFragmentAnimationController(TaskFragmentOrganizer organizer) {
|
TaskFragmentAnimationController(@NonNull TaskFragmentOrganizer organizer) {
|
||||||
mOrganizer = organizer;
|
mOrganizer = organizer;
|
||||||
mDefinition = new RemoteAnimationDefinition();
|
mDefinition = new RemoteAnimationDefinition();
|
||||||
final RemoteAnimationAdapter animationAdapter =
|
final RemoteAnimationAdapter animationAdapter =
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ class TaskFragmentAnimationRunner extends IRemoteAnimationRunner.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Creates the animator given the transition type and windows. */
|
/** Creates the animator given the transition type and windows. */
|
||||||
|
@NonNull
|
||||||
private Animator createAnimator(@WindowManager.TransitionOldType int transit,
|
private Animator createAnimator(@WindowManager.TransitionOldType int transit,
|
||||||
@NonNull RemoteAnimationTarget[] targets,
|
@NonNull RemoteAnimationTarget[] targets,
|
||||||
@NonNull IRemoteAnimationFinishedCallback finishedCallback) {
|
@NonNull IRemoteAnimationFinishedCallback finishedCallback) {
|
||||||
@@ -161,6 +162,7 @@ class TaskFragmentAnimationRunner extends IRemoteAnimationRunner.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** List of {@link TaskFragmentAnimationAdapter} to handle animations on all window targets. */
|
/** List of {@link TaskFragmentAnimationAdapter} to handle animations on all window targets. */
|
||||||
|
@NonNull
|
||||||
private List<TaskFragmentAnimationAdapter> createAnimationAdapters(
|
private List<TaskFragmentAnimationAdapter> createAnimationAdapters(
|
||||||
@WindowManager.TransitionOldType int transit,
|
@WindowManager.TransitionOldType int transit,
|
||||||
@NonNull RemoteAnimationTarget[] targets) {
|
@NonNull RemoteAnimationTarget[] targets) {
|
||||||
@@ -180,12 +182,14 @@ class TaskFragmentAnimationRunner extends IRemoteAnimationRunner.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
private List<TaskFragmentAnimationAdapter> createOpenAnimationAdapters(
|
private List<TaskFragmentAnimationAdapter> createOpenAnimationAdapters(
|
||||||
@NonNull RemoteAnimationTarget[] targets) {
|
@NonNull RemoteAnimationTarget[] targets) {
|
||||||
return createOpenCloseAnimationAdapters(targets, true /* isOpening */,
|
return createOpenCloseAnimationAdapters(targets, true /* isOpening */,
|
||||||
mAnimationSpec::loadOpenAnimation);
|
mAnimationSpec::loadOpenAnimation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
private List<TaskFragmentAnimationAdapter> createCloseAnimationAdapters(
|
private List<TaskFragmentAnimationAdapter> createCloseAnimationAdapters(
|
||||||
@NonNull RemoteAnimationTarget[] targets) {
|
@NonNull RemoteAnimationTarget[] targets) {
|
||||||
return createOpenCloseAnimationAdapters(targets, false /* isOpening */,
|
return createOpenCloseAnimationAdapters(targets, false /* isOpening */,
|
||||||
@@ -196,6 +200,7 @@ class TaskFragmentAnimationRunner extends IRemoteAnimationRunner.Stub {
|
|||||||
* Creates {@link TaskFragmentAnimationAdapter} for OPEN and CLOSE types of transition.
|
* Creates {@link TaskFragmentAnimationAdapter} for OPEN and CLOSE types of transition.
|
||||||
* @param isOpening {@code true} for OPEN type, {@code false} for CLOSE type.
|
* @param isOpening {@code true} for OPEN type, {@code false} for CLOSE type.
|
||||||
*/
|
*/
|
||||||
|
@NonNull
|
||||||
private List<TaskFragmentAnimationAdapter> createOpenCloseAnimationAdapters(
|
private List<TaskFragmentAnimationAdapter> createOpenCloseAnimationAdapters(
|
||||||
@NonNull RemoteAnimationTarget[] targets, boolean isOpening,
|
@NonNull RemoteAnimationTarget[] targets, boolean isOpening,
|
||||||
@NonNull BiFunction<RemoteAnimationTarget, Rect, Animation> animationProvider) {
|
@NonNull BiFunction<RemoteAnimationTarget, Rect, Animation> animationProvider) {
|
||||||
@@ -238,6 +243,7 @@ class TaskFragmentAnimationRunner extends IRemoteAnimationRunner.Stub {
|
|||||||
return adapters;
|
return adapters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
private TaskFragmentAnimationAdapter createOpenCloseAnimationAdapter(
|
private TaskFragmentAnimationAdapter createOpenCloseAnimationAdapter(
|
||||||
@NonNull RemoteAnimationTarget target,
|
@NonNull RemoteAnimationTarget target,
|
||||||
@NonNull BiFunction<RemoteAnimationTarget, Rect, Animation> animationProvider,
|
@NonNull BiFunction<RemoteAnimationTarget, Rect, Animation> animationProvider,
|
||||||
@@ -259,6 +265,7 @@ class TaskFragmentAnimationRunner extends IRemoteAnimationRunner.Stub {
|
|||||||
return new TaskFragmentAnimationAdapter(animation, target);
|
return new TaskFragmentAnimationAdapter(animation, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
private List<TaskFragmentAnimationAdapter> createChangeAnimationAdapters(
|
private List<TaskFragmentAnimationAdapter> createChangeAnimationAdapters(
|
||||||
@NonNull RemoteAnimationTarget[] targets) {
|
@NonNull RemoteAnimationTarget[] targets) {
|
||||||
final List<TaskFragmentAnimationAdapter> adapters = new ArrayList<>();
|
final List<TaskFragmentAnimationAdapter> adapters = new ArrayList<>();
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ class TaskFragmentAnimationSpec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** For target that doesn't need to be animated. */
|
/** For target that doesn't need to be animated. */
|
||||||
|
@NonNull
|
||||||
static Animation createNoopAnimation(@NonNull RemoteAnimationTarget target) {
|
static Animation createNoopAnimation(@NonNull RemoteAnimationTarget target) {
|
||||||
// Noop but just keep the target showing/hiding.
|
// Noop but just keep the target showing/hiding.
|
||||||
final float alpha = target.mode == MODE_CLOSING ? 0f : 1f;
|
final float alpha = target.mode == MODE_CLOSING ? 0f : 1f;
|
||||||
@@ -85,6 +86,7 @@ class TaskFragmentAnimationSpec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Animation for target that is opening in a change transition. */
|
/** Animation for target that is opening in a change transition. */
|
||||||
|
@NonNull
|
||||||
Animation createChangeBoundsOpenAnimation(@NonNull RemoteAnimationTarget target) {
|
Animation createChangeBoundsOpenAnimation(@NonNull RemoteAnimationTarget target) {
|
||||||
final Rect bounds = target.localBounds;
|
final Rect bounds = target.localBounds;
|
||||||
// The target will be animated in from left or right depends on its position.
|
// The target will be animated in from left or right depends on its position.
|
||||||
@@ -101,6 +103,7 @@ class TaskFragmentAnimationSpec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Animation for target that is closing in a change transition. */
|
/** Animation for target that is closing in a change transition. */
|
||||||
|
@NonNull
|
||||||
Animation createChangeBoundsCloseAnimation(@NonNull RemoteAnimationTarget target) {
|
Animation createChangeBoundsCloseAnimation(@NonNull RemoteAnimationTarget target) {
|
||||||
final Rect bounds = target.localBounds;
|
final Rect bounds = target.localBounds;
|
||||||
// The target will be animated out to left or right depends on its position.
|
// The target will be animated out to left or right depends on its position.
|
||||||
@@ -121,6 +124,7 @@ class TaskFragmentAnimationSpec {
|
|||||||
* @return the return array always has two elements. The first one is for the start leash, and
|
* @return the return array always has two elements. The first one is for the start leash, and
|
||||||
* the second one is for the end leash.
|
* the second one is for the end leash.
|
||||||
*/
|
*/
|
||||||
|
@NonNull
|
||||||
Animation[] createChangeBoundsChangeAnimations(@NonNull RemoteAnimationTarget target) {
|
Animation[] createChangeBoundsChangeAnimations(@NonNull RemoteAnimationTarget target) {
|
||||||
// Both start bounds and end bounds are in screen coordinates. We will post translate
|
// Both start bounds and end bounds are in screen coordinates. We will post translate
|
||||||
// to the local coordinates in TaskFragmentAnimationAdapter#onAnimationUpdate
|
// to the local coordinates in TaskFragmentAnimationAdapter#onAnimationUpdate
|
||||||
@@ -177,6 +181,7 @@ class TaskFragmentAnimationSpec {
|
|||||||
return new Animation[]{startSet, endSet};
|
return new Animation[]{startSet, endSet};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
Animation loadOpenAnimation(@NonNull RemoteAnimationTarget target,
|
Animation loadOpenAnimation(@NonNull RemoteAnimationTarget target,
|
||||||
@NonNull Rect wholeAnimationBounds) {
|
@NonNull Rect wholeAnimationBounds) {
|
||||||
final boolean isEnter = target.mode != MODE_CLOSING;
|
final boolean isEnter = target.mode != MODE_CLOSING;
|
||||||
@@ -198,6 +203,7 @@ class TaskFragmentAnimationSpec {
|
|||||||
return animation;
|
return animation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
Animation loadCloseAnimation(@NonNull RemoteAnimationTarget target,
|
Animation loadCloseAnimation(@NonNull RemoteAnimationTarget target,
|
||||||
@NonNull Rect wholeAnimationBounds) {
|
@NonNull Rect wholeAnimationBounds) {
|
||||||
final boolean isEnter = target.mode != MODE_CLOSING;
|
final boolean isEnter = target.mode != MODE_CLOSING;
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ package androidx.window.extensions.embedding;
|
|||||||
|
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
|
||||||
import android.annotation.Nullable;
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.WindowConfiguration.WindowingMode;
|
import android.app.WindowConfiguration.WindowingMode;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -30,6 +28,9 @@ import android.util.Size;
|
|||||||
import android.window.TaskFragmentInfo;
|
import android.window.TaskFragmentInfo;
|
||||||
import android.window.WindowContainerTransaction;
|
import android.window.WindowContainerTransaction;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -175,6 +176,7 @@ class TaskFragmentContainer {
|
|||||||
&& mInfo.getActivities().size() == collectNonFinishingActivities().size();
|
&& mInfo.getActivities().size() == collectNonFinishingActivities().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
ActivityStack toActivityStack() {
|
ActivityStack toActivityStack() {
|
||||||
return new ActivityStack(collectNonFinishingActivities(), isEmpty());
|
return new ActivityStack(collectNonFinishingActivities(), isEmpty());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -322,8 +322,8 @@ public class SplitControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOnActivityReparentToTask_sameProcess() {
|
public void testOnActivityReparentedToTask_sameProcess() {
|
||||||
mSplitController.onActivityReparentToTask(TASK_ID, new Intent(),
|
mSplitController.onActivityReparentedToTask(TASK_ID, new Intent(),
|
||||||
mActivity.getActivityToken());
|
mActivity.getActivityToken());
|
||||||
|
|
||||||
// Treated as on activity created, but allow to split as primary.
|
// Treated as on activity created, but allow to split as primary.
|
||||||
@@ -333,13 +333,13 @@ public class SplitControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOnActivityReparentToTask_diffProcess() {
|
public void testOnActivityReparentedToTask_diffProcess() {
|
||||||
// Create an empty TaskFragment to initialize for the Task.
|
// Create an empty TaskFragment to initialize for the Task.
|
||||||
mSplitController.newContainer(new Intent(), mActivity, TASK_ID);
|
mSplitController.newContainer(new Intent(), mActivity, TASK_ID);
|
||||||
final IBinder activityToken = new Binder();
|
final IBinder activityToken = new Binder();
|
||||||
final Intent intent = new Intent();
|
final Intent intent = new Intent();
|
||||||
|
|
||||||
mSplitController.onActivityReparentToTask(TASK_ID, intent, activityToken);
|
mSplitController.onActivityReparentedToTask(TASK_ID, intent, activityToken);
|
||||||
|
|
||||||
// Treated as starting new intent
|
// Treated as starting new intent
|
||||||
verify(mSplitController, never()).resolveActivityToContainer(any(), anyBoolean());
|
verify(mSplitController, never()).resolveActivityToContainer(any(), anyBoolean());
|
||||||
|
|||||||
@@ -1566,7 +1566,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
if (task == mLastParentBeforePip && task != null) {
|
if (task == mLastParentBeforePip && task != null) {
|
||||||
// Notify the TaskFragmentOrganizer that the activity is reparented back from pip.
|
// Notify the TaskFragmentOrganizer that the activity is reparented back from pip.
|
||||||
mAtmService.mWindowOrganizerController.mTaskFragmentOrganizerController
|
mAtmService.mWindowOrganizerController.mTaskFragmentOrganizerController
|
||||||
.onActivityReparentToTask(this);
|
.onActivityReparentedToTask(this);
|
||||||
// Activity's reparented back from pip, clear the links once established
|
// Activity's reparented back from pip, clear the links once established
|
||||||
clearLastParentBeforePip();
|
clearLastParentBeforePip();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ package com.android.server.wm;
|
|||||||
|
|
||||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||||
import static android.window.TaskFragmentOrganizer.putErrorInfoInBundle;
|
import static android.window.TaskFragmentOrganizer.putErrorInfoInBundle;
|
||||||
import static android.window.TaskFragmentTransaction.TYPE_ACTIVITY_REPARENT_TO_TASK;
|
import static android.window.TaskFragmentTransaction.TYPE_ACTIVITY_REPARENTED_TO_TASK;
|
||||||
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_APPEARED;
|
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_APPEARED;
|
||||||
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_ERROR;
|
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_ERROR;
|
||||||
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_INFO_CHANGED;
|
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_INFO_CHANGED;
|
||||||
@@ -277,7 +277,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
TaskFragmentTransaction.Change prepareActivityReparentToTask(
|
TaskFragmentTransaction.Change prepareActivityReparentedToTask(
|
||||||
@NonNull ActivityRecord activity) {
|
@NonNull ActivityRecord activity) {
|
||||||
if (activity.finishing) {
|
if (activity.finishing) {
|
||||||
Slog.d(TAG, "Reparent activity=" + activity.token + " is finishing");
|
Slog.d(TAG, "Reparent activity=" + activity.token + " is finishing");
|
||||||
@@ -315,7 +315,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
}
|
}
|
||||||
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Activity=%s reparent to taskId=%d",
|
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Activity=%s reparent to taskId=%d",
|
||||||
activity.token, task.mTaskId);
|
activity.token, task.mTaskId);
|
||||||
return new TaskFragmentTransaction.Change(TYPE_ACTIVITY_REPARENT_TO_TASK)
|
return new TaskFragmentTransaction.Change(TYPE_ACTIVITY_REPARENTED_TO_TASK)
|
||||||
.setTaskId(task.mTaskId)
|
.setTaskId(task.mTaskId)
|
||||||
.setActivityIntent(activity.intent)
|
.setActivityIntent(activity.intent)
|
||||||
.setActivityToken(activityToken);
|
.setActivityToken(activityToken);
|
||||||
@@ -521,7 +521,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
mAtmService.mWindowManager.mWindowPlacerLocked.requestTraversal();
|
mAtmService.mWindowManager.mWindowPlacerLocked.requestTraversal();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onActivityReparentToTask(@NonNull ActivityRecord activity) {
|
void onActivityReparentedToTask(@NonNull ActivityRecord activity) {
|
||||||
final ITaskFragmentOrganizer organizer;
|
final ITaskFragmentOrganizer organizer;
|
||||||
if (activity.mLastTaskFragmentOrganizerBeforePip != null) {
|
if (activity.mLastTaskFragmentOrganizerBeforePip != null) {
|
||||||
// If the activity is previously embedded in an organized TaskFragment.
|
// If the activity is previously embedded in an organized TaskFragment.
|
||||||
@@ -547,7 +547,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addPendingEvent(new PendingTaskFragmentEvent.Builder(
|
addPendingEvent(new PendingTaskFragmentEvent.Builder(
|
||||||
PendingTaskFragmentEvent.EVENT_ACTIVITY_REPARENT_TO_TASK, organizer)
|
PendingTaskFragmentEvent.EVENT_ACTIVITY_REPARENTED_TO_TASK, organizer)
|
||||||
.setActivity(activity)
|
.setActivity(activity)
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
@@ -601,7 +601,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
static final int EVENT_INFO_CHANGED = 2;
|
static final int EVENT_INFO_CHANGED = 2;
|
||||||
static final int EVENT_PARENT_INFO_CHANGED = 3;
|
static final int EVENT_PARENT_INFO_CHANGED = 3;
|
||||||
static final int EVENT_ERROR = 4;
|
static final int EVENT_ERROR = 4;
|
||||||
static final int EVENT_ACTIVITY_REPARENT_TO_TASK = 5;
|
static final int EVENT_ACTIVITY_REPARENTED_TO_TASK = 5;
|
||||||
|
|
||||||
@IntDef(prefix = "EVENT_", value = {
|
@IntDef(prefix = "EVENT_", value = {
|
||||||
EVENT_APPEARED,
|
EVENT_APPEARED,
|
||||||
@@ -609,7 +609,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
EVENT_INFO_CHANGED,
|
EVENT_INFO_CHANGED,
|
||||||
EVENT_PARENT_INFO_CHANGED,
|
EVENT_PARENT_INFO_CHANGED,
|
||||||
EVENT_ERROR,
|
EVENT_ERROR,
|
||||||
EVENT_ACTIVITY_REPARENT_TO_TASK
|
EVENT_ACTIVITY_REPARENTED_TO_TASK
|
||||||
})
|
})
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
public @interface EventType {}
|
public @interface EventType {}
|
||||||
@@ -900,8 +900,8 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
case PendingTaskFragmentEvent.EVENT_ERROR:
|
case PendingTaskFragmentEvent.EVENT_ERROR:
|
||||||
return state.prepareTaskFragmentError(event.mErrorCallbackToken, taskFragment,
|
return state.prepareTaskFragmentError(event.mErrorCallbackToken, taskFragment,
|
||||||
event.mOpType, event.mException);
|
event.mOpType, event.mException);
|
||||||
case PendingTaskFragmentEvent.EVENT_ACTIVITY_REPARENT_TO_TASK:
|
case PendingTaskFragmentEvent.EVENT_ACTIVITY_REPARENTED_TO_TASK:
|
||||||
return state.prepareActivityReparentToTask(event.mActivity);
|
return state.prepareActivityReparentedToTask(event.mActivity);
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unknown TaskFragmentEvent=" + event.mEventType);
|
throw new IllegalArgumentException("Unknown TaskFragmentEvent=" + event.mEventType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -474,7 +474,7 @@ public class AppTransitionTests extends WindowTestsBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testActivityRecordReparentToTaskFragment() {
|
public void testActivityRecordReparentedToTaskFragment() {
|
||||||
final ActivityRecord activity = createActivityRecord(mDc);
|
final ActivityRecord activity = createActivityRecord(mDc);
|
||||||
final SurfaceControl activityLeash = mock(SurfaceControl.class);
|
final SurfaceControl activityLeash = mock(SurfaceControl.class);
|
||||||
doNothing().when(activity).setDropInputMode(anyInt());
|
doNothing().when(activity).setDropInputMode(anyInt());
|
||||||
|
|||||||
@@ -302,7 +302,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOnActivityReparentToTask_activityInOrganizerProcess_useActivityToken() {
|
public void testOnActivityReparentedToTask_activityInOrganizerProcess_useActivityToken() {
|
||||||
// Make sure the activity pid/uid is the same as the organizer caller.
|
// Make sure the activity pid/uid is the same as the organizer caller.
|
||||||
final int pid = Binder.getCallingPid();
|
final int pid = Binder.getCallingPid();
|
||||||
final int uid = Binder.getCallingUid();
|
final int uid = Binder.getCallingUid();
|
||||||
@@ -314,17 +314,18 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
task.effectiveUid = uid;
|
task.effectiveUid = uid;
|
||||||
|
|
||||||
// No need to notify organizer if it is not embedded.
|
// No need to notify organizer if it is not embedded.
|
||||||
mController.onActivityReparentToTask(activity);
|
mController.onActivityReparentedToTask(activity);
|
||||||
mController.dispatchPendingEvents();
|
mController.dispatchPendingEvents();
|
||||||
|
|
||||||
verify(mOrganizer, never()).onActivityReparentToTask(anyInt(), any(), any());
|
verify(mOrganizer, never()).onActivityReparentedToTask(anyInt(), any(), any());
|
||||||
|
|
||||||
// Notify organizer if it was embedded before entered Pip.
|
// Notify organizer if it was embedded before entered Pip.
|
||||||
activity.mLastTaskFragmentOrganizerBeforePip = mIOrganizer;
|
activity.mLastTaskFragmentOrganizerBeforePip = mIOrganizer;
|
||||||
mController.onActivityReparentToTask(activity);
|
mController.onActivityReparentedToTask(activity);
|
||||||
mController.dispatchPendingEvents();
|
mController.dispatchPendingEvents();
|
||||||
|
|
||||||
verify(mOrganizer).onActivityReparentToTask(task.mTaskId, activity.intent, activity.token);
|
verify(mOrganizer).onActivityReparentedToTask(task.mTaskId, activity.intent,
|
||||||
|
activity.token);
|
||||||
|
|
||||||
// Notify organizer if there is any embedded in the Task.
|
// Notify organizer if there is any embedded in the Task.
|
||||||
final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
|
final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
|
||||||
@@ -335,15 +336,15 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
DEFAULT_TASK_FRAGMENT_ORGANIZER_PROCESS_NAME);
|
DEFAULT_TASK_FRAGMENT_ORGANIZER_PROCESS_NAME);
|
||||||
activity.reparent(taskFragment, POSITION_TOP);
|
activity.reparent(taskFragment, POSITION_TOP);
|
||||||
activity.mLastTaskFragmentOrganizerBeforePip = null;
|
activity.mLastTaskFragmentOrganizerBeforePip = null;
|
||||||
mController.onActivityReparentToTask(activity);
|
mController.onActivityReparentedToTask(activity);
|
||||||
mController.dispatchPendingEvents();
|
mController.dispatchPendingEvents();
|
||||||
|
|
||||||
verify(mOrganizer, times(2))
|
verify(mOrganizer, times(2))
|
||||||
.onActivityReparentToTask(task.mTaskId, activity.intent, activity.token);
|
.onActivityReparentedToTask(task.mTaskId, activity.intent, activity.token);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOnActivityReparentToTask_activityNotInOrganizerProcess_useTemporaryToken() {
|
public void testOnActivityReparentedToTask_activityNotInOrganizerProcess_useTemporaryToken() {
|
||||||
final int pid = Binder.getCallingPid();
|
final int pid = Binder.getCallingPid();
|
||||||
final int uid = Binder.getCallingUid();
|
final int uid = Binder.getCallingUid();
|
||||||
mTaskFragment.setTaskFragmentOrganizer(mOrganizer.getOrganizerToken(), uid,
|
mTaskFragment.setTaskFragmentOrganizer(mOrganizer.getOrganizerToken(), uid,
|
||||||
@@ -364,11 +365,11 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
// Notify organizer if it was embedded before entered Pip.
|
// Notify organizer if it was embedded before entered Pip.
|
||||||
// Create a temporary token since the activity doesn't belong to the same process.
|
// Create a temporary token since the activity doesn't belong to the same process.
|
||||||
activity.mLastTaskFragmentOrganizerBeforePip = mIOrganizer;
|
activity.mLastTaskFragmentOrganizerBeforePip = mIOrganizer;
|
||||||
mController.onActivityReparentToTask(activity);
|
mController.onActivityReparentedToTask(activity);
|
||||||
mController.dispatchPendingEvents();
|
mController.dispatchPendingEvents();
|
||||||
|
|
||||||
// Allow organizer to reparent activity in other process using the temporary token.
|
// Allow organizer to reparent activity in other process using the temporary token.
|
||||||
verify(mOrganizer).onActivityReparentToTask(eq(task.mTaskId), eq(activity.intent),
|
verify(mOrganizer).onActivityReparentedToTask(eq(task.mTaskId), eq(activity.intent),
|
||||||
token.capture());
|
token.capture());
|
||||||
final IBinder temporaryToken = token.getValue();
|
final IBinder temporaryToken = token.getValue();
|
||||||
assertNotEquals(activity.token, temporaryToken);
|
assertNotEquals(activity.token, temporaryToken);
|
||||||
|
|||||||
@@ -340,7 +340,7 @@ public class TaskFragmentTest extends WindowTestsBase {
|
|||||||
activity.reparent(task, POSITION_TOP);
|
activity.reparent(task, POSITION_TOP);
|
||||||
|
|
||||||
// Notify the organizer about the reparent.
|
// Notify the organizer about the reparent.
|
||||||
verify(mAtm.mTaskFragmentOrganizerController).onActivityReparentToTask(activity);
|
verify(mAtm.mTaskFragmentOrganizerController).onActivityReparentedToTask(activity);
|
||||||
assertNull(activity.mLastTaskFragmentOrganizerBeforePip);
|
assertNull(activity.mLastTaskFragmentOrganizerBeforePip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user