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 android.content.Context;
20 
21 import com.android.launcher3.InvariantDeviceProfile;
22 import com.android.launcher3.graphics.IconShape;
23 import com.android.launcher3.graphics.LauncherPreviewRenderer;
24 
25 /**
26  * Wrapper class to provide access to {@link BaseIconFactory} and also to provide pool of this class
27  * that are threadsafe.
28  */
29 public class LauncherIcons extends BaseIconFactory implements AutoCloseable {
30 
31     private static final Object sPoolSync = new Object();
32     private static LauncherIcons sPool;
33     private static int sPoolId = 0;
34 
obtain(Context context)35     public static LauncherIcons obtain(Context context) {
36         return obtain(context, IconShape.getShape().enableShapeDetection());
37     }
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, boolean shapeDetection)43     public static LauncherIcons obtain(Context context, boolean shapeDetection) {
44         if (context instanceof LauncherPreviewRenderer.PreviewContext) {
45             return ((LauncherPreviewRenderer.PreviewContext) context).newLauncherIcons(context,
46                     shapeDetection);
47         }
48 
49         int poolId;
50         synchronized (sPoolSync) {
51             if (sPool != null) {
52                 LauncherIcons m = sPool;
53                 sPool = m.next;
54                 m.next = null;
55                 return m;
56             }
57             poolId = sPoolId;
58         }
59 
60         InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(context);
61         return new LauncherIcons(context, idp.fillResIconDpi, idp.iconBitmapSize, poolId,
62                 shapeDetection);
63     }
64 
clearPool()65     public static void clearPool() {
66         synchronized (sPoolSync) {
67             sPool = null;
68             sPoolId++;
69         }
70     }
71 
72     private final int mPoolId;
73 
74     private LauncherIcons next;
75 
LauncherIcons(Context context, int fillResIconDpi, int iconBitmapSize, int poolId, boolean shapeDetection)76     protected LauncherIcons(Context context, int fillResIconDpi, int iconBitmapSize, int poolId,
77             boolean shapeDetection) {
78         super(context, fillResIconDpi, iconBitmapSize, shapeDetection);
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
close()99     public void close() {
100         recycle();
101     }
102 }
103