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.annotation.NonNull; 23 import android.app.WindowConfiguration.ActivityType; 24 import android.compat.annotation.UnsupportedAppUsage; 25 import android.os.IBinder; 26 import android.os.Parcel; 27 import android.os.Parcelable; 28 import android.os.RemoteException; 29 import android.util.ArraySet; 30 import android.util.Slog; 31 import android.util.SparseArray; 32 import android.view.WindowManager.TransitionOldType; 33 34 /** 35 * Defines which animation types should be overridden by which remote animation. 36 * 37 * @hide 38 */ 39 public class RemoteAnimationDefinition implements Parcelable { 40 41 private final SparseArray<RemoteAnimationAdapterEntry> mTransitionAnimationMap; 42 43 @UnsupportedAppUsage RemoteAnimationDefinition()44 public RemoteAnimationDefinition() { 45 mTransitionAnimationMap = new SparseArray<>(); 46 } 47 48 /** 49 * Registers a remote animation for a specific transition. 50 * 51 * @param transition The old transition type. Must be one of WindowManager.TRANSIT_OLD_* values. 52 * @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 */ 56 @UnsupportedAppUsage addRemoteAnimation(@ransitionOldType int transition, @ActivityType int activityTypeFilter, RemoteAnimationAdapter adapter)57 public void addRemoteAnimation(@TransitionOldType 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 old transition type. Must be one of WindowManager.TRANSIT_OLD_* values. 68 * @param adapter The adapter that described how to run the remote animation. 69 */ 70 @UnsupportedAppUsage addRemoteAnimation(@ransitionOldType int transition, RemoteAnimationAdapter adapter)71 public void addRemoteAnimation(@TransitionOldType int transition, 72 RemoteAnimationAdapter adapter) { 73 addRemoteAnimation(transition, ACTIVITY_TYPE_UNDEFINED, adapter); 74 } 75 76 /** 77 * Checks whether a remote animation for specific transition is defined. 78 * 79 * @param transition The old transition type. Must be one of WindowManager.TRANSIT_OLD_* values. 80 * @param activityTypes The set of activity types of activities that are involved in the 81 * transition. Will be used for filtering. 82 * @return Whether this definition has defined a remote animation for the specified transition. 83 */ hasTransition(@ransitionOldType int transition, ArraySet<Integer> activityTypes)84 public boolean hasTransition(@TransitionOldType int transition, 85 ArraySet<Integer> activityTypes) { 86 return getAdapter(transition, activityTypes) != null; 87 } 88 89 /** 90 * Retrieves the remote animation for a specific transition. 91 * 92 * @param transition The old transition type. Must be one of WindowManager.TRANSIT_OLD_* values. 93 * @param activityTypes The set of activity types of activities that are involved in the 94 * transition. Will be used for filtering. 95 * @return The remote animation adapter for the specified transition. 96 */ getAdapter(@ransitionOldType int transition, ArraySet<Integer> activityTypes)97 public @Nullable RemoteAnimationAdapter getAdapter(@TransitionOldType int transition, 98 ArraySet<Integer> activityTypes) { 99 final RemoteAnimationAdapterEntry entry = mTransitionAnimationMap.get(transition); 100 if (entry == null) { 101 return null; 102 } 103 if (entry.activityTypeFilter == ACTIVITY_TYPE_UNDEFINED 104 || activityTypes.contains(entry.activityTypeFilter)) { 105 return entry.adapter; 106 } else { 107 return null; 108 } 109 } 110 RemoteAnimationDefinition(Parcel in)111 public RemoteAnimationDefinition(Parcel in) { 112 final int size = in.readInt(); 113 mTransitionAnimationMap = new SparseArray<>(size); 114 for (int i = 0; i < size; i++) { 115 final int transition = in.readInt(); 116 final RemoteAnimationAdapterEntry entry = in.readTypedObject( 117 RemoteAnimationAdapterEntry.CREATOR); 118 mTransitionAnimationMap.put(transition, entry); 119 } 120 } 121 122 /** 123 * To be called by system_server to keep track which pid is running the remote animations inside 124 * this definition. 125 */ setCallingPidUid(int pid, int uid)126 public void setCallingPidUid(int pid, int uid) { 127 for (int i = mTransitionAnimationMap.size() - 1; i >= 0; i--) { 128 mTransitionAnimationMap.valueAt(i).adapter.setCallingPidUid(pid, uid); 129 } 130 } 131 132 /** 133 * Links the death of the runner to the provided death recipient. 134 */ linkToDeath(IBinder.DeathRecipient deathRecipient)135 public void linkToDeath(IBinder.DeathRecipient deathRecipient) { 136 try { 137 for (int i = 0; i < mTransitionAnimationMap.size(); i++) { 138 mTransitionAnimationMap.valueAt(i).adapter.getRunner().asBinder() 139 .linkToDeath(deathRecipient, 0 /* flags */); 140 } 141 } catch (RemoteException e) { 142 Slog.e("RemoteAnimationDefinition", "Failed to link to death recipient"); 143 } 144 } 145 146 @Override describeContents()147 public int describeContents() { 148 return 0; 149 } 150 151 @Override writeToParcel(Parcel dest, int flags)152 public void writeToParcel(Parcel dest, int flags) { 153 final int size = mTransitionAnimationMap.size(); 154 dest.writeInt(size); 155 for (int i = 0; i < size; i++) { 156 dest.writeInt(mTransitionAnimationMap.keyAt(i)); 157 dest.writeTypedObject(mTransitionAnimationMap.valueAt(i), flags); 158 } 159 } 160 161 public static final @NonNull Creator<RemoteAnimationDefinition> CREATOR = 162 new Creator<RemoteAnimationDefinition>() { 163 public RemoteAnimationDefinition createFromParcel(Parcel in) { 164 return new RemoteAnimationDefinition(in); 165 } 166 167 public RemoteAnimationDefinition[] newArray(int size) { 168 return new RemoteAnimationDefinition[size]; 169 } 170 }; 171 172 private static class RemoteAnimationAdapterEntry implements Parcelable { 173 174 final RemoteAnimationAdapter adapter; 175 176 /** 177 * Only run the transition if one of the activities matches the filter. 178 * {@link WindowConfiguration.ACTIVITY_TYPE_UNDEFINED} means no filter 179 */ 180 @ActivityType final int activityTypeFilter; 181 RemoteAnimationAdapterEntry(RemoteAnimationAdapter adapter, int activityTypeFilter)182 RemoteAnimationAdapterEntry(RemoteAnimationAdapter adapter, int activityTypeFilter) { 183 this.adapter = adapter; 184 this.activityTypeFilter = activityTypeFilter; 185 } 186 RemoteAnimationAdapterEntry(Parcel in)187 private RemoteAnimationAdapterEntry(Parcel in) { 188 adapter = in.readTypedObject(RemoteAnimationAdapter.CREATOR); 189 activityTypeFilter = in.readInt(); 190 } 191 192 @Override writeToParcel(Parcel dest, int flags)193 public void writeToParcel(Parcel dest, int flags) { 194 dest.writeTypedObject(adapter, flags); 195 dest.writeInt(activityTypeFilter); 196 } 197 198 @Override describeContents()199 public int describeContents() { 200 return 0; 201 } 202 203 public static final @NonNull Parcelable.Creator<RemoteAnimationAdapterEntry> CREATOR = 204 new Parcelable.Creator<RemoteAnimationAdapterEntry>() { 205 @Override 206 public RemoteAnimationAdapterEntry createFromParcel(Parcel in) { 207 return new RemoteAnimationAdapterEntry(in); 208 } 209 210 @Override 211 public RemoteAnimationAdapterEntry[] newArray(int size) { 212 return new RemoteAnimationAdapterEntry[size]; 213 } 214 }; 215 } 216 } 217