• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.graphics.Rect;
29 import android.os.IBinder;
30 import android.os.Parcel;
31 import android.os.Parcelable;
32 
33 import java.util.ArrayList;
34 import java.util.List;
35 
36 /**
37  * Stores information about a particular TaskFragment.
38  * @hide
39  */
40 @TestApi
41 public final class TaskFragmentInfo implements Parcelable {
42 
43     /**
44      * Client assigned unique token in {@link TaskFragmentCreationParams#getFragmentToken()} to
45      * create this TaskFragment with.
46      */
47     @NonNull
48     private final IBinder mFragmentToken;
49 
50     @NonNull
51     private final WindowContainerToken mToken;
52 
53     @NonNull
54     private final Configuration mConfiguration = new Configuration();
55 
56     /** The number of the running activities in the TaskFragment. */
57     private final int mRunningActivityCount;
58 
59     /** Whether this TaskFragment is visible on the window hierarchy. */
60     private final boolean mIsVisible;
61 
62     /**
63      * List of Activity tokens that are children of this TaskFragment. It only contains Activities
64      * that belong to the organizer process for security.
65      */
66     @NonNull
67     private final List<IBinder> mActivities = new ArrayList<>();
68 
69     /**
70      * List of Activity tokens that were explicitly requested to be launched in this TaskFragment.
71      * It only contains Activities that belong to the organizer process for security.
72      */
73     @NonNull
74     private final List<IBinder> mInRequestedTaskFragmentActivities = new ArrayList<>();
75 
76     /** Relative position of the fragment's top left corner in the parent container. */
77     private final Point mPositionInParent = new Point();
78 
79     /**
80      * Whether the last running activity in the TaskFragment was finished due to clearing task while
81      * launching an activity in the host Task.
82      */
83     private final boolean mIsTaskClearedForReuse;
84 
85     /**
86      * Whether the last running activity in the TaskFragment was reparented to a different Task
87      * because it is entering PiP.
88      */
89     private final boolean mIsTaskFragmentClearedForPip;
90 
91     /**
92      * Whether the last running activity of the TaskFragment was removed because it was reordered to
93      * front of the Task.
94      */
95     private final boolean mIsClearedForReorderActivityToFront;
96 
97     /**
98      * The maximum {@link android.content.pm.ActivityInfo.WindowLayout#minWidth} and
99      * {@link android.content.pm.ActivityInfo.WindowLayout#minHeight} aggregated from the
100      * TaskFragment's child activities.
101      */
102     @NonNull
103     private final Point mMinimumDimensions = new Point();
104 
105     private final boolean mIsTopNonFishingChild;
106 
107     /** @hide */
TaskFragmentInfo( @onNull IBinder fragmentToken, @NonNull WindowContainerToken token, @NonNull Configuration configuration, int runningActivityCount, boolean isVisible, @NonNull List<IBinder> activities, @NonNull List<IBinder> inRequestedTaskFragmentActivities, @NonNull Point positionInParent, boolean isTaskClearedForReuse, boolean isTaskFragmentClearedForPip, boolean isClearedForReorderActivityToFront, @NonNull Point minimumDimensions, boolean isTopNonFinishingChild)108     public TaskFragmentInfo(
109             @NonNull IBinder fragmentToken, @NonNull WindowContainerToken token,
110             @NonNull Configuration configuration, int runningActivityCount,
111             boolean isVisible, @NonNull List<IBinder> activities,
112             @NonNull List<IBinder> inRequestedTaskFragmentActivities,
113             @NonNull Point positionInParent, boolean isTaskClearedForReuse,
114             boolean isTaskFragmentClearedForPip, boolean isClearedForReorderActivityToFront,
115             @NonNull Point minimumDimensions, boolean isTopNonFinishingChild) {
116         mFragmentToken = requireNonNull(fragmentToken);
117         mToken = requireNonNull(token);
118         mConfiguration.setTo(configuration);
119         mRunningActivityCount = runningActivityCount;
120         mIsVisible = isVisible;
121         mActivities.addAll(activities);
122         mInRequestedTaskFragmentActivities.addAll(inRequestedTaskFragmentActivities);
123         mPositionInParent.set(positionInParent);
124         mIsTaskClearedForReuse = isTaskClearedForReuse;
125         mIsTaskFragmentClearedForPip = isTaskFragmentClearedForPip;
126         mIsClearedForReorderActivityToFront = isClearedForReorderActivityToFront;
127         mMinimumDimensions.set(minimumDimensions);
128         mIsTopNonFishingChild = isTopNonFinishingChild;
129     }
130 
131     @NonNull
getFragmentToken()132     public IBinder getFragmentToken() {
133         return mFragmentToken;
134     }
135 
136     @NonNull
getToken()137     public WindowContainerToken getToken() {
138         return mToken;
139     }
140 
141     @NonNull
getConfiguration()142     public Configuration getConfiguration() {
143         return mConfiguration;
144     }
145 
isEmpty()146     public boolean isEmpty() {
147         return mRunningActivityCount == 0;
148     }
149 
hasRunningActivity()150     public boolean hasRunningActivity() {
151         return mRunningActivityCount > 0;
152     }
153 
getRunningActivityCount()154     public int getRunningActivityCount() {
155         return mRunningActivityCount;
156     }
157 
isVisible()158     public boolean isVisible() {
159         return mIsVisible;
160     }
161 
162     @NonNull
getActivities()163     public List<IBinder> getActivities() {
164         return mActivities;
165     }
166 
167     @NonNull
getActivitiesRequestedInTaskFragment()168     public List<IBinder> getActivitiesRequestedInTaskFragment() {
169         return mInRequestedTaskFragmentActivities;
170     }
171 
172     /** Returns the relative position of the fragment's top left corner in the parent container. */
173     @NonNull
getPositionInParent()174     public Point getPositionInParent() {
175         return mPositionInParent;
176     }
177 
isTaskClearedForReuse()178     public boolean isTaskClearedForReuse() {
179         return mIsTaskClearedForReuse;
180     }
181 
182     /** @hide */
isTaskFragmentClearedForPip()183     public boolean isTaskFragmentClearedForPip() {
184         return mIsTaskFragmentClearedForPip;
185     }
186 
187     /** @hide */
isClearedForReorderActivityToFront()188     public boolean isClearedForReorderActivityToFront() {
189         return mIsClearedForReorderActivityToFront;
190     }
191 
192     @WindowingMode
getWindowingMode()193     public int getWindowingMode() {
194         return mConfiguration.windowConfiguration.getWindowingMode();
195     }
196 
197     /**
198      * Returns the minimum width this TaskFragment can be resized to.
199      * Client side must not {@link WindowContainerTransaction#setRelativeBounds}
200      * that {@link Rect#width()} is shorter than the reported value.
201      * @hide pending unhide
202      */
getMinimumWidth()203     public int getMinimumWidth() {
204         return mMinimumDimensions.x;
205     }
206 
207     /**
208      * Returns the minimum width this TaskFragment can be resized to.
209      * Client side must not {@link WindowContainerTransaction#setRelativeBounds}
210      * that {@link Rect#height()} is shorter than the reported value.
211      * @hide pending unhide
212      */
getMinimumHeight()213     public int getMinimumHeight() {
214         return mMinimumDimensions.y;
215     }
216 
217     /**
218      * Indicates that this TaskFragment is the top non-finishing child of its parent container
219      * among all Activities and TaskFragment siblings.
220      *
221      * @hide
222      */
isTopNonFinishingChild()223     public boolean isTopNonFinishingChild() {
224         return mIsTopNonFishingChild;
225     }
226 
227     /**
228      * Returns {@code true} if the parameters that are important for task fragment organizers are
229      * equal between this {@link TaskFragmentInfo} and {@param that}.
230      * Note that this method is usually called with
231      * {@link com.android.server.wm.WindowOrganizerController#configurationsAreEqualForOrganizer(
232      * Configuration, Configuration)} to determine if this {@link TaskFragmentInfo} should
233      * be dispatched to the client.
234      */
equalsForTaskFragmentOrganizer(@ullable TaskFragmentInfo that)235     public boolean equalsForTaskFragmentOrganizer(@Nullable TaskFragmentInfo that) {
236         if (that == null) {
237             return false;
238         }
239 
240         return mFragmentToken.equals(that.mFragmentToken)
241                 && mToken.equals(that.mToken)
242                 && mRunningActivityCount == that.mRunningActivityCount
243                 && mIsVisible == that.mIsVisible
244                 && getWindowingMode() == that.getWindowingMode()
245                 && mActivities.equals(that.mActivities)
246                 && mInRequestedTaskFragmentActivities.equals(
247                         that.mInRequestedTaskFragmentActivities)
248                 && mPositionInParent.equals(that.mPositionInParent)
249                 && mIsTaskClearedForReuse == that.mIsTaskClearedForReuse
250                 && mIsTaskFragmentClearedForPip == that.mIsTaskFragmentClearedForPip
251                 && mIsClearedForReorderActivityToFront == that.mIsClearedForReorderActivityToFront
252                 && mMinimumDimensions.equals(that.mMinimumDimensions)
253                 && mIsTopNonFishingChild == that.mIsTopNonFishingChild;
254     }
255 
TaskFragmentInfo(Parcel in)256     private TaskFragmentInfo(Parcel in) {
257         mFragmentToken = in.readStrongBinder();
258         mToken = in.readTypedObject(WindowContainerToken.CREATOR);
259         mConfiguration.readFromParcel(in);
260         mRunningActivityCount = in.readInt();
261         mIsVisible = in.readBoolean();
262         in.readBinderList(mActivities);
263         in.readBinderList(mInRequestedTaskFragmentActivities);
264         mPositionInParent.readFromParcel(in);
265         mIsTaskClearedForReuse = in.readBoolean();
266         mIsTaskFragmentClearedForPip = in.readBoolean();
267         mIsClearedForReorderActivityToFront = in.readBoolean();
268         mMinimumDimensions.readFromParcel(in);
269         mIsTopNonFishingChild = in.readBoolean();
270     }
271 
272     /** @hide */
273     @Override
writeToParcel(@onNull Parcel dest, int flags)274     public void writeToParcel(@NonNull Parcel dest, int flags) {
275         dest.writeStrongBinder(mFragmentToken);
276         dest.writeTypedObject(mToken, flags);
277         mConfiguration.writeToParcel(dest, flags);
278         dest.writeInt(mRunningActivityCount);
279         dest.writeBoolean(mIsVisible);
280         dest.writeBinderList(mActivities);
281         dest.writeBinderList(mInRequestedTaskFragmentActivities);
282         mPositionInParent.writeToParcel(dest, flags);
283         dest.writeBoolean(mIsTaskClearedForReuse);
284         dest.writeBoolean(mIsTaskFragmentClearedForPip);
285         dest.writeBoolean(mIsClearedForReorderActivityToFront);
286         mMinimumDimensions.writeToParcel(dest, flags);
287         dest.writeBoolean(mIsTopNonFishingChild);
288     }
289 
290     @NonNull
291     public static final Creator<TaskFragmentInfo> CREATOR =
292             new Creator<TaskFragmentInfo>() {
293                 @Override
294                 public TaskFragmentInfo createFromParcel(Parcel in) {
295                     return new TaskFragmentInfo(in);
296                 }
297 
298                 @Override
299                 public TaskFragmentInfo[] newArray(int size) {
300                     return new TaskFragmentInfo[size];
301                 }
302             };
303 
304     @Override
toString()305     public String toString() {
306         return "TaskFragmentInfo{"
307                 + " fragmentToken=" + mFragmentToken
308                 + " token=" + mToken
309                 + " runningActivityCount=" + mRunningActivityCount
310                 + " isVisible=" + mIsVisible
311                 + " activities=" + mActivities
312                 + " inRequestedTaskFragmentActivities" + mInRequestedTaskFragmentActivities
313                 + " positionInParent=" + mPositionInParent
314                 + " isTaskClearedForReuse=" + mIsTaskClearedForReuse
315                 + " isTaskFragmentClearedForPip=" + mIsTaskFragmentClearedForPip
316                 + " mIsClearedForReorderActivityToFront=" + mIsClearedForReorderActivityToFront
317                 + " minimumDimensions=" + mMinimumDimensions
318                 + " isTopNonFinishingChild=" + mIsTopNonFishingChild
319                 + "}";
320     }
321 
322     /** @hide */
323     @Override
describeContents()324     public int describeContents() {
325         return 0;
326     }
327 }
328