• 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.WINDOWING_MODE_UNDEFINED;
20 import static android.app.WindowConfiguration.WindowingMode;
21 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
22 
23 import android.annotation.NonNull;
24 import android.annotation.Nullable;
25 import android.annotation.RequiresPermission;
26 import android.annotation.TestApi;
27 import android.content.pm.ActivityInfo.ScreenOrientation;
28 import android.graphics.Rect;
29 import android.os.IBinder;
30 import android.os.Parcel;
31 import android.os.Parcelable;
32 
33 /**
34  * Data object for options to create TaskFragment with.
35  * @hide
36  */
37 @TestApi
38 public final class TaskFragmentCreationParams implements Parcelable {
39 
40     /** The organizer that will organize this TaskFragment. */
41     @NonNull
42     private final TaskFragmentOrganizerToken mOrganizer;
43 
44     /**
45      * Unique token assigned from the client organizer to identify the {@link TaskFragmentInfo} when
46      * a new TaskFragment is created with this option.
47      */
48     @NonNull
49     private final IBinder mFragmentToken;
50 
51     /**
52      * Activity token used to identify the leaf Task to create the TaskFragment in. It has to belong
53      * to the same app as the root Activity of the target Task.
54      */
55     @NonNull
56     private final IBinder mOwnerToken;
57 
58     /**
59      * The initial relative bounds of the TaskFragment in parent coordinate.
60      * Fills parent if empty.
61      */
62     @NonNull
63     private final Rect mInitialRelativeBounds = new Rect();
64 
65     /** The initial windowing mode of the TaskFragment. Inherits from parent if not set. */
66     @WindowingMode
67     private final int mWindowingMode;
68 
69     /**
70      * The fragment token of the paired primary TaskFragment.
71      * When it is set, the new TaskFragment will be positioned right above the paired TaskFragment.
72      * Otherwise, the new TaskFragment will be positioned on the top of the Task by default.
73      *
74      * This is different from {@link WindowContainerTransaction#setAdjacentTaskFragments} as we may
75      * set this when the pair of TaskFragments are stacked, while adjacent is only set on the pair
76      * of TaskFragments that are in split.
77      *
78      * This is needed in case we need to launch a placeholder Activity to split below a transparent
79      * always-expand Activity.
80      *
81      * This should not be used with {@link #mPairedActivityToken}.
82      */
83     @Nullable
84     private final IBinder mPairedPrimaryFragmentToken;
85 
86     /**
87      * The Activity token to place the new TaskFragment on top of.
88      * When it is set, the new TaskFragment will be positioned right above the target Activity.
89      * Otherwise, the new TaskFragment will be positioned on the top of the Task by default.
90      *
91      * This is needed in case we need to place an Activity into TaskFragment to launch placeholder
92      * below a transparent always-expand Activity, or when there is another Intent being started in
93      * a TaskFragment above.
94      *
95      * This should not be used with {@link #mPairedPrimaryFragmentToken}.
96      */
97     @Nullable
98     private final IBinder mPairedActivityToken;
99 
100     /**
101      * If {@code true}, transitions are allowed even if the TaskFragment is empty. If
102      * {@code false}, transitions will wait until the TaskFragment becomes non-empty or other
103      * conditions are met. Default to {@code false}.
104      */
105     private final boolean mAllowTransitionWhenEmpty;
106 
107     /**
108      * The override orientation for the TaskFragment. This is effective only for a system organizer.
109      * The value is ignored otherwise. Default to {@code SCREEN_ORIENTATION_UNSPECIFIED}.
110      *
111      * @see TaskFragmentOrganizer#registerOrganizer(boolean)
112      */
113     private final @ScreenOrientation int mOverrideOrientation;
114 
TaskFragmentCreationParams( @onNull TaskFragmentOrganizerToken organizer, @NonNull IBinder fragmentToken, @NonNull IBinder ownerToken, @NonNull Rect initialRelativeBounds, @WindowingMode int windowingMode, @Nullable IBinder pairedPrimaryFragmentToken, @Nullable IBinder pairedActivityToken, boolean allowTransitionWhenEmpty, @ScreenOrientation int overrideOrientation)115     private TaskFragmentCreationParams(
116             @NonNull TaskFragmentOrganizerToken organizer, @NonNull IBinder fragmentToken,
117             @NonNull IBinder ownerToken, @NonNull Rect initialRelativeBounds,
118             @WindowingMode int windowingMode, @Nullable IBinder pairedPrimaryFragmentToken,
119             @Nullable IBinder pairedActivityToken, boolean allowTransitionWhenEmpty,
120             @ScreenOrientation int overrideOrientation) {
121         if (pairedPrimaryFragmentToken != null && pairedActivityToken != null) {
122             throw new IllegalArgumentException("pairedPrimaryFragmentToken and"
123                     + " pairedActivityToken should not be set at the same time.");
124         }
125         mOrganizer = organizer;
126         mFragmentToken = fragmentToken;
127         mOwnerToken = ownerToken;
128         mInitialRelativeBounds.set(initialRelativeBounds);
129         mWindowingMode = windowingMode;
130         mPairedPrimaryFragmentToken = pairedPrimaryFragmentToken;
131         mPairedActivityToken = pairedActivityToken;
132         mAllowTransitionWhenEmpty = allowTransitionWhenEmpty;
133         mOverrideOrientation = overrideOrientation;
134     }
135 
136     @NonNull
getOrganizer()137     public TaskFragmentOrganizerToken getOrganizer() {
138         return mOrganizer;
139     }
140 
141     @NonNull
getFragmentToken()142     public IBinder getFragmentToken() {
143         return mFragmentToken;
144     }
145 
146     @NonNull
getOwnerToken()147     public IBinder getOwnerToken() {
148         return mOwnerToken;
149     }
150 
151     @NonNull
getInitialRelativeBounds()152     public Rect getInitialRelativeBounds() {
153         return mInitialRelativeBounds;
154     }
155 
156     @WindowingMode
getWindowingMode()157     public int getWindowingMode() {
158         return mWindowingMode;
159     }
160 
161     /**
162      * TODO(b/232476698): remove the hide with adding CTS for this in next release.
163      * @hide
164      */
165     @Nullable
getPairedPrimaryFragmentToken()166     public IBinder getPairedPrimaryFragmentToken() {
167         return mPairedPrimaryFragmentToken;
168     }
169 
170     /**
171      * TODO(b/232476698): remove the hide with adding CTS for this in next release.
172      * @hide
173      */
174     @Nullable
getPairedActivityToken()175     public IBinder getPairedActivityToken() {
176         return mPairedActivityToken;
177     }
178 
179     /** @hide */
getAllowTransitionWhenEmpty()180     public boolean getAllowTransitionWhenEmpty() {
181         return mAllowTransitionWhenEmpty;
182     }
183 
184     /** @hide */
getOverrideOrientation()185     public @ScreenOrientation int getOverrideOrientation() {
186         return mOverrideOrientation;
187     }
188 
TaskFragmentCreationParams(Parcel in)189     private TaskFragmentCreationParams(Parcel in) {
190         mOrganizer = TaskFragmentOrganizerToken.CREATOR.createFromParcel(in);
191         mFragmentToken = in.readStrongBinder();
192         mOwnerToken = in.readStrongBinder();
193         mInitialRelativeBounds.readFromParcel(in);
194         mWindowingMode = in.readInt();
195         mPairedPrimaryFragmentToken = in.readStrongBinder();
196         mPairedActivityToken = in.readStrongBinder();
197         mAllowTransitionWhenEmpty = in.readBoolean();
198         mOverrideOrientation = in.readInt();
199     }
200 
201     /** @hide */
202     @Override
writeToParcel(@onNull Parcel dest, int flags)203     public void writeToParcel(@NonNull Parcel dest, int flags) {
204         mOrganizer.writeToParcel(dest, flags);
205         dest.writeStrongBinder(mFragmentToken);
206         dest.writeStrongBinder(mOwnerToken);
207         mInitialRelativeBounds.writeToParcel(dest, flags);
208         dest.writeInt(mWindowingMode);
209         dest.writeStrongBinder(mPairedPrimaryFragmentToken);
210         dest.writeStrongBinder(mPairedActivityToken);
211         dest.writeBoolean(mAllowTransitionWhenEmpty);
212         dest.writeInt(mOverrideOrientation);
213     }
214 
215     @NonNull
216     public static final Creator<TaskFragmentCreationParams> CREATOR =
217             new Creator<TaskFragmentCreationParams>() {
218                 @Override
219                 public TaskFragmentCreationParams createFromParcel(Parcel in) {
220                     return new TaskFragmentCreationParams(in);
221                 }
222 
223                 @Override
224                 public TaskFragmentCreationParams[] newArray(int size) {
225                     return new TaskFragmentCreationParams[size];
226                 }
227             };
228 
229     @Override
toString()230     public String toString() {
231         return "TaskFragmentCreationParams{"
232                 + " organizer=" + mOrganizer
233                 + " fragmentToken=" + mFragmentToken
234                 + " ownerToken=" + mOwnerToken
235                 + " initialRelativeBounds=" + mInitialRelativeBounds
236                 + " windowingMode=" + mWindowingMode
237                 + " pairedFragmentToken=" + mPairedPrimaryFragmentToken
238                 + " pairedActivityToken=" + mPairedActivityToken
239                 + " allowTransitionWhenEmpty=" + mAllowTransitionWhenEmpty
240                 + " overrideOrientation=" + mOverrideOrientation
241                 + "}";
242     }
243 
244     /** @hide */
245     @Override
describeContents()246     public int describeContents() {
247         return 0;
248     }
249 
250     /** Builder to construct the options to create TaskFragment with. */
251     public static final class Builder {
252 
253         @NonNull
254         private final TaskFragmentOrganizerToken mOrganizer;
255 
256         @NonNull
257         private final IBinder mFragmentToken;
258 
259         @NonNull
260         private final IBinder mOwnerToken;
261 
262         @NonNull
263         private final Rect mInitialRelativeBounds = new Rect();
264 
265         @WindowingMode
266         private int mWindowingMode = WINDOWING_MODE_UNDEFINED;
267 
268         @Nullable
269         private IBinder mPairedPrimaryFragmentToken;
270 
271         @Nullable
272         private IBinder mPairedActivityToken;
273 
274         private boolean mAllowTransitionWhenEmpty;
275 
276         private @ScreenOrientation int mOverrideOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
277 
Builder(@onNull TaskFragmentOrganizerToken organizer, @NonNull IBinder fragmentToken, @NonNull IBinder ownerToken)278         public Builder(@NonNull TaskFragmentOrganizerToken organizer,
279                 @NonNull IBinder fragmentToken, @NonNull IBinder ownerToken) {
280             mOrganizer = organizer;
281             mFragmentToken = fragmentToken;
282             mOwnerToken = ownerToken;
283         }
284 
285         /**
286          * Sets the initial relative bounds for the TaskFragment in parent coordinate.
287          * Set to empty to fill parent.
288          */
289         @NonNull
setInitialRelativeBounds(@onNull Rect bounds)290         public Builder setInitialRelativeBounds(@NonNull Rect bounds) {
291             mInitialRelativeBounds.set(bounds);
292             return this;
293         }
294 
295         /** Sets the initial windowing mode for the TaskFragment. */
296         @NonNull
setWindowingMode(@indowingMode int windowingMode)297         public Builder setWindowingMode(@WindowingMode int windowingMode) {
298             mWindowingMode = windowingMode;
299             return this;
300         }
301 
302         /**
303          * Sets the fragment token of the paired primary TaskFragment.
304          * When it is set, the new TaskFragment will be positioned right above the paired
305          * TaskFragment. Otherwise, the new TaskFragment will be positioned on the top of the Task
306          * by default.
307          *
308          * This is needed in case we need to launch a placeholder Activity to split below a
309          * transparent always-expand Activity.
310          *
311          * This should not be used with {@link #setPairedActivityToken}.
312          *
313          * TODO(b/232476698): remove the hide with adding CTS for this in next release.
314          * @hide
315          */
316         @NonNull
setPairedPrimaryFragmentToken(@ullable IBinder fragmentToken)317         public Builder setPairedPrimaryFragmentToken(@Nullable IBinder fragmentToken) {
318             mPairedPrimaryFragmentToken = fragmentToken;
319             return this;
320         }
321 
322         /**
323          * Sets the Activity token to place the new TaskFragment on top of.
324          * When it is set, the new TaskFragment will be positioned right above the target Activity.
325          * Otherwise, the new TaskFragment will be positioned on the top of the Task by default.
326          *
327          * This is needed in case we need to place an Activity into TaskFragment to launch
328          * placeholder below a transparent always-expand Activity, or when there is another Intent
329          * being started in a TaskFragment above.
330          *
331          * This should not be used with {@link #setPairedPrimaryFragmentToken}.
332          *
333          * TODO(b/232476698): remove the hide with adding CTS for this in next release.
334          * @hide
335          */
336         @NonNull
setPairedActivityToken(@ullable IBinder activityToken)337         public Builder setPairedActivityToken(@Nullable IBinder activityToken) {
338             mPairedActivityToken = activityToken;
339             return this;
340         }
341 
342         /**
343          * Sets whether transitions are allowed when the TaskFragment is empty. If {@code true},
344          * transitions are allowed when the TaskFragment is empty. If {@code false}, transitions
345          * will wait until the TaskFragment becomes non-empty or other conditions are met. Default
346          * to {@code false}.
347          *
348          * @hide
349          */
350         @NonNull
setAllowTransitionWhenEmpty(boolean allowTransitionWhenEmpty)351         public Builder setAllowTransitionWhenEmpty(boolean allowTransitionWhenEmpty) {
352             mAllowTransitionWhenEmpty = allowTransitionWhenEmpty;
353             return this;
354         }
355 
356         /**
357          * Sets the override orientation for the TaskFragment. This is effective only for a system
358          * organizer. The value is ignored otherwise. Default to
359          * {@code SCREEN_ORIENTATION_UNSPECIFIED}.
360          *
361          * @see TaskFragmentOrganizer#registerOrganizer(boolean)
362          *
363          * @hide
364          */
365         @RequiresPermission(value = android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
366         @NonNull
setOverrideOrientation(@creenOrientation int overrideOrientation)367         public Builder setOverrideOrientation(@ScreenOrientation int overrideOrientation) {
368             mOverrideOrientation = overrideOrientation;
369             return this;
370         }
371 
372         /** Constructs the options to create TaskFragment with. */
373         @NonNull
build()374         public TaskFragmentCreationParams build() {
375             return new TaskFragmentCreationParams(mOrganizer, mFragmentToken, mOwnerToken,
376                     mInitialRelativeBounds, mWindowingMode, mPairedPrimaryFragmentToken,
377                     mPairedActivityToken, mAllowTransitionWhenEmpty, mOverrideOrientation);
378         }
379     }
380 }
381