Home | History | Annotate | Download | only in dynamicui
      1 /*
      2  * Copyright (C) 2016 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.dynamicui;
     18 
     19 import android.content.Context;
     20 import android.graphics.Color;
     21 import android.support.v4.graphics.ColorUtils;
     22 import android.support.v7.graphics.Palette;
     23 import android.util.Log;
     24 
     25 import com.android.launcher3.Utilities;
     26 
     27 /**
     28  * Saves and loads colors extracted from the wallpaper, as well as the associated wallpaper id.
     29  */
     30 public class ExtractedColors {
     31     private static final String TAG = "ExtractedColors";
     32 
     33     public static final int DEFAULT_LIGHT = Color.WHITE;
     34     public static final int DEFAULT_DARK = Color.BLACK;
     35     public static final int DEFAULT_COLOR = DEFAULT_LIGHT;
     36 
     37     // These color profile indices should NOT be changed, since they are used when saving and
     38     // loading extracted colors. New colors should always be added at the end.
     39     public static final int VERSION_INDEX = 0;
     40     public static final int HOTSEAT_INDEX = 1;
     41     public static final int STATUS_BAR_INDEX = 2;
     42     // public static final int VIBRANT_INDEX = 2;
     43     // public static final int VIBRANT_DARK_INDEX = 3;
     44     // public static final int VIBRANT_LIGHT_INDEX = 4;
     45     // public static final int MUTED_INDEX = 5;
     46     // public static final int MUTED_DARK_INDEX = 6;
     47     // public static final int MUTED_LIGHT_INDEX = 7;
     48 
     49     public static final int NUM_COLOR_PROFILES = 2;
     50     private static final int VERSION = 1;
     51 
     52     private static final String COLOR_SEPARATOR = ",";
     53 
     54     private int[] mColors;
     55 
     56     public ExtractedColors() {
     57         // The first entry is reserved for the version number.
     58         mColors = new int[NUM_COLOR_PROFILES + 1];
     59         mColors[VERSION_INDEX] = VERSION;
     60     }
     61 
     62     public void setColorAtIndex(int index, int color) {
     63         if (index > VERSION_INDEX && index < mColors.length) {
     64             mColors[index] = color;
     65         } else {
     66             Log.e(TAG, "Attempted to set a color at an invalid index " + index);
     67         }
     68     }
     69 
     70     /**
     71      * Encodes {@link #mColors} as a comma-separated String.
     72      */
     73     String encodeAsString() {
     74         StringBuilder colorsStringBuilder = new StringBuilder();
     75         for (int color : mColors) {
     76             colorsStringBuilder.append(color).append(COLOR_SEPARATOR);
     77         }
     78         return colorsStringBuilder.toString();
     79     }
     80 
     81     /**
     82      * Decodes a comma-separated String into {@link #mColors}.
     83      */
     84     void decodeFromString(String colorsString) {
     85         String[] splitColorsString = colorsString.split(COLOR_SEPARATOR);
     86         mColors = new int[splitColorsString.length];
     87         for (int i = 0; i < mColors.length; i++) {
     88             mColors[i] = Integer.parseInt(splitColorsString[i]);
     89         }
     90     }
     91 
     92     /**
     93      * Loads colors and wallpaper id from {@link Utilities#getPrefs(Context)}.
     94      * These were saved there in {@link ColorExtractionService}.
     95      */
     96     public void load(Context context) {
     97         String encodedString = Utilities.getPrefs(context).getString(
     98                 ExtractionUtils.EXTRACTED_COLORS_PREFERENCE_KEY, VERSION + "");
     99 
    100         decodeFromString(encodedString);
    101 
    102         if (mColors[VERSION_INDEX] != VERSION) {
    103             ExtractionUtils.startColorExtractionService(context);
    104         }
    105     }
    106 
    107     /** @param index must be one of the index values defined at the top of this class. */
    108     public int getColor(int index, int defaultColor) {
    109         if (index > VERSION_INDEX && index < mColors.length) {
    110             return mColors[index];
    111         }
    112         return defaultColor;
    113     }
    114 
    115     /**
    116      * Updates colors based on the palette.
    117      * If the palette is null, the default color is used in all cases.
    118      */
    119     public void updatePalette(Palette palette) {
    120         if (palette == null) {
    121             for (int i = 0; i < NUM_COLOR_PROFILES; i++) {
    122                 setColorAtIndex(i, ExtractedColors.DEFAULT_COLOR);
    123             }
    124         } else {
    125             // We currently don't use any of the colors defined by the Palette API,
    126             // but this is how we would add them if we ever need them.
    127 
    128             // setColorAtIndex(ExtractedColors.VIBRANT_INDEX,
    129                 // palette.getVibrantColor(ExtractedColors.DEFAULT_COLOR));
    130             // setColorAtIndex(ExtractedColors.VIBRANT_DARK_INDEX,
    131                 // palette.getDarkVibrantColor(ExtractedColors.DEFAULT_DARK));
    132             // setColorAtIndex(ExtractedColors.VIBRANT_LIGHT_INDEX,
    133                 // palette.getLightVibrantColor(ExtractedColors.DEFAULT_LIGHT));
    134             // setColorAtIndex(ExtractedColors.MUTED_INDEX,
    135                 // palette.getMutedColor(DEFAULT_COLOR));
    136             // setColorAtIndex(ExtractedColors.MUTED_DARK_INDEX,
    137                 // palette.getDarkMutedColor(ExtractedColors.DEFAULT_DARK));
    138             // setColorAtIndex(ExtractedColors.MUTED_LIGHT_INDEX,
    139                 // palette.getLightVibrantColor(ExtractedColors.DEFAULT_LIGHT));
    140         }
    141     }
    142 
    143     /**
    144      * The hotseat's color is defined as follows:
    145      * - 12% black for super light wallpaper
    146      * - 18% white for super dark
    147      * - 25% white otherwise
    148      */
    149     public void updateHotseatPalette(Palette hotseatPalette) {
    150         int hotseatColor;
    151         if (hotseatPalette != null && ExtractionUtils.isSuperLight(hotseatPalette)) {
    152             hotseatColor = ColorUtils.setAlphaComponent(Color.BLACK, (int) (0.12f * 255));
    153         } else if (hotseatPalette != null && ExtractionUtils.isSuperDark(hotseatPalette)) {
    154             hotseatColor = ColorUtils.setAlphaComponent(Color.WHITE, (int) (0.18f * 255));
    155         } else {
    156             hotseatColor = ColorUtils.setAlphaComponent(Color.WHITE, (int) (0.25f * 255));
    157         }
    158         setColorAtIndex(HOTSEAT_INDEX, hotseatColor);
    159     }
    160 
    161     public void updateStatusBarPalette(Palette statusBarPalette) {
    162         setColorAtIndex(STATUS_BAR_INDEX, ExtractionUtils.isSuperLight(statusBarPalette) ?
    163                 DEFAULT_LIGHT : DEFAULT_DARK);
    164     }
    165 }
    166