Added ColorExtractionService and ExtractedColors.

- Launcher has an instance of ExtractedColors, which is loaded from
  LauncherProvider in onCreate() and whenever the wallpaper changes.
  - When the wallpaper changes, the ColorExtractionService is started
    in the :wallpaper-chooser process.
  - ColorExtractionService builds an ExtractedColors instance and saves
    it as a String in LauncherProvider.
  - When the results are saved, Launcher gets a callback through
    LauncherProviderChangeListener and reloads the ExtractedColors.
- Whenever Launcher loads Extractecolors, it also re-colors items
  (currently a no-op).

Change-Id: I319e2cfe0a86abcbc6bb39ef6b9fbbcad54ad743
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 207121b..f076094 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -53,6 +53,7 @@
 import com.android.launcher3.compat.UserHandleCompat;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.dynamicui.ExtractionUtils;
 import com.android.launcher3.util.ManagedProfileHeuristic;
 import com.android.launcher3.util.NoLocaleSqliteContext;
 import com.android.launcher3.util.Thunk;
@@ -257,7 +258,7 @@
     }
 
     @Override
-    public Bundle call(String method, String arg, Bundle extras) {
+    public Bundle call(String method, final String arg, final Bundle extras) {
         if (Binder.getCallingUid() != Process.myUid()) {
             return null;
         }
@@ -277,13 +278,19 @@
                 return result;
             }
             case LauncherSettings.Settings.METHOD_SET_BOOLEAN: {
-                boolean value = extras.getBoolean(LauncherSettings.Settings.EXTRA_VALUE);
+                final boolean value = extras.getBoolean(LauncherSettings.Settings.EXTRA_VALUE);
                 Utilities.getPrefs(getContext()).edit().putBoolean(arg, value).apply();
-                synchronized (LISTENER_LOCK) {
-                    if (mListener != null) {
-                        mListener.onSettingsChanged(arg, value);
+                new MainThreadExecutor().execute(new Runnable() {
+                    @Override
+                    public void run() {
+                        synchronized (LISTENER_LOCK) {
+                            if (mListener != null) {
+                                mListener.onSettingsChanged(arg, value);
+                            }
+                        }
+
                     }
-                }
+                });
                 if (extras.getBoolean(LauncherSettings.Settings.NOTIFY_BACKUP)) {
                     LauncherBackupAgentHelper.dataChanged(getContext());
                 }
@@ -291,6 +298,29 @@
                 result.putBoolean(LauncherSettings.Settings.EXTRA_VALUE, value);
                 return result;
             }
+            case LauncherSettings.Settings.METHOD_SET_EXTRACTED_COLORS_AND_WALLPAPER_ID: {
+                String extractedColors = extras.getString(
+                        LauncherSettings.Settings.EXTRA_EXTRACTED_COLORS);
+                int wallpaperId = extras.getInt(LauncherSettings.Settings.EXTRA_WALLPAPER_ID);
+                Utilities.getPrefs(getContext()).edit()
+                        .putString(ExtractionUtils.EXTRACTED_COLORS_PREFERENCE_KEY, extractedColors)
+                        .putInt(ExtractionUtils.WALLPAPER_ID_PREFERENCE_KEY, wallpaperId)
+                        .apply();
+                new MainThreadExecutor().execute(new Runnable() {
+                    @Override
+                    public void run() {
+                        synchronized (LISTENER_LOCK) {
+                            if (mListener != null) {
+                                mListener.onExtractedColorsChanged();
+                            }
+                        }
+
+                    }
+                });
+                Bundle result = new Bundle();
+                result.putString(LauncherSettings.Settings.EXTRA_VALUE, extractedColors);
+                return result;
+            }
             case LauncherSettings.Settings.METHOD_CLEAR_EMPTY_DB_FLAG: {
                 clearFlagEmptyDbCreated();
                 return null;