diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java index 8876a1ba34..808cf70a50 100644 --- a/src/com/android/launcher3/BaseDraggingActivity.java +++ b/src/com/android/launcher3/BaseDraggingActivity.java @@ -17,12 +17,7 @@ package com.android.launcher3; import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION; -import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; -import static com.android.launcher3.util.Executors.THREAD_POOL_EXECUTOR; -import android.app.WallpaperColors; -import android.app.WallpaperManager; -import android.app.WallpaperManager.OnColorsChangedListener; import android.content.Context; import android.content.res.Configuration; import android.graphics.Point; @@ -32,6 +27,7 @@ import android.view.ActionMode; import android.view.Display; import android.view.View; +import androidx.annotation.MainThread; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -41,9 +37,11 @@ import com.android.launcher3.util.ActivityOptionsWrapper; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener; import com.android.launcher3.util.DisplayController.Info; +import com.android.launcher3.util.OnColorHintListener; import com.android.launcher3.util.RunnableList; import com.android.launcher3.util.Themes; import com.android.launcher3.util.TraceHelper; +import com.android.launcher3.util.WallpaperColorHints; import com.android.launcher3.util.WindowBounds; /** @@ -51,7 +49,7 @@ import com.android.launcher3.util.WindowBounds; */ @SuppressWarnings("NewApi") public abstract class BaseDraggingActivity extends BaseActivity - implements OnColorsChangedListener, DisplayInfoChangeListener { + implements OnColorHintListener, DisplayInfoChangeListener { private static final String TAG = "BaseDraggingActivity"; @@ -63,8 +61,7 @@ public abstract class BaseDraggingActivity extends BaseActivity protected boolean mIsSafeModeEnabled; private Runnable mOnStartCallback; - private RunnableList mOnResumeCallbacks = new RunnableList(); - + private final RunnableList mOnResumeCallbacks = new RunnableList(); private int mThemeRes = R.style.AppTheme; @Override @@ -76,10 +73,7 @@ public abstract class BaseDraggingActivity extends BaseActivity DisplayController.INSTANCE.get(this).addChangeListener(this); // Update theme - if (Utilities.ATLEAST_P) { - THREAD_POOL_EXECUTOR.execute(() -> getSystemService(WallpaperManager.class) - .addOnColorsChangedListener(this, MAIN_EXECUTOR.getHandler())); - } + WallpaperColorHints.get(this).registerOnColorHintsChangedListener(this); int themeRes = Themes.getActivityThemeRes(this); if (themeRes != mThemeRes) { mThemeRes = themeRes; @@ -97,8 +91,9 @@ public abstract class BaseDraggingActivity extends BaseActivity mOnResumeCallbacks.add(callback); } + @MainThread @Override - public void onColorsChanged(WallpaperColors wallpaperColors, int which) { + public void onColorHintsChanged(int colorHints) { updateTheme(); } @@ -175,10 +170,8 @@ public abstract class BaseDraggingActivity extends BaseActivity @Override protected void onDestroy() { super.onDestroy(); - if (Utilities.ATLEAST_P) { - getSystemService(WallpaperManager.class).removeOnColorsChangedListener(this); - } DisplayController.INSTANCE.get(this).removeChangeListener(this); + WallpaperColorHints.get(this).unregisterOnColorsChangedListener(this); } public void runOnceOnStart(Runnable action) { diff --git a/src/com/android/launcher3/util/Themes.java b/src/com/android/launcher3/util/Themes.java index a5c663f72a..60951ba05a 100644 --- a/src/com/android/launcher3/util/Themes.java +++ b/src/com/android/launcher3/util/Themes.java @@ -21,8 +21,6 @@ import static android.app.WallpaperColors.HINT_SUPPORTS_DARK_THEME; import static com.android.launcher3.LauncherPrefs.THEMED_ICONS; -import android.app.WallpaperColors; -import android.app.WallpaperManager; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Color; @@ -48,16 +46,9 @@ public class Themes { public static final String KEY_THEMED_ICONS = "themed_icons"; + /** Gets the WallpaperColorHints and then uses those to get the correct activity theme res. */ public static int getActivityThemeRes(Context context) { - final int colorHints; - if (Utilities.ATLEAST_P) { - WallpaperColors colors = context.getSystemService(WallpaperManager.class) - .getWallpaperColors(WallpaperManager.FLAG_SYSTEM); - colorHints = colors == null ? 0 : colors.getColorHints(); - } else { - colorHints = 0; - } - return getActivityThemeRes(context, colorHints); + return getActivityThemeRes(context, WallpaperColorHints.get(context).getHints()); } public static int getActivityThemeRes(Context context, int wallpaperColorHints) { diff --git a/src/com/android/launcher3/util/WallpaperColorHints.kt b/src/com/android/launcher3/util/WallpaperColorHints.kt new file mode 100644 index 0000000000..1361c1ed21 --- /dev/null +++ b/src/com/android/launcher3/util/WallpaperColorHints.kt @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.util + +import android.app.WallpaperColors +import android.app.WallpaperManager +import android.app.WallpaperManager.FLAG_SYSTEM +import android.app.WallpaperManager.OnColorsChangedListener +import android.content.Context +import androidx.annotation.MainThread +import androidx.annotation.VisibleForTesting +import com.android.launcher3.Utilities +import com.android.launcher3.util.Executors.MAIN_EXECUTOR +import com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR + +/** + * This class caches the system's wallpaper color hints for use by other classes as a performance + * enhancer. It also centralizes all the WallpaperManager color hint code in one location. + */ +class WallpaperColorHints(private val context: Context) : SafeCloseable { + var hints: Int = 0 + private set + private val wallpaperManager + get() = context.getSystemService(WallpaperManager::class.java)!! + private val onColorHintsChangedListeners = mutableListOf() + private val onClose: SafeCloseable + + init { + if (Utilities.ATLEAST_S) { + hints = wallpaperManager.getWallpaperColors(FLAG_SYSTEM)?.colorHints ?: 0 + val onColorsChangedListener = OnColorsChangedListener { colors, which -> + onColorsChanged(colors, which) + } + UI_HELPER_EXECUTOR.execute { + wallpaperManager.addOnColorsChangedListener( + onColorsChangedListener, + MAIN_EXECUTOR.handler + ) + } + onClose = SafeCloseable { + UI_HELPER_EXECUTOR.execute { + wallpaperManager.removeOnColorsChangedListener(onColorsChangedListener) + } + } + } else { + onClose = SafeCloseable {} + } + } + + @MainThread + private fun onColorsChanged(colors: WallpaperColors?, which: Int) { + if ((which and FLAG_SYSTEM) != 0 && Utilities.ATLEAST_S) { + val newHints = colors?.colorHints ?: 0 + if (newHints != hints) { + hints = newHints + onColorHintsChangedListeners.forEach { it.onColorHintsChanged(newHints) } + } + } + } + + override fun close() = onClose.close() + + fun registerOnColorHintsChangedListener(listener: OnColorHintListener) { + onColorHintsChangedListeners.add(listener) + } + + fun unregisterOnColorsChangedListener(listener: OnColorHintListener) { + onColorHintsChangedListeners.remove(listener) + } + + companion object { + @VisibleForTesting + @JvmField + val INSTANCE = MainThreadInitializedObject { WallpaperColorHints(it) } + @JvmStatic fun get(context: Context): WallpaperColorHints = INSTANCE.get(context) + } +} + +interface OnColorHintListener { + fun onColorHintsChanged(colorHints: Int) +} diff --git a/tests/src/com/android/launcher3/util/LauncherModelHelper.java b/tests/src/com/android/launcher3/util/LauncherModelHelper.java index 4580082b96..261436b3ac 100644 --- a/tests/src/com/android/launcher3/util/LauncherModelHelper.java +++ b/tests/src/com/android/launcher3/util/LauncherModelHelper.java @@ -227,7 +227,8 @@ public class LauncherModelHelper { UserCache.INSTANCE, InstallSessionHelper.INSTANCE, LauncherPrefs.INSTANCE, LauncherAppState.INSTANCE, InvariantDeviceProfile.INSTANCE, DisplayController.INSTANCE, CustomWidgetManager.INSTANCE, - SettingsCache.INSTANCE, PluginManagerWrapper.INSTANCE, LockedUserState.INSTANCE, + SettingsCache.INSTANCE, PluginManagerWrapper.INSTANCE, + LockedUserState.INSTANCE, WallpaperColorHints.INSTANCE, ItemInstallQueue.INSTANCE, WindowManagerProxy.INSTANCE); // System settings cache content provider. Ensure that they are statically initialized