Merge "Fullscreen image preview (Part 3)" into ub-launcher3-master
diff --git a/res/layout/grid_item_rotation.xml b/res/layout/grid_item_rotation.xml
deleted file mode 100755
index a255fc8..0000000
--- a/res/layout/grid_item_rotation.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- Copyright (C) 2017 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.
--->
-<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/daily_refresh"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginTop="8dp"
- android:background="@color/secondary_color"
- android:clickable="true"
- android:focusable="true"
- android:foreground="?attr/selectableItemBackground"
- android:paddingEnd="@dimen/rotation_tile_padding_right"
- android:paddingLeft="@dimen/rotation_tile_padding_left"
- android:paddingRight="@dimen/rotation_tile_padding_right"
- android:paddingStart="@dimen/rotation_tile_padding_left"
- app:cardCornerRadius="?android:dialogCornerRadius"
- app:cardElevation="0dp">
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom|center_horizontal"
- android:layout_marginBottom="@dimen/rotation_tile_textarea_margin_bottom"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/rotation_tile_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="@dimen/rotation_tile_textarea_title_margin_bottom"
- android:text="@string/daily_refresh_tile_title"
- android:textColor="@color/rotation_tile_enabled_title_text_color"
- android:textSize="@dimen/rotation_tile_title_size" />
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
-
- <ImageView
- android:id="@+id/rotation_tile_refresh_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="@dimen/rotation_tile_refresh_icon_offset"
- android:layout_marginStart="@dimen/rotation_tile_refresh_icon_offset"
- android:src="@drawable/ic_refresh_18px" />
-
- <TextView
- android:id="@+id/rotation_tile_message"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="@dimen/rotation_tile_textarea_subtitle_margin_left"
- android:layout_marginStart="@dimen/rotation_tile_textarea_subtitle_margin_left"
- android:text="@string/daily_refresh_tile_subtitle"
- android:textColor="@color/rotation_tile_enabled_subtitle_text_color"
- android:textSize="@dimen/abc_text_size_caption_material" />
-
- </LinearLayout>
-
- </LinearLayout>
-
-</androidx.cardview.widget.CardView>
diff --git a/res/values-notnight-v26/picker_colors.xml b/res/values-notnight-v26/picker_colors.xml
index 0cadb67..9b8150d 100755
--- a/res/values-notnight-v26/picker_colors.xml
+++ b/res/values-notnight-v26/picker_colors.xml
@@ -37,15 +37,6 @@
<color name="select_wallpaper_header_text_color">@color/textColorSecondary</color>
- <color name="rotation_tile_enabled_background_color">@color/accent_color</color>
- <color name="rotation_tile_enabled_title_text_color">@color/material_white_text</color>
- <color name="rotation_tile_enabled_subtitle_text_color">@color/white_70_alpha</color>
- <color name="rotation_tile_enabled_refresh_icon_color">@color/white_70_alpha</color>
- <color name="rotation_tile_not_enabled_background_color">@color/secondary_color</color>
- <color name="rotation_tile_not_enabled_title_text_color">@color/accent_color</color>
- <color name="rotation_tile_not_enabled_subtitle_text_color">@color/black_54_alpha</color>
- <color name="rotation_tile_not_enabled_refresh_icon_color">@color/black_54_alpha</color>
-
<color name="individual_tile_title_scrim_color">@color/white_80_alpha</color>
<color name="individual_tile_title_text_color">@color/textColorPrimary</color>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 45d73ce..56bc73f 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -86,15 +86,6 @@
<dimen name="select_wallpaper_header_height">48dp</dimen>
<dimen name="select_wallpaper_header_margin_left">12dp</dimen>
- <!-- Dimensions for "daily refresh" rotation tile in individual picker. -->
- <dimen name="rotation_tile_padding_left">16dp</dimen>
- <dimen name="rotation_tile_padding_right">16dp</dimen>
- <dimen name="rotation_tile_title_size">14sp</dimen>
- <dimen name="rotation_tile_textarea_margin_bottom">16dp</dimen>
- <dimen name="rotation_tile_textarea_title_margin_bottom">2dp</dimen>
- <dimen name="rotation_tile_textarea_subtitle_margin_left">4dp</dimen>
- <dimen name="rotation_tile_refresh_icon_offset">-3dp</dimen>
-
<!-- Dimensions for wallpaper tiles in individual picker when in desktop mode. -->
<dimen name="tile_desktop_progress_bar_size">40dp</dimen>
diff --git a/res/values/picker_colors.xml b/res/values/picker_colors.xml
index 3780a30..ee7d998 100755
--- a/res/values/picker_colors.xml
+++ b/res/values/picker_colors.xml
@@ -56,15 +56,6 @@
<color name="select_wallpaper_header_text_color">@color/white_60_alpha</color>
- <color name="rotation_tile_enabled_background_color">@color/accent_color</color>
- <color name="rotation_tile_enabled_title_text_color">@color/material_white_100</color>
- <color name="rotation_tile_enabled_subtitle_text_color">@color/white_88_alpha</color>
- <color name="rotation_tile_enabled_refresh_icon_color">@color/white_88_alpha</color>
- <color name="rotation_tile_not_enabled_background_color">@color/secondary_color</color>
- <color name="rotation_tile_not_enabled_title_text_color">@color/material_white_100</color>
- <color name="rotation_tile_not_enabled_subtitle_text_color">@color/white_88_alpha</color>
- <color name="rotation_tile_not_enabled_refresh_icon_color">@color/white_88_alpha</color>
-
<color name="individual_tile_title_scrim_color">@color/translucent_black</color>
<color name="individual_tile_title_text_color">@color/material_white_100</color>
diff --git a/src/com/android/wallpaper/picker/CategoryFragment.java b/src/com/android/wallpaper/picker/CategoryFragment.java
index 007df5e..27b57b2 100755
--- a/src/com/android/wallpaper/picker/CategoryFragment.java
+++ b/src/com/android/wallpaper/picker/CategoryFragment.java
@@ -22,8 +22,10 @@
import static com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_COLLAPSED;
import android.app.Activity;
+import android.app.WallpaperColors;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.content.res.ColorStateList;
import android.graphics.Rect;
import android.graphics.RectF;
import android.net.Uri;
@@ -74,6 +76,7 @@
import com.android.wallpaper.util.WallpaperConnection.WallpaperConnectionListener;
import com.android.wallpaper.widget.LiveTileOverlay;
import com.android.wallpaper.widget.PreviewPager;
+import com.android.wallpaper.widget.WallpaperColorsLoader;
import com.bumptech.glide.Glide;
import com.bumptech.glide.MemoryCategory;
@@ -149,6 +152,7 @@
private ImageView mHomeImageWallpaper;
private boolean mIsCollapsingByUserSelecting;
private TimeTicker mTicker;
+ private ImageView mLockIcon;
private TextView mLockTime;
private TextView mLockDate;
@@ -178,6 +182,7 @@
lockscreenPreviewCard.findViewById(R.id.workspace_surface).setVisibility(View.GONE);
lockscreenPreviewCard.findViewById(R.id.wallpaper_surface).setVisibility(View.GONE);
lockscreenPreviewCard.findViewById(R.id.lock_overlay).setVisibility(View.VISIBLE);
+ mLockIcon = lockscreenPreviewCard.findViewById(R.id.lock_icon);
mLockTime = lockscreenPreviewCard.findViewById(R.id.lock_time);
mLockDate = lockscreenPreviewCard.findViewById(R.id.lock_date);
mWallPaperPreviews.add(lockscreenPreviewCard);
@@ -676,6 +681,12 @@
} else {
LiveTileOverlay.INSTANCE.detach(thumbnailView.getOverlay());
}
+
+ WallpaperColorsLoader.getWallpaperColors(
+ wallpaperInfo.getThumbAsset(getContext()),
+ thumbnailView.getMeasuredWidth(),
+ thumbnailView.getMeasuredHeight(),
+ this::updateLockScreenPreviewColor);
}
thumbnailView.setOnClickListener(view -> {
@@ -684,6 +695,16 @@
});
}
+ private void updateLockScreenPreviewColor(WallpaperColors colors) {
+ int color = getContext().getColor(
+ (colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) == 0
+ ? R.color.text_color_light
+ : R.color.text_color_dark);
+ mLockIcon.setImageTintList(ColorStateList.valueOf(color));
+ mLockDate.setTextColor(color);
+ mLockTime.setTextColor(color);
+ }
+
private void updateWallpaperSurface() {
mWallpaperSurface.getHolder().addCallback(mWallpaperSurfaceCallback);
}
diff --git a/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java b/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java
index 2e32ba1..6da3372 100755
--- a/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java
+++ b/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java
@@ -27,7 +27,6 @@
import android.content.res.Configuration;
import android.content.res.Resources.NotFoundException;
import android.graphics.Point;
-import android.graphics.PorterDuff.Mode;
import android.graphics.Rect;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
@@ -38,13 +37,10 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.cardview.widget.CardView;
import androidx.fragment.app.DialogFragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -54,7 +50,6 @@
import com.android.wallpaper.R;
import com.android.wallpaper.asset.Asset;
import com.android.wallpaper.asset.Asset.DrawableLoadedListener;
-import com.android.wallpaper.config.Flags;
import com.android.wallpaper.model.Category;
import com.android.wallpaper.model.CategoryProvider;
import com.android.wallpaper.model.CategoryReceiver;
@@ -65,7 +60,6 @@
import com.android.wallpaper.model.WallpaperRotationInitializer;
import com.android.wallpaper.model.WallpaperRotationInitializer.Listener;
import com.android.wallpaper.model.WallpaperRotationInitializer.NetworkPreference;
-import com.android.wallpaper.model.WallpaperRotationInitializer.RotationInitializationState;
import com.android.wallpaper.module.FormFactorChecker;
import com.android.wallpaper.module.FormFactorChecker.FormFactor;
import com.android.wallpaper.module.Injector;
@@ -288,20 +282,6 @@
}
}
- private static int getResIdForRotationState(@RotationInitializationState int rotationState) {
- switch (rotationState) {
- case WallpaperRotationInitializer.ROTATION_NOT_INITIALIZED:
- return R.string.daily_refresh_tile_subtitle;
- case WallpaperRotationInitializer.ROTATION_HOME_ONLY:
- return R.string.home_screen_message;
- case WallpaperRotationInitializer.ROTATION_HOME_AND_LOCK:
- return R.string.home_and_lock_short_label;
- default:
- Log.e(TAG, "Unknown rotation intialization state: " + rotationState);
- return R.string.home_screen_message;
- }
- }
-
private void updateDesktopDailyRotationThumbnail(DesktopRotationHolder holder) {
int wallpapersIndex = mRandom.nextInt(mWallpapers.size());
Asset newThumbnailAsset = mWallpapers.get(wallpapersIndex).getThumbAsset(
@@ -600,25 +580,10 @@
mStagedSetWallpaperErrorDialogFragment = null;
}
- if (isRotationEnabled()) {
- if (mFormFactor == FormFactorChecker.FORM_FACTOR_MOBILE) {
- // Refresh the state of the "start rotation" in case something changed the current daily
- // rotation while this fragment was paused.
- RotationHolder rotationHolder = (RotationHolder) mImageGrid
- .findViewHolderForAdapterPosition(
- SPECIAL_FIXED_TILE_ADAPTER_POSITION);
- // The RotationHolder may be null if the RecyclerView has not created the view
- // holder yet.
- if (rotationHolder != null && Flags.dynamicStartRotationTileEnabled) {
- refreshRotationHolder(rotationHolder);
- }
- } else if (mFormFactor == FormFactorChecker.FORM_FACTOR_DESKTOP) {
- if (mWasUpdateRunnableRun && !mWallpapers.isEmpty()) {
- // Must be resuming from a previously stopped state, so re-schedule the update of the
- // daily wallpapers tile thumbnail.
- mUpdateDailyWallpaperThumbRunnable.run();
- }
- }
+ if (shouldShowRotationTile() && mWasUpdateRunnableRun && !mWallpapers.isEmpty()) {
+ // Must be resuming from a previously stopped state, so re-schedule the update of the
+ // daily wallpapers tile thumbnail.
+ mUpdateDailyWallpaperThumbRunnable.run();
}
}
@@ -698,31 +663,6 @@
mTestingMode = testingMode;
}
- /**
- * Asynchronously fetches the refreshed rotation initialization state that is up to date with the
- * state of the user's device and binds the state of the current category's rotation to the "start
- * rotation" tile.
- */
- private void refreshRotationHolder(RotationHolder rotationHolder) {
- mWallpaperRotationInitializer.fetchRotationInitializationState(getContext(),
- rotationState -> {
- // Update the UI state of the "start rotation" tile displayed on screen.
- // Do this in a Handler so it is scheduled at the end of the message queue.
- // This is necessary to ensure we do not remove or add data from the adapter
- // while the layout is still being computed. RecyclerView documentation
- // therefore recommends performing such changes in a Handler.
- new Handler().post(() -> {
- // A config change may have destroyed the activity since the refresh
- // started, so check for that to avoid an NPE.
- if (getActivity() == null) {
- return;
- }
-
- rotationHolder.bindRotationInitializationState(rotationState);
- });
- });
- }
-
@Override
public void startRotation(@NetworkPreference final int networkPreference) {
if (!isRotationEnabled()) {
@@ -851,7 +791,6 @@
mCurrentWallpaperBottomSheetPresenter.setCurrentWallpapersExpanded(true);
}
-
@Override
public void onSet(int destination) {
if (mSelectedWallpaperInfo == null) {
@@ -989,7 +928,7 @@
return;
}
int index = mWallpapers.indexOf(wallpaperInfo);
- index = (isRotationEnabled() || mCategory.supportsCustomPhotos())
+ index = (shouldShowRotationTile() || mCategory.supportsCustomPhotos())
? index + 1 : index;
ViewHolder holder = mImageGrid.findViewHolderForAdapterPosition(index);
if (holder != null) {
@@ -1005,7 +944,7 @@
return;
}
int index = mWallpapers.indexOf(wallpaperInfo);
- index = (isRotationEnabled() || mCategory.supportsCustomPhotos())
+ index = (shouldShowRotationTile() || mCategory.supportsCustomPhotos())
? index + 1 : index;
ViewHolder holder = mImageGrid.findViewHolderForAdapterPosition(index);
if (holder != null) {
@@ -1056,90 +995,8 @@
}
}
- /**
- * ViewHolder subclass for "daily refresh" tile in the RecyclerView, only shown if rotation is
- * enabled for this category.
- */
- private class RotationHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
-
- private CardView mTileLayout;
- private TextView mRotationMessage;
- private TextView mRotationTitle;
- private ImageView mRefreshIcon;
-
- RotationHolder(View itemView) {
- super(itemView);
- itemView.setOnClickListener(this);
-
- mTileLayout = itemView.findViewById(R.id.daily_refresh);
- mRotationMessage = itemView.findViewById(R.id.rotation_tile_message);
- mRotationTitle = itemView.findViewById(R.id.rotation_tile_title);
- mRefreshIcon = itemView.findViewById(R.id.rotation_tile_refresh_icon);
- mTileLayout.getLayoutParams().height = mTileSizePx.y;
-
- // If the feature flag for "dynamic start rotation tile" is not enabled, fall back to the
- // static UI with a blue accent color background and "Tap to turn on" text.
- if (!Flags.dynamicStartRotationTileEnabled) {
- mTileLayout.setBackgroundColor(
- getResources().getColor(R.color.rotation_tile_enabled_background_color));
- mRotationMessage.setText(R.string.daily_refresh_tile_subtitle);
- mRotationTitle.setTextColor(
- getResources().getColor(R.color.rotation_tile_enabled_title_text_color));
- mRotationMessage.setTextColor(
- getResources().getColor(R.color.rotation_tile_enabled_subtitle_text_color));
- mRefreshIcon.setColorFilter(
- getResources().getColor(R.color.rotation_tile_enabled_refresh_icon_color),
- Mode.SRC_IN);
- return;
- }
-
- // Initialize the state of the "start rotation" tile (i.e., whether it is gray or blue to
- // indicate if rotation is turned on for the current category) with last-known rotation state
- // that could be stale. The last-known rotation state is correct in most cases and is a good
- // starting point but may not be accurate if the user set a wallpaper through a 3rd party app
- // while this app was paused.
- int rotationState = mWallpaperRotationInitializer.getRotationInitializationStateDirty(
- getContext());
- bindRotationInitializationState(rotationState);
- }
-
- @Override
- public void onClick(View v) {
- DialogFragment startRotationDialogFragment = new StartRotationDialogFragment();
- startRotationDialogFragment.setTargetFragment(
- IndividualPickerFragment.this, UNUSED_REQUEST_CODE);
- startRotationDialogFragment.show(getFragmentManager(), TAG_START_ROTATION_DIALOG);
- }
-
- /**
- * Binds the provided rotation initialization state to the RotationHolder and updates the tile's
- * UI to be in sync with the state (i.e., message and color appropriately reflect the state to
- * the user).
- */
- void bindRotationInitializationState(@RotationInitializationState int rotationState) {
- int newBackgroundColor =
- (rotationState == WallpaperRotationInitializer.ROTATION_NOT_INITIALIZED)
- ? getResources().getColor(R.color.rotation_tile_not_enabled_background_color)
- : getResources().getColor(R.color.rotation_tile_enabled_background_color);
- int newTitleTextColor =
- (rotationState == WallpaperRotationInitializer.ROTATION_NOT_INITIALIZED)
- ? getResources().getColor(R.color.rotation_tile_not_enabled_title_text_color)
- : getResources().getColor(R.color.rotation_tile_enabled_title_text_color);
- int newSubtitleTextColor =
- (rotationState == WallpaperRotationInitializer.ROTATION_NOT_INITIALIZED)
- ? getResources().getColor(R.color.rotation_tile_not_enabled_subtitle_text_color)
- : getResources().getColor(R.color.rotation_tile_enabled_subtitle_text_color);
- int newRefreshIconColor =
- (rotationState == WallpaperRotationInitializer.ROTATION_NOT_INITIALIZED)
- ? getResources().getColor(R.color.rotation_tile_not_enabled_refresh_icon_color)
- : getResources().getColor(R.color.rotation_tile_enabled_refresh_icon_color);
-
- mTileLayout.setCardBackgroundColor(newBackgroundColor);
- mRotationTitle.setTextColor(newTitleTextColor);
- mRotationMessage.setText(getResIdForRotationState(rotationState));
- mRotationMessage.setTextColor(newSubtitleTextColor);
- mRefreshIcon.setColorFilter(newRefreshIconColor, Mode.SRC_IN);
- }
+ private boolean shouldShowRotationTile() {
+ return mFormFactor == FormFactorChecker.FORM_FACTOR_DESKTOP && isRotationEnabled();
}
/**
@@ -1178,7 +1035,7 @@
@Override
public int getItemViewType(int position) {
- if (isRotationEnabled() && position == SPECIAL_FIXED_TILE_ADAPTER_POSITION) {
+ if (shouldShowRotationTile() && position == SPECIAL_FIXED_TILE_ADAPTER_POSITION) {
return ITEM_VIEW_TYPE_ROTATION;
}
@@ -1213,26 +1070,18 @@
@Override
public int getItemCount() {
- return (isRotationEnabled() || mCategory.supportsCustomPhotos())
+ return (shouldShowRotationTile() || mCategory.supportsCustomPhotos())
? mWallpapers.size() + 1
: mWallpapers.size();
}
private ViewHolder createRotationHolder(ViewGroup parent) {
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
- View view;
-
- if (mFormFactor == FormFactorChecker.FORM_FACTOR_DESKTOP) {
- view = layoutInflater.inflate(R.layout.grid_item_rotation_desktop, parent, false);
- SelectionAnimator selectionAnimator =
- new CheckmarkSelectionAnimator(getActivity(), view);
- return new DesktopRotationHolder(
- getActivity(), mTileSizePx.y, view, selectionAnimator,
- IndividualPickerFragment.this);
- } else { // MOBILE
- view = layoutInflater.inflate(R.layout.grid_item_rotation, parent, false);
- return new RotationHolder(view);
- }
+ View view = layoutInflater.inflate(R.layout.grid_item_rotation_desktop, parent, false);
+ SelectionAnimator selectionAnimator =
+ new CheckmarkSelectionAnimator(getActivity(), view);
+ return new DesktopRotationHolder(getActivity(), mTileSizePx.y, view, selectionAnimator,
+ IndividualPickerFragment.this);
}
private ViewHolder createIndividualHolder(ViewGroup parent) {
@@ -1383,7 +1232,7 @@
}
void onBindIndividualHolder(ViewHolder holder, int position) {
- int wallpaperIndex = (isRotationEnabled() || mCategory.supportsCustomPhotos())
+ int wallpaperIndex = (shouldShowRotationTile() || mCategory.supportsCustomPhotos())
? position - 1 : position;
WallpaperInfo wallpaper = mWallpapers.get(wallpaperIndex);
((IndividualHolder) holder).bindWallpaper(wallpaper);
diff --git a/src/com/android/wallpaper/widget/WallpaperColorsLoader.java b/src/com/android/wallpaper/widget/WallpaperColorsLoader.java
new file mode 100644
index 0000000..5ea5c15
--- /dev/null
+++ b/src/com/android/wallpaper/widget/WallpaperColorsLoader.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wallpaper.widget;
+
+import android.app.WallpaperColors;
+import android.graphics.Bitmap;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import com.android.wallpaper.asset.Asset;
+
+/** A class to load the {@link WallpaperColors} from wallpaper {@link Asset}. */
+public class WallpaperColorsLoader {
+ private static final String TAG = "WallpaperColorsLoader";
+
+ /** Callback of loading {@link WallpaperColors}. */
+ public interface Callback {
+ /** Gets called when {@link WallpaperColors} parsing is succeed. */
+ void onSuccess(WallpaperColors colors);
+
+ /** Gets called when {@link WallpaperColors} parsing is failed. */
+ default void onFailure() {
+ Log.i(TAG, "Can't get wallpaper colors from a null bitmap.");
+ }
+ }
+
+ /** Gets the {@link WallpaperColors} from the wallpaper {@link Asset}. */
+ public static void getWallpaperColors(@NonNull Asset asset, int targetWidth, int targetHeight,
+ @NonNull Callback callback) {
+ asset.decodeBitmap(targetWidth, targetHeight, bitmap -> {
+ if (bitmap != null) {
+ boolean shouldRecycle = false;
+ if (bitmap.getConfig() == Bitmap.Config.HARDWARE) {
+ bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, false);
+ shouldRecycle = true;
+ }
+ callback.onSuccess(WallpaperColors.fromBitmap(bitmap));
+ if (shouldRecycle) {
+ bitmap.recycle();
+ }
+ } else {
+ callback.onFailure();
+ }
+ });
+ }
+}