1 /*
<lambda>null2  * Copyright (C) 2023 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.util
18 
19 import android.app.WallpaperColors
20 import android.app.WallpaperManager
21 import android.app.WallpaperManager.FLAG_SYSTEM
22 import android.app.WallpaperManager.OnColorsChangedListener
23 import android.content.Context
24 import androidx.annotation.MainThread
25 import androidx.annotation.VisibleForTesting
26 import com.android.launcher3.Utilities
27 import com.android.launcher3.util.Executors.MAIN_EXECUTOR
28 import com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR
29 
30 /**
31  * This class caches the system's wallpaper color hints for use by other classes as a performance
32  * enhancer. It also centralizes all the WallpaperManager color hint code in one location.
33  */
34 class WallpaperColorHints(private val context: Context) : SafeCloseable {
35     var hints: Int = 0
36         private set
37     private val wallpaperManager
38         get() = context.getSystemService(WallpaperManager::class.java)!!
39     private val onColorHintsChangedListeners = mutableListOf<OnColorHintListener>()
40     private val onClose: SafeCloseable
41 
42     init {
43         if (Utilities.ATLEAST_S) {
44             hints = wallpaperManager.getWallpaperColors(FLAG_SYSTEM)?.colorHints ?: 0
45             val onColorsChangedListener = OnColorsChangedListener { colors, which ->
46                 onColorsChanged(colors, which)
47             }
48             UI_HELPER_EXECUTOR.execute {
49                 wallpaperManager.addOnColorsChangedListener(
50                     onColorsChangedListener,
51                     MAIN_EXECUTOR.handler
52                 )
53             }
54             onClose = SafeCloseable {
55                 UI_HELPER_EXECUTOR.execute {
56                     wallpaperManager.removeOnColorsChangedListener(onColorsChangedListener)
57                 }
58             }
59         } else {
60             onClose = SafeCloseable {}
61         }
62     }
63 
64     @MainThread
65     private fun onColorsChanged(colors: WallpaperColors?, which: Int) {
66         if ((which and FLAG_SYSTEM) != 0 && Utilities.ATLEAST_S) {
67             val newHints = colors?.colorHints ?: 0
68             if (newHints != hints) {
69                 hints = newHints
70                 onColorHintsChangedListeners.forEach { it.onColorHintsChanged(newHints) }
71             }
72         }
73     }
74 
75     override fun close() = onClose.close()
76 
77     fun registerOnColorHintsChangedListener(listener: OnColorHintListener) {
78         onColorHintsChangedListeners.add(listener)
79     }
80 
81     fun unregisterOnColorsChangedListener(listener: OnColorHintListener) {
82         onColorHintsChangedListeners.remove(listener)
83     }
84 
85     companion object {
86         @VisibleForTesting
87         @JvmField
88         val INSTANCE = MainThreadInitializedObject { WallpaperColorHints(it) }
89         @JvmStatic fun get(context: Context): WallpaperColorHints = INSTANCE.get(context)
90     }
91 }
92 
93 interface OnColorHintListener {
onColorHintsChangednull94     fun onColorHintsChanged(colorHints: Int)
95 }
96