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