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