1 /* 2 * Copyright (C) 2016 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 com.android.launcher3.icons; 18 19 import static com.android.launcher3.config.FeatureFlags.ENABLE_FORCED_MONO_ICON; 20 21 import android.content.Context; 22 import android.graphics.drawable.Drawable; 23 24 import com.android.launcher3.InvariantDeviceProfile; 25 import com.android.launcher3.graphics.IconShape; 26 import com.android.launcher3.graphics.LauncherPreviewRenderer; 27 import com.android.launcher3.util.Themes; 28 29 /** 30 * Wrapper class to provide access to {@link BaseIconFactory} and also to provide pool of this class 31 * that are threadsafe. 32 */ 33 public class LauncherIcons extends BaseIconFactory implements AutoCloseable { 34 35 private static final Object sPoolSync = new Object(); 36 private static LauncherIcons sPool; 37 private static int sPoolId = 0; 38 39 /** 40 * Return a new Message instance from the global pool. Allows us to 41 * avoid allocating new objects in many cases. 42 */ obtain(Context context)43 public static LauncherIcons obtain(Context context) { 44 if (context instanceof LauncherPreviewRenderer.PreviewContext) { 45 return ((LauncherPreviewRenderer.PreviewContext) context).newLauncherIcons(context); 46 } 47 48 int poolId; 49 synchronized (sPoolSync) { 50 if (sPool != null) { 51 LauncherIcons m = sPool; 52 sPool = m.next; 53 m.next = null; 54 return m; 55 } 56 poolId = sPoolId; 57 } 58 59 InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(context); 60 return new LauncherIcons(context, idp.fillResIconDpi, idp.iconBitmapSize, poolId); 61 } 62 clearPool()63 public static void clearPool() { 64 synchronized (sPoolSync) { 65 sPool = null; 66 sPoolId++; 67 } 68 } 69 70 private final int mPoolId; 71 72 private LauncherIcons next; 73 74 private MonochromeIconFactory mMonochromeIconFactory; 75 LauncherIcons(Context context, int fillResIconDpi, int iconBitmapSize, int poolId)76 protected LauncherIcons(Context context, int fillResIconDpi, int iconBitmapSize, int poolId) { 77 super(context, fillResIconDpi, iconBitmapSize, IconShape.getShape().enableShapeDetection()); 78 mMonoIconEnabled = Themes.isThemedIconEnabled(context); 79 mPoolId = poolId; 80 } 81 82 /** 83 * Recycles a LauncherIcons that may be in-use. 84 */ recycle()85 public void recycle() { 86 synchronized (sPoolSync) { 87 if (sPoolId != mPoolId) { 88 return; 89 } 90 // Clear any temporary state variables 91 clear(); 92 93 next = sPool; 94 sPool = this; 95 } 96 } 97 98 @Override getMonochromeDrawable(Drawable base)99 protected Drawable getMonochromeDrawable(Drawable base) { 100 Drawable mono = super.getMonochromeDrawable(base); 101 if (mono != null || !ENABLE_FORCED_MONO_ICON.get()) { 102 return mono; 103 } 104 if (mMonochromeIconFactory == null) { 105 mMonochromeIconFactory = new MonochromeIconFactory(mIconBitmapSize); 106 } 107 return mMonochromeIconFactory.wrap(base); 108 } 109 110 @Override close()111 public void close() { 112 recycle(); 113 } 114 } 115