1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.window;
18 
19 import static android.app.WindowConfiguration.WindowingMode;
20 
21 import static java.util.Objects.requireNonNull;
22 
23 import android.annotation.NonNull;
24 import android.annotation.Nullable;
25 import android.annotation.TestApi;
26 import android.content.res.Configuration;
27 import android.graphics.Point;
28 import android.os.IBinder;
29 import android.os.Parcel;
30 import android.os.Parcelable;
31 
32 import java.util.ArrayList;
33 import java.util.List;
34 
35 /**
36  * Stores information about a particular TaskFragment.
37  * @hide
38  */
39 @TestApi
40 public final class TaskFragmentInfo implements Parcelable {
41 
42     /**
43      * Client assigned unique token in {@link TaskFragmentCreationParams#getFragmentToken()} to
44      * create this TaskFragment with.
45      */
46     @NonNull
47     private final IBinder mFragmentToken;
48 
49     @NonNull
50     private final WindowContainerToken mToken;
51 
52     @NonNull
53     private final Configuration mConfiguration = new Configuration();
54 
55     /** Whether the TaskFragment contains any child Window Container. */
56     private final boolean mIsEmpty;
57 
58     /** The number of the running activities in the TaskFragment. */
59     private final int mRunningActivityCount;
60 
61     /** Whether this TaskFragment is visible on the window hierarchy. */
62     private final boolean mIsVisible;
63 
64     /**
65      * List of Activity tokens that are children of this TaskFragment. It only contains Activities
66      * that belong to the organizer process for security.
67      */
68     @NonNull
69     private final List<IBinder> mActivities = new ArrayList<>();
70 
71     /** Relative position of the fragment's top left corner in the parent container. */
72     private final Point mPositionInParent;
73 
74     /**
75      * Whether the last running activity in the TaskFragment was finished due to clearing task while
76      * launching an activity in the host Task.
77      */
78     private final boolean mIsTaskClearedForReuse;
79 
80     /** @hide */
TaskFragmentInfo( @onNull IBinder fragmentToken, @NonNull WindowContainerToken token, @NonNull Configuration configuration, boolean isEmpty, int runningActivityCount, boolean isVisible, @NonNull List<IBinder> activities, @NonNull Point positionInParent, boolean isTaskClearedForReuse)81     public TaskFragmentInfo(
82             @NonNull IBinder fragmentToken, @NonNull WindowContainerToken token,
83             @NonNull Configuration configuration, boolean isEmpty, int runningActivityCount,
84             boolean isVisible, @NonNull List<IBinder> activities, @NonNull Point positionInParent,
85             boolean isTaskClearedForReuse) {
86         mFragmentToken = requireNonNull(fragmentToken);
87         mToken = requireNonNull(token);
88         mConfiguration.setTo(configuration);
89         mIsEmpty = isEmpty;
90         mRunningActivityCount = runningActivityCount;
91         mIsVisible = isVisible;
92         mActivities.addAll(activities);
93         mPositionInParent = requireNonNull(positionInParent);
94         mIsTaskClearedForReuse = isTaskClearedForReuse;
95     }
96 
97     @NonNull
getFragmentToken()98     public IBinder getFragmentToken() {
99         return mFragmentToken;
100     }
101 
102     @NonNull
getToken()103     public WindowContainerToken getToken() {
104         return mToken;
105     }
106 
107     @NonNull
getConfiguration()108     public Configuration getConfiguration() {
109         return mConfiguration;
110     }
111 
isEmpty()112     public boolean isEmpty() {
113         return mIsEmpty;
114     }
115 
hasRunningActivity()116     public boolean hasRunningActivity() {
117         return mRunningActivityCount > 0;
118     }
119 
getRunningActivityCount()120     public int getRunningActivityCount() {
121         return mRunningActivityCount;
122     }
123 
isVisible()124     public boolean isVisible() {
125         return mIsVisible;
126     }
127 
128     @NonNull
getActivities()129     public List<IBinder> getActivities() {
130         return mActivities;
131     }
132 
133     /** Returns the relative position of the fragment's top left corner in the parent container. */
134     @NonNull
getPositionInParent()135     public Point getPositionInParent() {
136         return mPositionInParent;
137     }
138 
isTaskClearedForReuse()139     public boolean isTaskClearedForReuse() {
140         return mIsTaskClearedForReuse;
141     }
142 
143     @WindowingMode
getWindowingMode()144     public int getWindowingMode() {
145         return mConfiguration.windowConfiguration.getWindowingMode();
146     }
147 
148     /**
149      * Returns {@code true} if the parameters that are important for task fragment organizers are
150      * equal between this {@link TaskFragmentInfo} and {@param that}.
151      */
equalsForTaskFragmentOrganizer(@ullable TaskFragmentInfo that)152     public boolean equalsForTaskFragmentOrganizer(@Nullable TaskFragmentInfo that) {
153         if (that == null) {
154             return false;
155         }
156 
157         return mFragmentToken.equals(that.mFragmentToken)
158                 && mToken.equals(that.mToken)
159                 && mIsEmpty == that.mIsEmpty
160                 && mRunningActivityCount == that.mRunningActivityCount
161                 && mIsVisible == that.mIsVisible
162                 && getWindowingMode() == that.getWindowingMode()
163                 && mActivities.equals(that.mActivities)
164                 && mPositionInParent.equals(that.mPositionInParent)
165                 && mIsTaskClearedForReuse == that.mIsTaskClearedForReuse;
166     }
167 
TaskFragmentInfo(Parcel in)168     private TaskFragmentInfo(Parcel in) {
169         mFragmentToken = in.readStrongBinder();
170         mToken = in.readTypedObject(WindowContainerToken.CREATOR);
171         mConfiguration.readFromParcel(in);
172         mIsEmpty = in.readBoolean();
173         mRunningActivityCount = in.readInt();
174         mIsVisible = in.readBoolean();
175         in.readBinderList(mActivities);
176         mPositionInParent = requireNonNull(in.readTypedObject(Point.CREATOR));
177         mIsTaskClearedForReuse = in.readBoolean();
178     }
179 
180     /** @hide */
181     @Override
writeToParcel(@onNull Parcel dest, int flags)182     public void writeToParcel(@NonNull Parcel dest, int flags) {
183         dest.writeStrongBinder(mFragmentToken);
184         dest.writeTypedObject(mToken, flags);
185         mConfiguration.writeToParcel(dest, flags);
186         dest.writeBoolean(mIsEmpty);
187         dest.writeInt(mRunningActivityCount);
188         dest.writeBoolean(mIsVisible);
189         dest.writeBinderList(mActivities);
190         dest.writeTypedObject(mPositionInParent, flags);
191         dest.writeBoolean(mIsTaskClearedForReuse);
192     }
193 
194     @NonNull
195     public static final Creator<TaskFragmentInfo> CREATOR =
196             new Creator<TaskFragmentInfo>() {
197                 @Override
198                 public TaskFragmentInfo createFromParcel(Parcel in) {
199                     return new TaskFragmentInfo(in);
200                 }
201 
202                 @Override
203                 public TaskFragmentInfo[] newArray(int size) {
204                     return new TaskFragmentInfo[size];
205                 }
206             };
207 
208     @Override
toString()209     public String toString() {
210         return "TaskFragmentInfo{"
211                 + " fragmentToken=" + mFragmentToken
212                 + " token=" + mToken
213                 + " isEmpty=" + mIsEmpty
214                 + " runningActivityCount=" + mRunningActivityCount
215                 + " isVisible=" + mIsVisible
216                 + " activities=" + mActivities
217                 + " positionInParent=" + mPositionInParent
218                 + " isTaskClearedForReuse=" + mIsTaskClearedForReuse
219                 + "}";
220     }
221 
222     /** @hide */
223     @Override
describeContents()224     public int describeContents() {
225         return 0;
226     }
227 }
228