1 /*
2  * Copyright (C) 2022 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 android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.annotation.SuppressLint;
22 import android.annotation.TestApi;
23 import android.app.WindowConfiguration;
24 import android.content.res.Configuration;
25 import android.os.Parcel;
26 import android.os.Parcelable;
27 import android.view.SurfaceControl;
28 
29 import java.util.Objects;
30 
31 /**
32  * The information about the parent Task of a particular TaskFragment.
33  *
34  * @hide
35  */
36 @SuppressLint("UnflaggedApi") // @TestApi to replace legacy usages.
37 @TestApi
38 public final class TaskFragmentParentInfo implements Parcelable {
39     @NonNull
40     private final Configuration mConfiguration = new Configuration();
41 
42     private final int mDisplayId;
43 
44     private final boolean mVisible;
45 
46     private final boolean mHasDirectActivity;
47 
48     @Nullable private final SurfaceControl mDecorSurface;
49 
50     /** @hide */
TaskFragmentParentInfo(@onNull Configuration configuration, int displayId, boolean visible, boolean hasDirectActivity, @Nullable SurfaceControl decorSurface)51     public TaskFragmentParentInfo(@NonNull Configuration configuration, int displayId,
52             boolean visible, boolean hasDirectActivity, @Nullable SurfaceControl decorSurface) {
53         mConfiguration.setTo(configuration);
54         mDisplayId = displayId;
55         mVisible = visible;
56         mHasDirectActivity = hasDirectActivity;
57         mDecorSurface = decorSurface;
58     }
59 
60     /** @hide */
TaskFragmentParentInfo(@onNull TaskFragmentParentInfo info)61     public TaskFragmentParentInfo(@NonNull TaskFragmentParentInfo info) {
62         mConfiguration.setTo(info.getConfiguration());
63         mDisplayId = info.mDisplayId;
64         mVisible = info.mVisible;
65         mHasDirectActivity = info.mHasDirectActivity;
66         mDecorSurface = info.mDecorSurface;
67     }
68 
69     /**
70      * The {@link Configuration} of the parent Task
71      *
72      * @hide
73      */
74     @NonNull
getConfiguration()75     public Configuration getConfiguration() {
76         return mConfiguration;
77     }
78 
79     /**
80      * The display ID of the parent Task. {@link android.view.Display#INVALID_DISPLAY} means the
81      * Task is detached from previously associated display.
82      *
83      * @hide
84      */
getDisplayId()85     public int getDisplayId() {
86         return mDisplayId;
87     }
88 
89     /**
90      * Whether the parent Task is visible or not
91      *
92      * @hide
93      */
isVisible()94     public boolean isVisible() {
95         return mVisible;
96     }
97 
98     /**
99      * Whether the parent Task has any direct child activity, which is not embedded in any
100      * TaskFragment, or not.
101      *
102      * @hide
103      */
hasDirectActivity()104     public boolean hasDirectActivity() {
105         return mHasDirectActivity;
106     }
107 
108     /**
109      * Returns {@code true} if the parameters which are important for task fragment
110      * organizers are equal between this {@link TaskFragmentParentInfo} and {@code that}.
111      * Note that this method is usually called with
112      * {@link com.android.server.wm.WindowOrganizerController#configurationsAreEqualForOrganizer(
113      * Configuration, Configuration)} to determine if this {@link TaskFragmentParentInfo} should
114      * be dispatched to the client.
115      *
116      * @hide
117      */
equalsForTaskFragmentOrganizer(@ullable TaskFragmentParentInfo that)118     public boolean equalsForTaskFragmentOrganizer(@Nullable TaskFragmentParentInfo that) {
119         if (that == null) {
120             return false;
121         }
122         return getWindowingMode() == that.getWindowingMode() && mDisplayId == that.mDisplayId
123                 && mVisible == that.mVisible && mHasDirectActivity == that.mHasDirectActivity
124                 && mDecorSurface == that.mDecorSurface;
125     }
126 
127     /** @hide */
128     @Nullable
getDecorSurface()129     public SurfaceControl getDecorSurface() {
130         return mDecorSurface;
131     }
132 
133     @WindowConfiguration.WindowingMode
getWindowingMode()134     private int getWindowingMode() {
135         return mConfiguration.windowConfiguration.getWindowingMode();
136     }
137 
138     @Override
toString()139     public String toString() {
140         return TaskFragmentParentInfo.class.getSimpleName() + ":{"
141                 + "config=" + mConfiguration
142                 + ", displayId=" + mDisplayId
143                 + ", visible=" + mVisible
144                 + ", hasDirectActivity=" + mHasDirectActivity
145                 + ", decorSurface=" + mDecorSurface
146                 + "}";
147     }
148 
149     /**
150      * Indicates that whether this {@link TaskFragmentParentInfo} equals to {@code obj}.
151      * Note that {@link #equalsForTaskFragmentOrganizer(TaskFragmentParentInfo)} should be used
152      * for most cases because not all {@link Configuration} properties are interested for
153      * {@link TaskFragmentOrganizer}.
154      */
155     @Override
equals(Object obj)156     public boolean equals(Object obj) {
157         if (obj == this) {
158             return true;
159         }
160         if (!(obj instanceof TaskFragmentParentInfo)) {
161             return false;
162         }
163         final TaskFragmentParentInfo that = (TaskFragmentParentInfo) obj;
164         return mConfiguration.equals(that.mConfiguration)
165                 && mDisplayId == that.mDisplayId
166                 && mVisible == that.mVisible
167                 && mHasDirectActivity == that.mHasDirectActivity
168                 && mDecorSurface == that.mDecorSurface;
169     }
170 
171     @Override
hashCode()172     public int hashCode() {
173         int result = mConfiguration.hashCode();
174         result = 31 * result + mDisplayId;
175         result = 31 * result + (mVisible ? 1 : 0);
176         result = 31 * result + (mHasDirectActivity ? 1 : 0);
177         result = 31 * result + Objects.hashCode(mDecorSurface);
178         return result;
179     }
180 
181     @SuppressLint("UnflaggedApi") // @TestApi to replace legacy usages.
182     @Override
writeToParcel(@onNull Parcel dest, int flags)183     public void writeToParcel(@NonNull Parcel dest, int flags) {
184         mConfiguration.writeToParcel(dest, flags);
185         dest.writeInt(mDisplayId);
186         dest.writeBoolean(mVisible);
187         dest.writeBoolean(mHasDirectActivity);
188         dest.writeTypedObject(mDecorSurface, flags);
189     }
190 
TaskFragmentParentInfo(Parcel in)191     private TaskFragmentParentInfo(Parcel in) {
192         mConfiguration.readFromParcel(in);
193         mDisplayId = in.readInt();
194         mVisible = in.readBoolean();
195         mHasDirectActivity = in.readBoolean();
196         mDecorSurface = in.readTypedObject(SurfaceControl.CREATOR);
197     }
198 
199     @SuppressLint("UnflaggedApi") // @TestApi to replace legacy usages.
200     @NonNull
201     public static final Creator<TaskFragmentParentInfo> CREATOR =
202             new Creator<TaskFragmentParentInfo>() {
203                 @Override
204                 public TaskFragmentParentInfo createFromParcel(Parcel in) {
205                     return new TaskFragmentParentInfo(in);
206                 }
207 
208                 @Override
209                 public TaskFragmentParentInfo[] newArray(int size) {
210                     return new TaskFragmentParentInfo[size];
211                 }
212             };
213 
214     @SuppressLint("UnflaggedApi") // @TestApi to replace legacy usages.
215     @Override
describeContents()216     public int describeContents() {
217         return 0;
218     }
219 }
220