Merge changes from topic "task_fragment_organizer" into sc-v2-dev
* changes: Implement WCT#create/deleteTaskFragment Add TaskFragmentOrganizer API Add WindowContainerTransaction APIs for create/deleteTaskFragment
This commit is contained in:
40
core/java/android/window/ITaskFragmentOrganizer.aidl
Normal file
40
core/java/android/window/ITaskFragmentOrganizer.aidl
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.window;
|
||||||
|
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.window.TaskFragmentAppearedInfo;
|
||||||
|
import android.window.TaskFragmentInfo;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
oneway interface ITaskFragmentOrganizer {
|
||||||
|
void onTaskFragmentAppeared(in TaskFragmentAppearedInfo taskFragmentAppearedInfo);
|
||||||
|
void onTaskFragmentInfoChanged(in TaskFragmentInfo taskFragmentInfo);
|
||||||
|
void onTaskFragmentVanished(in TaskFragmentInfo taskFragmentInfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the parent leaf Task of organized TaskFragments is changed.
|
||||||
|
* When the leaf Task is changed, the organizer may want to update the TaskFragments in one
|
||||||
|
* transaction.
|
||||||
|
*
|
||||||
|
* For case like screen size change, it will trigger onTaskFragmentParentInfoChanged with new
|
||||||
|
* Task bounds, but may not trigger onTaskFragmentInfoChanged because there can be an override
|
||||||
|
* bounds.
|
||||||
|
*/
|
||||||
|
void onTaskFragmentParentInfoChanged(in IBinder fragmentToken, in Configuration parentConfig);
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.window;
|
||||||
|
|
||||||
|
import android.window.ITaskFragmentOrganizer;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
interface ITaskFragmentOrganizerController {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a TaskFragmentOrganizer to manage TaskFragments.
|
||||||
|
*/
|
||||||
|
void registerOrganizer(in ITaskFragmentOrganizer organizer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregisters a previously registered TaskFragmentOrganizer.
|
||||||
|
*/
|
||||||
|
void unregisterOrganizer(in ITaskFragmentOrganizer organizer);
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@ import android.view.SurfaceControl;
|
|||||||
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.window.IDisplayAreaOrganizerController;
|
import android.window.IDisplayAreaOrganizerController;
|
||||||
|
import android.window.ITaskFragmentOrganizerController;
|
||||||
import android.window.ITaskOrganizerController;
|
import android.window.ITaskOrganizerController;
|
||||||
import android.window.ITransitionPlayer;
|
import android.window.ITransitionPlayer;
|
||||||
import android.window.IWindowContainerTransactionCallback;
|
import android.window.IWindowContainerTransactionCallback;
|
||||||
@@ -77,6 +78,9 @@ interface IWindowOrganizerController {
|
|||||||
/** @return An interface enabling the management of display area organizers. */
|
/** @return An interface enabling the management of display area organizers. */
|
||||||
IDisplayAreaOrganizerController getDisplayAreaOrganizerController();
|
IDisplayAreaOrganizerController getDisplayAreaOrganizerController();
|
||||||
|
|
||||||
|
/** @return An interface enabling the management of task fragment organizers. */
|
||||||
|
ITaskFragmentOrganizerController getTaskFragmentOrganizerController();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a transition player with Core. There is only one of these at a time and calling
|
* Registers a transition player with Core. There is only one of these at a time and calling
|
||||||
* this will replace the existing one if set.
|
* this will replace the existing one if set.
|
||||||
|
|||||||
23
core/java/android/window/TaskFragmentAppearedInfo.aidl
Normal file
23
core/java/android/window/TaskFragmentAppearedInfo.aidl
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.window;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data object for the TaskFragment info provided when a TaskFragment is presented to an organizer.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
parcelable TaskFragmentAppearedInfo;
|
||||||
86
core/java/android/window/TaskFragmentAppearedInfo.java
Normal file
86
core/java/android/window/TaskFragmentAppearedInfo.java
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.window;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.view.SurfaceControl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data object for the TaskFragment info provided when a TaskFragment is presented to an organizer.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public final class TaskFragmentAppearedInfo implements Parcelable {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final TaskFragmentInfo mTaskFragmentInfo;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final SurfaceControl mLeash;
|
||||||
|
|
||||||
|
public TaskFragmentAppearedInfo(
|
||||||
|
@NonNull TaskFragmentInfo taskFragmentInfo, @NonNull SurfaceControl leash) {
|
||||||
|
mTaskFragmentInfo = taskFragmentInfo;
|
||||||
|
mLeash = leash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaskFragmentInfo getTaskFragmentInfo() {
|
||||||
|
return mTaskFragmentInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SurfaceControl getLeash() {
|
||||||
|
return mLeash;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TaskFragmentAppearedInfo(Parcel in) {
|
||||||
|
mTaskFragmentInfo = in.readTypedObject(TaskFragmentInfo.CREATOR);
|
||||||
|
mLeash = in.readTypedObject(SurfaceControl.CREATOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||||
|
dest.writeTypedObject(mTaskFragmentInfo, flags);
|
||||||
|
dest.writeTypedObject(mLeash, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static final Creator<TaskFragmentAppearedInfo> CREATOR =
|
||||||
|
new Creator<TaskFragmentAppearedInfo>() {
|
||||||
|
@Override
|
||||||
|
public TaskFragmentAppearedInfo createFromParcel(Parcel in) {
|
||||||
|
return new TaskFragmentAppearedInfo(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TaskFragmentAppearedInfo[] newArray(int size) {
|
||||||
|
return new TaskFragmentAppearedInfo[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TaskFragmentAppearedInfo{"
|
||||||
|
+ " taskFragmentInfo=" + mTaskFragmentInfo
|
||||||
|
+ "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
23
core/java/android/window/TaskFragmentCreationParams.aidl
Normal file
23
core/java/android/window/TaskFragmentCreationParams.aidl
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.window;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data object for options to create TaskFragment with.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
parcelable TaskFragmentCreationParams;
|
||||||
121
core/java/android/window/TaskFragmentCreationParams.java
Normal file
121
core/java/android/window/TaskFragmentCreationParams.java
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.window;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data object for options to create TaskFragment with.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public final class TaskFragmentCreationParams implements Parcelable {
|
||||||
|
|
||||||
|
/** The organizer that will organize this TaskFragment. */
|
||||||
|
@NonNull
|
||||||
|
private final ITaskFragmentOrganizer mOrganizer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unique token assigned from the client organizer to identify the {@link TaskFragmentInfo} when
|
||||||
|
* a new TaskFragment is created with this option.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
private final IBinder mFragmentToken;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activity token used to identify the leaf Task to create the TaskFragment in. It has to belong
|
||||||
|
* to the same app as the root Activity of the target Task.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
private final IBinder mOwnerToken;
|
||||||
|
|
||||||
|
/** The initial bounds of the TaskFragment. Fill parent if empty. */
|
||||||
|
@NonNull
|
||||||
|
private final Rect mInitialBounds = new Rect();
|
||||||
|
|
||||||
|
private TaskFragmentCreationParams(
|
||||||
|
@NonNull ITaskFragmentOrganizer organizer, @NonNull IBinder fragmentToken,
|
||||||
|
@NonNull IBinder ownerToken, @NonNull Rect initialBounds) {
|
||||||
|
mOrganizer = organizer;
|
||||||
|
mFragmentToken = fragmentToken;
|
||||||
|
mOwnerToken = ownerToken;
|
||||||
|
mInitialBounds.set(initialBounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITaskFragmentOrganizer getOrganizer() {
|
||||||
|
return mOrganizer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBinder getFragmentToken() {
|
||||||
|
return mFragmentToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBinder getOwnerToken() {
|
||||||
|
return mOwnerToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rect getInitialBounds() {
|
||||||
|
return mInitialBounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TaskFragmentCreationParams(Parcel in) {
|
||||||
|
mOrganizer = ITaskFragmentOrganizer.Stub.asInterface(in.readStrongBinder());
|
||||||
|
mFragmentToken = in.readStrongBinder();
|
||||||
|
mOwnerToken = in.readStrongBinder();
|
||||||
|
mInitialBounds.readFromParcel(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||||
|
dest.writeStrongInterface(mOrganizer);
|
||||||
|
dest.writeStrongBinder(mFragmentToken);
|
||||||
|
dest.writeStrongBinder(mOwnerToken);
|
||||||
|
mInitialBounds.writeToParcel(dest, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static final Creator<TaskFragmentCreationParams> CREATOR =
|
||||||
|
new Creator<TaskFragmentCreationParams>() {
|
||||||
|
@Override
|
||||||
|
public TaskFragmentCreationParams createFromParcel(Parcel in) {
|
||||||
|
return new TaskFragmentCreationParams(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TaskFragmentCreationParams[] newArray(int size) {
|
||||||
|
return new TaskFragmentCreationParams[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TaskFragmentCreationParams{"
|
||||||
|
+ " organizer=" + mOrganizer
|
||||||
|
+ " fragmentToken=" + mFragmentToken
|
||||||
|
+ " ownerToken=" + mOwnerToken
|
||||||
|
+ " initialBounds=" + mInitialBounds
|
||||||
|
+ "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
23
core/java/android/window/TaskFragmentInfo.aidl
Normal file
23
core/java/android/window/TaskFragmentInfo.aidl
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.window;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores information about a particular TaskFragment.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
parcelable TaskFragmentInfo;
|
||||||
145
core/java/android/window/TaskFragmentInfo.java
Normal file
145
core/java/android/window/TaskFragmentInfo.java
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.window;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores information about a particular TaskFragment.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public final class TaskFragmentInfo implements Parcelable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client assigned unique token in {@link TaskFragmentCreationParams#fragmentToken} to create
|
||||||
|
* this TaskFragment with.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
private final IBinder mFragmentToken;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The component name of the initial root activity of this TaskFragment, which will be used
|
||||||
|
* to configure the relationships for TaskFragments.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
private final ComponentName mInitialComponentName;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final WindowContainerToken mToken;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final Configuration mConfiguration = new Configuration();
|
||||||
|
|
||||||
|
/** Whether the TaskFragment contains any child Activity. */
|
||||||
|
private final boolean mIsEmpty;
|
||||||
|
|
||||||
|
/** Whether this TaskFragment is visible on the window hierarchy. */
|
||||||
|
private final boolean mIsVisible;
|
||||||
|
|
||||||
|
public TaskFragmentInfo(
|
||||||
|
@NonNull IBinder fragmentToken, @NonNull ComponentName initialComponentName,
|
||||||
|
@NonNull WindowContainerToken token, @NonNull Configuration configuration,
|
||||||
|
boolean isEmpty, boolean isVisible) {
|
||||||
|
if (fragmentToken == null || initialComponentName == null) {
|
||||||
|
throw new IllegalArgumentException("Invalid TaskFragmentInfo.");
|
||||||
|
}
|
||||||
|
mFragmentToken = fragmentToken;
|
||||||
|
mInitialComponentName = initialComponentName;
|
||||||
|
mToken = token;
|
||||||
|
mConfiguration.setTo(configuration);
|
||||||
|
mIsEmpty = isEmpty;
|
||||||
|
mIsVisible = isVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBinder getFragmentToken() {
|
||||||
|
return mFragmentToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ComponentName getInitialComponentName() {
|
||||||
|
return mInitialComponentName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WindowContainerToken getToken() {
|
||||||
|
return mToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Configuration getConfiguration() {
|
||||||
|
return mConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return mIsEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isVisible() {
|
||||||
|
return mIsVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TaskFragmentInfo(Parcel in) {
|
||||||
|
mFragmentToken = in.readStrongBinder();
|
||||||
|
mInitialComponentName = in.readTypedObject(ComponentName.CREATOR);
|
||||||
|
mToken = in.readTypedObject(WindowContainerToken.CREATOR);
|
||||||
|
mConfiguration.readFromParcel(in);
|
||||||
|
mIsEmpty = in.readBoolean();
|
||||||
|
mIsVisible = in.readBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||||
|
dest.writeStrongBinder(mFragmentToken);
|
||||||
|
dest.writeTypedObject(mInitialComponentName, flags);
|
||||||
|
dest.writeTypedObject(mToken, flags);
|
||||||
|
mConfiguration.writeToParcel(dest, flags);
|
||||||
|
dest.writeBoolean(mIsEmpty);
|
||||||
|
dest.writeBoolean(mIsVisible);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static final Creator<TaskFragmentInfo> CREATOR =
|
||||||
|
new Creator<TaskFragmentInfo>() {
|
||||||
|
@Override
|
||||||
|
public TaskFragmentInfo createFromParcel(Parcel in) {
|
||||||
|
return new TaskFragmentInfo(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TaskFragmentInfo[] newArray(int size) {
|
||||||
|
return new TaskFragmentInfo[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TaskFragmentInfo{"
|
||||||
|
+ " fragmentToken=" + mFragmentToken
|
||||||
|
+ " initialComponentName=" + mInitialComponentName
|
||||||
|
+ " token=" + mToken
|
||||||
|
+ " isEmpty=" + mIsEmpty
|
||||||
|
+ " isVisible=" + mIsVisible
|
||||||
|
+ "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
131
core/java/android/window/TaskFragmentOrganizer.java
Normal file
131
core/java/android/window/TaskFragmentOrganizer.java
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.window;
|
||||||
|
|
||||||
|
import android.annotation.CallSuper;
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for WindowManager to delegate control of {@link com.android.server.wm.TaskFragment}.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public class TaskFragmentOrganizer extends WindowOrganizer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callbacks from WM Core are posted on this executor.
|
||||||
|
*/
|
||||||
|
private final Executor mExecutor;
|
||||||
|
|
||||||
|
public TaskFragmentOrganizer(@NonNull Executor executor) {
|
||||||
|
mExecutor = executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the executor to run callbacks on.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Executor getExecutor() {
|
||||||
|
return mExecutor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a TaskFragmentOrganizer to manage TaskFragments.
|
||||||
|
*/
|
||||||
|
@CallSuper
|
||||||
|
public void registerOrganizer() {
|
||||||
|
try {
|
||||||
|
getController().registerOrganizer(mInterface);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregisters a previously registered TaskFragmentOrganizer.
|
||||||
|
*/
|
||||||
|
@CallSuper
|
||||||
|
public void unregisterOrganizer() {
|
||||||
|
try {
|
||||||
|
getController().unregisterOrganizer(mInterface);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called when a TaskFragment is created and organized by this organizer. */
|
||||||
|
public void onTaskFragmentAppeared(
|
||||||
|
@NonNull TaskFragmentAppearedInfo taskFragmentAppearedInfo) {}
|
||||||
|
|
||||||
|
/** Called when the status of an organized TaskFragment is changed. */
|
||||||
|
public void onTaskFragmentInfoChanged(@NonNull TaskFragmentInfo taskFragmentInfo) {}
|
||||||
|
|
||||||
|
/** Called when an organized TaskFragment is removed. */
|
||||||
|
public void onTaskFragmentVanished(@NonNull TaskFragmentInfo taskFragmentInfo) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the parent leaf Task of organized TaskFragments is changed.
|
||||||
|
* When the leaf Task is changed, the organizer may want to update the TaskFragments in one
|
||||||
|
* transaction.
|
||||||
|
*
|
||||||
|
* For case like screen size change, it will trigger onTaskFragmentParentInfoChanged with new
|
||||||
|
* Task bounds, but may not trigger onTaskFragmentInfoChanged because there can be an override
|
||||||
|
* bounds.
|
||||||
|
*/
|
||||||
|
public void onTaskFragmentParentInfoChanged(
|
||||||
|
@NonNull IBinder fragmentToken, @NonNull Configuration parentConfig) {}
|
||||||
|
|
||||||
|
private final ITaskFragmentOrganizer mInterface = new ITaskFragmentOrganizer.Stub() {
|
||||||
|
@Override
|
||||||
|
public void onTaskFragmentAppeared(@NonNull TaskFragmentAppearedInfo taskFragmentInfo) {
|
||||||
|
mExecutor.execute(
|
||||||
|
() -> TaskFragmentOrganizer.this.onTaskFragmentAppeared(taskFragmentInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTaskFragmentInfoChanged(@NonNull TaskFragmentInfo taskFragmentInfo) {
|
||||||
|
mExecutor.execute(
|
||||||
|
() -> TaskFragmentOrganizer.this.onTaskFragmentInfoChanged(taskFragmentInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTaskFragmentVanished(@NonNull TaskFragmentInfo taskFragmentInfo) {
|
||||||
|
mExecutor.execute(
|
||||||
|
() -> TaskFragmentOrganizer.this.onTaskFragmentVanished(taskFragmentInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTaskFragmentParentInfoChanged(
|
||||||
|
@NonNull IBinder fragmentToken, @NonNull Configuration parentConfig) {
|
||||||
|
mExecutor.execute(
|
||||||
|
() -> TaskFragmentOrganizer.this.onTaskFragmentParentInfoChanged(
|
||||||
|
fragmentToken, parentConfig));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private ITaskFragmentOrganizerController getController() {
|
||||||
|
try {
|
||||||
|
return getWindowOrganizerController().getTaskFragmentOrganizerController();
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
|
|||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.annotation.TestApi;
|
import android.annotation.TestApi;
|
||||||
import android.app.WindowConfiguration;
|
import android.app.WindowConfiguration;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
@@ -325,7 +326,8 @@ public final class WindowContainerTransaction implements Parcelable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets to containers adjacent to each other. Containers below two visible adjacent roots will
|
* Sets to containers adjacent to each other. Containers below two visible adjacent roots will
|
||||||
* be made invisible. This currently only applies to Task containers created by organizer.
|
* be made invisible. This currently only applies to TaskFragment containers created by
|
||||||
|
* organizer.
|
||||||
* @param root1 the first root.
|
* @param root1 the first root.
|
||||||
* @param root2 the second root.
|
* @param root2 the second root.
|
||||||
*/
|
*/
|
||||||
@@ -377,6 +379,102 @@ public final class WindowContainerTransaction implements Parcelable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new TaskFragment with the given options.
|
||||||
|
* @param taskFragmentOptions the options used to create the TaskFragment.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public WindowContainerTransaction createTaskFragment(
|
||||||
|
@NonNull TaskFragmentCreationParams taskFragmentOptions) {
|
||||||
|
final HierarchyOp hierarchyOp =
|
||||||
|
new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT)
|
||||||
|
.setTaskFragmentCreationOptions(taskFragmentOptions)
|
||||||
|
.build();
|
||||||
|
mHierarchyOps.add(hierarchyOp);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes an existing TaskFragment. Any remaining activities below it will be destroyed.
|
||||||
|
* @param taskFragment the TaskFragment to be removed.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public WindowContainerTransaction deleteTaskFragment(
|
||||||
|
@NonNull WindowContainerToken taskFragment) {
|
||||||
|
final HierarchyOp hierarchyOp =
|
||||||
|
new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT)
|
||||||
|
.setContainer(taskFragment.asBinder())
|
||||||
|
.build();
|
||||||
|
mHierarchyOps.add(hierarchyOp);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts an activity in the TaskFragment.
|
||||||
|
* @param fragmentToken client assigned unique token to create TaskFragment with specified in
|
||||||
|
* {@link TaskFragmentCreationParams#fragmentToken}.
|
||||||
|
* @param activityIntent intent to start the activity.
|
||||||
|
* @param activityOptions ActivityOptions to start the activity with.
|
||||||
|
* @see android.content.Context#startActivity(Intent, Bundle).
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public WindowContainerTransaction startActivityInTaskFragment(
|
||||||
|
@NonNull IBinder fragmentToken, @NonNull Intent activityIntent,
|
||||||
|
@Nullable Bundle activityOptions) {
|
||||||
|
final HierarchyOp hierarchyOp =
|
||||||
|
new HierarchyOp.Builder(
|
||||||
|
HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT)
|
||||||
|
.setContainer(fragmentToken)
|
||||||
|
.setActivityIntent(activityIntent)
|
||||||
|
.setLaunchOptions(activityOptions)
|
||||||
|
.build();
|
||||||
|
mHierarchyOps.add(hierarchyOp);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves an activity into the TaskFragment.
|
||||||
|
* @param fragmentToken client assigned unique token to create TaskFragment with specified in
|
||||||
|
* {@link TaskFragmentCreationParams#fragmentToken}.
|
||||||
|
* @param activityToken activity to be reparented.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public WindowContainerTransaction reparentActivityToTaskFragment(
|
||||||
|
@NonNull IBinder fragmentToken, @NonNull IBinder activityToken) {
|
||||||
|
final HierarchyOp hierarchyOp =
|
||||||
|
new HierarchyOp.Builder(
|
||||||
|
HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT)
|
||||||
|
.setReparentContainer(fragmentToken)
|
||||||
|
.setContainer(activityToken)
|
||||||
|
.build();
|
||||||
|
mHierarchyOps.add(hierarchyOp);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reparents all children of one TaskFragment to another.
|
||||||
|
* @param oldParent children of this TaskFragment will be reparented.
|
||||||
|
* @param newParent the new parent TaskFragment to move the children to. If {@code null}, the
|
||||||
|
* children will be moved to the leaf Task.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public WindowContainerTransaction reparentChildren(
|
||||||
|
@NonNull WindowContainerToken oldParent,
|
||||||
|
@Nullable WindowContainerToken newParent) {
|
||||||
|
final HierarchyOp hierarchyOp =
|
||||||
|
new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_CHILDREN)
|
||||||
|
.setContainer(oldParent.asBinder())
|
||||||
|
.setReparentContainer(newParent.asBinder())
|
||||||
|
.build();
|
||||||
|
mHierarchyOps.add(hierarchyOp);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merges another WCT into this one.
|
* Merges another WCT into this one.
|
||||||
* @param transfer When true, this will transfer everything from other potentially leaving
|
* @param transfer When true, this will transfer everything from other potentially leaving
|
||||||
@@ -705,6 +803,11 @@ public final class WindowContainerTransaction implements Parcelable {
|
|||||||
public static final int HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS = 4;
|
public static final int HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS = 4;
|
||||||
public static final int HIERARCHY_OP_TYPE_LAUNCH_TASK = 5;
|
public static final int HIERARCHY_OP_TYPE_LAUNCH_TASK = 5;
|
||||||
public static final int HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT = 6;
|
public static final int HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT = 6;
|
||||||
|
public static final int HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT = 7;
|
||||||
|
public static final int HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT = 8;
|
||||||
|
public static final int HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT = 9;
|
||||||
|
public static final int HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT = 10;
|
||||||
|
public static final int HIERARCHY_OP_TYPE_REPARENT_CHILDREN = 11;
|
||||||
|
|
||||||
// The following key(s) are for use with mLaunchOptions:
|
// The following key(s) are for use with mLaunchOptions:
|
||||||
// When launching a task (eg. from recents), this is the taskId to be launched.
|
// When launching a task (eg. from recents), this is the taskId to be launched.
|
||||||
@@ -732,6 +835,13 @@ public final class WindowContainerTransaction implements Parcelable {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private Bundle mLaunchOptions;
|
private Bundle mLaunchOptions;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Intent mActivityIntent;
|
||||||
|
|
||||||
|
// Used as options for WindowContainerTransaction#createTaskFragment().
|
||||||
|
@Nullable
|
||||||
|
private TaskFragmentCreationParams mTaskFragmentCreationOptions;
|
||||||
|
|
||||||
public static HierarchyOp createForReparent(
|
public static HierarchyOp createForReparent(
|
||||||
@NonNull IBinder container, @Nullable IBinder reparent, boolean toTop) {
|
@NonNull IBinder container, @Nullable IBinder reparent, boolean toTop) {
|
||||||
return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_REPARENT)
|
return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_REPARENT)
|
||||||
@@ -808,6 +918,8 @@ public final class WindowContainerTransaction implements Parcelable {
|
|||||||
mWindowingModes = copy.mWindowingModes;
|
mWindowingModes = copy.mWindowingModes;
|
||||||
mActivityTypes = copy.mActivityTypes;
|
mActivityTypes = copy.mActivityTypes;
|
||||||
mLaunchOptions = copy.mLaunchOptions;
|
mLaunchOptions = copy.mLaunchOptions;
|
||||||
|
mActivityIntent = copy.mActivityIntent;
|
||||||
|
mTaskFragmentCreationOptions = copy.mTaskFragmentCreationOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected HierarchyOp(Parcel in) {
|
protected HierarchyOp(Parcel in) {
|
||||||
@@ -818,6 +930,8 @@ public final class WindowContainerTransaction implements Parcelable {
|
|||||||
mWindowingModes = in.createIntArray();
|
mWindowingModes = in.createIntArray();
|
||||||
mActivityTypes = in.createIntArray();
|
mActivityTypes = in.createIntArray();
|
||||||
mLaunchOptions = in.readBundle();
|
mLaunchOptions = in.readBundle();
|
||||||
|
mActivityIntent = in.readTypedObject(Intent.CREATOR);
|
||||||
|
mTaskFragmentCreationOptions = in.readTypedObject(TaskFragmentCreationParams.CREATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getType() {
|
public int getType() {
|
||||||
@@ -860,6 +974,16 @@ public final class WindowContainerTransaction implements Parcelable {
|
|||||||
return mLaunchOptions;
|
return mLaunchOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Intent getActivityIntent() {
|
||||||
|
return mActivityIntent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public TaskFragmentCreationParams getTaskFragmentCreationOptions() {
|
||||||
|
return mTaskFragmentCreationOptions;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
switch (mType) {
|
switch (mType) {
|
||||||
@@ -884,6 +1008,19 @@ public final class WindowContainerTransaction implements Parcelable {
|
|||||||
case HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT:
|
case HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT:
|
||||||
return "{SetAdjacentFlagRoot: container=" + mContainer + " clearRoot=" + mToTop
|
return "{SetAdjacentFlagRoot: container=" + mContainer + " clearRoot=" + mToTop
|
||||||
+ "}";
|
+ "}";
|
||||||
|
case HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT:
|
||||||
|
return "{CreateTaskFragment: options=" + mTaskFragmentCreationOptions + "}";
|
||||||
|
case HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT:
|
||||||
|
return "{DeleteTaskFragment: taskFragment=" + mContainer + "}";
|
||||||
|
case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT:
|
||||||
|
return "{StartActivityInTaskFragment: fragmentToken=" + mContainer + " intent="
|
||||||
|
+ mActivityIntent + " options=" + mLaunchOptions + "}";
|
||||||
|
case HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT:
|
||||||
|
return "{ReparentActivityToTaskFragment: fragmentToken=" + mReparent
|
||||||
|
+ " activity=" + mContainer + "}";
|
||||||
|
case HIERARCHY_OP_TYPE_REPARENT_CHILDREN:
|
||||||
|
return "{ReparentChildren: oldParent=" + mContainer + " newParent=" + mReparent
|
||||||
|
+ "}";
|
||||||
default:
|
default:
|
||||||
return "{mType=" + mType + " container=" + mContainer + " reparent=" + mReparent
|
return "{mType=" + mType + " container=" + mContainer + " reparent=" + mReparent
|
||||||
+ " mToTop=" + mToTop + " mWindowingMode=" + mWindowingModes
|
+ " mToTop=" + mToTop + " mWindowingMode=" + mWindowingModes
|
||||||
@@ -900,6 +1037,8 @@ public final class WindowContainerTransaction implements Parcelable {
|
|||||||
dest.writeIntArray(mWindowingModes);
|
dest.writeIntArray(mWindowingModes);
|
||||||
dest.writeIntArray(mActivityTypes);
|
dest.writeIntArray(mActivityTypes);
|
||||||
dest.writeBundle(mLaunchOptions);
|
dest.writeBundle(mLaunchOptions);
|
||||||
|
dest.writeTypedObject(mActivityIntent, flags);
|
||||||
|
dest.writeTypedObject(mTaskFragmentCreationOptions, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -940,6 +1079,12 @@ public final class WindowContainerTransaction implements Parcelable {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private Bundle mLaunchOptions;
|
private Bundle mLaunchOptions;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Intent mActivityIntent;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private TaskFragmentCreationParams mTaskFragmentCreationOptions;
|
||||||
|
|
||||||
Builder(int type) {
|
Builder(int type) {
|
||||||
mType = type;
|
mType = type;
|
||||||
}
|
}
|
||||||
@@ -974,6 +1119,17 @@ public final class WindowContainerTransaction implements Parcelable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Builder setActivityIntent(@Nullable Intent activityIntent) {
|
||||||
|
mActivityIntent = activityIntent;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder setTaskFragmentCreationOptions(
|
||||||
|
@Nullable TaskFragmentCreationParams taskFragmentCreationOptions) {
|
||||||
|
mTaskFragmentCreationOptions = taskFragmentCreationOptions;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
HierarchyOp build() {
|
HierarchyOp build() {
|
||||||
final HierarchyOp hierarchyOp = new HierarchyOp(mType);
|
final HierarchyOp hierarchyOp = new HierarchyOp(mType);
|
||||||
hierarchyOp.mContainer = mContainer;
|
hierarchyOp.mContainer = mContainer;
|
||||||
@@ -986,6 +1142,8 @@ public final class WindowContainerTransaction implements Parcelable {
|
|||||||
: null;
|
: null;
|
||||||
hierarchyOp.mToTop = mToTop;
|
hierarchyOp.mToTop = mToTop;
|
||||||
hierarchyOp.mLaunchOptions = mLaunchOptions;
|
hierarchyOp.mLaunchOptions = mLaunchOptions;
|
||||||
|
hierarchyOp.mActivityIntent = mActivityIntent;
|
||||||
|
hierarchyOp.mTaskFragmentCreationOptions = mTaskFragmentCreationOptions;
|
||||||
|
|
||||||
return hierarchyOp;
|
return hierarchyOp;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -721,6 +721,12 @@
|
|||||||
"group": "WM_DEBUG_IME",
|
"group": "WM_DEBUG_IME",
|
||||||
"at": "com\/android\/server\/wm\/WindowState.java"
|
"at": "com\/android\/server\/wm\/WindowState.java"
|
||||||
},
|
},
|
||||||
|
"-1311436264": {
|
||||||
|
"message": "Unregister task fragment organizer=%s uid=%d pid=%d",
|
||||||
|
"level": "VERBOSE",
|
||||||
|
"group": "WM_DEBUG_WINDOW_ORGANIZER",
|
||||||
|
"at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
|
||||||
|
},
|
||||||
"-1305966693": {
|
"-1305966693": {
|
||||||
"message": "Sending position change to %s, onTop: %b",
|
"message": "Sending position change to %s, onTop: %b",
|
||||||
"level": "VERBOSE",
|
"level": "VERBOSE",
|
||||||
@@ -1219,6 +1225,12 @@
|
|||||||
"group": "WM_DEBUG_STATES",
|
"group": "WM_DEBUG_STATES",
|
||||||
"at": "com\/android\/server\/wm\/ActivityRecord.java"
|
"at": "com\/android\/server\/wm\/ActivityRecord.java"
|
||||||
},
|
},
|
||||||
|
"-706481945": {
|
||||||
|
"message": "TaskFragment parent info changed name=%s parentTaskId=%d",
|
||||||
|
"level": "VERBOSE",
|
||||||
|
"group": "WM_DEBUG_WINDOW_ORGANIZER",
|
||||||
|
"at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
|
||||||
|
},
|
||||||
"-705939410": {
|
"-705939410": {
|
||||||
"message": "Waiting for pause to complete...",
|
"message": "Waiting for pause to complete...",
|
||||||
"level": "VERBOSE",
|
"level": "VERBOSE",
|
||||||
@@ -1381,6 +1393,12 @@
|
|||||||
"group": "WM_SHOW_TRANSACTIONS",
|
"group": "WM_SHOW_TRANSACTIONS",
|
||||||
"at": "com\/android\/server\/wm\/WindowAnimator.java"
|
"at": "com\/android\/server\/wm\/WindowAnimator.java"
|
||||||
},
|
},
|
||||||
|
"-542756093": {
|
||||||
|
"message": "TaskFragment vanished name=%s",
|
||||||
|
"level": "VERBOSE",
|
||||||
|
"group": "WM_DEBUG_WINDOW_ORGANIZER",
|
||||||
|
"at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
|
||||||
|
},
|
||||||
"-532081937": {
|
"-532081937": {
|
||||||
"message": " Commit activity becoming invisible: %s",
|
"message": " Commit activity becoming invisible: %s",
|
||||||
"level": "VERBOSE",
|
"level": "VERBOSE",
|
||||||
@@ -2743,6 +2761,12 @@
|
|||||||
"group": "WM_DEBUG_STATES",
|
"group": "WM_DEBUG_STATES",
|
||||||
"at": "com\/android\/server\/wm\/TaskFragment.java"
|
"at": "com\/android\/server\/wm\/TaskFragment.java"
|
||||||
},
|
},
|
||||||
|
"1022095595": {
|
||||||
|
"message": "TaskFragment info changed name=%s",
|
||||||
|
"level": "VERBOSE",
|
||||||
|
"group": "WM_DEBUG_WINDOW_ORGANIZER",
|
||||||
|
"at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
|
||||||
|
},
|
||||||
"1023413388": {
|
"1023413388": {
|
||||||
"message": "Finish waiting for pause of: %s",
|
"message": "Finish waiting for pause of: %s",
|
||||||
"level": "VERBOSE",
|
"level": "VERBOSE",
|
||||||
@@ -2929,6 +2953,12 @@
|
|||||||
"group": "WM_DEBUG_STATES",
|
"group": "WM_DEBUG_STATES",
|
||||||
"at": "com\/android\/server\/wm\/ActivityRecord.java"
|
"at": "com\/android\/server\/wm\/ActivityRecord.java"
|
||||||
},
|
},
|
||||||
|
"1284122013": {
|
||||||
|
"message": "TaskFragment appeared name=%s",
|
||||||
|
"level": "VERBOSE",
|
||||||
|
"group": "WM_DEBUG_WINDOW_ORGANIZER",
|
||||||
|
"at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
|
||||||
|
},
|
||||||
"1288731814": {
|
"1288731814": {
|
||||||
"message": "WindowState.hideLw: setting mFocusMayChange true",
|
"message": "WindowState.hideLw: setting mFocusMayChange true",
|
||||||
"level": "INFO",
|
"level": "INFO",
|
||||||
@@ -3223,6 +3253,12 @@
|
|||||||
"group": "WM_DEBUG_ORIENTATION",
|
"group": "WM_DEBUG_ORIENTATION",
|
||||||
"at": "com\/android\/server\/wm\/DisplayContent.java"
|
"at": "com\/android\/server\/wm\/DisplayContent.java"
|
||||||
},
|
},
|
||||||
|
"1653025361": {
|
||||||
|
"message": "Register task fragment organizer=%s uid=%d pid=%d",
|
||||||
|
"level": "VERBOSE",
|
||||||
|
"group": "WM_DEBUG_WINDOW_ORGANIZER",
|
||||||
|
"at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
|
||||||
|
},
|
||||||
"1653210583": {
|
"1653210583": {
|
||||||
"message": "Removing app %s delayed=%b animation=%s animating=%b",
|
"message": "Removing app %s delayed=%b animation=%s animating=%b",
|
||||||
"level": "VERBOSE",
|
"level": "VERBOSE",
|
||||||
|
|||||||
@@ -602,18 +602,6 @@ class Task extends TaskFragment {
|
|||||||
*/
|
*/
|
||||||
private boolean mForceNotOrganized;
|
private boolean mForceNotOrganized;
|
||||||
|
|
||||||
/**
|
|
||||||
* This task was created by the task organizer which has the following implementations.
|
|
||||||
* <ul>
|
|
||||||
* <lis>The task won't be removed when it is empty. Removal has to be an explicit request
|
|
||||||
* from the task organizer.</li>
|
|
||||||
* <li>Unlike other non-root tasks, it's direct children are visible to the task
|
|
||||||
* organizer for ordering purposes.</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
@VisibleForTesting
|
|
||||||
boolean mCreatedByOrganizer;
|
|
||||||
|
|
||||||
// Tracking cookie for the creation of this task.
|
// Tracking cookie for the creation of this task.
|
||||||
IBinder mLaunchCookie;
|
IBinder mLaunchCookie;
|
||||||
|
|
||||||
@@ -641,7 +629,7 @@ class Task extends TaskFragment {
|
|||||||
IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor,
|
IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor,
|
||||||
boolean _createdByOrganizer, IBinder _launchCookie, boolean _deferTaskAppear,
|
boolean _createdByOrganizer, IBinder _launchCookie, boolean _deferTaskAppear,
|
||||||
boolean _removeWithTaskOrganizer) {
|
boolean _removeWithTaskOrganizer) {
|
||||||
super(atmService);
|
super(atmService, _createdByOrganizer);
|
||||||
|
|
||||||
mTaskId = _taskId;
|
mTaskId = _taskId;
|
||||||
mUserId = _userId;
|
mUserId = _userId;
|
||||||
@@ -693,7 +681,6 @@ class Task extends TaskFragment {
|
|||||||
mHandler = new ActivityTaskHandler(mTaskSupervisor.mLooper);
|
mHandler = new ActivityTaskHandler(mTaskSupervisor.mLooper);
|
||||||
mCurrentUser = mAtmService.mAmInternal.getCurrentUserId();
|
mCurrentUser = mAtmService.mAmInternal.getCurrentUserId();
|
||||||
|
|
||||||
mCreatedByOrganizer = _createdByOrganizer;
|
|
||||||
mLaunchCookie = _launchCookie;
|
mLaunchCookie = _launchCookie;
|
||||||
mDeferTaskAppear = _deferTaskAppear;
|
mDeferTaskAppear = _deferTaskAppear;
|
||||||
mRemoveWithTaskOrganizer = _removeWithTaskOrganizer;
|
mRemoveWithTaskOrganizer = _removeWithTaskOrganizer;
|
||||||
|
|||||||
@@ -74,13 +74,17 @@ import android.app.servertransaction.ClientTransaction;
|
|||||||
import android.app.servertransaction.NewIntentItem;
|
import android.app.servertransaction.NewIntentItem;
|
||||||
import android.app.servertransaction.PauseActivityItem;
|
import android.app.servertransaction.PauseActivityItem;
|
||||||
import android.app.servertransaction.ResumeActivityItem;
|
import android.app.servertransaction.ResumeActivityItem;
|
||||||
|
import android.content.ComponentName;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.proto.ProtoOutputStream;
|
import android.util.proto.ProtoOutputStream;
|
||||||
import android.view.DisplayInfo;
|
import android.view.DisplayInfo;
|
||||||
|
import android.window.ITaskFragmentOrganizer;
|
||||||
|
import android.window.TaskFragmentInfo;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.protolog.common.ProtoLog;
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
@@ -181,6 +185,38 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private ActivityRecord mResumedActivity = null;
|
private ActivityRecord mResumedActivity = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This TaskFragment was created by an organizer which has the following implementations.
|
||||||
|
* <ul>
|
||||||
|
* <li>The TaskFragment won't be removed when it is empty. Removal has to be an explicit
|
||||||
|
* request from the organizer.</li>
|
||||||
|
* <li>If this fragment is a Task object then unlike other non-root tasks, it's direct
|
||||||
|
* children are visible to the organizer for ordering purposes.</li>
|
||||||
|
* <li>A TaskFragment can be created by {@link android.window.TaskFragmentOrganizer}, and
|
||||||
|
* a Task can be created by {@link android.window.TaskOrganizer}.</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
boolean mCreatedByOrganizer;
|
||||||
|
|
||||||
|
/** Organizer that organizing this TaskFragment. */
|
||||||
|
// TODO(b/190433129) set the value when creating TaskFragment from WCT.
|
||||||
|
@Nullable
|
||||||
|
private ITaskFragmentOrganizer mTaskFragmentOrganizer;
|
||||||
|
|
||||||
|
/** Client assigned unique token for this TaskFragment if this is created by an organizer. */
|
||||||
|
// TODO(b/190433129) set the value when creating TaskFragment from WCT.
|
||||||
|
@Nullable
|
||||||
|
private IBinder mFragmentToken;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The component name of the root activity that initiated this TaskFragment, which will be used
|
||||||
|
* to configure the relationships for TaskFragments.
|
||||||
|
*/
|
||||||
|
// TODO(b/190433129) set the value when creating TaskFragment from WCT.
|
||||||
|
@Nullable
|
||||||
|
private ComponentName mInitialComponentName;
|
||||||
|
|
||||||
private final Rect mTmpInsets = new Rect();
|
private final Rect mTmpInsets = new Rect();
|
||||||
private final Rect mTmpBounds = new Rect();
|
private final Rect mTmpBounds = new Rect();
|
||||||
private final Rect mTmpFullBounds = new Rect();
|
private final Rect mTmpFullBounds = new Rect();
|
||||||
@@ -229,12 +265,13 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskFragment(ActivityTaskManagerService atmService) {
|
TaskFragment(ActivityTaskManagerService atmService, boolean createdByOrganizer) {
|
||||||
super(atmService.mWindowManager);
|
super(atmService.mWindowManager);
|
||||||
|
|
||||||
mAtmService = atmService;
|
mAtmService = atmService;
|
||||||
mTaskSupervisor = atmService.mTaskSupervisor;
|
mTaskSupervisor = atmService.mTaskSupervisor;
|
||||||
mRootWindowContainer = mAtmService.mRootWindowContainer;
|
mRootWindowContainer = mAtmService.mRootWindowContainer;
|
||||||
|
mCreatedByOrganizer = createdByOrganizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setAdjacentTaskFragment(TaskFragment taskFragment) {
|
void setAdjacentTaskFragment(TaskFragment taskFragment) {
|
||||||
@@ -1900,6 +1937,25 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|
|||||||
return getTopChild().getActivityType();
|
return getTopChild().getActivityType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@link TaskFragmentInfo} with information from this TaskFragment. Should not be
|
||||||
|
* called from {@link Task}.
|
||||||
|
*/
|
||||||
|
TaskFragmentInfo getTaskFragmentInfo() {
|
||||||
|
return new TaskFragmentInfo(
|
||||||
|
mFragmentToken,
|
||||||
|
mInitialComponentName,
|
||||||
|
mRemoteToken.toWindowContainerToken(),
|
||||||
|
getConfiguration(),
|
||||||
|
getChildCount() == 0,
|
||||||
|
isVisible());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
IBinder getFragmentToken() {
|
||||||
|
return mFragmentToken;
|
||||||
|
}
|
||||||
|
|
||||||
boolean dump(String prefix, FileDescriptor fd, PrintWriter pw, boolean dumpAll,
|
boolean dump(String prefix, FileDescriptor fd, PrintWriter pw, boolean dumpAll,
|
||||||
boolean dumpClient, String dumpPackage, final boolean needSep, Runnable header) {
|
boolean dumpClient, String dumpPackage, final boolean needSep, Runnable header) {
|
||||||
boolean printed = false;
|
boolean printed = false;
|
||||||
|
|||||||
@@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.server.wm;
|
||||||
|
|
||||||
|
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER;
|
||||||
|
|
||||||
|
import android.os.Binder;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.util.ArrayMap;
|
||||||
|
import android.util.ArraySet;
|
||||||
|
import android.view.SurfaceControl;
|
||||||
|
import android.window.ITaskFragmentOrganizer;
|
||||||
|
import android.window.ITaskFragmentOrganizerController;
|
||||||
|
import android.window.TaskFragmentAppearedInfo;
|
||||||
|
|
||||||
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores and manages the client {@link android.window.TaskFragmentOrganizer}.
|
||||||
|
*/
|
||||||
|
public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerController.Stub {
|
||||||
|
private static final String TAG = "TaskFragmentOrganizerController";
|
||||||
|
|
||||||
|
private final ActivityTaskManagerService mAtmService;
|
||||||
|
private final WindowManagerGlobalLock mGlobalLock;
|
||||||
|
private final Set<ITaskFragmentOrganizer> mOrganizers = new ArraySet<>();
|
||||||
|
private final Map<ITaskFragmentOrganizer, DeathRecipient> mDeathRecipients = new ArrayMap<>();
|
||||||
|
|
||||||
|
private class DeathRecipient implements IBinder.DeathRecipient {
|
||||||
|
final ITaskFragmentOrganizer mOrganizer;
|
||||||
|
|
||||||
|
DeathRecipient(ITaskFragmentOrganizer organizer) {
|
||||||
|
mOrganizer = organizer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void binderDied() {
|
||||||
|
removeOrganizer(mOrganizer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskFragmentOrganizerController(ActivityTaskManagerService atm) {
|
||||||
|
mAtmService = atm;
|
||||||
|
mGlobalLock = atm.mGlobalLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerOrganizer(ITaskFragmentOrganizer organizer) {
|
||||||
|
final int pid = Binder.getCallingPid();
|
||||||
|
final long uid = Binder.getCallingUid();
|
||||||
|
final long origId = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
synchronized (mGlobalLock) {
|
||||||
|
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER,
|
||||||
|
"Register task fragment organizer=%s uid=%d pid=%d",
|
||||||
|
organizer.asBinder(), uid, pid);
|
||||||
|
if (mOrganizers.contains(organizer)) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Replacing existing organizer currently unsupported");
|
||||||
|
}
|
||||||
|
|
||||||
|
final DeathRecipient dr = new DeathRecipient(organizer);
|
||||||
|
try {
|
||||||
|
organizer.asBinder().linkToDeath(dr, 0);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
// Oh well...
|
||||||
|
}
|
||||||
|
|
||||||
|
mOrganizers.add(organizer);
|
||||||
|
mDeathRecipients.put(organizer, dr);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(origId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unregisterOrganizer(ITaskFragmentOrganizer organizer) {
|
||||||
|
final int pid = Binder.getCallingPid();
|
||||||
|
final long uid = Binder.getCallingUid();
|
||||||
|
final long origId = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
synchronized (mGlobalLock) {
|
||||||
|
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER,
|
||||||
|
"Unregister task fragment organizer=%s uid=%d pid=%d",
|
||||||
|
organizer.asBinder(), uid, pid);
|
||||||
|
if (!mOrganizers.contains(organizer)) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"The task fragment organizer hasn't been registered.");
|
||||||
|
}
|
||||||
|
|
||||||
|
final DeathRecipient dr = mDeathRecipients.get(organizer);
|
||||||
|
organizer.asBinder().unlinkToDeath(dr, 0);
|
||||||
|
|
||||||
|
removeOrganizer(organizer);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(origId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onTaskFragmentAppeared(ITaskFragmentOrganizer organizer, TaskFragment tf) {
|
||||||
|
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment appeared name=%s", tf.getName());
|
||||||
|
try {
|
||||||
|
final SurfaceControl outSurfaceControl = new SurfaceControl(tf.getSurfaceControl(),
|
||||||
|
"TaskFragmentOrganizerController.onTaskFragmentInfoAppeared");
|
||||||
|
organizer.onTaskFragmentAppeared(
|
||||||
|
new TaskFragmentAppearedInfo(tf.getTaskFragmentInfo(), outSurfaceControl));
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
// Oh well...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onTaskFragmentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment tf) {
|
||||||
|
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment info changed name=%s", tf.getName());
|
||||||
|
try {
|
||||||
|
organizer.onTaskFragmentInfoChanged(tf.getTaskFragmentInfo());
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
// Oh well...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onTaskFragmentVanished(ITaskFragmentOrganizer organizer, TaskFragment tf) {
|
||||||
|
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment vanished name=%s", tf.getName());
|
||||||
|
try {
|
||||||
|
organizer.onTaskFragmentVanished(tf.getTaskFragmentInfo());
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
// Oh well...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onTaskFragmentParentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment tf) {
|
||||||
|
final Task parent = tf.getParent().asTask();
|
||||||
|
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER,
|
||||||
|
"TaskFragment parent info changed name=%s parentTaskId=%d",
|
||||||
|
tf.getName(), parent.mTaskId);
|
||||||
|
try {
|
||||||
|
organizer.onTaskFragmentParentInfoChanged(
|
||||||
|
tf.getFragmentToken(), parent.getConfiguration());
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
// Oh well...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeOrganizer(ITaskFragmentOrganizer organizer) {
|
||||||
|
synchronized (mGlobalLock) {
|
||||||
|
mOrganizers.remove(organizer);
|
||||||
|
mDeathRecipients.remove(organizer);
|
||||||
|
}
|
||||||
|
// TODO(b/190432728) move child activities of organized TaskFragment to leaf Task
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,12 +17,17 @@
|
|||||||
package com.android.server.wm;
|
package com.android.server.wm;
|
||||||
|
|
||||||
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT;
|
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT;
|
||||||
|
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT;
|
||||||
|
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT;
|
||||||
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_LAUNCH_TASK;
|
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_LAUNCH_TASK;
|
||||||
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER;
|
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER;
|
||||||
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT;
|
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT;
|
||||||
|
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
|
||||||
|
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_CHILDREN;
|
||||||
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS;
|
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS;
|
||||||
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT;
|
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT;
|
||||||
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT;
|
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT;
|
||||||
|
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
|
||||||
|
|
||||||
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER;
|
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER;
|
||||||
import static com.android.server.wm.ActivityTaskManagerService.LAYOUT_REASON_CONFIG_CHANGED;
|
import static com.android.server.wm.ActivityTaskManagerService.LAYOUT_REASON_CONFIG_CHANGED;
|
||||||
@@ -34,6 +39,7 @@ import static com.android.server.wm.WindowContainer.POSITION_TOP;
|
|||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.app.WindowConfiguration;
|
import android.app.WindowConfiguration;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
@@ -46,10 +52,12 @@ import android.util.ArraySet;
|
|||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
import android.window.IDisplayAreaOrganizerController;
|
import android.window.IDisplayAreaOrganizerController;
|
||||||
|
import android.window.ITaskFragmentOrganizerController;
|
||||||
import android.window.ITaskOrganizerController;
|
import android.window.ITaskOrganizerController;
|
||||||
import android.window.ITransitionPlayer;
|
import android.window.ITransitionPlayer;
|
||||||
import android.window.IWindowContainerTransactionCallback;
|
import android.window.IWindowContainerTransactionCallback;
|
||||||
import android.window.IWindowOrganizerController;
|
import android.window.IWindowOrganizerController;
|
||||||
|
import android.window.TaskFragmentCreationParams;
|
||||||
import android.window.WindowContainerTransaction;
|
import android.window.WindowContainerTransaction;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
@@ -95,6 +103,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
|
|
||||||
final TaskOrganizerController mTaskOrganizerController;
|
final TaskOrganizerController mTaskOrganizerController;
|
||||||
final DisplayAreaOrganizerController mDisplayAreaOrganizerController;
|
final DisplayAreaOrganizerController mDisplayAreaOrganizerController;
|
||||||
|
final TaskFragmentOrganizerController mTaskFragmentOrganizerController;
|
||||||
|
|
||||||
final TransitionController mTransitionController;
|
final TransitionController mTransitionController;
|
||||||
|
|
||||||
@@ -103,6 +112,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
mGlobalLock = atm.mGlobalLock;
|
mGlobalLock = atm.mGlobalLock;
|
||||||
mTaskOrganizerController = new TaskOrganizerController(mService);
|
mTaskOrganizerController = new TaskOrganizerController(mService);
|
||||||
mDisplayAreaOrganizerController = new DisplayAreaOrganizerController(mService);
|
mDisplayAreaOrganizerController = new DisplayAreaOrganizerController(mService);
|
||||||
|
mTaskFragmentOrganizerController = new TaskFragmentOrganizerController(atm);
|
||||||
mTransitionController = new TransitionController(atm);
|
mTransitionController = new TransitionController(atm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -501,13 +511,15 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
return effects;
|
return effects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final WindowContainer wc;
|
||||||
|
final IBinder fragmentToken;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT:
|
case HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT:
|
||||||
effects |= reparentChildrenTasksHierarchyOp(hop, transition, syncId);
|
effects |= reparentChildrenTasksHierarchyOp(hop, transition, syncId);
|
||||||
break;
|
break;
|
||||||
case HIERARCHY_OP_TYPE_REORDER:
|
case HIERARCHY_OP_TYPE_REORDER:
|
||||||
case HIERARCHY_OP_TYPE_REPARENT:
|
case HIERARCHY_OP_TYPE_REPARENT:
|
||||||
final WindowContainer wc = WindowContainer.fromBinder(hop.getContainer());
|
wc = WindowContainer.fromBinder(hop.getContainer());
|
||||||
if (wc == null || !wc.isAttached()) {
|
if (wc == null || !wc.isAttached()) {
|
||||||
Slog.e(TAG, "Attempt to operate on detached container: " + wc);
|
Slog.e(TAG, "Attempt to operate on detached container: " + wc);
|
||||||
break;
|
break;
|
||||||
@@ -543,6 +555,40 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
launchOpts.remove(WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID);
|
launchOpts.remove(WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID);
|
||||||
mService.startActivityFromRecents(taskId, launchOpts);
|
mService.startActivityFromRecents(taskId, launchOpts);
|
||||||
break;
|
break;
|
||||||
|
case HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT:
|
||||||
|
final TaskFragmentCreationParams taskFragmentCreationOptions =
|
||||||
|
hop.getTaskFragmentCreationOptions();
|
||||||
|
// TODO(b/190433129) add actual implementation on WM Core
|
||||||
|
break;
|
||||||
|
case HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT:
|
||||||
|
wc = WindowContainer.fromBinder(hop.getContainer());
|
||||||
|
if (wc == null || !wc.isAttached()) {
|
||||||
|
Slog.e(TAG, "Attempt to operate on detached container: " + wc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
final TaskFragment taskFragment = wc.asTaskFragment();
|
||||||
|
if (taskFragment == null || taskFragment.asTask() != null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Can only delete organized TaskFragment, but not Task.");
|
||||||
|
}
|
||||||
|
// TODO(b/190433129) add actual implementation on WM Core
|
||||||
|
break;
|
||||||
|
case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT:
|
||||||
|
fragmentToken = hop.getContainer();
|
||||||
|
final Intent activityIntent = hop.getActivityIntent();
|
||||||
|
final Bundle activityOptions = hop.getLaunchOptions();
|
||||||
|
// TODO(b/190433129) add actual implementation on WM Core
|
||||||
|
break;
|
||||||
|
case HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT:
|
||||||
|
fragmentToken = hop.getNewParent();
|
||||||
|
final ActivityRecord activity = ActivityRecord.forTokenLocked(hop.getContainer());
|
||||||
|
// TODO(b/190433129) add actual implementation on WM Core
|
||||||
|
break;
|
||||||
|
case HIERARCHY_OP_TYPE_REPARENT_CHILDREN:
|
||||||
|
final WindowContainer oldParent = WindowContainer.fromBinder(hop.getContainer());
|
||||||
|
final WindowContainer newParent = WindowContainer.fromBinder(hop.getNewParent());
|
||||||
|
// TODO(b/190433129) add actual implementation on WM Core
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return effects;
|
return effects;
|
||||||
}
|
}
|
||||||
@@ -704,8 +750,9 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int setAdjacentRootsHierarchyOp(WindowContainerTransaction.HierarchyOp hop) {
|
private int setAdjacentRootsHierarchyOp(WindowContainerTransaction.HierarchyOp hop) {
|
||||||
final Task root1 = WindowContainer.fromBinder(hop.getContainer()).asTask();
|
final TaskFragment root1 = WindowContainer.fromBinder(hop.getContainer()).asTaskFragment();
|
||||||
final Task root2 = WindowContainer.fromBinder(hop.getAdjacentRoot()).asTask();
|
final TaskFragment root2 =
|
||||||
|
WindowContainer.fromBinder(hop.getAdjacentRoot()).asTaskFragment();
|
||||||
if (!root1.mCreatedByOrganizer || !root2.mCreatedByOrganizer) {
|
if (!root1.mCreatedByOrganizer || !root2.mCreatedByOrganizer) {
|
||||||
throw new IllegalArgumentException("setAdjacentRootsHierarchyOp: Not created by"
|
throw new IllegalArgumentException("setAdjacentRootsHierarchyOp: Not created by"
|
||||||
+ " organizer root1=" + root1 + " root2=" + root2);
|
+ " organizer root1=" + root1 + " root2=" + root2);
|
||||||
@@ -747,6 +794,11 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
return mDisplayAreaOrganizerController;
|
return mDisplayAreaOrganizerController;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ITaskFragmentOrganizerController getTaskFragmentOrganizerController() {
|
||||||
|
return mTaskFragmentOrganizerController;
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
int startSyncWithOrganizer(IWindowContainerTransactionCallback callback) {
|
int startSyncWithOrganizer(IWindowContainerTransactionCallback callback) {
|
||||||
int id = mService.mWindowManager.mSyncEngine.startSyncSet(this);
|
int id = mService.mWindowManager.mSyncEngine.startSyncSet(this);
|
||||||
|
|||||||
Reference in New Issue
Block a user