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 android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.app.IApplicationThread;
22 import android.os.IBinder;
23 import android.os.Parcelable;
24 
25 /**
26  * Represents a remote transition animation and information required to run it (eg. the app thread
27  * that needs to be boosted).
28  * @hide
29  */
30 public final class RemoteTransition implements Parcelable {
31 
32     /** The actual remote-transition interface used to run the transition animation. */
33     private @NonNull IRemoteTransition mRemoteTransition;
34 
35     /** The application thread that will be running the remote transition. */
36     private @Nullable IApplicationThread mAppThread;
37 
38     /** A name for this that can be used for debugging. */
39     private @Nullable String mDebugName;
40 
41     /**
42      * Constructs with no app thread (animation runs in shell).
43      * @hide
44      */
RemoteTransition(@onNull IRemoteTransition remoteTransition)45     public RemoteTransition(@NonNull IRemoteTransition remoteTransition) {
46         this(remoteTransition, null /* appThread */, null /* debugName */);
47     }
48 
49     /**
50      * Constructs with no app thread (animation runs in shell).
51      * @hide
52      */
RemoteTransition(@onNull IRemoteTransition remoteTransition, @Nullable String debugName)53     public RemoteTransition(@NonNull IRemoteTransition remoteTransition,
54             @Nullable String debugName) {
55         this(remoteTransition, null /* appThread */, debugName);
56     }
57 
58     /** Get the IBinder associated with the underlying IRemoteTransition. */
asBinder()59     public @Nullable IBinder asBinder() {
60         return mRemoteTransition.asBinder();
61     }
62 
63     /**
64      * Creates a new RemoteTransition.
65      *
66      * @param remoteTransition
67      *   The actual remote-transition interface used to run the transition animation.
68      * @param appThread
69      *   The application thread that will be running the remote transition.
70      * @param debugName
71      *   A name for this that can be used for debugging.
72      * @hide
73      */
RemoteTransition( @onNull IRemoteTransition remoteTransition, @Nullable IApplicationThread appThread, @Nullable String debugName)74     public RemoteTransition(
75             @NonNull IRemoteTransition remoteTransition,
76             @Nullable IApplicationThread appThread,
77             @Nullable String debugName) {
78         this.mRemoteTransition = remoteTransition;
79         com.android.internal.util.AnnotationValidations.validate(
80                 NonNull.class, null, mRemoteTransition);
81         this.mAppThread = appThread;
82         this.mDebugName = debugName;
83 
84         // onConstructed(); // You can define this method to get a callback
85     }
86 
87     /**
88      * The actual remote-transition interface used to run the transition animation.
89      * @hide
90      */
getRemoteTransition()91     public @NonNull IRemoteTransition getRemoteTransition() {
92         return mRemoteTransition;
93     }
94 
95     /**
96      * The application thread that will be running the remote transition.
97      * @hide
98      */
getAppThread()99     public @Nullable IApplicationThread getAppThread() {
100         return mAppThread;
101     }
102 
103     /**
104      * A name for this that can be used for debugging.
105      */
getDebugName()106     public @Nullable String getDebugName() {
107         return mDebugName;
108     }
109 
110     /**
111      * The actual remote-transition interface used to run the transition animation.
112      * @hide
113      */
setRemoteTransition(@onNull IRemoteTransition value)114     public @NonNull RemoteTransition setRemoteTransition(@NonNull IRemoteTransition value) {
115         mRemoteTransition = value;
116         com.android.internal.util.AnnotationValidations.validate(
117                 NonNull.class, null, mRemoteTransition);
118         return this;
119     }
120 
121     /**
122      * The application thread that will be running the remote transition.
123      * @hide
124      */
setAppThread(@onNull IApplicationThread value)125     public @NonNull RemoteTransition setAppThread(@NonNull IApplicationThread value) {
126         mAppThread = value;
127         return this;
128     }
129 
130     /**
131      * A name for this that can be used for debugging.
132      */
setDebugName(@onNull String value)133     public @NonNull RemoteTransition setDebugName(@NonNull String value) {
134         mDebugName = value;
135         return this;
136     }
137 
138     @Override
toString()139     public String toString() {
140         // You can override field toString logic by defining methods like:
141         // String fieldNameToString() { ... }
142 
143         return "RemoteTransition { " +
144                 "remoteTransition = " + mRemoteTransition + ", " +
145                 "appThread = " + mAppThread + ", " +
146                 "debugName = " + mDebugName +
147         " }";
148     }
149 
150     @Override
writeToParcel(@onNull android.os.Parcel dest, int flags)151     public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
152         // You can override field parcelling by defining methods like:
153         // void parcelFieldName(Parcel dest, int flags) { ... }
154 
155         byte flg = 0;
156         if (mAppThread != null) flg |= 0x2;
157         if (mDebugName != null) flg |= 0x4;
158         dest.writeByte(flg);
159         dest.writeStrongInterface(mRemoteTransition);
160         if (mAppThread != null) dest.writeStrongInterface(mAppThread);
161         if (mDebugName != null) dest.writeString(mDebugName);
162     }
163 
164     @Override
describeContents()165     public int describeContents() { return 0; }
166 
167     /** @hide */
168     @SuppressWarnings({"unchecked", "RedundantCast"})
RemoteTransition(@onNull android.os.Parcel in)169     protected RemoteTransition(@NonNull android.os.Parcel in) {
170         // You can override field unparcelling by defining methods like:
171         // static FieldType unparcelFieldName(Parcel in) { ... }
172 
173         byte flg = in.readByte();
174         IRemoteTransition remoteTransition = IRemoteTransition.Stub.asInterface(in.readStrongBinder());
175         IApplicationThread appThread = (flg & 0x2) == 0 ? null : IApplicationThread.Stub.asInterface(in.readStrongBinder());
176         String debugName = (flg & 0x4) == 0 ? null : in.readString();
177 
178         this.mRemoteTransition = remoteTransition;
179         com.android.internal.util.AnnotationValidations.validate(
180                 NonNull.class, null, mRemoteTransition);
181         this.mAppThread = appThread;
182         this.mDebugName = debugName;
183     }
184 
185     public static final @NonNull Parcelable.Creator<RemoteTransition> CREATOR
186             = new Parcelable.Creator<RemoteTransition>() {
187         @Override
188         public RemoteTransition[] newArray(int size) {
189             return new RemoteTransition[size];
190         }
191 
192         @Override
193         public RemoteTransition createFromParcel(@NonNull android.os.Parcel in) {
194             return new RemoteTransition(in);
195         }
196     };
197 }
198