/* * Copyright (C) 2018 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.uioverrides; import android.content.Context; import android.graphics.Color; import android.util.Pair; import com.android.launcher3.uioverrides.dynamicui.WallpaperColorsCompat; import com.android.launcher3.uioverrides.dynamicui.WallpaperManagerCompat; import com.android.launcher3.uioverrides.dynamicui.ColorExtractionAlgorithm; import java.util.ArrayList; import static android.app.WallpaperManager.FLAG_SYSTEM; public class WallpaperColorInfo implements WallpaperManagerCompat.OnColorsChangedListenerCompat { private static final int MAIN_COLOR_LIGHT = 0xffdadce0; private static final int MAIN_COLOR_DARK = 0xff202124; private static final int MAIN_COLOR_REGULAR = 0xff000000; private static final int FALLBACK_COLOR = Color.WHITE; private static final Object sInstanceLock = new Object(); private static WallpaperColorInfo sInstance; public static WallpaperColorInfo getInstance(Context context) { synchronized (sInstanceLock) { if (sInstance == null) { sInstance = new WallpaperColorInfo(context.getApplicationContext()); } return sInstance; } } private final ArrayList mListeners = new ArrayList<>(); private final WallpaperManagerCompat mWallpaperManager; private final ColorExtractionAlgorithm mExtractionType; private int mMainColor; private int mSecondaryColor; private boolean mIsDark; private boolean mSupportsDarkText; private OnChangeListener[] mTempListeners; private WallpaperColorInfo(Context context) { mWallpaperManager = WallpaperManagerCompat.getInstance(context); mWallpaperManager.addOnColorsChangedListener(this); mExtractionType = new ColorExtractionAlgorithm(); update(mWallpaperManager.getWallpaperColors(FLAG_SYSTEM)); } public int getMainColor() { return mMainColor; } public int getSecondaryColor() { return mSecondaryColor; } public boolean isDark() { return mIsDark; } public boolean supportsDarkText() { return mSupportsDarkText; } public boolean isMainColorDark() { return mMainColor == MAIN_COLOR_DARK; } @Override public void onColorsChanged(WallpaperColorsCompat colors, int which) { if ((which & FLAG_SYSTEM) != 0) { update(colors); notifyChange(); } } private void update(WallpaperColorsCompat wallpaperColors) { Pair colors = mExtractionType.extractInto(wallpaperColors); if (colors != null) { mMainColor = colors.first; mSecondaryColor = colors.second; } else { mMainColor = FALLBACK_COLOR; mSecondaryColor = FALLBACK_COLOR; } mSupportsDarkText = wallpaperColors != null ? (wallpaperColors.getColorHints() & WallpaperColorsCompat.HINT_SUPPORTS_DARK_TEXT) > 0 : false; mIsDark = wallpaperColors != null ? (wallpaperColors.getColorHints() & WallpaperColorsCompat.HINT_SUPPORTS_DARK_THEME) > 0 : false; } public void addOnChangeListener(OnChangeListener listener) { mListeners.add(listener); } public void removeOnChangeListener(OnChangeListener listener) { mListeners.remove(listener); } private void notifyChange() { OnChangeListener[] copy = mTempListeners != null && mTempListeners.length == mListeners.size() ? mTempListeners : new OnChangeListener[mListeners.size()]; // Create a new array to avoid concurrent modification when the activity destroys itself. mTempListeners = mListeners.toArray(copy); for (OnChangeListener listener : mTempListeners) { listener.onExtractedColorsChanged(this); } } public interface OnChangeListener { void onExtractedColorsChanged(WallpaperColorInfo wallpaperColorInfo); } }