Inspired by https://github.com/DotOS/android_packages_apps_Customizations Change-Id: I96670305884efaae8ba1d707ddd406375ed78ed1 Co-authored-by: Adithya R <gh0strider.2k18.reborn@gmail.com>lineage-19.1
parent
025087c2da
commit
814ffba7d5
@ -0,0 +1,8 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:shape="oval"> |
||||
<size |
||||
android:width="@dimen/component_color_chip_medium_size" |
||||
android:height="@dimen/component_color_chip_medium_size" /> |
||||
<solid android:color="@android:color/black" /> |
||||
</shape> |
@ -0,0 +1,10 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<item> |
||||
<shape android:shape="rectangle"> |
||||
<corners android:topLeftRadius="@dimen/component_color_chip_small_size_default" /> |
||||
<size android:width="@dimen/component_color_chip_small_size_default" android:height="@dimen/component_color_chip_small_size_default" /> |
||||
<solid android:color="@android:color/black" /> |
||||
</shape> |
||||
</item> |
||||
</selector> |
@ -0,0 +1,10 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<item> |
||||
<shape android:shape="rectangle"> |
||||
<corners android:bottomLeftRadius="@dimen/component_color_chip_small_size_default" /> |
||||
<size android:width="@dimen/component_color_chip_small_size_default" android:height="@dimen/component_color_chip_small_size_default" /> |
||||
<solid android:color="@android:color/black" /> |
||||
</shape> |
||||
</item> |
||||
</selector> |
@ -0,0 +1,10 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<item> |
||||
<shape android:shape="rectangle"> |
||||
<corners android:topRightRadius="@dimen/component_color_chip_small_size_default" /> |
||||
<size android:width="@dimen/component_color_chip_small_size_default" android:height="@dimen/component_color_chip_small_size_default" /> |
||||
<solid android:color="@android:color/black" /> |
||||
</shape> |
||||
</item> |
||||
</selector> |
@ -0,0 +1,10 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<item> |
||||
<shape android:shape="rectangle"> |
||||
<corners android:bottomRightRadius="@dimen/component_color_chip_small_size_default" /> |
||||
<size android:width="@dimen/component_color_chip_small_size_default" android:height="@dimen/component_color_chip_small_size_default" /> |
||||
<solid android:color="@android:color/black" /> |
||||
</shape> |
||||
</item> |
||||
</selector> |
@ -0,0 +1,24 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:clipChildren="false" |
||||
android:clipToPadding="false" |
||||
android:orientation="vertical" |
||||
android:paddingBottom="@dimen/color_option_tile_padding_bottom"> |
||||
|
||||
<RelativeLayout |
||||
android:id="@+id/option_tile" |
||||
android:layout_width="@dimen/option_tile_width_big" |
||||
android:layout_height="@dimen/option_tile_width_big" |
||||
android:layout_gravity="center_horizontal" |
||||
android:background="@drawable/option_border_color" |
||||
android:gravity="center"> |
||||
|
||||
<ImageView |
||||
android:id="@+id/color_preview_icon" |
||||
android:layout_width="@dimen/component_color_chip_container_medium_size" |
||||
android:layout_height="@dimen/component_color_chip_container_medium_size" |
||||
android:layout_marginHorizontal="@dimen/color_option_tile_margin_horizontal" /> |
||||
</RelativeLayout> |
||||
</FrameLayout> |
@ -0,0 +1,6 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:id="@+id/color_option_container" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:orientation="horizontal" /> |
@ -0,0 +1,27 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<com.google.android.customization.picker.color.ColorSectionView |
||||
xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:orientation="vertical"> |
||||
|
||||
<FrameLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:paddingHorizontal="@dimen/separated_tabs_horizontal_margin"> |
||||
|
||||
<include layout="@layout/separated_tabs" /> |
||||
</FrameLayout> |
||||
|
||||
<androidx.viewpager2.widget.ViewPager2 |
||||
android:id="@+id/color_view_pager" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="@dimen/color_options_container_top_margin" |
||||
android:clipChildren="false" |
||||
android:clipToPadding="false" |
||||
android:minHeight="@dimen/color_options_container_min_height" |
||||
android:paddingHorizontal="@dimen/section_horizontal_padding" /> |
||||
|
||||
|
||||
</com.google.android.customization.picker.color.ColorSectionView> |
@ -0,0 +1,53 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:clipChildren="false" |
||||
android:clipToPadding="false" |
||||
android:orientation="vertical" |
||||
android:paddingBottom="@dimen/color_option_tile_padding_bottom"> |
||||
|
||||
<FrameLayout |
||||
android:id="@+id/option_tile" |
||||
android:layout_width="@dimen/option_tile_width_big" |
||||
android:layout_height="@dimen/option_tile_width_big" |
||||
android:layout_gravity="center_horizontal" |
||||
android:background="@drawable/option_border_color"> |
||||
|
||||
<ImageView |
||||
android:id="@+id/color_preview_0" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_gravity="center" |
||||
android:layout_marginEnd="@dimen/color_seed_chip_margin" |
||||
android:layout_marginBottom="@dimen/color_seed_chip_margin" |
||||
android:src="@drawable/color_chip_seed_filled0" /> |
||||
|
||||
<ImageView |
||||
android:id="@+id/color_preview_1" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_gravity="center" |
||||
android:layout_marginStart="@dimen/color_seed_chip_margin" |
||||
android:layout_marginBottom="@dimen/color_seed_chip_margin" |
||||
android:src="@drawable/color_chip_seed_filled2" /> |
||||
|
||||
<ImageView |
||||
android:id="@+id/color_preview_2" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_gravity="center" |
||||
android:layout_marginTop="@dimen/color_seed_chip_margin" |
||||
android:layout_marginEnd="@dimen/color_seed_chip_margin" |
||||
android:src="@drawable/color_chip_seed_filled1" /> |
||||
|
||||
<ImageView |
||||
android:id="@+id/color_preview_3" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_gravity="center" |
||||
android:layout_marginStart="@dimen/color_seed_chip_margin" |
||||
android:layout_marginTop="@dimen/color_seed_chip_margin" |
||||
android:src="@drawable/color_chip_seed_filled3" /> |
||||
</FrameLayout> |
||||
</FrameLayout> |
@ -0,0 +1,34 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<!-- |
||||
|
||||
Copyright (C) 2018 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. |
||||
--> |
||||
<resources> |
||||
<!-- Color section --> |
||||
<dimen name="color_option_tile_margin_horizontal">2dp</dimen> |
||||
<dimen name="color_option_tile_padding_bottom">11dp</dimen> |
||||
<dimen name="color_options_container_min_height">96dp</dimen> |
||||
<dimen name="color_options_container_top_margin">24dp</dimen> |
||||
<dimen name="color_seed_chip_margin">12dp</dimen> |
||||
<dimen name="color_seed_option_tile_padding">10dp</dimen> |
||||
<dimen name="color_seed_option_tile_padding_selected">6dp</dimen> |
||||
<dimen name="component_color_chip_container_medium_size">48dp</dimen> |
||||
<dimen name="component_color_chip_medium_size">48dp</dimen> |
||||
<dimen name="component_color_chip_small_size_default">24dp</dimen> |
||||
<dimen name="component_color_chip_small_size_selected">32dp</dimen> |
||||
<dimen name="option_tile_width_big">82dp</dimen> |
||||
<!-- Default page horizontal margin (24dp) - separated tabs inset horizontal (4dp) --> |
||||
<dimen name="separated_tabs_horizontal_margin">20dp</dimen> |
||||
</resources> |
@ -0,0 +1,59 @@ |
||||
package com.google.android.customization.model.color |
||||
|
||||
import android.annotation.SuppressLint |
||||
import android.content.res.ColorStateList |
||||
import android.content.res.Configuration |
||||
import android.graphics.drawable.GradientDrawable |
||||
import android.view.View |
||||
import android.widget.ImageView |
||||
import com.android.wallpaper.R |
||||
|
||||
class ColorBundle( |
||||
title: String?, |
||||
map: Map<String?, String?>?, |
||||
isDefault: Boolean, |
||||
index: Int, |
||||
private val mPreviewInfo: PreviewInfo |
||||
) : ColorOption( |
||||
title!!, map!!, isDefault, index |
||||
) { |
||||
class PreviewInfo( |
||||
val secondaryColorLight: Int, |
||||
val secondaryColorDark: Int, |
||||
) |
||||
|
||||
@SuppressLint("UseCompatLoadingForDrawables") |
||||
override fun bindThumbnailTile(view: View) { |
||||
val resources = view.context.resources |
||||
val thumbnailView = view.findViewById<ImageView>(R.id.color_preview_icon) |
||||
val secondaryColor = |
||||
if ((resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES) mPreviewInfo.secondaryColorDark |
||||
else mPreviewInfo.secondaryColorLight |
||||
val gradientDrawable = view.resources.getDrawable( |
||||
R.drawable.color_chip_medium_filled, thumbnailView.context.theme |
||||
) as GradientDrawable |
||||
if (secondaryColor != 0) { |
||||
gradientDrawable.setTintList(ColorStateList.valueOf(secondaryColor)) |
||||
} else { |
||||
gradientDrawable.setTintList(ColorStateList.valueOf(resources.getColor(R.color.material_white_100))) |
||||
} |
||||
thumbnailView.setImageDrawable(gradientDrawable) |
||||
val context = view.context |
||||
if (mContentDescription == null) { |
||||
val string = context.getString(R.string.default_theme_title) |
||||
mContentDescription = if (mIsDefault) { |
||||
string |
||||
} else { |
||||
mTitle |
||||
} |
||||
} |
||||
view.contentDescription = mContentDescription |
||||
} |
||||
|
||||
override fun getLayoutResId(): Int { |
||||
return R.layout.color_option |
||||
} |
||||
|
||||
override val source: String |
||||
get() = "preset" |
||||
} |
@ -0,0 +1,238 @@ |
||||
package com.google.android.customization.model.color |
||||
|
||||
import android.app.WallpaperColors |
||||
import android.content.ContentResolver |
||||
import android.content.Context |
||||
import android.database.ContentObserver |
||||
import android.net.Uri |
||||
import android.os.Handler |
||||
import android.os.Looper |
||||
import android.os.SystemClock |
||||
import android.provider.Settings |
||||
import android.text.TextUtils |
||||
import android.util.Log |
||||
import com.android.wallpaper.R |
||||
import com.android.customization.model.CustomizationManager |
||||
import com.android.customization.model.CustomizationManager.OptionsFetchedListener |
||||
import com.google.android.customization.picker.color.ColorSectionView |
||||
import org.json.JSONException |
||||
import org.json.JSONObject |
||||
import java.util.concurrent.Executors |
||||
|
||||
class ColorCustomizationManager( |
||||
val mProvider: ColorOptionsProvider, |
||||
private val mContentResolver: ContentResolver |
||||
) : CustomizationManager<ColorOption> { |
||||
var mCurrentOverlays: Map<String, String>? = null |
||||
private var mCurrentSource: String? = null |
||||
var mHomeWallpaperColors: WallpaperColors? = null |
||||
var mLockWallpaperColors: WallpaperColors? = null |
||||
|
||||
companion object { |
||||
var COLOR_OVERLAY_SETTINGS: Set<String>? = null |
||||
private var sColorCustomizationManager: ColorCustomizationManager? = null |
||||
val sExecutorService = Executors.newSingleThreadExecutor()!! |
||||
fun getInstance( |
||||
context: Context |
||||
): ColorCustomizationManager? { |
||||
if (sColorCustomizationManager == null) { |
||||
val applicationContext = context.applicationContext |
||||
sColorCustomizationManager = ColorCustomizationManager( |
||||
ColorProvider( |
||||
applicationContext, applicationContext.getString( |
||||
R.string.themes_stub_package |
||||
) |
||||
), applicationContext.contentResolver |
||||
) |
||||
} |
||||
return sColorCustomizationManager |
||||
} |
||||
|
||||
init { |
||||
val hashSet = HashSet<String>() |
||||
COLOR_OVERLAY_SETTINGS = hashSet |
||||
hashSet.add("android.theme.customization.system_palette") |
||||
hashSet.add("android.theme.customization.accent_color") |
||||
hashSet.add("android.theme.customization.color_source") |
||||
} |
||||
} |
||||
|
||||
init { |
||||
mContentResolver.registerContentObserver(Settings.Secure.CONTENT_URI, true, object : |
||||
ContentObserver(Handler(Looper.getMainLooper())) { |
||||
override fun onChange(selfChange: Boolean, uri: Uri?) { |
||||
super.onChange(selfChange, uri) |
||||
if (TextUtils.equals( |
||||
uri!!.lastPathSegment, |
||||
"theme_customization_overlay_packages" |
||||
) |
||||
) { |
||||
mCurrentOverlays = null |
||||
} |
||||
|
||||
} |
||||
}) |
||||
} |
||||
|
||||
val currentColorSource: String? |
||||
get() { |
||||
if (mCurrentSource == null) { |
||||
parseSettings(storedOverlays) |
||||
} |
||||
return mCurrentSource |
||||
} |
||||
val storedOverlays: String? |
||||
get() = Settings.Secure.getString(mContentResolver, "theme_customization_overlay_packages") |
||||
|
||||
fun parseSettings(str: String?) { |
||||
val hashMap = HashMap<String, String>() |
||||
if (str != null) { |
||||
try { |
||||
val jSONObject = JSONObject(str) |
||||
val names = jSONObject.names() |
||||
if (names != null) { |
||||
for (i in 0 until names.length()) { |
||||
val string = names.getString(i) |
||||
if ((COLOR_OVERLAY_SETTINGS as HashSet<String>?)!!.contains(string)) { |
||||
try { |
||||
hashMap[string] = jSONObject.getString(string) |
||||
} catch (e: JSONException) { |
||||
Log.e( |
||||
"ColorCustomizationManager", |
||||
"parseColorOverlays: " + e.localizedMessage, |
||||
e |
||||
) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} catch (e2: JSONException) { |
||||
Log.e("ColorCustomizationManager", e2.localizedMessage!!) |
||||
} |
||||
} |
||||
mCurrentSource = hashMap.remove("android.theme.customization.color_source") |
||||
mCurrentOverlays = hashMap |
||||
} |
||||
|
||||
override fun isAvailable(): Boolean { |
||||
return true |
||||
} |
||||
|
||||
fun setThemeBundle(colorSectionController: ColorSectionController, option: ColorOption) { |
||||
if (SystemClock.elapsedRealtime() - colorSectionController.mLastColorApplyingTime >= 500) { |
||||
colorSectionController.mLastColorApplyingTime = SystemClock.elapsedRealtime() |
||||
val callback: CustomizationManager.Callback = object : CustomizationManager.Callback { |
||||
override fun onError(th2: Throwable?) { |
||||
Log.w("ColorSectionController", "Apply theme with error: null") |
||||
} |
||||
|
||||
override fun onSuccess() { |
||||
val colorSectionView: ColorSectionView = |
||||
colorSectionController.mColorSectionView!! |
||||
colorSectionView.announceForAccessibility( |
||||
colorSectionView.context.getString( |
||||
R.string.color_changed |
||||
) |
||||
) |
||||
val wallpaperColors = colorSectionController.mLockWallpaperColors |
||||
var i3 = 0 |
||||
val z2 = |
||||
wallpaperColors == null || wallpaperColors == colorSectionController.mHomeWallpaperColors |
||||
if (TextUtils.equals(option.source, "preset")) { |
||||
i3 = 26 |
||||
} else if (z2) { |
||||
i3 = 25 |
||||
} else { |
||||
val source = option.source |
||||
if (source == "lock_wallpaper") { |
||||
i3 = 24 |
||||
} else if (source == "home_wallpaper") { |
||||
i3 = 23 |
||||
} |
||||
} |
||||
colorSectionController.mEventLogger.logColorApplied(i3, option.mIndex) |
||||
} |
||||
} |
||||
sExecutorService.submit { |
||||
applyBundle(option, callback) |
||||
} |
||||
return |
||||
} |
||||
} |
||||
|
||||
private fun applyBundle(option: ColorOption, callback: CustomizationManager.Callback) { |
||||
var mStoredOverlays = storedOverlays |
||||
if (TextUtils.isEmpty(mStoredOverlays) || mStoredOverlays == null) { |
||||
mStoredOverlays = "{}" |
||||
} |
||||
var z4: Boolean |
||||
var jSONObject: JSONObject? = null |
||||
try { |
||||
jSONObject = JSONObject(mStoredOverlays) |
||||
try { |
||||
val jsonPackages: JSONObject = option.getJsonPackages(true) |
||||
val it: Iterator<*> = |
||||
(COLOR_OVERLAY_SETTINGS as HashSet?)!!.iterator() |
||||
while (it.hasNext()) { |
||||
jSONObject.remove(it.next() as String?) |
||||
} |
||||
val keys: Iterator<String> = jsonPackages.keys() |
||||
while (keys.hasNext()) { |
||||
val next = keys.next() |
||||
jSONObject.put(next, jsonPackages.get(next)) |
||||
} |
||||
jSONObject.put( |
||||
"android.theme.customization.color_source", |
||||
option.source |
||||
) |
||||
jSONObject.put( |
||||
"android.theme.customization.color_index", |
||||
option.mIndex.toString() |
||||
) |
||||
if ("preset" != option.source) { |
||||
val wallpaperColors = mLockWallpaperColors |
||||
if (wallpaperColors != null && wallpaperColors != mHomeWallpaperColors) { |
||||
z4 = false |
||||
jSONObject.put( |
||||
"android.theme.customization.color_both", |
||||
if (!z4) "1" else "0" |
||||
) |
||||
} |
||||
z4 = true |
||||
jSONObject.put( |
||||
"android.theme.customization.color_both", |
||||
if (!z4) "1" else "0" |
||||
) |
||||
} else { |
||||
jSONObject.remove("android.theme.customization.color_both") |
||||
} |
||||
} catch (e2: JSONException) { |
||||
e2.printStackTrace() |
||||
Handler(Looper.getMainLooper()).post { |
||||
val success = Settings.Secure.putString( |
||||
mContentResolver, |
||||
"theme_customization_overlay_packages", jSONObject.toString() |
||||
) |
||||
if (success) callback.onSuccess() |
||||
else callback.onError(null) |
||||
} |
||||
return |
||||
} |
||||
} catch (e3: JSONException) { |
||||
e3.printStackTrace() |
||||
} |
||||
Handler(Looper.getMainLooper()).post { |
||||
val success = jSONObject != null && Settings.Secure.putString( |
||||
mContentResolver, |
||||
"theme_customization_overlay_packages", jSONObject.toString() |
||||
) |
||||
if (success) callback.onSuccess() |
||||
else callback.onError(null) |
||||
} |
||||
} |
||||
|
||||
override fun apply(option: ColorOption, callback: CustomizationManager.Callback) { |
||||
applyBundle(option, callback) |
||||
} |
||||
override fun fetchOptions(callback: OptionsFetchedListener<ColorOption>, reload: Boolean) {} |
||||
} |
@ -0,0 +1,97 @@ |
||||
package com.google.android.customization.model.color |
||||
|
||||
import android.text.TextUtils |
||||
import android.util.Log |
||||
import com.android.customization.model.CustomizationManager |
||||
import com.android.customization.model.CustomizationOption |
||||
import org.json.JSONException |
||||
import org.json.JSONObject |
||||
import java.util.* |
||||
import java.util.stream.Collectors |
||||
|
||||
abstract class ColorOption( |
||||
val mTitle: String, |
||||
map: Map<String?, String?>, |
||||
val mIsDefault: Boolean, |
||||
val mIndex: Int |
||||
) : CustomizationOption<ColorOption> { |
||||
var mContentDescription: CharSequence? = null |
||||
private val mPackagesByCategory: Map<String?, String?> |
||||
|
||||
fun getJsonPackages(z: Boolean): JSONObject { |
||||
val jSONObject: JSONObject = if (mIsDefault) { |
||||
JSONObject() |
||||
} else { |
||||
val jSONObject2 = JSONObject(mPackagesByCategory) |
||||
val keys = jSONObject2.keys() |
||||
val hashSet: HashSet<String> = HashSet<String>() |
||||
while (keys.hasNext()) { |
||||
val next = keys.next() |
||||
if (jSONObject2.isNull(next)) { |
||||
hashSet.add(next) |
||||
} |
||||
} |
||||
val it: Iterator<*> = hashSet.iterator() |
||||
while (it.hasNext()) { |
||||
jSONObject2.remove(it.next() as String?) |
||||
} |
||||
jSONObject2 |
||||
} |
||||
if (z) { |
||||
try { |
||||
jSONObject.put(TIMESTAMP_FIELD, System.currentTimeMillis()) |
||||
} catch (unused: JSONException) { |
||||
Log.e("ColorOption", "Couldn't add timestamp to serialized themebundle") |
||||
} |
||||
} |
||||
return jSONObject |
||||
} |
||||
|
||||
abstract val source: String |
||||
|
||||
override fun getTitle(): String { |
||||
return mTitle |
||||
} |
||||
|
||||
override fun isActive(customizationManager: CustomizationManager<ColorOption>): Boolean { |
||||
val colorCustomizationManager = customizationManager as ColorCustomizationManager |
||||
if (mIsDefault) { |
||||
val storedOverlays = colorCustomizationManager.storedOverlays |
||||
if (!TextUtils.isEmpty(storedOverlays) && "{}" != storedOverlays) { |
||||
if (colorCustomizationManager.mCurrentOverlays == null) { |
||||
colorCustomizationManager.parseSettings(colorCustomizationManager.storedOverlays) |
||||
} |
||||
if (colorCustomizationManager.mCurrentOverlays!!.isNotEmpty() && |
||||
(storedOverlays!!.contains("android.theme.customization.system_palette") || |
||||
storedOverlays.contains("android.theme.customization.accent_color")) |
||||
) { |
||||
return false |
||||
} |
||||
} |
||||
return true |
||||
} |
||||
if (colorCustomizationManager.mCurrentOverlays == null) { |
||||
colorCustomizationManager.parseSettings(colorCustomizationManager.storedOverlays) |
||||
} |
||||
val map = colorCustomizationManager.mCurrentOverlays |
||||
val currentColorSource = colorCustomizationManager.currentColorSource |
||||
return (TextUtils.isEmpty(currentColorSource) || source == currentColorSource) && mPackagesByCategory == map |
||||
} |
||||
|
||||
companion object { |
||||
const val TIMESTAMP_FIELD = "_applied_timestamp" |
||||
} |
||||
|
||||
init { |
||||
mPackagesByCategory = Collections.unmodifiableMap( |
||||
map.entries.stream().filter { t -> t.value != null } |
||||
.collect( |
||||
Collectors.toMap( |
||||
{ t -> t.key }, |
||||
{ t -> t.value } |
||||
) |
||||
) as Map<String?, String?> |
||||
) |
||||
|
||||
} |
||||
} |
@ -0,0 +1,3 @@ |
||||
package com.google.android.customization.model.color |
||||
|
||||
interface ColorOptionsProvider |
@ -0,0 +1,241 @@ |
||||
package com.google.android.customization.model.color |
||||
|
||||
import android.app.WallpaperColors |
||||
import android.content.Context |
||||
import android.content.res.ColorStateList |
||||
import android.util.Log |
||||
import androidx.core.graphics.ColorUtils |
||||
import com.android.customization.model.ResourcesApkProvider |
||||
import com.android.wallpaper.compat.WallpaperManagerCompat |
||||
import com.android.wallpaper.module.InjectorProvider |
||||
import com.android.systemui.monet.ColorScheme |
||||
import com.google.android.customization.model.color.ColorUtils.toColorString |
||||
import kotlinx.coroutines.CoroutineScope |
||||
import java.util.* |
||||
import kotlin.collections.ArrayList |
||||
import kotlin.collections.HashMap |
||||
|
||||
class ColorProvider(context: Context, stubPackageName: String) : |
||||
ResourcesApkProvider(context, stubPackageName), ColorOptionsProvider { |
||||
var colorBundles: List<ColorOption>? = null |
||||
var homeWallpaperColors: WallpaperColors? = null |
||||
var lockWallpaperColors: WallpaperColors? = null |
||||
val scope: CoroutineScope? = null |
||||
private fun buildBundle( |
||||
seed: Int, |
||||
index: Int, |
||||
mIsDefault: Boolean, |
||||
source: String?, |
||||
list: ArrayList<ColorOption> |
||||
) { |
||||
|
||||
val hashMap: HashMap<String?, String?> = HashMap() |
||||
val colorScheme = ColorScheme(seed, false) |
||||
val colorSchemeDark = ColorScheme(seed, true) |
||||
val secondaryColorLight = intArrayOf( |
||||
ColorUtils.setAlphaComponent(colorScheme.accent1[2], 255), ColorUtils.setAlphaComponent( |
||||
colorScheme.accent1[2], 255 |
||||
), ColorStateList.valueOf( |
||||
colorScheme.accent3[6] |
||||
).withLStar(85.0f).colors[0], ColorUtils.setAlphaComponent( |
||||
colorScheme.accent1[6], 255 |
||||
) |
||||
) |
||||
val secondaryColorDark = intArrayOf( |
||||
ColorUtils.setAlphaComponent(colorSchemeDark.accent1[2], 255), |
||||
ColorUtils.setAlphaComponent( |
||||
colorSchemeDark.accent1[2], 255 |
||||
), |
||||
ColorStateList.valueOf( |
||||
colorSchemeDark.accent3[6] |
||||
).withLStar(85.0f).colors[0], |
||||
ColorUtils.setAlphaComponent( |
||||
colorSchemeDark.accent1[6], 255 |
||||
) |
||||
) |
||||
var source3 = "" |
||||
val source2 = if (mIsDefault) { |
||||
source3 |
||||
} else { |
||||
toColorString(seed) |
||||
} |
||||
hashMap["android.theme.customization.system_palette"] = source2 |
||||
if (!mIsDefault) { |
||||
source3 = toColorString(seed) |
||||
} |
||||
hashMap["android.theme.customization.accent_color"] = source3 |
||||
list.add( |
||||
ColorSeedOption( |
||||
source, |
||||
hashMap, |
||||
mIsDefault, |
||||
source!!, |
||||
1 + index, |
||||
ColorSeedOption.PreviewInfo(secondaryColorLight, secondaryColorDark) |
||||
) |
||||
) |
||||
} |
||||
|
||||
private fun loadPreset() { |
||||
val bundlesList = ArrayList<String>() |
||||
val bundleNames = mStubApkResources.getStringArray( |
||||
mStubApkResources.getIdentifier( |
||||
"color_bundles", |
||||
"array", |
||||
mStubPackageName |
||||
) |
||||
) |
||||
for (i in bundleNames.indices) { |
||||
if (i == 4) break |
||||
bundlesList.add(bundleNames[i]) |
||||
} |
||||
val colorPresetBundles = ArrayList<ColorOption>() |
||||
var position = 1; |
||||
for (bundle in bundlesList) { |
||||
val hashMap: HashMap<String?, String?> = HashMap() |
||||
val bundleName = getItemStringFromStub("bundle_name_", bundle) |
||||
val bundleColorPrimary = getItemColorFromStub("color_primary_", bundle) |
||||
val bundleColorSecondary = getItemColorFromStub("color_secondary_", bundle) |
||||
hashMap["android.theme.customization.system_palette"] = |
||||
toColorString(bundleColorSecondary) |
||||
hashMap["android.theme.customization.accent_color"] = toColorString(bundleColorPrimary) |
||||
val accentColor = ColorScheme(bundleColorPrimary, false).accentColor |
||||
val accentColor2 = ColorScheme(bundleColorPrimary, true).accentColor |
||||
colorPresetBundles.add( |
||||
ColorBundle( |
||||
bundleName, |
||||
hashMap, |
||||
false, |
||||
index = position, |
||||
mPreviewInfo = ColorBundle.PreviewInfo( |
||||
accentColor, |
||||
accentColor2 |
||||
) |
||||
) |
||||
) |
||||
position++ |
||||
} |
||||
this.colorBundles = colorPresetBundles |
||||
} |
||||
|
||||
fun buildColorSeeds( |
||||
wallpaperColors: WallpaperColors, |
||||
count: Int, |
||||
source: String?, |
||||
isDefault: Boolean, |
||||
list: ArrayList<ColorOption> |
||||
) { |
||||
val list2: List<Int> |
||||
val list3: List<Int> |
||||
val seedColors: List<Int> = ColorScheme.getSeedColors(wallpaperColors) |
||||
loadPreset() |
||||
buildBundle( |
||||
seedColors[0], |
||||
0, |
||||
isDefault, |
||||
source, |
||||
list |
||||
) |
||||
val size = seedColors.size - 1 |
||||
list2 = if (size <= 0) { |
||||
ArrayList() |
||||
} else if (size != 1) { |
||||
val arrayList: ArrayList<Int> = ArrayList(size) |
||||
val listIterator = seedColors.listIterator(1) |
||||
while (listIterator.hasNext()) { |
||||
arrayList.add(listIterator.next()) |
||||
} |
||||
arrayList |
||||
} else if (seedColors.isNotEmpty()) { |
||||
listOf(seedColors[seedColors.size - 1]) |
||||
} else { |
||||
throw NoSuchElementException("List is empty.") |
||||
} |
||||
val i3 = count - 1 |
||||
var index4 = 0 |
||||
if (i3 >= 0) { |
||||
list3 = if (i3 == 0) { |
||||
ArrayList() |
||||
} else (if (i3 >= list2.size) { |
||||
list2 |
||||
} else if (i3 == 1) { |
||||
listOf(list2[0]) |
||||
} else { |
||||
val arrayList2: ArrayList<Int> = ArrayList(i3) |
||||
var i5 = 0 |
||||
for (obj in list2) { |
||||
arrayList2.add(obj) |
||||
i5++ |
||||
if (i5 == i3) { |
||||
break |
||||
} |
||||
} |
||||
arrayList2 |
||||
}) |
||||
for (seed in list3) { |
||||
index4++ |
||||
buildBundle(seed, index4, false, source, list) |
||||
} |
||||
return |
||||
} |
||||
throw IllegalArgumentException("Requested element count $i3 is less than zero.") |
||||
} |
||||
|
||||
companion object { |
||||
|
||||
fun loadSeedColors( |
||||
colorProvider: ColorProvider, |
||||
wallpaperColors: WallpaperColors?, |
||||
wallpaperColors2: WallpaperColors? |
||||
) { |
||||
val arrayList = ArrayList<ColorOption>() |
||||
if (wallpaperColors != null) { |
||||
val count = if (wallpaperColors2 == null) 4 else 2 |
||||
if (wallpaperColors2 != null) { |
||||
val wallpaperManagerCompat: WallpaperManagerCompat = |
||||
InjectorProvider.getInjector() |
||||
.getWallpaperManagerCompat(colorProvider.mContext) |
||||
var isDefault = true |
||||
if (wallpaperManagerCompat.getWallpaperId(WallpaperManagerCompat.FLAG_LOCK) <= wallpaperManagerCompat.getWallpaperId( |
||||
WallpaperManagerCompat.FLAG_SYSTEM |
||||
) |
||||
) { |
||||
isDefault = false |
||||
} |
||||
colorProvider.buildColorSeeds( |
||||
if (isDefault) wallpaperColors2 else wallpaperColors, |
||||
count, |
||||
if (isDefault) "lock_wallpaper" else "home_wallpaper", |
||||
true, |
||||
arrayList |
||||
) |
||||
colorProvider.buildColorSeeds( |
||||
if (isDefault) wallpaperColors else wallpaperColors2, |
||||
count, |
||||
if (isDefault) "home_wallpaper" else "lock_wallpaper", |
||||
false, |
||||
arrayList |
||||
) |
||||
} else { |
||||
colorProvider.buildColorSeeds( |
||||
wallpaperColors, |
||||
count, |
||||
"home_wallpaper", |
||||
true, |
||||
arrayList |
||||
) |
||||
} |
||||
val list = colorProvider.colorBundles |
||||
val arrayList2 = ArrayList<ColorOption>() |
||||
if (list != null) { |
||||
for (t in list) { |
||||
arrayList2.add(t) |
||||
} |
||||
} |
||||
arrayList.addAll(arrayList2) |
||||
colorProvider.colorBundles = arrayList |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,260 @@ |
||||
package com.google.android.customization.model.color |
||||
|
||||
import android.app.Activity |
||||
import android.app.WallpaperColors |
||||
import android.content.Context |
||||
import android.os.Bundle |
||||
import android.os.Handler |
||||
import android.os.Looper |
||||
import android.util.Log |
||||
import android.view.LayoutInflater |
||||
import android.view.View |
||||
import android.view.ViewGroup |
||||
import android.widget.LinearLayout |
||||
import androidx.lifecycle.LifecycleOwner |
||||
import androidx.lifecycle.lifecycleScope |
||||
import androidx.recyclerview.widget.RecyclerView |
||||
import androidx.viewpager2.widget.ViewPager2 |
||||
import com.android.customization.model.CustomizationManager |
||||
import com.android.customization.module.CustomizationInjector |
||||
import com.android.customization.module.ThemesUserEventLogger |
||||
import com.android.customization.widget.OptionSelectorController |
||||
import com.android.wallpaper.R |
||||
import com.android.wallpaper.model.CustomizationSectionController; |
||||
import com.android.wallpaper.model.CustomizationSectionController.CustomizationSectionNavigationController; |
||||
import com.android.wallpaper.module.InjectorProvider |
||||
import com.android.wallpaper.widget.SeparatedTabLayout |
||||
import com.android.wallpaper.model.WallpaperColorsViewModel |
||||
import com.google.android.customization.picker.color.ColorSectionView |
||||
import kotlinx.coroutines.launch |
||||
|
||||
|
||||
class ColorSectionController( |
||||
activity: Activity?, |
||||
wallpaperColorsViewModel: WallpaperColorsViewModel, |
||||
lifecycleOwner: LifecycleOwner, |
||||
bundle: Bundle?, |
||||
private val navigationController: CustomizationSectionNavigationController |
||||
) : CustomizationSectionController<ColorSectionView?> { |
||||
|
||||
val mColorManager: ColorCustomizationManager |
||||
var mColorSectionView: ColorSectionView? = null |
||||
private var mColorSectionAdapter = ColorSectionAdapter() |
||||
private lateinit var mColorViewPager: ViewPager2 |
||||
val mEventLogger: ThemesUserEventLogger |
||||
var mHomeWallpaperColors: WallpaperColors? = null |
||||
private var mHomeWallpaperColorsReady = false |
||||
private val mLifecycleOwner: LifecycleOwner |
||||
var mLockWallpaperColors: WallpaperColors? = null |
||||
private var mLockWallpaperColorsReady = false |
||||
val mPresetColorOptions: MutableList<ColorOption?> = ArrayList() |
||||
var mSelectedColor: ColorOption? = null |
||||
private var mTabLayout: SeparatedTabLayout? = null |
||||
private var mTabPositionToRestore: Int? = null |
||||
val mWallpaperColorOptions: MutableList<ColorOption?> = ArrayList() |
||||
private val mWallpaperColorsViewModel: WallpaperColorsViewModel |
||||
var mLastColorApplyingTime: Long = 0 |
||||
|
||||
|
||||
inner class ColorSectionAdapter : |
||||
RecyclerView.Adapter<RecyclerView.ViewHolder>() { |
||||
private val mItemCounts = 2 |
||||
|
||||
inner class ColorOptionsViewHolder(view: View) : |
||||
RecyclerView.ViewHolder( |
||||
view |
||||
) |
||||
|
||||
override fun getItemCount(): Int { |
||||
return mItemCounts |
||||
} |
||||
|
||||
override fun getItemViewType(i: Int): Int { |
||||
return R.layout.color_options_view |
||||
} |
||||
|
||||
override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, position: Int) { |
||||
val view = viewHolder.itemView as? RecyclerView ?: return |
||||
val colorSectionController = this@ColorSectionController |
||||
val colorOptions = |
||||
if (position == 0) colorSectionController.mWallpaperColorOptions |
||||
else colorSectionController.mPresetColorOptions |
||||
val optionSelectorController = OptionSelectorController( |
||||
view, |
||||
colorOptions, |
||||
true, |
||||
OptionSelectorController.CheckmarkStyle.CENTER |
||||
) |
||||
optionSelectorController.initOptions(colorSectionController.mColorManager) |
||||
colorSectionController.setUpColorOptionsController(optionSelectorController) |
||||
} |
||||
|
||||
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): RecyclerView.ViewHolder { |
||||
return ColorOptionsViewHolder( |
||||
LayoutInflater.from(viewGroup.context).inflate(i, viewGroup, false) |
||||
) |
||||
} |
||||
} |
||||
|
||||
override fun createView(context: Context): ColorSectionView { |
||||
mColorSectionView = LayoutInflater.from(context) |
||||
.inflate(R.layout.color_section_view, null as ViewGroup?) as ColorSectionView |
||||
mColorViewPager = mColorSectionView!!.requireViewById<ViewPager2>(R.id.color_view_pager) |
||||
mTabLayout = mColorSectionView!!.requireViewById(R.id.separated_tabs) |
||||
if (mColorViewPager.adapter == null) { |
||||
mColorViewPager.setAdapter(mColorSectionAdapter) |
||||
} |
||||
mTabLayout!!.setViewPager(mColorViewPager) |
||||
mWallpaperColorsViewModel.homeWallpaperColors.observe(mLifecycleOwner) { |
||||
mHomeWallpaperColors = it |
||||
mHomeWallpaperColorsReady = true |
||||
maybeLoadColors() |
||||
} |
||||
|
||||
mWallpaperColorsViewModel.lockWallpaperColors.observe(mLifecycleOwner) { |
||||
mLockWallpaperColors = it |
||||
mLockWallpaperColorsReady = true |
||||
maybeLoadColors() |
||||
} |
||||
|
||||
mLifecycleOwner.lifecycleScope.launchWhenResumed { |
||||
mTabPositionToRestore?.let { mColorViewPager.setCurrentItem(it, false) } |
||||
} |
||||
|
||||
return mColorSectionView!! |
||||
} |
||||
|
||||
override fun isAvailable(context: Context?): Boolean { |
||||
return context != null && ColorUtils.isMonetEnabled(context) |
||||
} |
||||
|
||||
private fun maybeLoadColors() { |
||||
if (mHomeWallpaperColorsReady && mLockWallpaperColorsReady) { |
||||
val wallpaperColors = mHomeWallpaperColors |
||||
var wallpaperColors2 = mLockWallpaperColors |
||||
mColorManager.mHomeWallpaperColors = wallpaperColors |
||||
mColorManager.mLockWallpaperColors = wallpaperColors2 |
||||
val optionsFetcher = |
||||
object : CustomizationManager.OptionsFetchedListener<ColorOption?> { |
||||
override fun onError(th: Throwable?) { |
||||
if (th != null) { |
||||
Log.e("ColorSectionController", "Error loading theme bundles", th) |
||||
} |
||||
} |
||||
|
||||
override fun onOptionsLoaded(list: List<ColorOption?>) { |
||||
if (list.isNotEmpty()) { |
||||
var colorOption: ColorOption? |
||||
val colorOption2: ColorOption |
||||
mWallpaperColorOptions.clear() |
||||
mPresetColorOptions.clear() |
||||
for (colorOption3 in list) { |
||||
if (colorOption3 is ColorSeedOption) { |
||||
mWallpaperColorOptions.add(colorOption3) |
||||
} else if (colorOption3 is ColorBundle) { |
||||
mPresetColorOptions.add(colorOption3) |
||||
} |
||||
} |
||||
val allColors = ArrayList<ColorOption?>() |
||||
allColors.addAll(mWallpaperColorOptions) |
||||
allColors.addAll(mPresetColorOptions) |
||||
val iterator = allColors.iterator() |
||||
while (true) { |
||||
if (!iterator.hasNext()) { |
||||
colorOption = null |
||||
break |
||||
} |
||||
colorOption = iterator.next() |
||||
if (colorOption!!.isActive(mColorManager)) { |
||||
break |
||||
} |
||||
} |
||||
if (colorOption == null) { |
||||
colorOption2 = |
||||
(if (mWallpaperColorOptions.isEmpty()) mPresetColorOptions[0]!! else mWallpaperColorOptions[0]!!) |
||||
colorOption = colorOption2 |
||||
} |
||||
mSelectedColor = colorOption |
||||
mColorViewPager.post { |
||||
mColorViewPager.adapter?.notifyItemChanged(0) |
||||
if (mTabLayout != null && mTabLayout!!.tabCount == 0) { |
||||
val newTab = mTabLayout!!.newTab() |
||||
newTab.setText(R.string.wallpaper_color_tab) |
||||
mTabLayout!!.addTab(newTab, 0, mTabLayout!!.tabCount == 0) |
||||
val newTab2 = mTabLayout!!.newTab() |
||||
newTab2.setText(R.string.preset_color_tab) |
||||
mTabLayout!!.addTab(newTab2, 1, mTabLayout!!.tabCount == 0) |
||||
} |
||||
if (mWallpaperColorOptions.isEmpty()) { |
||||
mTabLayout!!.getTabAt(0)!!.view.isEnabled = false |
||||
mColorViewPager.setCurrentItem(1, false) |
||||
} |
||||
mColorViewPager.setCurrentItem( |
||||
if ("preset" == mColorManager.currentColorSource) 1 else 0, |
||||
false |
||||
) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
if (wallpaperColors2 != null && wallpaperColors2 == wallpaperColors) { |
||||
wallpaperColors2 = null |
||||
} |
||||
val wallpaperColors3 = mColorManager.mHomeWallpaperColors |
||||
val colorProvider = mColorManager.mProvider as ColorProvider |
||||
val wallpapersColorsChanged = (colorProvider.homeWallpaperColors == wallpaperColors3 |
||||
) || (colorProvider.lockWallpaperColors == wallpaperColors2) |
||||
if (wallpapersColorsChanged) { |
||||
colorProvider.homeWallpaperColors = wallpaperColors3 |
||||
colorProvider.lockWallpaperColors = wallpaperColors2 |
||||
} |
||||
val list = colorProvider.colorBundles |
||||
if (list == null || wallpapersColorsChanged) { |
||||
mLifecycleOwner.lifecycleScope.launch { |
||||
if (wallpapersColorsChanged) { |
||||
ColorProvider.loadSeedColors( |
||||
colorProvider, |
||||
wallpaperColors3, |
||||
wallpaperColors2 |
||||
) |
||||
} |
||||
optionsFetcher.onOptionsLoaded(colorProvider.colorBundles!!) |
||||
} |
||||
} else { |
||||
optionsFetcher.onOptionsLoaded(list) |
||||
} |
||||
} |
||||
} |
||||
|
||||
fun setUpColorOptionsController(optionSelectorController: OptionSelectorController<ColorOption>) { |
||||
if (mSelectedColor != null && optionSelectorController.containsOption(mSelectedColor)) { |
||||
optionSelectorController.setSelectedOption(mSelectedColor) |
||||
} |
||||
optionSelectorController.addListener { |
||||
if (mSelectedColor != it) { |
||||
mSelectedColor = (it as ColorOption) |
||||
Handler(Looper.getMainLooper()).postDelayed({ |
||||
mColorManager.setThemeBundle(this, it) |
||||
}, 100L) |
||||
return@addListener |
||||
} |
||||
} |
||||
} |
||||
|
||||
override fun onSaveInstanceState(bundle: Bundle) { |
||||
val viewPager2 = mColorViewPager |
||||
bundle.putInt("COLOR_TAB_POSITION", viewPager2.currentItem) |
||||
} |
||||
|
||||
init { |
||||
mEventLogger = |
||||
(InjectorProvider.getInjector() as CustomizationInjector).getUserEventLogger(activity) as ThemesUserEventLogger |
||||
mColorManager = |
||||
ColorCustomizationManager.getInstance(activity!!)!! |
||||
mWallpaperColorsViewModel = wallpaperColorsViewModel |
||||
mLifecycleOwner = lifecycleOwner |
||||
if (bundle != null && bundle.containsKey("COLOR_TAB_POSITION")) { |
||||
mTabPositionToRestore = bundle.getInt("COLOR_TAB_POSITION") |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,56 @@ |
||||
package com.google.android.customization.model.color |
||||
|
||||
import android.content.res.Configuration |
||||
import android.graphics.PorterDuff |
||||
import android.view.View |
||||
import android.widget.ImageView |
||||
import com.android.wallpaper.R |
||||
|
||||
class ColorSeedOption( |
||||
title: String?, |
||||
map: Map<String?, String?>?, |
||||
isDefault: Boolean, |
||||
override val source: String, |
||||
index: Int, |
||||
private val mPreviewInfo: PreviewInfo |
||||
) : ColorOption( |
||||
title!!, map!!, isDefault, index |
||||
) { |
||||
private val mPreviewColorIds = intArrayOf( |
||||
R.id.color_preview_0, |
||||
R.id.color_preview_1, |
||||
R.id.color_preview_2, |
||||
R.id.color_preview_3 |
||||
) |
||||
|
||||
override fun bindThumbnailTile(view: View) { |
||||
val padding: Int |
||||
val resources = view.context.resources |
||||
var iterator = 0 |
||||
val mPreviewColorTint = |
||||
if ((resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES) mPreviewInfo.darkColors else mPreviewInfo.lightColors |
||||
padding = if (view.isActivated) { |
||||
resources.getDimensionPixelSize(R.dimen.color_seed_option_tile_padding_selected) |
||||
} else { |
||||
resources.getDimensionPixelSize(R.dimen.color_seed_option_tile_padding) |
||||
} |
||||
while (true) { |
||||
if (iterator < mPreviewColorIds.size) { |
||||
val imageView = view.findViewById<View>(mPreviewColorIds[iterator]) as ImageView |
||||
imageView.drawable.setColorFilter(mPreviewColorTint[iterator], PorterDuff.Mode.SRC) |
||||
imageView.setPadding(padding, padding, padding, padding) |
||||
iterator++ |
||||
} else { |
||||
view.contentDescription = |
||||
view.context.getString(R.string.wallpaper_color_title) |
||||
return |
||||
} |
||||
} |
||||
} |
||||
|
||||
override fun getLayoutResId(): Int { |
||||
return R.layout.color_seed_option |
||||
} |
||||
|
||||
class PreviewInfo(var lightColors: IntArray, var darkColors: IntArray) |
||||
} |
@ -0,0 +1,47 @@ |
||||
package com.google.android.customization.model.color; |
||||
|
||||
import android.content.Context; |
||||
import android.content.pm.ApplicationInfo; |
||||
import android.content.pm.PackageManager; |
||||
import android.content.res.Resources; |
||||
import android.os.SystemProperties; |
||||
import android.util.Log; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
import androidx.annotation.Nullable; |
||||
|
||||
public final class ColorUtils { |
||||
public static int sFlagId; |
||||
@Nullable |
||||
public static Resources sSysuiRes; |
||||
|
||||
public static boolean isMonetEnabled(@NonNull Context context) { |
||||
boolean monet = SystemProperties.getBoolean("persist.systemui.flag_monet", false); |
||||
if (monet) { |
||||
return true; |
||||
} |
||||
if (sSysuiRes == null) { |
||||
try { |
||||
PackageManager packageManager = context.getPackageManager(); |
||||
ApplicationInfo applicationInfo = packageManager.getApplicationInfo( |
||||
"com.android.systemui", 0); |
||||
if (applicationInfo != null) { |
||||
sSysuiRes = packageManager.getResourcesForApplication(applicationInfo); |
||||
} |
||||
} catch (PackageManager.NameNotFoundException e) { |
||||
Log.w("ColorUtils", "Couldn't read color flag, skipping section", e); |
||||
} |
||||
} |
||||
if (sFlagId == 0 && sSysuiRes != null) { |
||||
sFlagId = sSysuiRes.getIdentifier("flag_monet", "bool", "com.android.systemui"); |
||||
} |
||||
if (sFlagId <= 0) { |
||||
return false; |
||||
} |
||||
return sSysuiRes.getBoolean(sFlagId); |
||||
} |
||||
|
||||
public static String toColorString(int color) { |
||||
return String.format("#%06X", color & 0x00ffffff); |
||||
} |
||||
} |
@ -0,0 +1,8 @@ |
||||
package com.google.android.customization.picker.color |
||||
|
||||
import android.content.Context |
||||
import android.util.AttributeSet |
||||
import com.android.wallpaper.picker.SectionView |
||||
|
||||
class ColorSectionView(context: Context?, attributeSet: AttributeSet?) : |
||||
SectionView(context, attributeSet) |
Loading…
Reference in new issue