• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.util;
18 
19 import static android.app.WallpaperColors.HINT_SUPPORTS_DARK_TEXT;
20 import static android.app.WallpaperColors.HINT_SUPPORTS_DARK_THEME;
21 
22 import android.app.WallpaperColors;
23 import android.app.WallpaperManager;
24 import android.content.Context;
25 import android.content.res.TypedArray;
26 import android.graphics.Color;
27 import android.graphics.ColorMatrix;
28 import android.graphics.drawable.Drawable;
29 import android.util.AttributeSet;
30 import android.util.SparseArray;
31 import android.util.TypedValue;
32 
33 import com.android.launcher3.R;
34 import com.android.launcher3.Utilities;
35 import com.android.launcher3.config.FeatureFlags;
36 import com.android.launcher3.icons.GraphicsUtils;
37 
38 /**
39  * Various utility methods associated with theming.
40  */
41 @SuppressWarnings("NewApi")
42 public class Themes {
43 
44     public static final String KEY_THEMED_ICONS = "themed_icons";
45 
getActivityThemeRes(Context context)46     public static int getActivityThemeRes(Context context) {
47         final int colorHints;
48         if (Utilities.ATLEAST_P) {
49             WallpaperColors colors = context.getSystemService(WallpaperManager.class)
50                     .getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
51             colorHints = colors == null ? 0 : colors.getColorHints();
52         } else {
53             colorHints = 0;
54         }
55         return getActivityThemeRes(context, colorHints);
56     }
57 
getActivityThemeRes(Context context, int wallpaperColorHints)58     public static int getActivityThemeRes(Context context, int wallpaperColorHints) {
59         boolean supportsDarkText = Utilities.ATLEAST_S
60                 && (wallpaperColorHints & HINT_SUPPORTS_DARK_TEXT) != 0;
61         boolean isMainColorDark = Utilities.ATLEAST_S
62                 && (wallpaperColorHints & HINT_SUPPORTS_DARK_THEME) != 0;
63 
64         if (Utilities.isDarkTheme(context)) {
65             return supportsDarkText ? R.style.AppTheme_Dark_DarkText
66                     : isMainColorDark ? R.style.AppTheme_Dark_DarkMainColor : R.style.AppTheme_Dark;
67         } else {
68             return supportsDarkText ? R.style.AppTheme_DarkText
69                     : isMainColorDark ? R.style.AppTheme_DarkMainColor : R.style.AppTheme;
70         }
71     }
72 
73     /**
74      * Returns true if workspace icon theming is enabled
75      */
isThemedIconEnabled(Context context)76     public static boolean isThemedIconEnabled(Context context) {
77         return FeatureFlags.ENABLE_THEMED_ICONS.get()
78                 && Utilities.getPrefs(context).getBoolean(KEY_THEMED_ICONS, false);
79     }
80 
getDefaultBodyFont(Context context)81     public static String getDefaultBodyFont(Context context) {
82         TypedArray ta = context.obtainStyledAttributes(android.R.style.TextAppearance_DeviceDefault,
83                 new int[]{android.R.attr.fontFamily});
84         String value = ta.getString(0);
85         ta.recycle();
86         return value;
87     }
88 
getDialogCornerRadius(Context context)89     public static float getDialogCornerRadius(Context context) {
90         return getDimension(context, android.R.attr.dialogCornerRadius,
91                 context.getResources().getDimension(R.dimen.default_dialog_corner_radius));
92     }
93 
getDimension(Context context, int attr, float defaultValue)94     public static float getDimension(Context context, int attr, float defaultValue) {
95         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
96         float value = ta.getDimension(0, defaultValue);
97         ta.recycle();
98         return value;
99     }
100 
getColorAccent(Context context)101     public static int getColorAccent(Context context) {
102         return getAttrColor(context, android.R.attr.colorAccent);
103     }
104 
105     /** Returns the background color attribute. */
getColorBackground(Context context)106     public static int getColorBackground(Context context) {
107         return getAttrColor(context, android.R.attr.colorBackground);
108     }
109 
110     /** Returns the floating background color attribute. */
getColorBackgroundFloating(Context context)111     public static int getColorBackgroundFloating(Context context) {
112         return getAttrColor(context, android.R.attr.colorBackgroundFloating);
113     }
114 
getAttrColor(Context context, int attr)115     public static int getAttrColor(Context context, int attr) {
116         return GraphicsUtils.getAttrColor(context, attr);
117     }
118 
getAttrBoolean(Context context, int attr)119     public static boolean getAttrBoolean(Context context, int attr) {
120         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
121         boolean value = ta.getBoolean(0, false);
122         ta.recycle();
123         return value;
124     }
125 
getAttrDrawable(Context context, int attr)126     public static Drawable getAttrDrawable(Context context, int attr) {
127         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
128         Drawable value = ta.getDrawable(0);
129         ta.recycle();
130         return value;
131     }
132 
getAttrInteger(Context context, int attr)133     public static int getAttrInteger(Context context, int attr) {
134         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
135         int value = ta.getInteger(0, 0);
136         ta.recycle();
137         return value;
138     }
139 
140     /**
141      * Scales a color matrix such that, when applied to color R G B A, it produces R' G' B' A' where
142      * R' = r * R
143      * G' = g * G
144      * B' = b * B
145      * A' = a * A
146      *
147      * The matrix will, for instance, turn white into r g b a, and black will remain black.
148      *
149      * @param color The color r g b a
150      * @param target The ColorMatrix to scale
151      */
setColorScaleOnMatrix(int color, ColorMatrix target)152     public static void setColorScaleOnMatrix(int color, ColorMatrix target) {
153         target.setScale(Color.red(color) / 255f, Color.green(color) / 255f,
154                 Color.blue(color) / 255f, Color.alpha(color) / 255f);
155     }
156 
157     /**
158      * Changes a color matrix such that, when applied to srcColor, it produces dstColor.
159      *
160      * Note that values on the last column of target ColorMatrix can be negative, and may result in
161      * negative values when applied on a color. Such negative values will be automatically shifted
162      * up to 0 by the framework.
163      *
164      * @param srcColor The color to start from
165      * @param dstColor The color to create by applying target on srcColor
166      * @param target The ColorMatrix to transform the color
167      */
setColorChangeOnMatrix(int srcColor, int dstColor, ColorMatrix target)168     public static void setColorChangeOnMatrix(int srcColor, int dstColor, ColorMatrix target) {
169         target.reset();
170         target.getArray()[4] = Color.red(dstColor) - Color.red(srcColor);
171         target.getArray()[9] = Color.green(dstColor) - Color.green(srcColor);
172         target.getArray()[14] = Color.blue(dstColor) - Color.blue(srcColor);
173         target.getArray()[19] = Color.alpha(dstColor) - Color.alpha(srcColor);
174     }
175 
176     /**
177      * Creates a map for attribute-name to value for all the values in {@param attrs} which can be
178      * held in memory for later use.
179      */
createValueMap(Context context, AttributeSet attrSet, IntArray keysToIgnore)180     public static SparseArray<TypedValue> createValueMap(Context context, AttributeSet attrSet,
181             IntArray keysToIgnore) {
182         int count = attrSet.getAttributeCount();
183         IntArray attrNameArray = new IntArray(count);
184         for (int i = 0; i < count; i++) {
185             attrNameArray.add(attrSet.getAttributeNameResource(i));
186         }
187         attrNameArray.removeAllValues(keysToIgnore);
188 
189         int[] attrNames = attrNameArray.toArray();
190         SparseArray<TypedValue> result = new SparseArray<>(attrNames.length);
191         TypedArray ta = context.obtainStyledAttributes(attrSet, attrNames);
192         for (int i = 0; i < attrNames.length; i++) {
193             TypedValue tv = new TypedValue();
194             ta.getValue(i, tv);
195             result.put(attrNames[i], tv);
196         }
197 
198         return result;
199     }
200 }
201