parts: introduce berry styles
Change-Id: Ifaacc78eed5234cdbe2fd089a06524bdf1193c8f
Signed-off-by: Joey <joey@lineageos.org>
diff --git a/Android.mk b/Android.mk
index d73478c..12763b9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -9,6 +9,7 @@
android-support-v13 \
android-support-dynamic-animation \
android-support-v7-recyclerview \
+ android-support-v7-palette \
android-support-v7-preference \
android-support-v7-appcompat \
android-support-v14-preference \
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 152ddd5..6e2cd9b 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -189,6 +189,24 @@
android:resource="@string/summary_empty" />
</activity-alias>
+ <!-- Style settings (Display category) -->
+ <activity-alias
+ android:name=".style.StylePreferences"
+ android:label="@string/style_title"
+ android:targetActivity="PartsActivity">
+ <intent-filter android:priority="-3">
+ <action android:name="org.lineageos.lineageparts.action.SETTINGS" />
+ <action android:name="org.lineageos.lineageparts.STYLE_SETTINGS" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <meta-data
+ android:name="com.android.settings.category"
+ android:value="com.android.settings.category.ia.display" />
+ <meta-data
+ android:name="com.android.settings.summary"
+ android:resource="@string/style_summary" />
+ </activity-alias>
+
<!-- Anonymous Statistics -->
<receiver android:name=".lineagestats.ReportingServiceManager"
android:enabled="true"
diff --git a/res/drawable/ic_automagic.xml b/res/drawable/ic_automagic.xml
new file mode 100644
index 0000000..03f420f
--- /dev/null
+++ b/res/drawable/ic_automagic.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright (C) 2018 The LineageOS 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <path
+ android:fillColor="?android:attr/colorAccent"
+ android:pathData="M7.5,5.6L5,7L6.4,4.5L5,2L7.5,3.4L10,2L8.6,4.5L10,7L7.5,5.6M19.5,15.4L22,14L20.6,16.5L22,19L19.5,17.6L17,19L18.4,16.5L17,14L19.5,15.4M22,2L20.6,4.5L22,7L19.5,5.6L17,7L18.4,4.5L17,2L19.5,3.4L22,2M13.34,12.78L15.78,10.34L13.66,8.22L11.22,10.66L13.34,12.78M14.37,7.29L16.71,9.63C17.1,10 17.1,10.65 16.71,11.04L5.04,22.71C4.65,23.1 4,23.1 3.63,22.71L1.29,20.37C0.9,20 0.9,19.35 1.29,18.96L12.96,7.29C13.35,6.9 14,6.9 14.37,7.29Z" />
+</vector>
diff --git a/res/drawable/ic_style_auto.xml b/res/drawable/ic_style_auto.xml
new file mode 100644
index 0000000..80b6832
--- /dev/null
+++ b/res/drawable/ic_style_auto.xml
@@ -0,0 +1,27 @@
+<!--
+ Copyright (C) 2018 The LineageOS 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="?android:attr/colorAccent"
+ android:pathData="M19,5v14H5V5H19
+M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3L19,3z
+M10.7,13.3h2.6L12,9.2L10.7,13.3z
+M14.6,17l-0.8-2.2h-3.6L9.4,17H7.3l3.6-10h2.2l3.6,10H14.6z" />
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_style_dark.xml b/res/drawable/ic_style_dark.xml
new file mode 100644
index 0000000..5def313
--- /dev/null
+++ b/res/drawable/ic_style_dark.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright (C) 2018 The LineageOS 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="32.0"
+ android:viewportWidth="32.0">
+ <path
+ android:fillColor="?android:attr/colorAccent"
+ android:pathData="M26.86,17.31C25.97,22.93 21.2,27 15.51,27c-6.34,0 -11.5,-5.16 -11.5,-11.5S9.16,4 15.51,4c0.64,0 1.3,0.06 1.95,0.17c0.46,0.08 1.27,0.11 1.28,0.57c0,0.46 -0.23,0.31 -0.7,0.4c-3.5,0.69 -6.04,4.43 -6.04,7.8c0,3.9 3.16,7.07 7.04,7.07c2.51,0 5.58,-1.44 6.92,-3.77c0.18,-0.32 0.14,-0.52 0.48,-0.52c0.11,0 0.22,0.02 0.32,0.05C27.18,15.94 26.93,16.86 26.86,17.31z" />
+</vector>
diff --git a/res/drawable/ic_style_light.xml b/res/drawable/ic_style_light.xml
new file mode 100644
index 0000000..5ed6ff3
--- /dev/null
+++ b/res/drawable/ic_style_light.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright (C) 2018 The LineageOS 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="24.0"
+ android:viewportWidth="24.0">
+ <path
+ android:fillColor="?android:attr/colorAccent"
+ android:pathData="M6.76,4.84l-1.8,-1.79 -1.41,1.41 1.79,1.79 1.42,-1.41zM4,10.5L1,10.5v2h3v-2zM13,0.55h-2L11,3.5h2L13,0.55zM20.45,4.46l-1.41,-1.41 -1.79,1.79 1.41,1.41 1.79,-1.79zM17.24,18.16l1.79,1.8 1.41,-1.41 -1.8,-1.79 -1.4,1.4zM20,10.5v2h3v-2h-3zM12,5.5c-3.31,0 -6,2.69 -6,6s2.69,6 6,6 6,-2.69 6,-6 -2.69,-6 -6,-6zM11,22.45h2L13,19.5h-2v2.95zM3.55,18.54l1.41,1.41 1.79,-1.8 -1.41,-1.41 -1.79,1.8z" />
+</vector>
diff --git a/res/drawable/ic_style_time.xml b/res/drawable/ic_style_time.xml
new file mode 100644
index 0000000..c01b7aa
--- /dev/null
+++ b/res/drawable/ic_style_time.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright (C) 2018 The LineageOS 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="?android:attr/colorAccent"
+ android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8zM12.5,7H11v6l5.25,3.15 0.75,-1.23 -4.5,-2.67z"/>
+</vector>
diff --git a/res/layout/style_item_accent_preview.xml b/res/layout/style_item_accent_preview.xml
new file mode 100644
index 0000000..8dacdac
--- /dev/null
+++ b/res/layout/style_item_accent_preview.xml
@@ -0,0 +1,28 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/item_accent_layout"
+ android:layout_width="match_parent"
+ android:layout_height="48dp"
+ android:focusable="false"
+ android:paddingHorizontal="16dp"
+ android:paddingVertical="8dp"
+ android:focusableInTouchMode="false"
+ android:gravity="center_vertical"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:id="@+id/item_accent_preview"
+ android:layout_width="@dimen/style_accent_preview"
+ android:layout_height="@dimen/style_accent_preview"
+ android:layout_marginEnd="16dp"/>
+
+ <TextView
+ android:id="@+id/item_accent_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxLines="1"
+ android:ellipsize="end"
+ android:textColor="?android:textColorPrimary"
+ android:textSize="18sp"
+ tools:text="Default" />
+</LinearLayout>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 31fb124..9ef1f3b 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -365,4 +365,33 @@
<item>3</item>
</string-array>
+ <string-array name="style_entries" translatable="false">
+ <item>@string/style_global_entry_automatic</item>
+ <item>@string/style_global_entry_time</item>
+ <item>@string/style_global_entry_light</item>
+ <item>@string/style_global_entry_dark</item>
+ </string-array>
+
+ <!-- Global style values -->
+ <string-array name="style_values" translatable="false">
+ <item>0</item> <!-- Based on wallpaper -->
+ <item>1</item> <!-- Based on LiveDisplay -->
+ <item>2</item> <!-- Force light -->
+ <item>3</item> <!-- Force dark -->
+ </string-array>
+
+ <!-- Supported accent packages -->
+ <string-array name="accent_packages" translatable="false">
+ <item>org.lineageos.overlay.accent.red</item>
+ <item>org.lineageos.overlay.accent.pink</item>
+ <item>org.lineageos.overlay.accent.purple</item>
+ <item>org.lineageos.overlay.accent.blue</item>
+ <item>org.lineageos.overlay.accent.cyan</item>
+ <item>org.lineageos.overlay.accent.green</item>
+ <item>org.lineageos.overlay.accent.orange</item>
+ <item>org.lineageos.overlay.accent.yellow</item>
+ <item>org.lineageos.overlay.accent.brown</item>
+ <item>org.lineageos.overlay.accent.black</item>
+ </string-array>
+
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 9e31a1f..52ddb2d 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -55,5 +55,9 @@
<dimen name="fab_press_translation_z">9dp</dimen>
<dimen name="profile_instruction_padding">8dp</dimen>
+
+ <!-- Berry lite -->
+ <dimen name="style_accent_preview">32dp</dimen>
+ <dimen name="style_accent_icon">24dp</dimen>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1ce916d..4f5b47b 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -672,4 +672,22 @@
<!-- Egg: Title for the easter egg activity -->
<string name="egg_title" translatable="false">LineageOS Easter Egg</string>
+
+ <!-- Berry Lite -->
+ <string name="style_title">Style</string>
+ <string name="style_summary">Choose system colors</string>
+ <string name="style_global_title">Style</string>
+ <string name="style_global_entry_automatic">Automatic (wallpaper)</string>
+ <string name="style_global_entry_light">Light</string>
+ <string name="style_global_entry_dark">Dark</string>
+ <string name="style_global_entry_time">Automatic (time of the day)</string>
+ <string name="style_accent_title">Accent color</string>
+ <string name="style_accent_configuration_not_supported">The current accent isn\'t compatible with the selected style. In order to proceed another accent has to be selected, do you want to continue?</string>
+ <string name="style_accent_configuration_positive">Proceed</string>
+ <string name="style_automagic_title">Automagic</string>
+ <string name="style_automagic_description">Tune the style to match your wallpaper</string>
+ <string name="style_automagic_dialog_content">Suggested style: <b>%1$s</b> with <b>%2$s</b> accent.\nDo you want to apply it?</string>
+ <string name="style_automagic_dialog_positive">Apply</string>
+ <string name="style_accent_default_name">Default</string>
+ <string name="style_permission_error">Storage access permission is needed to analyze your wallpaper, please grant it to use this feature</string>
</resources>
diff --git a/res/xml/parts_catalog.xml b/res/xml/parts_catalog.xml
index 6318f03..db18231 100644
--- a/res/xml/parts_catalog.xml
+++ b/res/xml/parts_catalog.xml
@@ -116,4 +116,10 @@
android:summary="@string/touchscreen_gesture_settings_summary"
android:fragment="org.lineageos.lineageparts.gestures.TouchscreenGestureSettings"
lineage:xmlRes="@xml/touchscreen_gesture_settings" />
+
+ <part android:key="style"
+ android:title="@string/style_title"
+ android:summary="@string/style_summary"
+ android:fragment="org.lineageos.lineageparts.style.StylePreferences"
+ lineage:xmlRes="@xml/style_preferences" />
</parts-catalog>
diff --git a/res/xml/style_preferences.xml b/res/xml/style_preferences.xml
new file mode 100644
index 0000000..d623a9e
--- /dev/null
+++ b/res/xml/style_preferences.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2018 The LineageOS 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.
+-->
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <lineageos.preference.LineageSystemSettingListPreference
+ android:defaultValue="0"
+ android:entries="@array/style_entries"
+ android:entryValues="@array/style_values"
+ android:key="berry_global_style"
+ android:summary="%s"
+ android:icon="@drawable/ic_style_auto"
+ android:title="@string/style_global_title" />
+
+ <Preference
+ android:key="style_accent"
+ android:title="@string/style_accent_title" />
+
+ <Preference
+ android:key="style_automagic"
+ android:icon="@drawable/ic_automagic"
+ android:summary="@string/style_automagic_description"
+ android:title="@string/style_automagic_title" />
+
+</PreferenceScreen>
diff --git a/src/org/lineageos/lineageparts/style/StylePreferences.java b/src/org/lineageos/lineageparts/style/StylePreferences.java
new file mode 100644
index 0000000..8d9361c
--- /dev/null
+++ b/src/org/lineageos/lineageparts/style/StylePreferences.java
@@ -0,0 +1,402 @@
+/*
+ * Copyright (C) 2018 The LineageOS 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 org.lineageos.lineageparts.style;
+
+import android.Manifest;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.WallpaperManager;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.annotation.ColorInt;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v7.preference.Preference;
+import android.support.v7.graphics.Palette;
+import android.text.TextUtils;
+import android.util.Log;
+import android.widget.Toast;
+
+import org.lineageos.lineageparts.R;
+import org.lineageos.lineageparts.SettingsPreferenceFragment;
+import org.lineageos.lineageparts.style.models.Accent;
+import org.lineageos.lineageparts.style.models.Style;
+import org.lineageos.lineageparts.style.models.StyleStatus;
+import org.lineageos.lineageparts.style.util.AccentAdapter;
+import org.lineageos.lineageparts.style.util.AccentUtils;
+import org.lineageos.lineageparts.style.util.OverlayManager;
+import org.lineageos.lineageparts.style.util.UIUtils;
+
+import java.util.List;
+
+import lineageos.providers.LineageSettings;
+
+public class StylePreferences extends SettingsPreferenceFragment {
+ private static final String TAG = "StylePreferences";
+ private static final int INDEX_WALLPAPER = 0;
+ private static final int INDEX_TIME = 1;
+ private static final int INDEX_LIGHT = 2;
+ private static final int INDEX_DARK = 3;
+
+ private Preference mStylePref;
+ private Preference mAccentPref;
+
+ private List<Accent> mAccents;
+
+ private StyleStatus mStyleStatus;
+
+ private byte mOkStatus = 0;
+
+ @Override
+ public void onCreate(Bundle savedInstance) {
+ super.onCreate(savedInstance);
+
+ addPreferencesFromResource(R.xml.style_preferences);
+
+
+ mStylePref = findPreference("berry_global_style");
+ mStylePref.setOnPreferenceChangeListener(this::onStyleChange);
+ setupStylePref();
+
+ mAccents = AccentUtils.getAccents(getContext(), mStyleStatus);
+ mAccentPref = findPreference("style_accent");
+ mAccentPref.setOnPreferenceClickListener(this::onAccentClick);
+ setupAccentPref();
+
+ Preference automagic = findPreference("style_automagic");
+ automagic.setOnPreferenceClickListener(p -> onAutomagicClick());
+ }
+
+ private boolean onAccentClick(Preference preference) {
+ mAccents = AccentUtils.getAccents(getContext(), mStyleStatus);
+
+ new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.style_accent_title)
+ .setAdapter(new AccentAdapter(mAccents, getContext()),
+ (dialog, i) -> onAccentSelected(mAccents.get(i)))
+ .setNegativeButton(android.R.string.cancel, null)
+ .show();
+
+ return true;
+ }
+
+ private void setupAccentPref() {
+ String currentAccent = LineageSettings.System.getString(getContext().getContentResolver(),
+ LineageSettings.System.BERRY_CURRENT_ACCENT);
+ try {
+ updateAccentPref(AccentUtils.getAccent(getContext(), currentAccent));
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, currentAccent + ": package not found.");
+ }
+ }
+
+ private void onAccentSelected(Accent accent) {
+ String previousAccent = LineageSettings.System.getString(getContext().getContentResolver(),
+ LineageSettings.System.BERRY_CURRENT_ACCENT);
+
+ OverlayManager om = new OverlayManager(getContext());
+ if (!TextUtils.isEmpty(previousAccent)) {
+ // Disable previous theme
+ om.setEnabled(previousAccent, false);
+ }
+
+ LineageSettings.System.putString(getContext().getContentResolver(),
+ LineageSettings.System.BERRY_CURRENT_ACCENT, accent.getPackageName());
+
+ if (!TextUtils.isEmpty(accent.getPackageName())) {
+ // Enable new theme
+ om.setEnabled(accent.getPackageName(), true);
+ }
+ updateAccentPref(accent);
+ }
+
+ private void updateAccentPref(Accent accent) {
+ int size = getResources().getDimensionPixelSize(R.dimen.style_accent_icon);
+
+ mAccentPref.setSummary(accent.getName());
+ mAccentPref.setIcon(UIUtils.getAccentBitmap(getResources(), size, accent.getColor()));
+ }
+
+ private boolean onAutomagicClick() {
+ if (!hasStoragePermission()) {
+ Toast.makeText(getContext(), getString(R.string.style_permission_error),
+ Toast.LENGTH_LONG).show();
+ return false;
+ }
+
+ Bitmap bitmap = getWallpaperBitmap();
+ if (bitmap == null) {
+ return false;
+ }
+
+ Accent[] accentsArray = new Accent[mAccents.size()];
+ mAccents.toArray(accentsArray);
+
+ Palette palette = Palette.from(bitmap).generate();
+ new AutomagicTask(palette, this::onAutomagicCompleted).execute(accentsArray);
+
+ return true;
+ }
+
+ private void onAutomagicCompleted(Style style) {
+ String styleType = getString(style.isLight() ?
+ R.string.style_global_entry_light : R.string.style_global_entry_dark).toLowerCase();
+ String accentName = style.getAccent().getName().toLowerCase();
+ String message = getString(R.string.style_automagic_dialog_content, styleType, accentName);
+
+ new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.style_automagic_title)
+ .setMessage(message)
+ .setPositiveButton(R.string.style_automagic_dialog_positive,
+ (dialog, i) -> applyStyle(style))
+ .setNegativeButton(android.R.string.cancel,
+ (dialog, i) -> increaseOkStatus())
+ .show();
+ }
+
+ private void setupStylePref() {
+ int preference = LineageSettings.System.getInt(getContext().getContentResolver(),
+ LineageSettings.System.BERRY_GLOBAL_STYLE, INDEX_WALLPAPER);
+
+ setStyleIcon(preference);
+ switch (preference) {
+ case INDEX_LIGHT:
+ mStyleStatus = StyleStatus.LIGHT_ONLY;
+ break;
+ case INDEX_DARK:
+ mStyleStatus = StyleStatus.DARK_ONLY;
+ break;
+ default:
+ mStyleStatus = StyleStatus.DYNAMIC;
+ break;
+ }
+ }
+
+ private void applyStyle(Style style) {
+ int value = style.isLight() ? INDEX_LIGHT : INDEX_DARK;
+ LineageSettings.System.putInt(getContext().getContentResolver(),
+ LineageSettings.System.BERRY_GLOBAL_STYLE, value);
+
+ onStyleChange(mStylePref, value);
+ onAccentSelected(style.getAccent());
+ }
+
+ private boolean onStyleChange(Preference preference, Object newValue) {
+ Integer value;
+ if (newValue instanceof String) {
+ value = Integer.valueOf((String) newValue);
+ } else if (newValue instanceof Integer) {
+ value = (Integer) newValue;
+ } else {
+ return false;
+ }
+
+ boolean accentCompatibility = checkAccentCompatibility(value);
+ if (!accentCompatibility) {
+ new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.style_global_title)
+ .setMessage(R.string.style_accent_configuration_not_supported)
+ .setPositiveButton(R.string.style_accent_configuration_positive,
+ (dialog, i) -> onAccentConflict(value))
+ .setNegativeButton(android.R.string.cancel, null)
+ .show();
+ return false;
+ }
+
+ LineageSettings.System.putInt(getContext().getContentResolver(),
+ LineageSettings.System.BERRY_GLOBAL_STYLE, value);
+
+ setStyleIcon(value);
+ return true;
+ }
+
+ private void setStyleIcon(int value) {
+ int icon;
+ switch (value) {
+ case INDEX_TIME:
+ icon = R.drawable.ic_style_time;
+ break;
+ case INDEX_LIGHT:
+ icon = R.drawable.ic_style_light;
+ break;
+ case INDEX_DARK:
+ icon = R.drawable.ic_style_dark;
+ break;
+ default:
+ icon = R.drawable.ic_style_auto;
+ break;
+ }
+
+ mStylePref.setIcon(icon);
+ }
+
+ private boolean checkAccentCompatibility(int value) {
+ String currentAccentPkg = LineageSettings.System.getString(
+ getContext().getContentResolver(), LineageSettings.System.BERRY_CURRENT_ACCENT);
+ StyleStatus supportedStatus;
+ try {
+ supportedStatus = AccentUtils.getAccent(getContext(), currentAccentPkg)
+ .getSupportedStatus();
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, e.getMessage());
+ supportedStatus = StyleStatus.DYNAMIC;
+ }
+
+ switch (supportedStatus) {
+ case LIGHT_ONLY:
+ return value == INDEX_LIGHT;
+ case DARK_ONLY:
+ return value == INDEX_DARK;
+ case DYNAMIC:
+ default: // Never happens, but compilation fails without this
+ return true;
+ }
+ }
+
+ private void onAccentConflict(int value) {
+ StyleStatus proposedStatus;
+ switch (value) {
+ case INDEX_LIGHT:
+ proposedStatus = StyleStatus.LIGHT_ONLY;
+ break;
+ case INDEX_DARK:
+ proposedStatus = StyleStatus.DARK_ONLY;
+ break;
+ default:
+ proposedStatus = StyleStatus.DYNAMIC;
+ break;
+ }
+
+ // Let the user pick the new accent
+ List<Accent> accents = AccentUtils.getAccents(getContext(), proposedStatus);
+
+ new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.style_accent_title)
+ .setAdapter(new AccentAdapter(accents, getContext()),
+ (dialog, i) -> {
+ onAccentSelected(accents.get(i));
+ onStyleChange(mStylePref, value);
+ })
+ .setNegativeButton(android.R.string.cancel, null)
+ .show();
+ }
+
+ @Nullable
+ private Bitmap getWallpaperBitmap() {
+ WallpaperManager manager = WallpaperManager.getInstance(getContext());
+ Drawable wallpaper = manager.getDrawable();
+
+ if (wallpaper == null) {
+ return null;
+ }
+
+ if (wallpaper instanceof BitmapDrawable) {
+ return ((BitmapDrawable) wallpaper).getBitmap();
+ }
+
+ Bitmap bitmap = Bitmap.createBitmap(wallpaper.getIntrinsicWidth(),
+ wallpaper.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+ wallpaper.setBounds(0, 0 , canvas.getWidth(), canvas.getHeight());
+ wallpaper.draw(canvas);
+ return bitmap;
+ }
+
+ private boolean hasStoragePermission() {
+ Activity activity = getActivity();
+ return activity != null &&
+ activity.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) ==
+ PackageManager.PERMISSION_GRANTED;
+ }
+
+ private void increaseOkStatus() {
+ mOkStatus++;
+ if (mOkStatus != 2) {
+ return;
+ }
+
+ mOkStatus = (byte) 0;
+ new AlertDialog.Builder(getActivity())
+ .setTitle(android.R.string.ok)
+ .setPositiveButton(android.R.string.ok, null)
+ .show();
+ }
+
+ private static final class AutomagicTask extends AsyncTask<Accent, Void, Style> {
+ private static final int COLOR_DEFAULT = Color.BLACK;
+
+ private final Palette mPalette;
+ private final Callback mCallback;
+
+ AutomagicTask(Palette palette, Callback callback) {
+ mPalette = palette;
+ mCallback = callback;
+ }
+
+ @NonNull
+ @Override
+ public Style doInBackground(Accent... accents) {
+ int wallpaperColor = mPalette.getVibrantColor(COLOR_DEFAULT);
+
+ // If vibrant color extraction failed, let's try muted color
+ if (wallpaperColor == COLOR_DEFAULT) {
+ wallpaperColor = mPalette.getMutedColor(COLOR_DEFAULT);
+ }
+
+ boolean isLight = UIUtils.isColorLight(wallpaperColor);
+ Accent bestAccent = getBestAccent(accents, wallpaperColor, isLight);
+
+ return new Style(bestAccent, isLight);
+ }
+
+ @Override
+ public void onPostExecute(Style style) {
+ mCallback.onDone(style);
+ }
+
+ private Accent getBestAccent(Accent[] accents, int wallpaperColor, boolean isLight) {
+ int bestIndex = 0;
+ double minDiff = Double.MAX_VALUE;
+ StyleStatus targetStatus = isLight ? StyleStatus.LIGHT_ONLY : StyleStatus.DARK_ONLY;
+
+ for (int i = 0; i < accents.length; i++) {
+ double diff = diff(accents[i].getColor(), wallpaperColor);
+ if (diff < minDiff && AccentUtils.isCompatible(targetStatus, accents[i])) {
+ bestIndex = i;
+ minDiff = diff;
+ }
+ }
+
+ return accents[bestIndex];
+ }
+
+ private double diff(@ColorInt int accent, @ColorInt int wallpaper) {
+ return Math.sqrt(Math.pow(Color.red(accent) - Color.red(wallpaper), 2) +
+ Math.pow(Color.green(accent) - Color.green(wallpaper), 2) +
+ Math.pow(Color.blue(accent) - Color.blue(wallpaper), 2));
+ }
+ }
+
+ private interface Callback {
+ void onDone(Style style);
+ }
+}
\ No newline at end of file
diff --git a/src/org/lineageos/lineageparts/style/models/Accent.java b/src/org/lineageos/lineageparts/style/models/Accent.java
new file mode 100644
index 0000000..e416571
--- /dev/null
+++ b/src/org/lineageos/lineageparts/style/models/Accent.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2018 The LineageOS 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 org.lineageos.lineageparts.style.models;
+
+import android.support.annotation.ColorInt;
+import android.support.annotation.NonNull;
+
+public class Accent {
+ @NonNull
+ private final String name;
+ @NonNull
+ private final String packageName;
+ @ColorInt
+ private final int color;
+ private StyleStatus supportedStatus;
+
+ public Accent(@NonNull String name, @NonNull String packageName, @ColorInt int color,
+ StyleStatus supportedStatus) {
+ this.name = name;
+ this.packageName = packageName;
+ this.color = color;
+ this.supportedStatus = supportedStatus;
+ }
+
+ @NonNull
+ public String getName() {
+ return name;
+ }
+
+ @NonNull
+ public String getPackageName() {
+ return packageName;
+ }
+
+ @ColorInt
+ public int getColor() {
+ return color;
+ }
+
+ public StyleStatus getSupportedStatus() {
+ return supportedStatus;
+ }
+}
\ No newline at end of file
diff --git a/src/org/lineageos/lineageparts/style/models/Style.java b/src/org/lineageos/lineageparts/style/models/Style.java
new file mode 100644
index 0000000..8a602c9
--- /dev/null
+++ b/src/org/lineageos/lineageparts/style/models/Style.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2018 The LineageOS 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 org.lineageos.lineageparts.style.models;
+
+import android.support.annotation.NonNull;
+
+public class Style {
+ @NonNull
+ private Accent accent;
+ private boolean isLight;
+
+ public Style(@NonNull Accent accent, boolean isLight) {
+ this.accent = accent;
+ this.isLight = isLight;
+ }
+
+ @NonNull
+ public Accent getAccent() {
+ return accent;
+ }
+
+ public boolean isLight() {
+ return isLight;
+ }
+}
\ No newline at end of file
diff --git a/src/org/lineageos/lineageparts/style/models/StyleStatus.java b/src/org/lineageos/lineageparts/style/models/StyleStatus.java
new file mode 100644
index 0000000..22968bf
--- /dev/null
+++ b/src/org/lineageos/lineageparts/style/models/StyleStatus.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2018 The LineageOS 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 org.lineageos.lineageparts.style.models;
+
+public enum StyleStatus {
+ DYNAMIC,
+ LIGHT_ONLY,
+ DARK_ONLY
+}
\ No newline at end of file
diff --git a/src/org/lineageos/lineageparts/style/util/AccentAdapter.java b/src/org/lineageos/lineageparts/style/util/AccentAdapter.java
new file mode 100644
index 0000000..a0dfb5e
--- /dev/null
+++ b/src/org/lineageos/lineageparts/style/util/AccentAdapter.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2018 The LineageOS 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 org.lineageos.lineageparts.style.util;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import org.lineageos.lineageparts.R;
+import org.lineageos.lineageparts.style.models.Accent;
+
+import java.util.List;
+
+public class AccentAdapter extends BaseAdapter {
+ private List<Accent> mAccents;
+ private Context mContext;
+ private boolean isDark;
+
+ public AccentAdapter(List<Accent> accents, Context context) {
+ mAccents = accents;
+ mContext = context;
+ }
+
+ @Override
+ public int getCount() {
+ return mAccents.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return null;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return 0;
+ }
+
+ @Override
+ public View getView(int position, @Nullable View argView, @NonNull ViewGroup parent) {
+ View view = generateItemView(argView);
+ if (view == null) {
+ return null;
+ }
+
+ Resources r = mContext.getResources();
+ Accent accent = mAccents.get(position);
+
+ ImageView preview = view.findViewById(R.id.item_accent_preview);
+ TextView name = view.findViewById(R.id.item_accent_name);
+
+ preview.setImageDrawable(UIUtils.getAccentBitmap(r,
+ r.getDimensionPixelSize(R.dimen.style_accent_preview), accent.getColor()));
+ name.setText(accent.getName());
+
+ return view;
+ }
+
+ @Nullable
+ private View generateItemView(@Nullable View argView) {
+ if (argView == null) {
+ LayoutInflater inflater = LayoutInflater.from(mContext);
+ return (inflater == null) ? null :
+ inflater.inflate(R.layout.style_item_accent_preview, null);
+ } else {
+ return argView;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/org/lineageos/lineageparts/style/util/AccentUtils.java b/src/org/lineageos/lineageparts/style/util/AccentUtils.java
new file mode 100644
index 0000000..6ad69ad
--- /dev/null
+++ b/src/org/lineageos/lineageparts/style/util/AccentUtils.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2018 The LineageOS 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 org.lineageos.lineageparts.style.util;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.graphics.Color;
+import android.support.annotation.ColorInt;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import android.util.Log;
+
+import org.lineageos.lineageparts.R;
+import org.lineageos.lineageparts.style.models.Accent;
+import org.lineageos.lineageparts.style.models.StyleStatus;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public final class AccentUtils {
+ private static final String TAG = "AccentUtils";
+ private static final String METADATA_COLOR = "lineage_berry_accent_preview";
+ private static final String METADATA_SUPPORTED_STYLES = "lineage_berry_accent_supported_styles";
+ private static final String METADATA_STYLE_DEFAULT = "dark|light";
+ private static final String METADATA_STYLE_DARK = "dark";
+ private static final String METADATA_STYLE_LIGHT = "light";
+ private static final int DEFAULT_COLOR = Color.BLACK;
+
+ private AccentUtils() {
+ }
+
+ public static List<Accent> getAccents(Context context, StyleStatus status) {
+ List<Accent> accents = new ArrayList<>();
+
+ // Add default accent
+ accents.add(getDefaultAccent(context));
+
+ String[] targets = context.getResources().getStringArray(R.array.accent_packages);
+ for (String target : targets) {
+ try {
+ Accent accent = getAccent(context, target);
+ if (accent != null && isCompatible(status, accent)) {
+ accents.add(accent);
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, e.getMessage());
+ }
+ }
+
+ return accents;
+ }
+
+ @Nullable
+ public static Accent getAccent(Context context, @Nullable String target)
+ throws PackageManager.NameNotFoundException {
+ if (TextUtils.isEmpty(target)) {
+ return getDefaultAccent(context);
+ }
+
+ PackageManager pm = context.getPackageManager();
+ ApplicationInfo ai = pm.getApplicationInfo(target, PackageManager.GET_META_DATA);
+
+ String name = ai.loadLabel(pm).toString();
+ int color = ai.metaData == null ? DEFAULT_COLOR :
+ ai.metaData.getInt(METADATA_COLOR, DEFAULT_COLOR);
+
+ String supportedStyles = ai.metaData == null ? METADATA_STYLE_DEFAULT :
+ ai.metaData.getString(METADATA_SUPPORTED_STYLES, METADATA_STYLE_DEFAULT);
+ boolean supportsDark = supportedStyles.contains(METADATA_STYLE_DARK);
+ boolean supportsLight = supportedStyles.contains(METADATA_STYLE_LIGHT);
+ StyleStatus status = (supportsLight && supportsDark) ? StyleStatus.DYNAMIC :
+ supportsLight ? StyleStatus.LIGHT_ONLY : StyleStatus.DARK_ONLY;
+
+ return new Accent(name, ai.packageName, color, status);
+ }
+
+ @NonNull
+ private static Accent getDefaultAccent(Context context) {
+ return new Accent(context.getString(R.string.style_accent_default_name),
+ "", Color.parseColor("#167C80"), StyleStatus.DYNAMIC);
+ }
+
+ public static boolean isCompatible(StyleStatus currentStatus, Accent accent) {
+ StyleStatus accentStatus = accent.getSupportedStatus();
+ return accentStatus == StyleStatus.DYNAMIC || currentStatus == accentStatus;
+ }
+}
\ No newline at end of file
diff --git a/src/org/lineageos/lineageparts/style/util/OverlayManager.java b/src/org/lineageos/lineageparts/style/util/OverlayManager.java
new file mode 100644
index 0000000..353a571
--- /dev/null
+++ b/src/org/lineageos/lineageparts/style/util/OverlayManager.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2018 The LineageOS 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 org.lineageos.lineageparts.style.util;
+
+import android.content.Context;
+import android.content.om.IOverlayManager;
+import android.content.om.OverlayInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.support.annotation.NonNull;
+
+public class OverlayManager {
+ private OverlayHelper mHelper;
+ private PackageManager mPackageManager;
+
+ public OverlayManager(Context context) {
+ this(context, ServiceManager.getService("overlay") == null ?
+ null : new OverlayHelper());
+ }
+
+ private OverlayManager(Context context, OverlayHelper helper) {
+ mHelper = helper;
+ mPackageManager = context.getPackageManager();
+ }
+
+ public void setEnabled(@NonNull String pkg, boolean enabled) {
+ if (!isChangeableOverlay(pkg)) {
+ return;
+ }
+
+ mHelper.setEnabled(pkg, enabled, UserHandle.myUserId());
+ }
+
+ public boolean isEnabled(@NonNull String pkg) {
+ return mHelper.isEnabled(pkg, UserHandle.myUserId());
+ }
+
+ private boolean isChangeableOverlay(@NonNull String pkg) {
+ try {
+ PackageInfo pi = mPackageManager.getPackageInfo(pkg, 0);
+ return pi != null && !pi.isStaticOverlay;
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ }
+
+ static class OverlayHelper {
+ private final IOverlayManager mService;
+
+ OverlayHelper() {
+ mService = IOverlayManager.Stub.asInterface(ServiceManager.getService("overlay"));
+ }
+
+ public void setEnabled(@NonNull String pkg, boolean enabled, int userId) {
+ try {
+ mService.setEnabled(pkg, enabled, userId);
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ public boolean isEnabled(@NonNull String pkg, int userId) {
+ try {
+ return mService.getOverlayInfo(pkg, userId).isEnabled();
+ } catch (RemoteException ignored) {
+ }
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/org/lineageos/lineageparts/style/util/UIUtils.java b/src/org/lineageos/lineageparts/style/util/UIUtils.java
new file mode 100644
index 0000000..bf2bba0
--- /dev/null
+++ b/src/org/lineageos/lineageparts/style/util/UIUtils.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018 The LineageOS 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 org.lineageos.lineageparts.style.util;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.NonNull;
+import android.support.v4.graphics.ColorUtils;
+import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
+
+public final class UIUtils {
+
+ private UIUtils() {
+ }
+
+ @NonNull
+ public static Drawable getAccentBitmap(Resources resources, int size, int color) {
+ Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
+
+ Canvas canvas = new Canvas(bitmap);
+ Paint paint = new Paint();
+ RectF rect = new RectF(new Rect(0, 0, size, size));
+ paint.setAntiAlias(true);
+ paint.setColor(color);
+ canvas.drawRoundRect(rect, size / 2, size / 2, paint);
+
+ return RoundedBitmapDrawableFactory.create(resources, bitmap);
+ }
+
+ public static boolean isColorLight(int color) {
+ int red = Color.red(color);
+ int green = Color.green(color);
+ int blue = Color.blue(color);
+
+ float hsl[] = new float[3];
+ ColorUtils.RGBToHSL(red, green, blue, hsl);
+ return hsl[2] > 0.5f;
+ }
+}
\ No newline at end of file