1 /* 2 * Copyright (C) 2017 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.graphics; 18 19 import com.android.internal.annotations.GuardedBy; 20 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.os.Parcel; 24 import android.os.Process; 25 import android.util.ArrayMap; 26 27 import java.util.ArrayList; 28 29 /** 30 * This class is used for Parceling Typeface object. 31 * Note: Typeface object can not be passed over the process boundary. 32 * 33 * @hide 34 */ 35 @android.ravenwood.annotation.RavenwoodKeepWholeClass 36 public class LeakyTypefaceStorage { 37 private static final Object sLock = new Object(); 38 39 @GuardedBy("sLock") 40 private static final ArrayList<Typeface> sStorage = new ArrayList<>(); 41 @GuardedBy("sLock") 42 private static final ArrayMap<Typeface, Integer> sTypefaceMap = new ArrayMap<>(); 43 44 /** 45 * Write typeface to parcel. 46 * 47 * You can't transfer Typeface to a different process. {@link readTypefaceFromParcel} will 48 * return {@code null} if the {@link readTypefaceFromParcel} is called in a different process. 49 * 50 * @param typeface A {@link Typeface} to be written. 51 * @param parcel A {@link Parcel} object. 52 */ writeTypefaceToParcel(@ullable Typeface typeface, @NonNull Parcel parcel)53 public static void writeTypefaceToParcel(@Nullable Typeface typeface, @NonNull Parcel parcel) { 54 parcel.writeInt(Process.myPid()); 55 synchronized (sLock) { 56 final int id; 57 final Integer i = sTypefaceMap.get(typeface); 58 if (i != null) { 59 id = i.intValue(); 60 } else { 61 id = sStorage.size(); 62 sStorage.add(typeface); 63 sTypefaceMap.put(typeface, id); 64 } 65 parcel.writeInt(id); 66 } 67 } 68 69 /** 70 * Read typeface from parcel. 71 * 72 * If the {@link Typeface} was created in another process, this method returns null. 73 * 74 * @param parcel A {@link Parcel} object 75 * @return A {@link Typeface} object. 76 */ readTypefaceFromParcel(@onNull Parcel parcel)77 public static @Nullable Typeface readTypefaceFromParcel(@NonNull Parcel parcel) { 78 final int pid = parcel.readInt(); 79 final int typefaceId = parcel.readInt(); 80 if (pid != Process.myPid()) { 81 return null; // The Typeface was created and written in another process. 82 } 83 synchronized (sLock) { 84 return sStorage.get(typefaceId); 85 } 86 } 87 } 88