• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 package com.android.customization.model.color;
17 
18 import android.content.Context;
19 import android.content.res.Configuration;
20 import android.content.res.Resources;
21 import android.graphics.Color;
22 import android.graphics.PorterDuff;
23 import android.view.View;
24 import android.widget.ImageView;
25 
26 import androidx.annotation.ColorInt;
27 import androidx.annotation.Dimension;
28 import androidx.annotation.NonNull;
29 import androidx.annotation.VisibleForTesting;
30 
31 import com.android.customization.model.ResourceConstants;
32 import com.android.systemui.monet.Style;
33 import com.android.wallpaper.R;
34 
35 import java.util.Collections;
36 import java.util.HashMap;
37 import java.util.Map;
38 
39 /**
40  * Represents a preset color available for the user to chose as their theming option.
41  */
42 public class ColorBundle extends ColorOption {
43 
44     private final PreviewInfo mPreviewInfo;
45 
ColorBundle(String title, Map<String, String> overlayPackages, boolean isDefault, Style style, int index, PreviewInfo previewInfo)46     @VisibleForTesting ColorBundle(String title,
47             Map<String, String> overlayPackages, boolean isDefault, Style style, int index,
48             PreviewInfo previewInfo) {
49         super(title, overlayPackages, isDefault, style, index);
50         mPreviewInfo = previewInfo;
51     }
52 
53     @Override
bindThumbnailTile(View view)54     public void bindThumbnailTile(View view) {
55         Resources res = view.getContext().getResources();
56         int primaryColor = mPreviewInfo.resolvePrimaryColor(res);
57         int secondaryColor = mPreviewInfo.resolveSecondaryColor(res);
58 
59         for (int i = 0; i < mPreviewColorIds.length; i++) {
60             ImageView colorPreviewImageView = view.findViewById(mPreviewColorIds[i]);
61             int color = i % 2 == 0 ? primaryColor : secondaryColor;
62             colorPreviewImageView.getDrawable().setColorFilter(color, PorterDuff.Mode.SRC);
63         }
64         view.setContentDescription(getContentDescription(view.getContext()));
65     }
66 
67     @Override
getPreviewInfo()68     public PreviewInfo getPreviewInfo() {
69         return mPreviewInfo;
70     }
71 
72     @Override
getLayoutResId()73     public int getLayoutResId() {
74         return R.layout.color_option;
75     }
76 
77     @Override
getSource()78     public String getSource() {
79         return ColorOptionsProvider.COLOR_SOURCE_PRESET;
80     }
81 
82     /**
83      * The preview information of {@link ColorBundle}
84      */
85     public static class PreviewInfo implements ColorOption.PreviewInfo {
86         @ColorInt
87         public final int secondaryColorLight;
88         @ColorInt public final int secondaryColorDark;
89         // Monet system palette and accent colors
90         @ColorInt public final int primaryColorLight;
91         @ColorInt public final int primaryColorDark;
92         @Dimension
93         public final int bottomSheetCornerRadius;
94 
95         @ColorInt private int mOverrideSecondaryColorLight = Color.TRANSPARENT;
96         @ColorInt private int mOverrideSecondaryColorDark = Color.TRANSPARENT;
97         @ColorInt private int mOverridePrimaryColorLight = Color.TRANSPARENT;
98         @ColorInt private int mOverridePrimaryColorDark = Color.TRANSPARENT;
99 
PreviewInfo( int secondaryColorLight, int secondaryColorDark, int colorSystemPaletteLight, int primaryColorDark, @Dimension int cornerRadius)100         private PreviewInfo(
101                 int secondaryColorLight, int secondaryColorDark, int colorSystemPaletteLight,
102                 int primaryColorDark, @Dimension int cornerRadius) {
103             this.secondaryColorLight = secondaryColorLight;
104             this.secondaryColorDark = secondaryColorDark;
105             this.primaryColorLight = colorSystemPaletteLight;
106             this.primaryColorDark = primaryColorDark;
107             this.bottomSheetCornerRadius = cornerRadius;
108         }
109 
110         /**
111          * Returns the accent color to be applied corresponding with the current configuration's
112          * UI mode.
113          * @return one of {@link #secondaryColorDark} or {@link #secondaryColorLight}
114          */
115         @ColorInt
resolveSecondaryColor(Resources res)116         public int resolveSecondaryColor(Resources res) {
117             boolean night = (res.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK)
118                     == Configuration.UI_MODE_NIGHT_YES;
119             if (mOverrideSecondaryColorDark != Color.TRANSPARENT
120                     || mOverrideSecondaryColorLight != Color.TRANSPARENT) {
121                 return night ? mOverrideSecondaryColorDark : mOverrideSecondaryColorLight;
122             }
123             return night ? secondaryColorDark : secondaryColorLight;
124         }
125 
126         /**
127          * Returns the palette (main) color to be applied corresponding with the current
128          * configuration's UI mode.
129          * @return one of {@link #secondaryColorDark} or {@link #secondaryColorLight}
130          */
131         @ColorInt
resolvePrimaryColor(Resources res)132         public int resolvePrimaryColor(Resources res) {
133             boolean night = (res.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK)
134                     == Configuration.UI_MODE_NIGHT_YES;
135             if (mOverridePrimaryColorDark != Color.TRANSPARENT
136                     || mOverridePrimaryColorLight != Color.TRANSPARENT) {
137                 return night ? mOverridePrimaryColorDark : mOverridePrimaryColorLight;
138             }
139             return night ? primaryColorDark
140                     : primaryColorLight;
141         }
142 
143         /**
144          * Sets accent colors to override the ones in this bundle
145          */
setOverrideAccentColors(int overrideColorAccentLight, int overrideColorAccentDark)146         public void setOverrideAccentColors(int overrideColorAccentLight,
147                 int overrideColorAccentDark) {
148             mOverrideSecondaryColorLight = overrideColorAccentLight;
149             mOverrideSecondaryColorDark = overrideColorAccentDark;
150         }
151 
152         /**
153          * Sets palette colors to override the ones in this bundle
154          */
setOverridePaletteColors(int overrideColorPaletteLight, int overrideColorPaletteDark)155         public void setOverridePaletteColors(int overrideColorPaletteLight,
156                 int overrideColorPaletteDark) {
157             mOverridePrimaryColorLight = overrideColorPaletteLight;
158             mOverridePrimaryColorDark = overrideColorPaletteDark;
159         }
160     }
161 
162     /**
163      * The builder of ColorBundle
164      */
165     public static class Builder {
166         protected String mTitle;
167         @ColorInt private int mSecondaryColorLight = Color.TRANSPARENT;
168         @ColorInt private int mSecondaryColorDark = Color.TRANSPARENT;
169         // System and Monet colors
170         @ColorInt private int mPrimaryColorLight = Color.TRANSPARENT;
171         @ColorInt private int mPrimaryColorDark = Color.TRANSPARENT;
172         private boolean mIsDefault;
173         private Style mStyle = Style.TONAL_SPOT;
174         private int mIndex;
175         protected Map<String, String> mPackages = new HashMap<>();
176 
177         /**
178          * Builds the ColorBundle
179          * @param context {@link Context}
180          * @return new {@link ColorBundle} object
181          */
build(Context context)182         public ColorBundle build(Context context) {
183             if (mTitle == null) {
184                 mTitle = context.getString(R.string.adaptive_color_title);
185             }
186             return new ColorBundle(mTitle, mPackages, mIsDefault, mStyle, mIndex,
187                     createPreviewInfo(context));
188         }
189 
190         /**
191          * Creates preview information
192          * @param context the {@link Context}
193          * @return the {@link PreviewInfo} object
194          */
createPreviewInfo(@onNull Context context)195         public PreviewInfo createPreviewInfo(@NonNull Context context) {
196             Resources system = context.getResources().getSystem();
197             return new PreviewInfo(mSecondaryColorLight,
198                     mSecondaryColorDark, mPrimaryColorLight, mPrimaryColorDark,
199                     system.getDimensionPixelOffset(
200                             system.getIdentifier(ResourceConstants.CONFIG_CORNERRADIUS, "dimen",
201                                     ResourceConstants.ANDROID_PACKAGE)));
202         }
203 
getPackages()204         public Map<String, String> getPackages() {
205             return Collections.unmodifiableMap(mPackages);
206         }
207 
208         /**
209          * Gets title of this {@link ColorBundle} object
210          * @return title string
211          */
getTitle()212         public String getTitle() {
213             return mTitle;
214         }
215 
216         /**
217          * Sets title of bundle
218          * @param title specified title
219          * @return this of {@link Builder}
220          */
setTitle(String title)221         public Builder setTitle(String title) {
222             mTitle = title;
223             return this;
224         }
225 
226         /**
227          * Sets color accent (light)
228          * @param colorSecondaryLight color accent light in {@link ColorInt}
229          * @return this of {@link Builder}
230          */
setColorSecondaryLight(@olorInt int colorSecondaryLight)231         public Builder setColorSecondaryLight(@ColorInt int colorSecondaryLight) {
232             mSecondaryColorLight = colorSecondaryLight;
233             return this;
234         }
235 
236         /**
237          * Sets color accent (dark)
238          * @param colorSecondaryDark color accent dark in {@link ColorInt}
239          * @return this of {@link Builder}
240          */
setColorSecondaryDark(@olorInt int colorSecondaryDark)241         public Builder setColorSecondaryDark(@ColorInt int colorSecondaryDark) {
242             mSecondaryColorDark = colorSecondaryDark;
243             return this;
244         }
245 
246         /**
247          * Sets color system palette (light)
248          * @param colorPrimaryLight color system palette in {@link ColorInt}
249          * @return this of {@link Builder}
250          */
setColorPrimaryLight(@olorInt int colorPrimaryLight)251         public Builder setColorPrimaryLight(@ColorInt int colorPrimaryLight) {
252             mPrimaryColorLight = colorPrimaryLight;
253             return this;
254         }
255 
256         /**
257          * Sets color system palette (dark)
258          * @param colorPrimaryDark color system palette in {@link ColorInt}
259          * @return this of {@link Builder}
260          */
setColorPrimaryDark(@olorInt int colorPrimaryDark)261         public Builder setColorPrimaryDark(@ColorInt int colorPrimaryDark) {
262             mPrimaryColorDark = colorPrimaryDark;
263             return this;
264         }
265 
266         /**
267          * Sets overlay package for bundle
268          * @param category the category of bundle
269          * @param packageName tha name of package in the category
270          * @return this of {@link Builder}
271          */
addOverlayPackage(String category, String packageName)272         public Builder addOverlayPackage(String category, String packageName) {
273             mPackages.put(category, packageName);
274             return this;
275         }
276 
277         /**
278          * Sets the style of this color seed
279          * @param style color style of {@link Style}
280          * @return this of {@link Builder}
281          */
setStyle(Style style)282         public Builder setStyle(Style style) {
283             mStyle = style;
284             return this;
285         }
286 
287         /**
288          * Sets color option index of bundle
289          * @param index color option index
290          * @return this of {@link Builder}
291          */
setIndex(int index)292         public Builder setIndex(int index) {
293             mIndex = index;
294             return this;
295         }
296 
297         /**
298          * Sets as default bundle
299          * @return this of {@link Builder}
300          */
asDefault()301         public Builder asDefault() {
302             mIsDefault = true;
303             return this;
304         }
305     }
306 }
307