diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 418b1d2d56..80ffa43dc2 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -141,6 +141,11 @@
+
+
+
= 0 && index < mColors.length) {
+ mColors[index] = color;
+ } else {
+ Log.e(TAG, "Attempted to set a color at an invalid index " + index);
+ }
+ }
+
+ /**
+ * Encodes {@link #mColors} as a comma-separated String.
+ */
+ String encodeAsString() {
+ StringBuilder colorsStringBuilder = new StringBuilder();
+ for (int color : mColors) {
+ colorsStringBuilder.append(color).append(COLOR_SEPARATOR);
+ }
+ return colorsStringBuilder.toString();
+ }
+
+ /**
+ * Decodes a comma-separated String into {@link #mColors}.
+ */
+ void decodeFromString(String colorsString) {
+ String[] splitColorsString = colorsString.split(COLOR_SEPARATOR);
+ mColors = new int[splitColorsString.length];
+ for (int i = 0; i < mColors.length; i++) {
+ mColors[i] = Integer.parseInt(splitColorsString[i]);
+ }
+ }
+
+ /**
+ * Loads colors and wallpaper id from {@link Utilities#getPrefs(Context)}.
+ * These were saved there in {@link ColorExtractionService}.
+ */
+ public void load(Context context) {
+ String encodedString = Utilities.getPrefs(context).getString(
+ ExtractionUtils.EXTRACTED_COLORS_PREFERENCE_KEY, DEFAULT_COLOR + "");
+
+ decodeFromString(encodedString);
+ }
+
+ /** @param index must be one of the index values defined at the top of this class. */
+ public int getColor(int index) {
+ if (index >= 0 && index < mColors.length) {
+ return mColors[index];
+ }
+ return DEFAULT_COLOR;
+ }
+
+ /**
+ * Updates colors based on the palette.
+ * If the palette is null, the default color is used in all cases.
+ */
+ public void updatePalette(Palette palette) {
+ if (palette == null) {
+ for (int i = 0; i < NUM_COLOR_PROFILES; i++) {
+ setColorAtIndex(i, ExtractedColors.DEFAULT_COLOR);
+ }
+ } else {
+ setColorAtIndex(ExtractedColors.DEFAULT_INDEX,
+ ExtractedColors.DEFAULT_COLOR);
+ setColorAtIndex(ExtractedColors.VIBRANT_INDEX,
+ palette.getVibrantColor(ExtractedColors.DEFAULT_COLOR));
+ setColorAtIndex(ExtractedColors.VIBRANT_DARK_INDEX,
+ palette.getDarkVibrantColor(ExtractedColors.DEFAULT_DARK));
+ setColorAtIndex(ExtractedColors.VIBRANT_LIGHT_INDEX,
+ palette.getLightVibrantColor(ExtractedColors.DEFAULT_LIGHT));
+ setColorAtIndex(ExtractedColors.MUTED_INDEX,
+ palette.getMutedColor(ExtractedColors.DEFAULT_COLOR));
+ setColorAtIndex(ExtractedColors.MUTED_DARK_INDEX,
+ palette.getDarkMutedColor(ExtractedColors.DEFAULT_DARK));
+ setColorAtIndex(ExtractedColors.MUTED_LIGHT_INDEX,
+ palette.getLightVibrantColor(ExtractedColors.DEFAULT_LIGHT));
+ }
+ }
+}
diff --git a/src/com/android/launcher3/dynamicui/ExtractionUtils.java b/src/com/android/launcher3/dynamicui/ExtractionUtils.java
new file mode 100644
index 0000000000..a2ff607135
--- /dev/null
+++ b/src/com/android/launcher3/dynamicui/ExtractionUtils.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2016 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.dynamicui;
+
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+
+import com.android.launcher3.Utilities;
+import com.android.wallpaperpicker.common.WallpaperManagerCompat;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Contains helper fields and methods related to extracting colors from the wallpaper.
+ */
+public class ExtractionUtils {
+ public static final String EXTRACTED_COLORS_PREFERENCE_KEY = "pref_extractedColors";
+ public static final String WALLPAPER_ID_PREFERENCE_KEY = "pref_wallpaperId";
+
+ /**
+ * Extract colors in the :wallpaper-chooser process, if the wallpaper id has changed.
+ * When the new colors are saved in the LauncherProvider,
+ * Launcher will be notified in Launcher#onSettingsChanged(String, String).
+ */
+ public static void startColorExtractionServiceIfNecessary(final Context context) {
+ // Run on a background thread, since the service is asynchronous anyway.
+ Utilities.THREAD_POOL_EXECUTOR.execute(new Runnable() {
+ @Override
+ public void run() {
+ if (hasWallpaperIdChanged(context)) {
+ context.startService(new Intent(context, ColorExtractionService.class));
+ }
+ }
+ });
+ }
+
+ private static boolean hasWallpaperIdChanged(Context context) {
+ if (!Utilities.isNycOrAbove()) {
+ // TODO: update an id in sharedprefs in onWallpaperChanged broadcast, and read it here.
+ return false;
+ }
+ final SharedPreferences sharedPrefs = Utilities.getPrefs(context);
+ int wallpaperId = getWallpaperId(WallpaperManager.getInstance(context));
+ int savedWallpaperId = sharedPrefs.getInt(ExtractionUtils.WALLPAPER_ID_PREFERENCE_KEY, -1);
+ return wallpaperId != savedWallpaperId;
+ }
+
+ public static int getWallpaperId(WallpaperManager wallpaperManager) {
+ // TODO: use WallpaperManager#getWallpaperId(WallpaperManager.FLAG_SET_SYSTEM) directly.
+ try {
+ Method getWallpaperId = WallpaperManager.class.getMethod("getWallpaperId", int.class);
+ return (int) getWallpaperId.invoke(wallpaperManager,
+ WallpaperManagerCompat.FLAG_SET_SYSTEM);
+ } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
+ return -1;
+ }
+ }
+}