1298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka/* 2298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * Copyright (C) 2017 The Android Open Source Project 3298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * 4298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * Licensed under the Apache License, Version 2.0 (the "License"); 5298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * you may not use this file except in compliance with the License. 6298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * You may obtain a copy of the License at 7298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * 8298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * http://www.apache.org/licenses/LICENSE-2.0 9298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * 10298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * Unless required by applicable law or agreed to in writing, software 11298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * distributed under the License is distributed on an "AS IS" BASIS, 12298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * See the License for the specific language governing permissions and 14298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * limitations under the License. 15298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka */ 16298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka 17298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonakapackage android.graphics; 18298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka 19298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonakaimport com.android.internal.annotations.GuardedBy; 20298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka 21298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonakaimport android.annotation.NonNull; 22298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonakaimport android.annotation.Nullable; 23298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonakaimport android.os.Parcel; 24298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonakaimport android.os.Process; 25298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonakaimport android.util.ArrayMap; 26298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka 27298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonakaimport java.util.ArrayList; 28298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka 29298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka/** 30298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * This class is used for Parceling Typeface object. 31298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * Note: Typeface object can not be passed over the process boundary. 32298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * 33298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * @hide 34298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka */ 35298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonakapublic class LeakyTypefaceStorage { 36298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka private static final Object sLock = new Object(); 37298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka 38298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka @GuardedBy("sLock") 39298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka private static final ArrayList<Typeface> sStorage = new ArrayList<>(); 40298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka @GuardedBy("sLock") 41298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka private static final ArrayMap<Typeface, Integer> sTypefaceMap = new ArrayMap<>(); 42298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka 43298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka /** 44298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * Write typeface to parcel. 45298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * 46298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * You can't transfer Typeface to a different process. {@link readTypefaceFromParcel} will 47298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * return {@code null} if the {@link readTypefaceFromParcel} is called in a different process. 48298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * 49298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * @param typeface A {@link Typeface} to be written. 50298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * @param parcel A {@link Parcel} object. 51298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka */ 52298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka public static void writeTypefaceToParcel(@Nullable Typeface typeface, @NonNull Parcel parcel) { 53298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka parcel.writeInt(Process.myPid()); 54298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka synchronized (sLock) { 55298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka final int id; 56298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka final Integer i = sTypefaceMap.get(typeface); 57298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka if (i != null) { 58298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka id = i.intValue(); 59298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka } else { 60298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka id = sStorage.size(); 61298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka sStorage.add(typeface); 62298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka sTypefaceMap.put(typeface, id); 63298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka } 64298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka parcel.writeInt(id); 65298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka } 66298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka } 67298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka 68298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka /** 69298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * Read typeface from parcel. 70298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * 71298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * If the {@link Typeface} was created in another process, this method returns null. 72298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * 73298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * @param parcel A {@link Parcel} object 74298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka * @return A {@link Typeface} object. 75298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka */ 76298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka public static @Nullable Typeface readTypefaceFromParcel(@NonNull Parcel parcel) { 77298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka final int pid = parcel.readInt(); 78298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka final int typefaceId = parcel.readInt(); 79298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka if (pid != Process.myPid()) { 80298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka return null; // The Typeface was created and written in another process. 81298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka } 82298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka synchronized (sLock) { 83298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka return sStorage.get(typefaceId); 84298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka } 85298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka } 86298bb2995b7544793006c0f93953c7aac2f08d61Seigo Nonaka} 87