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