blob: 82b0e40809ec727fe61a4b57c81f1d017aec71dc [file] [log] [blame]
/*
* 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.
*/
package com.android.wallpaper.model;
import android.app.Activity;
import android.app.WallpaperColors;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.DrawableRes;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import com.android.wallpaper.asset.Asset;
import com.android.wallpaper.config.BaseFlags;
import com.android.wallpaper.module.InjectorProvider;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* Interface for wallpaper info model.
*/
public abstract class WallpaperInfo implements Parcelable {
private static final ExecutorService sExecutor = Executors.newCachedThreadPool();
private ColorInfo mColorInfo = new ColorInfo();
private PriorityQueue<String> mEffectNames = new PriorityQueue<>();
protected final HashMap<String, String> mCropHints = new HashMap<>();
public WallpaperInfo() {
}
protected WallpaperInfo(Parcel in) {
mColorInfo = new ColorInfo(in.readParcelable(WallpaperColors.class.getClassLoader()),
in.readInt());
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeParcelable(mColorInfo.getWallpaperColors(), flags);
parcel.writeInt(mColorInfo.getPlaceholderColor());
}
public static final int BACKUP_NOT_ALLOWED = 0;
public static final int BACKUP_ALLOWED = 1;
/**
* @param context
* @return The title for this wallpaper, if applicable (as in a wallpaper "app" or live
* wallpaper), or null if not applicable.
*/
public String getTitle(Context context) {
return null;
}
/**
* Returns the content description for this wallpaper, or null if none exists.
*/
public String getContentDescription(Context context) {
return null;
}
/**
* @return The available attributions for this wallpaper, as a list of strings. These represent
* the author / website or any other attribution required to be displayed for this wallpaper
* regarding authorship, ownership, etc.
*/
public abstract List<String> getAttributions(Context context);
/**
* Returns the base (remote) image URL for this wallpaper, or null if none exists.
*/
public String getBaseImageUrl() {
return null;
}
/**
* Returns the action or "explore" URL for the wallpaper, or null if none exists.
*/
public String getActionUrl(Context unused) {
return null;
}
/** Returns the URI corresponding to the wallpaper, or null if none exists. */
public Uri getUri() {
return null;
}
/**
* Returns the icon to use to represent the action link corresponding to
* {@link #getActionUrl(Context)}
*/
/**
* @param context
* @return An overlay icon to be used instead of a thumbnail, if appropriate, or null if not
* applicable.
*/
public Drawable getOverlayIcon(Context context) {
return null;
}
;
@Override
public int describeContents() {
return 0;
}
/**
* @param context The client application's context.
* @return The {@link Asset} representing the wallpaper image.
*/
public abstract Asset getAsset(Context context);
/**
* @param context The client application's context.
* @return The {@link Asset} representing the wallpaper's thumbnail.
*/
public abstract Asset getThumbAsset(Context context);
/**
* @param context The client application's context.
* @return An {@link Asset} that is appropriately sized to be directly set to the desktop. By
* default, this just the full wallpaper image asset (#getAsset) but subclasses may provide an
* Asset sized exactly for the device's primary display (i.e., cropped prior to providing a
* bitmap or input stream).
*/
public Asset getDesktopAsset(Context context) {
return getAsset(context);
}
/**
* @return the {@link android.app.WallpaperInfo} associated with this wallpaper, which is
* generally present for live wallpapers, or null if there is none.
*/
public android.app.WallpaperInfo getWallpaperComponent() {
return null;
}
/**
* Returns the ID of the collection this image is associated with, if any.
*/
public abstract String getCollectionId(Context context);
/**
* Returns the ID of this wallpaper or null if there is no ID.
*/
public String getWallpaperId() {
return null;
}
/**
* Returns the distinct ID of the stored wallpaper or null if there is no ID.
*/
public String getStoredWallpaperId(Context context) {
if (getWallpaperId() == null) {
return null;
}
return getCollectionId(context) + "-" + getWallpaperId();
}
/**
* Returns whether backup is allowed for this wallpaper.
*/
@BackupPermission
public int getBackupPermission() {
return BACKUP_ALLOWED;
}
/**
* Shows the appropriate preview activity for this WallpaperInfo.
*
* @param srcActivity
* @param factory A factory for showing the inline preview activity for within this app.
* Only used for certain WallpaperInfo implementations that require an inline preview
* (as opposed to some external preview activity).
* @param requestCode Request code to pass in when starting the inline preview activity.
*/
public abstract void showPreview(Activity srcActivity, InlinePreviewIntentFactory factory,
int requestCode, boolean isAssetIdPresent);
/**
* Returns a Future to obtain a wallpaper color and a placeholder color calculated in a
* background thread for this wallpaper's thumbnail.
* If it's already available, the Future will return the color immediately.
* This is intended to be a "best effort" attempt and might not obtain a color if no low res
* thumbnail is available.
*/
public Future<ColorInfo> computeColorInfo(Context context) {
if (mColorInfo.getWallpaperColors() != null
&& mColorInfo.getPlaceholderColor() != Color.TRANSPARENT) {
return CompletableFuture.completedFuture(mColorInfo);
}
final Context appContext = context.getApplicationContext();
return sExecutor.submit(() -> {
synchronized (WallpaperInfo.this) {
if (mColorInfo.getWallpaperColors() != null
&& mColorInfo.getPlaceholderColor() != Color.TRANSPARENT) {
return mColorInfo;
}
Asset thumbAsset = getThumbAsset(appContext);
Bitmap lowResBitmap = thumbAsset.getLowResBitmap(appContext);
if (lowResBitmap == null) {
return new ColorInfo(
new WallpaperColors(Color.valueOf(Color.TRANSPARENT), null, null),
Color.TRANSPARENT);
}
mColorInfo = new ColorInfo(WallpaperColors.fromBitmap(lowResBitmap));
return mColorInfo;
}
});
}
/**
* Remove the effect name from this wallpaper, only use it for logging.
*/
public void removeEffectName(String effect) {
mEffectNames.remove(effect);
}
/**
* Add the effect name apply with this wallpaper, only use it for logging.
*/
public void addEffectName(String effect) {
mEffectNames.add(effect);
}
/**
* Returns the effects apply with this wallpaper.
*/
public String getEffectNames() {
if (mEffectNames.isEmpty()) {
return null;
}
String effectNames = "";
Iterator value = mEffectNames.iterator();
while (value.hasNext()) {
if (!effectNames.isEmpty()) {
effectNames += ",";
}
effectNames += value.next();
}
return effectNames;
}
/**
* Whether backup is allowed for this type of wallpaper.
*/
@IntDef({
BACKUP_NOT_ALLOWED,
BACKUP_ALLOWED
})
public @interface BackupPermission {
}
/**
* Returns a group name under which this Wallpaper should be grouped when displayed in
* a gallery, or an empty String if no grouping is required.
*/
public String getGroupName(Context context) {
return "";
}
/**
* Returns the resource id of a drawable to use as a badge when displaying this wallpaper
* in a gallery, or {@link Resources#ID_NULL} if no badge is required.
*/
@DrawableRes
public int getBadgeDrawableRes() {
return Resources.ID_NULL;
}
/** Sets the crop {@link Rect} of each displaySize for this wallpaper. */
public void setWallpaperCropHints(Map<Point, Rect> cropHints) {
if (cropHints == null) {
return;
}
cropHints.forEach((displaySize, rect) -> {
if (rect != null) {
mCropHints.put(displaySize.flattenToString(),
rect.flattenToString());
}
});
}
/** Returns the crop {@link Rect} of each displaySize for this wallpaper. */
public @Nullable Map<Point, Rect> getWallpaperCropHints() {
BaseFlags flags = InjectorProvider.getInjector().getFlags();
boolean isMultiCropEnabled =
flags.isMultiCropPreviewUiEnabled() && flags.isMultiCropEnabled();
if (!isMultiCropEnabled) {
return null;
}
Map<Point, Rect> cropHints = new HashMap<>();
mCropHints.forEach(
(displaySize, rect) -> cropHints.put(
Point.unflattenFromString(displaySize),
Rect.unflattenFromString(rect)));
return cropHints;
}
/**
* Inner class to keep wallpaper colors and placeholder color.
*/
public static class ColorInfo {
private WallpaperColors mWallpaperColors;
private Integer mPlaceholderColor = Color.TRANSPARENT;
public ColorInfo() {
}
public ColorInfo(WallpaperColors wallpaperColors) {
mWallpaperColors = wallpaperColors;
if (mWallpaperColors != null) {
mPlaceholderColor = mWallpaperColors.getPrimaryColor().toArgb();
}
}
public ColorInfo(WallpaperColors wallpaperColors, Integer placeholderColor) {
mWallpaperColors = wallpaperColors;
mPlaceholderColor = placeholderColor;
}
public WallpaperColors getWallpaperColors() {
return mWallpaperColors;
}
public Integer getPlaceholderColor() {
return mPlaceholderColor;
}
}
public ColorInfo getColorInfo() {
return mColorInfo;
}
}