• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package com.android.launcher3.icons
17 
18 import android.content.Context
19 import android.graphics.Canvas
20 import android.graphics.Color
21 import android.graphics.Path
22 import android.graphics.Rect
23 import android.graphics.drawable.AdaptiveIconDrawable
24 import android.os.UserHandle
25 import com.android.launcher3.Flags
26 import com.android.launcher3.InvariantDeviceProfile
27 import com.android.launcher3.dagger.ApplicationContext
28 import com.android.launcher3.dagger.LauncherAppSingleton
29 import com.android.launcher3.dagger.LauncherComponentProvider.appComponent
30 import com.android.launcher3.graphics.ThemeManager
31 import com.android.launcher3.pm.UserCache
32 import com.android.launcher3.util.UserIconInfo
33 import dagger.assisted.Assisted
34 import dagger.assisted.AssistedFactory
35 import dagger.assisted.AssistedInject
36 import java.util.concurrent.ConcurrentLinkedQueue
37 import javax.inject.Inject
38 
39 /**
40  * Wrapper class to provide access to [BaseIconFactory] and also to provide pool of this class that
41  * are threadsafe.
42  */
43 class LauncherIcons
44 @AssistedInject
45 internal constructor(
46     @ApplicationContext context: Context,
47     idp: InvariantDeviceProfile,
48     private var themeManager: ThemeManager,
49     private var userCache: UserCache,
50     @Assisted private val pool: ConcurrentLinkedQueue<LauncherIcons>,
51 ) : BaseIconFactory(context, idp.fillResIconDpi, idp.iconBitmapSize), AutoCloseable {
52 
53     private val iconScale = themeManager.iconState.iconScale
54 
55     init {
56         mThemeController = themeManager.themeController
57     }
58 
59     /** Recycles a LauncherIcons that may be in-use. */
recyclenull60     fun recycle() {
61         clear()
62         pool.add(this)
63     }
64 
getUserInfonull65     override fun getUserInfo(user: UserHandle): UserIconInfo {
66         return userCache.getUserInfo(user)
67     }
68 
getShapePathnull69     override fun getShapePath(drawable: AdaptiveIconDrawable, iconBounds: Rect): Path {
70         if (!Flags.enableLauncherIconShapes()) return super.getShapePath(drawable, iconBounds)
71         return themeManager.iconShape.getPath(iconBounds)
72     }
73 
getIconScalenull74     override fun getIconScale(): Float {
75         if (!Flags.enableLauncherIconShapes()) return super.getIconScale()
76         return themeManager.iconState.iconScale
77     }
78 
drawAdaptiveIconnull79     override fun drawAdaptiveIcon(
80         canvas: Canvas,
81         drawable: AdaptiveIconDrawable,
82         overridePath: Path,
83     ) {
84         if (!Flags.enableLauncherIconShapes()) {
85             super.drawAdaptiveIcon(canvas, drawable, overridePath)
86             return
87         }
88         canvas.clipPath(overridePath)
89         canvas.drawColor(Color.BLACK)
90         canvas.save()
91         canvas.scale(iconScale, iconScale, canvas.width / 2f, canvas.height / 2f)
92         if (drawable.background != null) {
93             drawable.background.draw(canvas)
94         }
95         if (drawable.foreground != null) {
96             drawable.foreground.draw(canvas)
97         }
98         canvas.restore()
99     }
100 
closenull101     override fun close() {
102         recycle()
103     }
104 
105     @AssistedFactory
106     internal interface LauncherIconsFactory {
createnull107         fun create(pool: ConcurrentLinkedQueue<LauncherIcons>): LauncherIcons
108     }
109 
110     @LauncherAppSingleton
111     class IconPool @Inject internal constructor(private val factory: LauncherIconsFactory) {
112         private var pool = ConcurrentLinkedQueue<LauncherIcons>()
113 
114         fun obtain(): LauncherIcons = pool.let { it.poll() ?: factory.create(it) }
115 
116         fun clear() {
117             pool = ConcurrentLinkedQueue()
118         }
119     }
120 
121     companion object {
122 
123         /**
124          * Return a new LauncherIcons instance from the global pool. Allows us to avoid allocating
125          * new objects in many cases.
126          */
127         @JvmStatic
obtainnull128         fun obtain(context: Context): LauncherIcons = context.appComponent.iconPool.obtain()
129 
130         @JvmStatic fun clearPool(context: Context) = context.appComponent.iconPool.clear()
131     }
132 }
133