Home | History | Annotate | Download | only in view
      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 
     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      */
     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      */
     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      */
     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      */
     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 
    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      */
    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
    124     public int describeContents() {
    125         return 0;
    126     }
    127 
    128     @Override
    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 
    159         RemoteAnimationAdapterEntry(RemoteAnimationAdapter adapter, int activityTypeFilter) {
    160             this.adapter = adapter;
    161             this.activityTypeFilter = activityTypeFilter;
    162         }
    163 
    164         private RemoteAnimationAdapterEntry(Parcel in) {
    165             adapter = in.readParcelable(RemoteAnimationAdapter.class.getClassLoader());
    166             activityTypeFilter = in.readInt();
    167         }
    168 
    169         @Override
    170         public void writeToParcel(Parcel dest, int flags) {
    171             dest.writeParcelable(adapter, flags);
    172             dest.writeInt(activityTypeFilter);
    173         }
    174 
    175         @Override
    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