Loading core/api/test-current.txt +11 −0 Original line number Original line Diff line number Diff line Loading @@ -541,7 +541,9 @@ package android.app { method @Nullable public android.graphics.Rect peekBitmapDimensions(); method @Nullable public android.graphics.Rect peekBitmapDimensions(); method @Nullable public android.graphics.Rect peekBitmapDimensions(int); method @Nullable public android.graphics.Rect peekBitmapDimensions(int); method @FlaggedApi("com.android.window.flags.multi_crop") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setBitmapWithCrops(@Nullable android.graphics.Bitmap, @NonNull java.util.Map<android.graphics.Point,android.graphics.Rect>, boolean, int) throws java.io.IOException; method @FlaggedApi("com.android.window.flags.multi_crop") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setBitmapWithCrops(@Nullable android.graphics.Bitmap, @NonNull java.util.Map<android.graphics.Point,android.graphics.Rect>, boolean, int) throws java.io.IOException; method @FlaggedApi("android.app.live_wallpaper_content_handling") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setBitmapWithDescription(@Nullable android.graphics.Bitmap, @NonNull android.app.wallpaper.WallpaperDescription, boolean, int) throws java.io.IOException; method @FlaggedApi("com.android.window.flags.multi_crop") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setStreamWithCrops(@NonNull java.io.InputStream, @NonNull java.util.Map<android.graphics.Point,android.graphics.Rect>, boolean, int) throws java.io.IOException; method @FlaggedApi("com.android.window.flags.multi_crop") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setStreamWithCrops(@NonNull java.io.InputStream, @NonNull java.util.Map<android.graphics.Point,android.graphics.Rect>, boolean, int) throws java.io.IOException; method @FlaggedApi("android.app.live_wallpaper_content_handling") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setStreamWithDescription(@NonNull java.io.InputStream, @NonNull android.app.wallpaper.WallpaperDescription, boolean, int) throws java.io.IOException; method public void setWallpaperZoomOut(@NonNull android.os.IBinder, float); method public void setWallpaperZoomOut(@NonNull android.os.IBinder, float); method public boolean shouldEnableWideColorGamut(); method public boolean shouldEnableWideColorGamut(); method public boolean wallpaperSupportsWcg(int); method public boolean wallpaperSupportsWcg(int); Loading Loading @@ -907,6 +909,15 @@ package android.app.usage { } } package android.app.wallpaper { public static final class WallpaperDescription.Builder { method @NonNull public android.app.wallpaper.WallpaperDescription.Builder setCropHints(@NonNull java.util.Map<android.graphics.Point,android.graphics.Rect>); method @NonNull public android.app.wallpaper.WallpaperDescription.Builder setCropHints(@NonNull android.util.SparseArray<android.graphics.Rect>); } } package android.appwidget { package android.appwidget { public class AppWidgetManager { public class AppWidgetManager { Loading core/java/android/app/WallpaperManager.java +42 −0 Original line number Original line Diff line number Diff line Loading @@ -2491,6 +2491,27 @@ public class WallpaperManager { return result.getInt(EXTRA_NEW_WALLPAPER_ID, 0); return result.getInt(EXTRA_NEW_WALLPAPER_ID, 0); } } /** * Version of setBitmap that allows specification of wallpaper metadata including how the * wallpaper will be positioned for different display sizes. * * @param fullImage A bitmap that will supply the wallpaper imagery. * @param description Wallpaper metadata including desired cropping * @param allowBackup {@code true} if the OS is permitted to back up this wallpaper * image for restore to a future device; {@code false} otherwise. * @param which Flags indicating which wallpaper(s) to configure with the new imagery. * @hide */ @FlaggedApi(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING) @TestApi @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setBitmapWithDescription(@Nullable Bitmap fullImage, @NonNull WallpaperDescription description, boolean allowBackup, @SetWallpaperFlags int which) throws IOException { return setBitmapWithCrops(fullImage, description.getCropHints(), allowBackup, which, mContext.getUserId()); } private final void validateRect(Rect rect) { private final void validateRect(Rect rect) { if (rect != null && rect.isEmpty()) { if (rect != null && rect.isEmpty()) { throw new IllegalArgumentException("visibleCrop rectangle must be valid and non-empty"); throw new IllegalArgumentException("visibleCrop rectangle must be valid and non-empty"); Loading Loading @@ -2699,6 +2720,27 @@ public class WallpaperManager { return result.getInt(EXTRA_NEW_WALLPAPER_ID, 0); return result.getInt(EXTRA_NEW_WALLPAPER_ID, 0); } } /** * Version of setStream that allows specification of wallpaper metadata including how the * wallpaper will be positioned for different display sizes. * * @param bitmapData A stream containing the raw data to install as a wallpaper. This * data can be in any format handled by {@link BitmapRegionDecoder}. * @param description Wallpaper metadata including desired cropping * @param allowBackup {@code true} if the OS is permitted to back up this wallpaper * image for restore to a future device; {@code false} otherwise. * @param which Flags indicating which wallpaper(s) to configure with the new imagery. * @hide */ @FlaggedApi(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING) @TestApi @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setStreamWithDescription(@NonNull InputStream bitmapData, @NonNull WallpaperDescription description, boolean allowBackup, @SetWallpaperFlags int which) throws IOException { return setStreamWithCrops(bitmapData, description.getCropHints(), allowBackup, which); } /** /** * Return whether any users are currently set to use the wallpaper * Return whether any users are currently set to use the wallpaper * with the given resource ID. That is, their wallpaper has been * with the given resource ID. That is, their wallpaper has been Loading core/java/android/app/wallpaper/WallpaperDescription.java +146 −6 Original line number Original line Diff line number Diff line Loading @@ -19,8 +19,14 @@ package android.app.wallpaper; import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING; import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING; import android.annotation.FlaggedApi; import android.annotation.FlaggedApi; import android.annotation.SuppressLint; import android.annotation.TestApi; import android.app.WallpaperInfo; import android.app.WallpaperInfo; import android.app.WallpaperManager; import android.app.WallpaperManager.ScreenOrientation; import android.content.ComponentName; import android.content.ComponentName; import android.graphics.Point; import android.graphics.Rect; import android.net.Uri; import android.net.Uri; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import android.os.Parcelable; Loading @@ -29,6 +35,8 @@ import android.text.Html; import android.text.Spanned; import android.text.Spanned; import android.text.SpannedString; import android.text.SpannedString; import android.util.Log; import android.util.Log; import android.util.Pair; import android.util.SparseArray; import androidx.annotation.NonNull; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.Nullable; Loading @@ -43,6 +51,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.Arrays; import java.util.List; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Objects; /** /** Loading Loading @@ -71,12 +80,15 @@ public final class WallpaperDescription implements Parcelable { @Nullable private final Uri mContextUri; @Nullable private final Uri mContextUri; @Nullable private final CharSequence mContextDescription; @Nullable private final CharSequence mContextDescription; @NonNull private final PersistableBundle mContent; @NonNull private final PersistableBundle mContent; @NonNull private final SparseArray<Rect> mCropHints; private final float mSampleSize; private WallpaperDescription(@Nullable ComponentName component, private WallpaperDescription(@Nullable ComponentName component, @Nullable String id, @Nullable Uri thumbnail, @Nullable CharSequence title, @Nullable String id, @Nullable Uri thumbnail, @Nullable CharSequence title, @Nullable List<CharSequence> description, @Nullable Uri contextUri, @Nullable List<CharSequence> description, @Nullable Uri contextUri, @Nullable CharSequence contextDescription, @Nullable CharSequence contextDescription, @Nullable PersistableBundle content) { @Nullable PersistableBundle content, @NonNull SparseArray<Rect> cropHints, float sampleSize) { this.mComponent = component; this.mComponent = component; this.mId = id; this.mId = id; this.mThumbnail = thumbnail; this.mThumbnail = thumbnail; Loading @@ -85,6 +97,8 @@ public final class WallpaperDescription implements Parcelable { this.mContextUri = contextUri; this.mContextUri = contextUri; this.mContextDescription = contextDescription; this.mContextDescription = contextDescription; this.mContent = (content != null) ? content : new PersistableBundle(); this.mContent = (content != null) ? content : new PersistableBundle(); this.mCropHints = cropHints; this.mSampleSize = sampleSize; } } /** @return the component for this wallpaper, or {@code null} for a static wallpaper */ /** @return the component for this wallpaper, or {@code null} for a static wallpaper */ Loading Loading @@ -134,6 +148,24 @@ public final class WallpaperDescription implements Parcelable { return mContent; return mContent; } } /** * @return the cropping for the current image as described in * {@link Builder#setCropHints(SparseArray)} * @hide */ @NonNull public SparseArray<Rect> getCropHints() { return mCropHints; } /** * @return the subsamling size as described in {@link Builder#setSampleSize(float)}. * @hide */ public float getSampleSize() { return mSampleSize; } ////// Comparison overrides ////// Comparison overrides @Override @Override Loading Loading @@ -163,9 +195,23 @@ public final class WallpaperDescription implements Parcelable { if (mContextDescription != null) { if (mContextDescription != null) { out.attribute(null, "contextdescription", toHtml(mContextDescription)); out.attribute(null, "contextdescription", toHtml(mContextDescription)); } } for (Pair<Integer, String> pair : screenDimensionPairs()) { @ScreenOrientation int orientation = pair.first; String attrName = pair.second; Rect cropHint = mCropHints.get(orientation); if (cropHint == null) continue; out.attributeInt(null, "cropLeft" + attrName, cropHint.left); out.attributeInt(null, "cropTop" + attrName, cropHint.top); out.attributeInt(null, "cropRight" + attrName, cropHint.right); out.attributeInt(null, "cropBottom" + attrName, cropHint.bottom); } out.attributeFloat(null, "sampleSize", mSampleSize); out.startTag(null, XML_TAG_DESCRIPTION); out.startTag(null, XML_TAG_DESCRIPTION); for (CharSequence s : mDescription) out.attribute(null, "descriptionline", toHtml(s)); for (CharSequence s : mDescription) out.attribute(null, "descriptionline", toHtml(s)); out.endTag(null, XML_TAG_DESCRIPTION); out.endTag(null, XML_TAG_DESCRIPTION); try { try { out.startTag(null, XML_TAG_CONTENT); out.startTag(null, XML_TAG_CONTENT); mContent.saveToXml(out); mContent.saveToXml(out); Loading Loading @@ -194,6 +240,19 @@ public final class WallpaperDescription implements Parcelable { CharSequence contextDescription = fromHtml( CharSequence contextDescription = fromHtml( in.getAttributeValue(null, "contextdescription")); in.getAttributeValue(null, "contextdescription")); SparseArray<Rect> cropHints = new SparseArray<>(); screenDimensionPairs().forEach(pair -> { @ScreenOrientation int orientation = pair.first; String attrName = pair.second; Rect crop = new Rect( in.getAttributeInt(null, "cropLeft" + attrName, 0), in.getAttributeInt(null, "cropTop" + attrName, 0), in.getAttributeInt(null, "cropRight" + attrName, 0), in.getAttributeInt(null, "cropBottom" + attrName, 0)); if (!crop.isEmpty()) cropHints.put(orientation, crop); }); float sampleSize = in.getAttributeFloat(null, "sampleSize", 1f); List<CharSequence> description = new ArrayList<>(); List<CharSequence> description = new ArrayList<>(); PersistableBundle content = null; PersistableBundle content = null; int type; int type; Loading @@ -213,7 +272,7 @@ public final class WallpaperDescription implements Parcelable { } } return new WallpaperDescription(componentName, id, thumbnail, title, description, return new WallpaperDescription(componentName, id, thumbnail, title, description, contextUri, contextDescription, content); contextUri, contextDescription, content, cropHints, sampleSize); } } private static String toHtml(@NonNull CharSequence c) { private static String toHtml(@NonNull CharSequence c) { Loading Loading @@ -253,6 +312,13 @@ public final class WallpaperDescription implements Parcelable { mContextUri = Uri.CREATOR.createFromParcel(in); mContextUri = Uri.CREATOR.createFromParcel(in); mContextDescription = in.readCharSequence(); mContextDescription = in.readCharSequence(); mContent = PersistableBundle.CREATOR.createFromParcel(in); mContent = PersistableBundle.CREATOR.createFromParcel(in); mCropHints = new SparseArray<>(); screenDimensionPairs().forEach(pair -> { int orientation = pair.first; Rect crop = in.readTypedObject(Rect.CREATOR); if (crop != null) mCropHints.put(orientation, crop); }); mSampleSize = in.readFloat(); } } @NonNull @NonNull Loading Loading @@ -283,6 +349,11 @@ public final class WallpaperDescription implements Parcelable { Uri.writeToParcel(dest, mContextUri); Uri.writeToParcel(dest, mContextUri); dest.writeCharSequence(mContextDescription); dest.writeCharSequence(mContextDescription); dest.writePersistableBundle(mContent); dest.writePersistableBundle(mContent); screenDimensionPairs().forEach(pair -> { int orientation = pair.first; dest.writeTypedObject(mCropHints.get(orientation), flags); }); dest.writeFloat(mSampleSize); } } ////// Builder ////// Builder Loading @@ -293,9 +364,17 @@ public final class WallpaperDescription implements Parcelable { */ */ @NonNull @NonNull public Builder toBuilder() { public Builder toBuilder() { return new Builder().setComponent(mComponent).setId(mId).setThumbnail(mThumbnail).setTitle( return new Builder() mTitle).setDescription(mDescription).setContextUri( .setComponent(mComponent) mContextUri).setContextDescription(mContextDescription).setContent(mContent); .setId(mId) .setThumbnail(mThumbnail) .setTitle(mTitle) .setDescription(mDescription) .setContextUri(mContextUri) .setContextDescription(mContextDescription) .setContent(mContent) .setCropHints(mCropHints) .setSampleSize(mSampleSize); } } /** Builder for the immutable {@link WallpaperDescription} class */ /** Builder for the immutable {@link WallpaperDescription} class */ Loading @@ -308,6 +387,9 @@ public final class WallpaperDescription implements Parcelable { @Nullable private Uri mContextUri; @Nullable private Uri mContextUri; @Nullable private CharSequence mContextDescription; @Nullable private CharSequence mContextDescription; @NonNull private PersistableBundle mContent = new PersistableBundle(); @NonNull private PersistableBundle mContent = new PersistableBundle(); @NonNull private SparseArray<Rect> mCropHints = new SparseArray<>(); private float mSampleSize = 1f; /** Creates a new, empty {@link Builder}. */ /** Creates a new, empty {@link Builder}. */ public Builder() {} public Builder() {} Loading Loading @@ -416,11 +498,69 @@ public final class WallpaperDescription implements Parcelable { return this; return this; } } /** * Defines which part of the source wallpaper image is in the stored crop file. * * @param cropHints map from screen dimensions to a sub-region of the image to display * for those dimensions. The {@code Rect} sub-region may have a larger * width/height ratio than the screen dimensions to apply a horizontal * parallax effect. If the map is empty or some entries are missing, the * system will apply a default strategy to position the wallpaper for * any unspecified screen dimensions. * @hide */ @NonNull @TestApi @SuppressLint("MissingGetterMatchingBuilder") public Builder setCropHints(@NonNull Map<Point, Rect> cropHints) { mCropHints = new SparseArray<>(); cropHints.forEach( (point, rect) -> mCropHints.put(WallpaperManager.getOrientation(point), rect)); return this; } /** * Defines which part of the source wallpaper image is in the stored crop file. * * @param cropHints map from {@link ScreenOrientation} to a sub-region of the image to * display for that screen orientation. * @hide */ @NonNull @TestApi @SuppressLint("MissingGetterMatchingBuilder") public Builder setCropHints(@NonNull SparseArray<Rect> cropHints) { mCropHints = cropHints; return this; } /** * How much the crop is sub-sampled. A value > 1 means that the image quality was reduced. * This is the ratio between the cropHint height and the actual stored crop file height. * height. * * @param sampleSize Sub-sampling value * @hide */ @NonNull public Builder setSampleSize(float sampleSize) { mSampleSize = sampleSize; return this; } /** Creates and returns the {@link WallpaperDescription} represented by this builder. */ /** Creates and returns the {@link WallpaperDescription} represented by this builder. */ @NonNull @NonNull public WallpaperDescription build() { public WallpaperDescription build() { return new WallpaperDescription(mComponent, mId, mThumbnail, mTitle, mDescription, return new WallpaperDescription(mComponent, mId, mThumbnail, mTitle, mDescription, mContextUri, mContextDescription, mContent); mContextUri, mContextDescription, mContent, mCropHints, mSampleSize); } } } } private static List<Pair<Integer, String>> screenDimensionPairs() { return List.of( new Pair<>(WallpaperManager.ORIENTATION_PORTRAIT, "Portrait"), new Pair<>(WallpaperManager.ORIENTATION_LANDSCAPE, "Landscape"), new Pair<>(WallpaperManager.ORIENTATION_SQUARE_PORTRAIT, "SquarePortrait"), new Pair<>(WallpaperManager.ORIENTATION_SQUARE_LANDSCAPE, "SquareLandscape")); } } } core/tests/coretests/src/android/app/wallpaper/WallpaperDescriptionTest.java +148 −32 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/api/test-current.txt +11 −0 Original line number Original line Diff line number Diff line Loading @@ -541,7 +541,9 @@ package android.app { method @Nullable public android.graphics.Rect peekBitmapDimensions(); method @Nullable public android.graphics.Rect peekBitmapDimensions(); method @Nullable public android.graphics.Rect peekBitmapDimensions(int); method @Nullable public android.graphics.Rect peekBitmapDimensions(int); method @FlaggedApi("com.android.window.flags.multi_crop") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setBitmapWithCrops(@Nullable android.graphics.Bitmap, @NonNull java.util.Map<android.graphics.Point,android.graphics.Rect>, boolean, int) throws java.io.IOException; method @FlaggedApi("com.android.window.flags.multi_crop") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setBitmapWithCrops(@Nullable android.graphics.Bitmap, @NonNull java.util.Map<android.graphics.Point,android.graphics.Rect>, boolean, int) throws java.io.IOException; method @FlaggedApi("android.app.live_wallpaper_content_handling") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setBitmapWithDescription(@Nullable android.graphics.Bitmap, @NonNull android.app.wallpaper.WallpaperDescription, boolean, int) throws java.io.IOException; method @FlaggedApi("com.android.window.flags.multi_crop") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setStreamWithCrops(@NonNull java.io.InputStream, @NonNull java.util.Map<android.graphics.Point,android.graphics.Rect>, boolean, int) throws java.io.IOException; method @FlaggedApi("com.android.window.flags.multi_crop") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setStreamWithCrops(@NonNull java.io.InputStream, @NonNull java.util.Map<android.graphics.Point,android.graphics.Rect>, boolean, int) throws java.io.IOException; method @FlaggedApi("android.app.live_wallpaper_content_handling") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setStreamWithDescription(@NonNull java.io.InputStream, @NonNull android.app.wallpaper.WallpaperDescription, boolean, int) throws java.io.IOException; method public void setWallpaperZoomOut(@NonNull android.os.IBinder, float); method public void setWallpaperZoomOut(@NonNull android.os.IBinder, float); method public boolean shouldEnableWideColorGamut(); method public boolean shouldEnableWideColorGamut(); method public boolean wallpaperSupportsWcg(int); method public boolean wallpaperSupportsWcg(int); Loading Loading @@ -907,6 +909,15 @@ package android.app.usage { } } package android.app.wallpaper { public static final class WallpaperDescription.Builder { method @NonNull public android.app.wallpaper.WallpaperDescription.Builder setCropHints(@NonNull java.util.Map<android.graphics.Point,android.graphics.Rect>); method @NonNull public android.app.wallpaper.WallpaperDescription.Builder setCropHints(@NonNull android.util.SparseArray<android.graphics.Rect>); } } package android.appwidget { package android.appwidget { public class AppWidgetManager { public class AppWidgetManager { Loading
core/java/android/app/WallpaperManager.java +42 −0 Original line number Original line Diff line number Diff line Loading @@ -2491,6 +2491,27 @@ public class WallpaperManager { return result.getInt(EXTRA_NEW_WALLPAPER_ID, 0); return result.getInt(EXTRA_NEW_WALLPAPER_ID, 0); } } /** * Version of setBitmap that allows specification of wallpaper metadata including how the * wallpaper will be positioned for different display sizes. * * @param fullImage A bitmap that will supply the wallpaper imagery. * @param description Wallpaper metadata including desired cropping * @param allowBackup {@code true} if the OS is permitted to back up this wallpaper * image for restore to a future device; {@code false} otherwise. * @param which Flags indicating which wallpaper(s) to configure with the new imagery. * @hide */ @FlaggedApi(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING) @TestApi @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setBitmapWithDescription(@Nullable Bitmap fullImage, @NonNull WallpaperDescription description, boolean allowBackup, @SetWallpaperFlags int which) throws IOException { return setBitmapWithCrops(fullImage, description.getCropHints(), allowBackup, which, mContext.getUserId()); } private final void validateRect(Rect rect) { private final void validateRect(Rect rect) { if (rect != null && rect.isEmpty()) { if (rect != null && rect.isEmpty()) { throw new IllegalArgumentException("visibleCrop rectangle must be valid and non-empty"); throw new IllegalArgumentException("visibleCrop rectangle must be valid and non-empty"); Loading Loading @@ -2699,6 +2720,27 @@ public class WallpaperManager { return result.getInt(EXTRA_NEW_WALLPAPER_ID, 0); return result.getInt(EXTRA_NEW_WALLPAPER_ID, 0); } } /** * Version of setStream that allows specification of wallpaper metadata including how the * wallpaper will be positioned for different display sizes. * * @param bitmapData A stream containing the raw data to install as a wallpaper. This * data can be in any format handled by {@link BitmapRegionDecoder}. * @param description Wallpaper metadata including desired cropping * @param allowBackup {@code true} if the OS is permitted to back up this wallpaper * image for restore to a future device; {@code false} otherwise. * @param which Flags indicating which wallpaper(s) to configure with the new imagery. * @hide */ @FlaggedApi(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING) @TestApi @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setStreamWithDescription(@NonNull InputStream bitmapData, @NonNull WallpaperDescription description, boolean allowBackup, @SetWallpaperFlags int which) throws IOException { return setStreamWithCrops(bitmapData, description.getCropHints(), allowBackup, which); } /** /** * Return whether any users are currently set to use the wallpaper * Return whether any users are currently set to use the wallpaper * with the given resource ID. That is, their wallpaper has been * with the given resource ID. That is, their wallpaper has been Loading
core/java/android/app/wallpaper/WallpaperDescription.java +146 −6 Original line number Original line Diff line number Diff line Loading @@ -19,8 +19,14 @@ package android.app.wallpaper; import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING; import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING; import android.annotation.FlaggedApi; import android.annotation.FlaggedApi; import android.annotation.SuppressLint; import android.annotation.TestApi; import android.app.WallpaperInfo; import android.app.WallpaperInfo; import android.app.WallpaperManager; import android.app.WallpaperManager.ScreenOrientation; import android.content.ComponentName; import android.content.ComponentName; import android.graphics.Point; import android.graphics.Rect; import android.net.Uri; import android.net.Uri; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import android.os.Parcelable; Loading @@ -29,6 +35,8 @@ import android.text.Html; import android.text.Spanned; import android.text.Spanned; import android.text.SpannedString; import android.text.SpannedString; import android.util.Log; import android.util.Log; import android.util.Pair; import android.util.SparseArray; import androidx.annotation.NonNull; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.Nullable; Loading @@ -43,6 +51,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.Arrays; import java.util.List; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Objects; /** /** Loading Loading @@ -71,12 +80,15 @@ public final class WallpaperDescription implements Parcelable { @Nullable private final Uri mContextUri; @Nullable private final Uri mContextUri; @Nullable private final CharSequence mContextDescription; @Nullable private final CharSequence mContextDescription; @NonNull private final PersistableBundle mContent; @NonNull private final PersistableBundle mContent; @NonNull private final SparseArray<Rect> mCropHints; private final float mSampleSize; private WallpaperDescription(@Nullable ComponentName component, private WallpaperDescription(@Nullable ComponentName component, @Nullable String id, @Nullable Uri thumbnail, @Nullable CharSequence title, @Nullable String id, @Nullable Uri thumbnail, @Nullable CharSequence title, @Nullable List<CharSequence> description, @Nullable Uri contextUri, @Nullable List<CharSequence> description, @Nullable Uri contextUri, @Nullable CharSequence contextDescription, @Nullable CharSequence contextDescription, @Nullable PersistableBundle content) { @Nullable PersistableBundle content, @NonNull SparseArray<Rect> cropHints, float sampleSize) { this.mComponent = component; this.mComponent = component; this.mId = id; this.mId = id; this.mThumbnail = thumbnail; this.mThumbnail = thumbnail; Loading @@ -85,6 +97,8 @@ public final class WallpaperDescription implements Parcelable { this.mContextUri = contextUri; this.mContextUri = contextUri; this.mContextDescription = contextDescription; this.mContextDescription = contextDescription; this.mContent = (content != null) ? content : new PersistableBundle(); this.mContent = (content != null) ? content : new PersistableBundle(); this.mCropHints = cropHints; this.mSampleSize = sampleSize; } } /** @return the component for this wallpaper, or {@code null} for a static wallpaper */ /** @return the component for this wallpaper, or {@code null} for a static wallpaper */ Loading Loading @@ -134,6 +148,24 @@ public final class WallpaperDescription implements Parcelable { return mContent; return mContent; } } /** * @return the cropping for the current image as described in * {@link Builder#setCropHints(SparseArray)} * @hide */ @NonNull public SparseArray<Rect> getCropHints() { return mCropHints; } /** * @return the subsamling size as described in {@link Builder#setSampleSize(float)}. * @hide */ public float getSampleSize() { return mSampleSize; } ////// Comparison overrides ////// Comparison overrides @Override @Override Loading Loading @@ -163,9 +195,23 @@ public final class WallpaperDescription implements Parcelable { if (mContextDescription != null) { if (mContextDescription != null) { out.attribute(null, "contextdescription", toHtml(mContextDescription)); out.attribute(null, "contextdescription", toHtml(mContextDescription)); } } for (Pair<Integer, String> pair : screenDimensionPairs()) { @ScreenOrientation int orientation = pair.first; String attrName = pair.second; Rect cropHint = mCropHints.get(orientation); if (cropHint == null) continue; out.attributeInt(null, "cropLeft" + attrName, cropHint.left); out.attributeInt(null, "cropTop" + attrName, cropHint.top); out.attributeInt(null, "cropRight" + attrName, cropHint.right); out.attributeInt(null, "cropBottom" + attrName, cropHint.bottom); } out.attributeFloat(null, "sampleSize", mSampleSize); out.startTag(null, XML_TAG_DESCRIPTION); out.startTag(null, XML_TAG_DESCRIPTION); for (CharSequence s : mDescription) out.attribute(null, "descriptionline", toHtml(s)); for (CharSequence s : mDescription) out.attribute(null, "descriptionline", toHtml(s)); out.endTag(null, XML_TAG_DESCRIPTION); out.endTag(null, XML_TAG_DESCRIPTION); try { try { out.startTag(null, XML_TAG_CONTENT); out.startTag(null, XML_TAG_CONTENT); mContent.saveToXml(out); mContent.saveToXml(out); Loading Loading @@ -194,6 +240,19 @@ public final class WallpaperDescription implements Parcelable { CharSequence contextDescription = fromHtml( CharSequence contextDescription = fromHtml( in.getAttributeValue(null, "contextdescription")); in.getAttributeValue(null, "contextdescription")); SparseArray<Rect> cropHints = new SparseArray<>(); screenDimensionPairs().forEach(pair -> { @ScreenOrientation int orientation = pair.first; String attrName = pair.second; Rect crop = new Rect( in.getAttributeInt(null, "cropLeft" + attrName, 0), in.getAttributeInt(null, "cropTop" + attrName, 0), in.getAttributeInt(null, "cropRight" + attrName, 0), in.getAttributeInt(null, "cropBottom" + attrName, 0)); if (!crop.isEmpty()) cropHints.put(orientation, crop); }); float sampleSize = in.getAttributeFloat(null, "sampleSize", 1f); List<CharSequence> description = new ArrayList<>(); List<CharSequence> description = new ArrayList<>(); PersistableBundle content = null; PersistableBundle content = null; int type; int type; Loading @@ -213,7 +272,7 @@ public final class WallpaperDescription implements Parcelable { } } return new WallpaperDescription(componentName, id, thumbnail, title, description, return new WallpaperDescription(componentName, id, thumbnail, title, description, contextUri, contextDescription, content); contextUri, contextDescription, content, cropHints, sampleSize); } } private static String toHtml(@NonNull CharSequence c) { private static String toHtml(@NonNull CharSequence c) { Loading Loading @@ -253,6 +312,13 @@ public final class WallpaperDescription implements Parcelable { mContextUri = Uri.CREATOR.createFromParcel(in); mContextUri = Uri.CREATOR.createFromParcel(in); mContextDescription = in.readCharSequence(); mContextDescription = in.readCharSequence(); mContent = PersistableBundle.CREATOR.createFromParcel(in); mContent = PersistableBundle.CREATOR.createFromParcel(in); mCropHints = new SparseArray<>(); screenDimensionPairs().forEach(pair -> { int orientation = pair.first; Rect crop = in.readTypedObject(Rect.CREATOR); if (crop != null) mCropHints.put(orientation, crop); }); mSampleSize = in.readFloat(); } } @NonNull @NonNull Loading Loading @@ -283,6 +349,11 @@ public final class WallpaperDescription implements Parcelable { Uri.writeToParcel(dest, mContextUri); Uri.writeToParcel(dest, mContextUri); dest.writeCharSequence(mContextDescription); dest.writeCharSequence(mContextDescription); dest.writePersistableBundle(mContent); dest.writePersistableBundle(mContent); screenDimensionPairs().forEach(pair -> { int orientation = pair.first; dest.writeTypedObject(mCropHints.get(orientation), flags); }); dest.writeFloat(mSampleSize); } } ////// Builder ////// Builder Loading @@ -293,9 +364,17 @@ public final class WallpaperDescription implements Parcelable { */ */ @NonNull @NonNull public Builder toBuilder() { public Builder toBuilder() { return new Builder().setComponent(mComponent).setId(mId).setThumbnail(mThumbnail).setTitle( return new Builder() mTitle).setDescription(mDescription).setContextUri( .setComponent(mComponent) mContextUri).setContextDescription(mContextDescription).setContent(mContent); .setId(mId) .setThumbnail(mThumbnail) .setTitle(mTitle) .setDescription(mDescription) .setContextUri(mContextUri) .setContextDescription(mContextDescription) .setContent(mContent) .setCropHints(mCropHints) .setSampleSize(mSampleSize); } } /** Builder for the immutable {@link WallpaperDescription} class */ /** Builder for the immutable {@link WallpaperDescription} class */ Loading @@ -308,6 +387,9 @@ public final class WallpaperDescription implements Parcelable { @Nullable private Uri mContextUri; @Nullable private Uri mContextUri; @Nullable private CharSequence mContextDescription; @Nullable private CharSequence mContextDescription; @NonNull private PersistableBundle mContent = new PersistableBundle(); @NonNull private PersistableBundle mContent = new PersistableBundle(); @NonNull private SparseArray<Rect> mCropHints = new SparseArray<>(); private float mSampleSize = 1f; /** Creates a new, empty {@link Builder}. */ /** Creates a new, empty {@link Builder}. */ public Builder() {} public Builder() {} Loading Loading @@ -416,11 +498,69 @@ public final class WallpaperDescription implements Parcelable { return this; return this; } } /** * Defines which part of the source wallpaper image is in the stored crop file. * * @param cropHints map from screen dimensions to a sub-region of the image to display * for those dimensions. The {@code Rect} sub-region may have a larger * width/height ratio than the screen dimensions to apply a horizontal * parallax effect. If the map is empty or some entries are missing, the * system will apply a default strategy to position the wallpaper for * any unspecified screen dimensions. * @hide */ @NonNull @TestApi @SuppressLint("MissingGetterMatchingBuilder") public Builder setCropHints(@NonNull Map<Point, Rect> cropHints) { mCropHints = new SparseArray<>(); cropHints.forEach( (point, rect) -> mCropHints.put(WallpaperManager.getOrientation(point), rect)); return this; } /** * Defines which part of the source wallpaper image is in the stored crop file. * * @param cropHints map from {@link ScreenOrientation} to a sub-region of the image to * display for that screen orientation. * @hide */ @NonNull @TestApi @SuppressLint("MissingGetterMatchingBuilder") public Builder setCropHints(@NonNull SparseArray<Rect> cropHints) { mCropHints = cropHints; return this; } /** * How much the crop is sub-sampled. A value > 1 means that the image quality was reduced. * This is the ratio between the cropHint height and the actual stored crop file height. * height. * * @param sampleSize Sub-sampling value * @hide */ @NonNull public Builder setSampleSize(float sampleSize) { mSampleSize = sampleSize; return this; } /** Creates and returns the {@link WallpaperDescription} represented by this builder. */ /** Creates and returns the {@link WallpaperDescription} represented by this builder. */ @NonNull @NonNull public WallpaperDescription build() { public WallpaperDescription build() { return new WallpaperDescription(mComponent, mId, mThumbnail, mTitle, mDescription, return new WallpaperDescription(mComponent, mId, mThumbnail, mTitle, mDescription, mContextUri, mContextDescription, mContent); mContextUri, mContextDescription, mContent, mCropHints, mSampleSize); } } } } private static List<Pair<Integer, String>> screenDimensionPairs() { return List.of( new Pair<>(WallpaperManager.ORIENTATION_PORTRAIT, "Portrait"), new Pair<>(WallpaperManager.ORIENTATION_LANDSCAPE, "Landscape"), new Pair<>(WallpaperManager.ORIENTATION_SQUARE_PORTRAIT, "SquarePortrait"), new Pair<>(WallpaperManager.ORIENTATION_SQUARE_LANDSCAPE, "SquareLandscape")); } } }
core/tests/coretests/src/android/app/wallpaper/WallpaperDescriptionTest.java +148 −32 File changed.Preview size limit exceeded, changes collapsed. Show changes