blob: 5a8ac544e27e531ae8f29946ca1b83d727940152 [file] [log] [blame]
Jorim Jaggif84e2f62018-01-16 14:17:59 +01001/*
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
17package android.view;
18
Jorim Jaggi77be1572018-03-09 16:48:24 +010019import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
20
Jorim Jaggif84e2f62018-01-16 14:17:59 +010021import android.annotation.Nullable;
Jorim Jaggi77be1572018-03-09 16:48:24 +010022import android.app.WindowConfiguration;
23import android.app.WindowConfiguration.ActivityType;
Artur Satayevad9254c2019-12-10 17:47:54 +000024import android.compat.annotation.UnsupportedAppUsage;
Winson Chung10fc25d2019-12-10 14:13:56 -080025import android.os.IBinder;
Jorim Jaggif84e2f62018-01-16 14:17:59 +010026import android.os.Parcel;
27import android.os.Parcelable;
Winson Chung10fc25d2019-12-10 14:13:56 -080028import android.os.RemoteException;
Jorim Jaggi77be1572018-03-09 16:48:24 +010029import android.util.ArraySet;
Winson Chung10fc25d2019-12-10 14:13:56 -080030import android.util.Slog;
Jorim Jaggif84e2f62018-01-16 14:17:59 +010031import android.util.SparseArray;
32import android.view.WindowManager.TransitionType;
33
34/**
35 * Defines which animation types should be overridden by which remote animation.
36 *
37 * @hide
38 */
39public class RemoteAnimationDefinition implements Parcelable {
40
Jorim Jaggi77be1572018-03-09 16:48:24 +010041 private final SparseArray<RemoteAnimationAdapterEntry> mTransitionAnimationMap;
Jorim Jaggif84e2f62018-01-16 14:17:59 +010042
Mathew Inwooda570dee2018-08-17 14:56:00 +010043 @UnsupportedAppUsage
Jorim Jaggif84e2f62018-01-16 14:17:59 +010044 public RemoteAnimationDefinition() {
45 mTransitionAnimationMap = new SparseArray<>();
46 }
47
48 /**
49 * Registers a remote animation for a specific transition.
50 *
51 * @param transition The transition type. Must be one of WindowManager.TRANSIT_* values.
Jorim Jaggi77be1572018-03-09 16:48:24 +010052 * @param activityTypeFilter The remote animation only runs if an activity with type of this
53 * parameter is involved in the transition.
54 * @param adapter The adapter that described how to run the remote animation.
55 */
Mathew Inwooda570dee2018-08-17 14:56:00 +010056 @UnsupportedAppUsage
Jorim Jaggi77be1572018-03-09 16:48:24 +010057 public void addRemoteAnimation(@TransitionType int transition,
58 @ActivityType int activityTypeFilter, RemoteAnimationAdapter adapter) {
59 mTransitionAnimationMap.put(transition,
60 new RemoteAnimationAdapterEntry(adapter, activityTypeFilter));
61 }
62
63 /**
64 * Registers a remote animation for a specific transition without defining an activity type
65 * filter.
66 *
67 * @param transition The transition type. Must be one of WindowManager.TRANSIT_* values.
Jorim Jaggif84e2f62018-01-16 14:17:59 +010068 * @param adapter The adapter that described how to run the remote animation.
69 */
Mathew Inwooda570dee2018-08-17 14:56:00 +010070 @UnsupportedAppUsage
Jorim Jaggif84e2f62018-01-16 14:17:59 +010071 public void addRemoteAnimation(@TransitionType int transition, RemoteAnimationAdapter adapter) {
Jorim Jaggi77be1572018-03-09 16:48:24 +010072 addRemoteAnimation(transition, ACTIVITY_TYPE_UNDEFINED, adapter);
Jorim Jaggif84e2f62018-01-16 14:17:59 +010073 }
74
75 /**
76 * Checks whether a remote animation for specific transition is defined.
77 *
78 * @param transition The transition type. Must be one of WindowManager.TRANSIT_* values.
Jorim Jaggi77be1572018-03-09 16:48:24 +010079 * @param activityTypes The set of activity types of activities that are involved in the
80 * transition. Will be used for filtering.
Jorim Jaggif84e2f62018-01-16 14:17:59 +010081 * @return Whether this definition has defined a remote animation for the specified transition.
82 */
Jorim Jaggi77be1572018-03-09 16:48:24 +010083 public boolean hasTransition(@TransitionType int transition, ArraySet<Integer> activityTypes) {
84 return getAdapter(transition, activityTypes) != null;
Jorim Jaggif84e2f62018-01-16 14:17:59 +010085 }
86
87 /**
88 * Retrieves the remote animation for a specific transition.
89 *
90 * @param transition The transition type. Must be one of WindowManager.TRANSIT_* values.
Jorim Jaggi77be1572018-03-09 16:48:24 +010091 * @param activityTypes The set of activity types of activities that are involved in the
92 * transition. Will be used for filtering.
Jorim Jaggif84e2f62018-01-16 14:17:59 +010093 * @return The remote animation adapter for the specified transition.
94 */
Jorim Jaggi77be1572018-03-09 16:48:24 +010095 public @Nullable RemoteAnimationAdapter getAdapter(@TransitionType int transition,
96 ArraySet<Integer> activityTypes) {
97 final RemoteAnimationAdapterEntry entry = mTransitionAnimationMap.get(transition);
98 if (entry == null) {
99 return null;
100 }
101 if (entry.activityTypeFilter == ACTIVITY_TYPE_UNDEFINED
102 || activityTypes.contains(entry.activityTypeFilter)) {
103 return entry.adapter;
104 } else {
105 return null;
106 }
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100107 }
108
109 public RemoteAnimationDefinition(Parcel in) {
Jorim Jaggi77be1572018-03-09 16:48:24 +0100110 final int size = in.readInt();
111 mTransitionAnimationMap = new SparseArray<>(size);
112 for (int i = 0; i < size; i++) {
113 final int transition = in.readInt();
114 final RemoteAnimationAdapterEntry entry = in.readTypedObject(
115 RemoteAnimationAdapterEntry.CREATOR);
116 mTransitionAnimationMap.put(transition, entry);
117 }
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100118 }
119
Jorim Jaggibc2aabe2018-03-08 17:27:43 +0100120 /**
121 * To be called by system_server to keep track which pid is running the remote animations inside
122 * this definition.
123 */
Jorim Jaggi589c5ba2019-07-30 16:50:13 +0200124 public void setCallingPidUid(int pid, int uid) {
Jorim Jaggibc2aabe2018-03-08 17:27:43 +0100125 for (int i = mTransitionAnimationMap.size() - 1; i >= 0; i--) {
Jorim Jaggi589c5ba2019-07-30 16:50:13 +0200126 mTransitionAnimationMap.valueAt(i).adapter.setCallingPidUid(pid, uid);
Jorim Jaggibc2aabe2018-03-08 17:27:43 +0100127 }
128 }
129
Winson Chung10fc25d2019-12-10 14:13:56 -0800130 /**
131 * Links the death of the runner to the provided death recipient.
132 */
133 public void linkToDeath(IBinder.DeathRecipient deathRecipient) {
134 try {
135 for (int i = 0; i < mTransitionAnimationMap.size(); i++) {
136 mTransitionAnimationMap.valueAt(i).adapter.getRunner().asBinder()
137 .linkToDeath(deathRecipient, 0 /* flags */);
138 }
139 } catch (RemoteException e) {
140 Slog.e("RemoteAnimationDefinition", "Failed to link to death recipient");
141 }
142 }
143
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100144 @Override
145 public int describeContents() {
146 return 0;
147 }
148
149 @Override
150 public void writeToParcel(Parcel dest, int flags) {
Jorim Jaggi77be1572018-03-09 16:48:24 +0100151 final int size = mTransitionAnimationMap.size();
152 dest.writeInt(size);
153 for (int i = 0; i < size; i++) {
154 dest.writeInt(mTransitionAnimationMap.keyAt(i));
155 dest.writeTypedObject(mTransitionAnimationMap.valueAt(i), flags);
156 }
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100157 }
158
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700159 public static final @android.annotation.NonNull Creator<RemoteAnimationDefinition> CREATOR =
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100160 new Creator<RemoteAnimationDefinition>() {
161 public RemoteAnimationDefinition createFromParcel(Parcel in) {
162 return new RemoteAnimationDefinition(in);
163 }
164
165 public RemoteAnimationDefinition[] newArray(int size) {
166 return new RemoteAnimationDefinition[size];
167 }
168 };
Jorim Jaggi77be1572018-03-09 16:48:24 +0100169
170 private static class RemoteAnimationAdapterEntry implements Parcelable {
171
172 final RemoteAnimationAdapter adapter;
173
174 /**
175 * Only run the transition if one of the activities matches the filter.
176 * {@link WindowConfiguration.ACTIVITY_TYPE_UNDEFINED} means no filter
177 */
178 @ActivityType final int activityTypeFilter;
179
180 RemoteAnimationAdapterEntry(RemoteAnimationAdapter adapter, int activityTypeFilter) {
181 this.adapter = adapter;
182 this.activityTypeFilter = activityTypeFilter;
183 }
184
185 private RemoteAnimationAdapterEntry(Parcel in) {
186 adapter = in.readParcelable(RemoteAnimationAdapter.class.getClassLoader());
187 activityTypeFilter = in.readInt();
188 }
189
190 @Override
191 public void writeToParcel(Parcel dest, int flags) {
192 dest.writeParcelable(adapter, flags);
193 dest.writeInt(activityTypeFilter);
194 }
195
196 @Override
197 public int describeContents() {
198 return 0;
199 }
200
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700201 private static final @android.annotation.NonNull Creator<RemoteAnimationAdapterEntry> CREATOR
Jorim Jaggi77be1572018-03-09 16:48:24 +0100202 = new Creator<RemoteAnimationAdapterEntry>() {
203
204 @Override
205 public RemoteAnimationAdapterEntry createFromParcel(Parcel in) {
206 return new RemoteAnimationAdapterEntry(in);
207 }
208
209 @Override
210 public RemoteAnimationAdapterEntry[] newArray(int size) {
211 return new RemoteAnimationAdapterEntry[size];
212 }
213 };
214 }
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100215}