1 /*
2  * Copyright (C) 2018 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.view;
18 
19 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
20 
21 import android.annotation.Nullable;
22 import android.app.WindowConfiguration;
23 import android.app.WindowConfiguration.ActivityType;
24 import android.os.Parcel;
25 import android.os.Parcelable;
26 import android.util.ArraySet;
27 import android.util.SparseArray;
28 import android.view.WindowManager.TransitionType;
29 
30 /**
31  * Defines which animation types should be overridden by which remote animation.
32  *
33  * @hide
34  */
35 public class RemoteAnimationDefinition implements Parcelable {
36 
37     private final SparseArray<RemoteAnimationAdapterEntry> mTransitionAnimationMap;
38 
RemoteAnimationDefinition()39     public RemoteAnimationDefinition() {
40         mTransitionAnimationMap = new SparseArray<>();
41     }
42 
43     /**
44      * Registers a remote animation for a specific transition.
45      *
46      * @param transition The transition type. Must be one of WindowManager.TRANSIT_* values.
47      * @param activityTypeFilter The remote animation only runs if an activity with type of this
48      *                           parameter is involved in the transition.
49      * @param adapter The adapter that described how to run the remote animation.
50      */
addRemoteAnimation(@ransitionType int transition, @ActivityType int activityTypeFilter, RemoteAnimationAdapter adapter)51     public void addRemoteAnimation(@TransitionType int transition,
52             @ActivityType int activityTypeFilter, RemoteAnimationAdapter adapter) {
53         mTransitionAnimationMap.put(transition,
54                 new RemoteAnimationAdapterEntry(adapter, activityTypeFilter));
55     }
56 
57     /**
58      * Registers a remote animation for a specific transition without defining an activity type
59      * filter.
60      *
61      * @param transition The transition type. Must be one of WindowManager.TRANSIT_* values.
62      * @param adapter The adapter that described how to run the remote animation.
63      */
addRemoteAnimation(@ransitionType int transition, RemoteAnimationAdapter adapter)64     public void addRemoteAnimation(@TransitionType int transition, RemoteAnimationAdapter adapter) {
65         addRemoteAnimation(transition, ACTIVITY_TYPE_UNDEFINED, adapter);
66     }
67 
68     /**
69      * Checks whether a remote animation for specific transition is defined.
70      *
71      * @param transition The transition type. Must be one of WindowManager.TRANSIT_* values.
72      * @param activityTypes The set of activity types of activities that are involved in the
73      *                      transition. Will be used for filtering.
74      * @return Whether this definition has defined a remote animation for the specified transition.
75      */
hasTransition(@ransitionType int transition, ArraySet<Integer> activityTypes)76     public boolean hasTransition(@TransitionType int transition, ArraySet<Integer> activityTypes) {
77         return getAdapter(transition, activityTypes) != null;
78     }
79 
80     /**
81      * Retrieves the remote animation for a specific transition.
82      *
83      * @param transition The transition type. Must be one of WindowManager.TRANSIT_* values.
84      * @param activityTypes The set of activity types of activities that are involved in the
85      *                      transition. Will be used for filtering.
86      * @return The remote animation adapter for the specified transition.
87      */
getAdapter(@ransitionType int transition, ArraySet<Integer> activityTypes)88     public @Nullable RemoteAnimationAdapter getAdapter(@TransitionType int transition,
89             ArraySet<Integer> activityTypes) {
90         final RemoteAnimationAdapterEntry entry = mTransitionAnimationMap.get(transition);
91         if (entry == null) {
92             return null;
93         }
94         if (entry.activityTypeFilter == ACTIVITY_TYPE_UNDEFINED
95                 || activityTypes.contains(entry.activityTypeFilter)) {
96             return entry.adapter;
97         } else {
98             return null;
99         }
100     }
101 
RemoteAnimationDefinition(Parcel in)102     public RemoteAnimationDefinition(Parcel in) {
103         final int size = in.readInt();
104         mTransitionAnimationMap = new SparseArray<>(size);
105         for (int i = 0; i < size; i++) {
106             final int transition = in.readInt();
107             final RemoteAnimationAdapterEntry entry = in.readTypedObject(
108                     RemoteAnimationAdapterEntry.CREATOR);
109             mTransitionAnimationMap.put(transition, entry);
110         }
111     }
112 
113     /**
114      * To be called by system_server to keep track which pid is running the remote animations inside
115      * this definition.
116      */
setCallingPid(int pid)117     public void setCallingPid(int pid) {
118         for (int i = mTransitionAnimationMap.size() - 1; i >= 0; i--) {
119             mTransitionAnimationMap.valueAt(i).adapter.setCallingPid(pid);
120         }
121     }
122 
123     @Override
describeContents()124     public int describeContents() {
125         return 0;
126     }
127 
128     @Override
writeToParcel(Parcel dest, int flags)129     public void writeToParcel(Parcel dest, int flags) {
130         final int size = mTransitionAnimationMap.size();
131         dest.writeInt(size);
132         for (int i = 0; i < size; i++) {
133             dest.writeInt(mTransitionAnimationMap.keyAt(i));
134             dest.writeTypedObject(mTransitionAnimationMap.valueAt(i), flags);
135         }
136     }
137 
138     public static final Creator<RemoteAnimationDefinition> CREATOR =
139             new Creator<RemoteAnimationDefinition>() {
140         public RemoteAnimationDefinition createFromParcel(Parcel in) {
141             return new RemoteAnimationDefinition(in);
142         }
143 
144         public RemoteAnimationDefinition[] newArray(int size) {
145             return new RemoteAnimationDefinition[size];
146         }
147     };
148 
149     private static class RemoteAnimationAdapterEntry implements Parcelable {
150 
151         final RemoteAnimationAdapter adapter;
152 
153         /**
154          * Only run the transition if one of the activities matches the filter.
155          * {@link WindowConfiguration.ACTIVITY_TYPE_UNDEFINED} means no filter
156          */
157         @ActivityType final int activityTypeFilter;
158 
RemoteAnimationAdapterEntry(RemoteAnimationAdapter adapter, int activityTypeFilter)159         RemoteAnimationAdapterEntry(RemoteAnimationAdapter adapter, int activityTypeFilter) {
160             this.adapter = adapter;
161             this.activityTypeFilter = activityTypeFilter;
162         }
163 
RemoteAnimationAdapterEntry(Parcel in)164         private RemoteAnimationAdapterEntry(Parcel in) {
165             adapter = in.readParcelable(RemoteAnimationAdapter.class.getClassLoader());
166             activityTypeFilter = in.readInt();
167         }
168 
169         @Override
writeToParcel(Parcel dest, int flags)170         public void writeToParcel(Parcel dest, int flags) {
171             dest.writeParcelable(adapter, flags);
172             dest.writeInt(activityTypeFilter);
173         }
174 
175         @Override
describeContents()176         public int describeContents() {
177             return 0;
178         }
179 
180         private static final Creator<RemoteAnimationAdapterEntry> CREATOR
181                 = new Creator<RemoteAnimationAdapterEntry>() {
182 
183             @Override
184             public RemoteAnimationAdapterEntry createFromParcel(Parcel in) {
185                 return new RemoteAnimationAdapterEntry(in);
186             }
187 
188             @Override
189             public RemoteAnimationAdapterEntry[] newArray(int size) {
190                 return new RemoteAnimationAdapterEntry[size];
191             }
192         };
193     }
194 }
195