summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/dynamicui/ExtractedColors.java
blob: 6a3011d3bfcbabd92810f1b3f71683290625c9c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
 * 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.content.Context;
import android.graphics.Color;
import android.support.v4.graphics.ColorUtils;
import android.support.v7.graphics.Palette;
import android.util.Log;

import com.android.launcher3.Utilities;

/**
 * Saves and loads colors extracted from the wallpaper, as well as the associated wallpaper id.
 */
public class ExtractedColors {
    private static final String TAG = "ExtractedColors";

    public static final int DEFAULT_LIGHT = Color.WHITE;
    public static final int DEFAULT_DARK = Color.BLACK;
    public static final int DEFAULT_COLOR = DEFAULT_LIGHT;

    // These color profile indices should NOT be changed, since they are used when saving and
    // loading extracted colors. New colors should always be added at the end.
    public static final int VERSION_INDEX = 0;
    public static final int HOTSEAT_INDEX = 1;
    public static final int STATUS_BAR_INDEX = 2;
    // public static final int VIBRANT_INDEX = 2;
    // public static final int VIBRANT_DARK_INDEX = 3;
    // public static final int VIBRANT_LIGHT_INDEX = 4;
    // public static final int MUTED_INDEX = 5;
    // public static final int MUTED_DARK_INDEX = 6;
    // public static final int MUTED_LIGHT_INDEX = 7;

    public static final int NUM_COLOR_PROFILES = 2;
    private static final int VERSION = 1;

    private static final String COLOR_SEPARATOR = ",";

    private int[] mColors;

    public ExtractedColors() {
        // The first entry is reserved for the version number.
        mColors = new int[NUM_COLOR_PROFILES + 1];
        mColors[VERSION_INDEX] = VERSION;
    }

    public void setColorAtIndex(int index, int color) {
        if (index > VERSION_INDEX && 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, VERSION + "");

        decodeFromString(encodedString);

        if (mColors[VERSION_INDEX] != VERSION) {
            ExtractionUtils.startColorExtractionService(context);
        }
    }

    /** @param index must be one of the index values defined at the top of this class. */
    public int getColor(int index, int defaultColor) {
        if (index > VERSION_INDEX && index < mColors.length) {
            return mColors[index];
        }
        return defaultColor;
    }

    /**
     * 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 {
            // We currently don't use any of the colors defined by the Palette API,
            // but this is how we would add them if we ever need them.

            // 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(DEFAULT_COLOR));
            // setColorAtIndex(ExtractedColors.MUTED_DARK_INDEX,
                // palette.getDarkMutedColor(ExtractedColors.DEFAULT_DARK));
            // setColorAtIndex(ExtractedColors.MUTED_LIGHT_INDEX,
                // palette.getLightVibrantColor(ExtractedColors.DEFAULT_LIGHT));
        }
    }

    /**
     * The hotseat's color is defined as follows:
     * - 12% black for super light wallpaper
     * - 18% white for super dark
     * - 25% white otherwise
     */
    public void updateHotseatPalette(Palette hotseatPalette) {
        int hotseatColor;
        if (hotseatPalette != null && ExtractionUtils.isSuperLight(hotseatPalette)) {
            hotseatColor = ColorUtils.setAlphaComponent(Color.BLACK, (int) (0.12f * 255));
        } else if (hotseatPalette != null && ExtractionUtils.isSuperDark(hotseatPalette)) {
            hotseatColor = ColorUtils.setAlphaComponent(Color.WHITE, (int) (0.18f * 255));
        } else {
            hotseatColor = ColorUtils.setAlphaComponent(Color.WHITE, (int) (0.25f * 255));
        }
        setColorAtIndex(HOTSEAT_INDEX, hotseatColor);
    }

    public void updateStatusBarPalette(Palette statusBarPalette) {
        setColorAtIndex(STATUS_BAR_INDEX, ExtractionUtils.isSuperLight(statusBarPalette) ?
                DEFAULT_LIGHT : DEFAULT_DARK);
    }
}