|
|
|
|
@@ -16,6 +16,11 @@
|
|
|
|
|
|
|
|
|
|
package android.app;
|
|
|
|
|
|
|
|
|
|
import static android.Manifest.permission.MANAGE_EXTERNAL_STORAGE;
|
|
|
|
|
import static android.Manifest.permission.READ_WALLPAPER_INTERNAL;
|
|
|
|
|
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
|
|
|
|
import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
|
|
|
|
|
|
|
|
|
|
import android.annotation.FloatRange;
|
|
|
|
|
import android.annotation.IntDef;
|
|
|
|
|
import android.annotation.NonNull;
|
|
|
|
|
@@ -28,6 +33,9 @@ import android.annotation.SystemApi;
|
|
|
|
|
import android.annotation.SystemService;
|
|
|
|
|
import android.annotation.TestApi;
|
|
|
|
|
import android.annotation.UiContext;
|
|
|
|
|
import android.app.compat.CompatChanges;
|
|
|
|
|
import android.compat.annotation.ChangeId;
|
|
|
|
|
import android.compat.annotation.EnabledSince;
|
|
|
|
|
import android.compat.annotation.UnsupportedAppUsage;
|
|
|
|
|
import android.content.ComponentName;
|
|
|
|
|
import android.content.ContentResolver;
|
|
|
|
|
@@ -84,6 +92,7 @@ import java.io.BufferedInputStream;
|
|
|
|
|
import java.io.ByteArrayOutputStream;
|
|
|
|
|
import java.io.File;
|
|
|
|
|
import java.io.FileInputStream;
|
|
|
|
|
import java.io.FileNotFoundException;
|
|
|
|
|
import java.io.FileOutputStream;
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.io.InputStream;
|
|
|
|
|
@@ -108,8 +117,26 @@ import java.util.concurrent.TimeUnit;
|
|
|
|
|
*/
|
|
|
|
|
@SystemService(Context.WALLPAPER_SERVICE)
|
|
|
|
|
public class WallpaperManager {
|
|
|
|
|
|
|
|
|
|
private static String TAG = "WallpaperManager";
|
|
|
|
|
private static final boolean DEBUG = false;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Trying to read the wallpaper file or bitmap in T will return
|
|
|
|
|
* the default wallpaper bitmap/file instead of throwing a SecurityException.
|
|
|
|
|
*/
|
|
|
|
|
@ChangeId
|
|
|
|
|
@EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
|
|
|
|
|
static final long RETURN_DEFAULT_ON_SECURITY_EXCEPTION = 239784307L;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* In U and later, attempting to read the wallpaper file or bitmap will throw an exception,
|
|
|
|
|
* (except with the READ_WALLPAPER_INTERNAL permission).
|
|
|
|
|
*/
|
|
|
|
|
@ChangeId
|
|
|
|
|
@EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
|
|
|
|
static final long THROW_ON_SECURITY_EXCEPTION = 237508058L;
|
|
|
|
|
|
|
|
|
|
private float mWallpaperXStep = -1;
|
|
|
|
|
private float mWallpaperYStep = -1;
|
|
|
|
|
private static final @NonNull RectF LOCAL_COLOR_BOUNDS =
|
|
|
|
|
@@ -585,7 +612,8 @@ public class WallpaperManager {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
synchronized (this) {
|
|
|
|
|
if (mCachedWallpaper != null && mCachedWallpaper.isValid(userId, which)) {
|
|
|
|
|
if (mCachedWallpaper != null && mCachedWallpaper.isValid(userId, which) && context
|
|
|
|
|
.checkSelfPermission(READ_WALLPAPER_INTERNAL) == PERMISSION_GRANTED) {
|
|
|
|
|
return mCachedWallpaper.mCachedWallpaper;
|
|
|
|
|
}
|
|
|
|
|
mCachedWallpaper = null;
|
|
|
|
|
@@ -596,6 +624,19 @@ public class WallpaperManager {
|
|
|
|
|
} catch (OutOfMemoryError e) {
|
|
|
|
|
Log.w(TAG, "Out of memory loading the current wallpaper: " + e);
|
|
|
|
|
} catch (SecurityException e) {
|
|
|
|
|
/*
|
|
|
|
|
* Apps with target SDK <= S can still access the wallpaper through
|
|
|
|
|
* READ_EXTERNAL_STORAGE. In T however, app that previously had access to the
|
|
|
|
|
* wallpaper via READ_EXTERNAL_STORAGE will get a SecurityException here.
|
|
|
|
|
* Thus, in T specifically, return the default wallpaper instead of crashing.
|
|
|
|
|
*/
|
|
|
|
|
if (CompatChanges.isChangeEnabled(RETURN_DEFAULT_ON_SECURITY_EXCEPTION)
|
|
|
|
|
&& !CompatChanges.isChangeEnabled(THROW_ON_SECURITY_EXCEPTION)) {
|
|
|
|
|
Log.w(TAG, "No permission to access wallpaper, returning default"
|
|
|
|
|
+ " wallpaper to avoid crashing legacy app.");
|
|
|
|
|
return getDefaultWallpaper(context, FLAG_SYSTEM);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (context.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.O_MR1) {
|
|
|
|
|
Log.w(TAG, "No permission to access wallpaper, suppressing"
|
|
|
|
|
+ " exception to avoid crashing legacy app.");
|
|
|
|
|
@@ -808,6 +849,18 @@ public class WallpaperManager {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <strong> Important note: </strong>
|
|
|
|
|
* <ul>
|
|
|
|
|
* <li>Up to version S, this method requires the
|
|
|
|
|
* {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission.</li>
|
|
|
|
|
* <li>Starting in T, directly accessing the wallpaper is not possible anymore,
|
|
|
|
|
* instead the default system wallpaper is returned
|
|
|
|
|
* (some versions of T may throw a {@code SecurityException}).</li>
|
|
|
|
|
* <li>From version U, this method should not be used
|
|
|
|
|
* and will always throw a @code SecurityException}.</li>
|
|
|
|
|
* </ul>
|
|
|
|
|
* <br>
|
|
|
|
|
*
|
|
|
|
|
* Retrieve the current system wallpaper; if
|
|
|
|
|
* no wallpaper is set, the system built-in static wallpaper is returned.
|
|
|
|
|
* This is returned as an
|
|
|
|
|
@@ -821,14 +874,28 @@ public class WallpaperManager {
|
|
|
|
|
* @return Returns a Drawable object that will draw the system wallpaper,
|
|
|
|
|
* or {@code null} if no system wallpaper exists or if the calling application
|
|
|
|
|
* is not able to access the wallpaper.
|
|
|
|
|
*
|
|
|
|
|
* @throws SecurityException as described in the note
|
|
|
|
|
*/
|
|
|
|
|
@RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
|
|
|
|
|
@Nullable
|
|
|
|
|
@RequiresPermission(anyOf = {MANAGE_EXTERNAL_STORAGE, READ_WALLPAPER_INTERNAL})
|
|
|
|
|
public Drawable getDrawable() {
|
|
|
|
|
return getDrawable(FLAG_SYSTEM);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <strong> Important note: </strong>
|
|
|
|
|
* <ul>
|
|
|
|
|
* <li>Up to version S, this method requires the
|
|
|
|
|
* {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission.</li>
|
|
|
|
|
* <li>Starting in T, directly accessing the wallpaper is not possible anymore,
|
|
|
|
|
* instead the default system wallpaper is returned
|
|
|
|
|
* (some versions of T may throw a {@code SecurityException}).</li>
|
|
|
|
|
* <li>From version U, this method should not be used
|
|
|
|
|
* and will always throw a @code SecurityException}.</li>
|
|
|
|
|
* </ul>
|
|
|
|
|
* <br>
|
|
|
|
|
*
|
|
|
|
|
* Retrieve the requested wallpaper; if
|
|
|
|
|
* no wallpaper is set, the requested built-in static wallpaper is returned.
|
|
|
|
|
* This is returned as an
|
|
|
|
|
@@ -844,9 +911,11 @@ public class WallpaperManager {
|
|
|
|
|
* @return Returns a Drawable object that will draw the requested wallpaper,
|
|
|
|
|
* or {@code null} if the requested wallpaper does not exist or if the calling application
|
|
|
|
|
* is not able to access the wallpaper.
|
|
|
|
|
*
|
|
|
|
|
* @throws SecurityException as described in the note
|
|
|
|
|
*/
|
|
|
|
|
@RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
|
|
|
|
|
@Nullable
|
|
|
|
|
@RequiresPermission(anyOf = {MANAGE_EXTERNAL_STORAGE, READ_WALLPAPER_INTERNAL})
|
|
|
|
|
public Drawable getDrawable(@SetWallpaperFlags int which) {
|
|
|
|
|
final ColorManagementProxy cmProxy = getColorManagementProxy();
|
|
|
|
|
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true, which, cmProxy);
|
|
|
|
|
@@ -1069,6 +1138,18 @@ public class WallpaperManager {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <strong> Important note: </strong>
|
|
|
|
|
* <ul>
|
|
|
|
|
* <li>Up to version S, this method requires the
|
|
|
|
|
* {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission.</li>
|
|
|
|
|
* <li>Starting in T, directly accessing the wallpaper is not possible anymore,
|
|
|
|
|
* instead the default system wallpaper is returned
|
|
|
|
|
* (some versions of T may throw a {@code SecurityException}).</li>
|
|
|
|
|
* <li>From version U, this method should not be used
|
|
|
|
|
* and will always throw a @code SecurityException}.</li>
|
|
|
|
|
* </ul>
|
|
|
|
|
* <br>
|
|
|
|
|
*
|
|
|
|
|
* Retrieve the current system wallpaper; if there is no wallpaper set,
|
|
|
|
|
* a null pointer is returned. This is returned as an
|
|
|
|
|
* abstract Drawable that you can install in a View to display whatever
|
|
|
|
|
@@ -1076,13 +1157,28 @@ public class WallpaperManager {
|
|
|
|
|
*
|
|
|
|
|
* @return Returns a Drawable object that will draw the wallpaper or a
|
|
|
|
|
* null pointer if wallpaper is unset.
|
|
|
|
|
*
|
|
|
|
|
* @throws SecurityException as described in the note
|
|
|
|
|
*/
|
|
|
|
|
@Nullable
|
|
|
|
|
@RequiresPermission(anyOf = {MANAGE_EXTERNAL_STORAGE, READ_WALLPAPER_INTERNAL})
|
|
|
|
|
public Drawable peekDrawable() {
|
|
|
|
|
return peekDrawable(FLAG_SYSTEM);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <strong> Important note: </strong>
|
|
|
|
|
* <ul>
|
|
|
|
|
* <li>Up to version S, this method requires the
|
|
|
|
|
* {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission.</li>
|
|
|
|
|
* <li>Starting in T, directly accessing the wallpaper is not possible anymore,
|
|
|
|
|
* instead the default system wallpaper is returned
|
|
|
|
|
* (some versions of T may throw a {@code SecurityException}).</li>
|
|
|
|
|
* <li>From version U, this method should not be used
|
|
|
|
|
* and will always throw a @code SecurityException}.</li>
|
|
|
|
|
* </ul>
|
|
|
|
|
* <br>
|
|
|
|
|
*
|
|
|
|
|
* Retrieve the requested wallpaper; if there is no wallpaper set,
|
|
|
|
|
* a null pointer is returned. This is returned as an
|
|
|
|
|
* abstract Drawable that you can install in a View to display whatever
|
|
|
|
|
@@ -1092,11 +1188,14 @@ public class WallpaperManager {
|
|
|
|
|
* IllegalArgumentException if an invalid wallpaper is requested.
|
|
|
|
|
* @return Returns a Drawable object that will draw the wallpaper or a null pointer if
|
|
|
|
|
* wallpaper is unset.
|
|
|
|
|
*
|
|
|
|
|
* @throws SecurityException as described in the note
|
|
|
|
|
*/
|
|
|
|
|
@Nullable
|
|
|
|
|
@RequiresPermission(anyOf = {MANAGE_EXTERNAL_STORAGE, READ_WALLPAPER_INTERNAL})
|
|
|
|
|
public Drawable peekDrawable(@SetWallpaperFlags int which) {
|
|
|
|
|
final ColorManagementProxy cmProxy = getColorManagementProxy();
|
|
|
|
|
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false, which, cmProxy);
|
|
|
|
|
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true, which, cmProxy);
|
|
|
|
|
if (bm != null) {
|
|
|
|
|
Drawable dr = new BitmapDrawable(mContext.getResources(), bm);
|
|
|
|
|
dr.setDither(false);
|
|
|
|
|
@@ -1106,6 +1205,18 @@ public class WallpaperManager {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <strong> Important note: </strong>
|
|
|
|
|
* <ul>
|
|
|
|
|
* <li>Up to version S, this method requires the
|
|
|
|
|
* {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission.</li>
|
|
|
|
|
* <li>Starting in T, directly accessing the wallpaper is not possible anymore,
|
|
|
|
|
* instead the default wallpaper is returned
|
|
|
|
|
* (some versions of T may throw a {@code SecurityException}).</li>
|
|
|
|
|
* <li>From version U, this method should not be used
|
|
|
|
|
* and will always throw a @code SecurityException}.</li>
|
|
|
|
|
* </ul>
|
|
|
|
|
* <br>
|
|
|
|
|
*
|
|
|
|
|
* Like {@link #getDrawable()}, but the returned Drawable has a number
|
|
|
|
|
* of limitations to reduce its overhead as much as possible. It will
|
|
|
|
|
* never scale the wallpaper (only centering it if the requested bounds
|
|
|
|
|
@@ -1117,14 +1228,28 @@ public class WallpaperManager {
|
|
|
|
|
* the same density as the screen (not in density compatibility mode).
|
|
|
|
|
*
|
|
|
|
|
* @return Returns a Drawable object that will draw the wallpaper.
|
|
|
|
|
*
|
|
|
|
|
* @throws SecurityException as described in the note
|
|
|
|
|
*/
|
|
|
|
|
@RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
|
|
|
|
|
@Nullable
|
|
|
|
|
@RequiresPermission(anyOf = {MANAGE_EXTERNAL_STORAGE, READ_WALLPAPER_INTERNAL})
|
|
|
|
|
public Drawable getFastDrawable() {
|
|
|
|
|
return getFastDrawable(FLAG_SYSTEM);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <strong> Important note: </strong>
|
|
|
|
|
* <ul>
|
|
|
|
|
* <li>Up to version S, this method requires the
|
|
|
|
|
* {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission.</li>
|
|
|
|
|
* <li>Starting in T, directly accessing the wallpaper is not possible anymore,
|
|
|
|
|
* instead the default system wallpaper is returned
|
|
|
|
|
* (some versions of T may throw a {@code SecurityException}).</li>
|
|
|
|
|
* <li>From version U, this method should not be used
|
|
|
|
|
* and will always throw a @code SecurityException}.</li>
|
|
|
|
|
* </ul>
|
|
|
|
|
* <br>
|
|
|
|
|
*
|
|
|
|
|
* Like {@link #getDrawable(int)}, but the returned Drawable has a number
|
|
|
|
|
* of limitations to reduce its overhead as much as possible. It will
|
|
|
|
|
* never scale the wallpaper (only centering it if the requested bounds
|
|
|
|
|
@@ -1138,9 +1263,11 @@ public class WallpaperManager {
|
|
|
|
|
* @param which The {@code FLAG_*} identifier of a valid wallpaper type. Throws
|
|
|
|
|
* IllegalArgumentException if an invalid wallpaper is requested.
|
|
|
|
|
* @return Returns a Drawable object that will draw the wallpaper.
|
|
|
|
|
*
|
|
|
|
|
* @throws SecurityException as described in the note
|
|
|
|
|
*/
|
|
|
|
|
@RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
|
|
|
|
|
@Nullable
|
|
|
|
|
@RequiresPermission(anyOf = {MANAGE_EXTERNAL_STORAGE, READ_WALLPAPER_INTERNAL})
|
|
|
|
|
public Drawable getFastDrawable(@SetWallpaperFlags int which) {
|
|
|
|
|
final ColorManagementProxy cmProxy = getColorManagementProxy();
|
|
|
|
|
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true, which, cmProxy);
|
|
|
|
|
@@ -1151,19 +1278,45 @@ public class WallpaperManager {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <strong> Important note: </strong>
|
|
|
|
|
* <ul>
|
|
|
|
|
* <li>Up to version S, this method requires the
|
|
|
|
|
* {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission.</li>
|
|
|
|
|
* <li>Starting in T, directly accessing the wallpaper is not possible anymore,
|
|
|
|
|
* instead the default system wallpaper is returned
|
|
|
|
|
* (some versions of T may throw a {@code SecurityException}).</li>
|
|
|
|
|
* <li>From version U, this method should not be used
|
|
|
|
|
* and will always throw a @code SecurityException}.</li>
|
|
|
|
|
* </ul>
|
|
|
|
|
* <br>
|
|
|
|
|
*
|
|
|
|
|
* Like {@link #getFastDrawable()}, but if there is no wallpaper set,
|
|
|
|
|
* a null pointer is returned.
|
|
|
|
|
*
|
|
|
|
|
* @return Returns an optimized Drawable object that will draw the
|
|
|
|
|
* wallpaper or a null pointer if these is none.
|
|
|
|
|
*
|
|
|
|
|
* @throws SecurityException as described in the note
|
|
|
|
|
*/
|
|
|
|
|
@RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
|
|
|
|
|
@Nullable
|
|
|
|
|
@RequiresPermission(anyOf = {MANAGE_EXTERNAL_STORAGE, READ_WALLPAPER_INTERNAL})
|
|
|
|
|
public Drawable peekFastDrawable() {
|
|
|
|
|
return peekFastDrawable(FLAG_SYSTEM);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <strong> Important note: </strong>
|
|
|
|
|
* <ul>
|
|
|
|
|
* <li>Up to version S, this method requires the
|
|
|
|
|
* {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission.</li>
|
|
|
|
|
* <li>Starting in T, directly accessing the wallpaper is not possible anymore,
|
|
|
|
|
* instead the default system wallpaper is returned
|
|
|
|
|
* (some versions of T may throw a {@code SecurityException}).</li>
|
|
|
|
|
* <li>From version U, this method should not be used
|
|
|
|
|
* and will always throw a @code SecurityException}.</li>
|
|
|
|
|
* </ul>
|
|
|
|
|
* <br>
|
|
|
|
|
*
|
|
|
|
|
* Like {@link #getFastDrawable()}, but if there is no wallpaper set,
|
|
|
|
|
* a null pointer is returned.
|
|
|
|
|
*
|
|
|
|
|
@@ -1171,12 +1324,14 @@ public class WallpaperManager {
|
|
|
|
|
* IllegalArgumentException if an invalid wallpaper is requested.
|
|
|
|
|
* @return Returns an optimized Drawable object that will draw the
|
|
|
|
|
* wallpaper or a null pointer if these is none.
|
|
|
|
|
*
|
|
|
|
|
* @throws SecurityException as described in the note
|
|
|
|
|
*/
|
|
|
|
|
@RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
|
|
|
|
|
@Nullable
|
|
|
|
|
@RequiresPermission(anyOf = {MANAGE_EXTERNAL_STORAGE, READ_WALLPAPER_INTERNAL})
|
|
|
|
|
public Drawable peekFastDrawable(@SetWallpaperFlags int which) {
|
|
|
|
|
final ColorManagementProxy cmProxy = getColorManagementProxy();
|
|
|
|
|
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false, which, cmProxy);
|
|
|
|
|
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true, which, cmProxy);
|
|
|
|
|
if (bm != null) {
|
|
|
|
|
return new FastBitmapDrawable(bm);
|
|
|
|
|
}
|
|
|
|
|
@@ -1194,7 +1349,6 @@ public class WallpaperManager {
|
|
|
|
|
* @hide
|
|
|
|
|
*/
|
|
|
|
|
@TestApi
|
|
|
|
|
@RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
|
|
|
|
|
public boolean wallpaperSupportsWcg(int which) {
|
|
|
|
|
if (!shouldEnableWideColorGamut()) {
|
|
|
|
|
return false;
|
|
|
|
|
@@ -1295,6 +1449,18 @@ public class WallpaperManager {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <strong> Important note: </strong>
|
|
|
|
|
* <ul>
|
|
|
|
|
* <li>Up to version S, this method requires the
|
|
|
|
|
* {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission.</li>
|
|
|
|
|
* <li>Starting in T, directly accessing the wallpaper is not possible anymore,
|
|
|
|
|
* instead the default system wallpaper is returned
|
|
|
|
|
* (some versions of T may throw a {@code SecurityException}).</li>
|
|
|
|
|
* <li>From version U, this method should not be used
|
|
|
|
|
* and will always throw a @code SecurityException}.</li>
|
|
|
|
|
* </ul>
|
|
|
|
|
* <br>
|
|
|
|
|
*
|
|
|
|
|
* Get an open, readable file descriptor to the given wallpaper image file.
|
|
|
|
|
* The caller is responsible for closing the file descriptor when done ingesting the file.
|
|
|
|
|
*
|
|
|
|
|
@@ -1305,14 +1471,17 @@ public class WallpaperManager {
|
|
|
|
|
* @param which The wallpaper whose image file is to be retrieved. Must be a single
|
|
|
|
|
* defined kind of wallpaper, either {@link #FLAG_SYSTEM} or
|
|
|
|
|
* {@link #FLAG_LOCK}.
|
|
|
|
|
* @return An open, readable file desriptor to the requested wallpaper image file;
|
|
|
|
|
* @return An open, readable file descriptor to the requested wallpaper image file;
|
|
|
|
|
* or {@code null} if no such wallpaper is configured or if the calling app does
|
|
|
|
|
* not have permission to read the current wallpaper.
|
|
|
|
|
*
|
|
|
|
|
* @see #FLAG_LOCK
|
|
|
|
|
* @see #FLAG_SYSTEM
|
|
|
|
|
*
|
|
|
|
|
* @throws SecurityException as described in the note
|
|
|
|
|
*/
|
|
|
|
|
@RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
|
|
|
|
|
@Nullable
|
|
|
|
|
@RequiresPermission(anyOf = {MANAGE_EXTERNAL_STORAGE, READ_WALLPAPER_INTERNAL})
|
|
|
|
|
public ParcelFileDescriptor getWallpaperFile(@SetWallpaperFlags int which) {
|
|
|
|
|
return getWallpaperFile(which, mContext.getUserId());
|
|
|
|
|
}
|
|
|
|
|
@@ -1475,13 +1644,18 @@ public class WallpaperManager {
|
|
|
|
|
} catch (RemoteException e) {
|
|
|
|
|
throw e.rethrowFromSystemServer();
|
|
|
|
|
} catch (SecurityException e) {
|
|
|
|
|
if (CompatChanges.isChangeEnabled(RETURN_DEFAULT_ON_SECURITY_EXCEPTION)
|
|
|
|
|
&& !CompatChanges.isChangeEnabled(THROW_ON_SECURITY_EXCEPTION)) {
|
|
|
|
|
Log.w(TAG, "No permission to access wallpaper, returning default"
|
|
|
|
|
+ " wallpaper file to avoid crashing legacy app.");
|
|
|
|
|
return getDefaultSystemWallpaperFile();
|
|
|
|
|
}
|
|
|
|
|
if (mContext.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.O_MR1) {
|
|
|
|
|
Log.w(TAG, "No permission to access wallpaper, suppressing"
|
|
|
|
|
+ " exception to avoid crashing legacy app.");
|
|
|
|
|
return null;
|
|
|
|
|
} else {
|
|
|
|
|
throw e;
|
|
|
|
|
}
|
|
|
|
|
throw e;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -2586,6 +2760,24 @@ public class WallpaperManager {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* util used in T to return a default system wallpaper file
|
|
|
|
|
* when third party apps attempt to read the wallpaper with {@link #getWallpaperFile}
|
|
|
|
|
*/
|
|
|
|
|
private static ParcelFileDescriptor getDefaultSystemWallpaperFile() {
|
|
|
|
|
for (String path: getDefaultSystemWallpaperPaths()) {
|
|
|
|
|
File file = new File(path);
|
|
|
|
|
if (file.exists()) {
|
|
|
|
|
try {
|
|
|
|
|
return ParcelFileDescriptor.open(file, MODE_READ_ONLY);
|
|
|
|
|
} catch (FileNotFoundException e) {
|
|
|
|
|
// continue; default wallpaper file not found on this path
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static InputStream getWallpaperInputStream(String path) {
|
|
|
|
|
if (!TextUtils.isEmpty(path)) {
|
|
|
|
|
final File file = new File(path);
|
|
|
|
|
@@ -2600,6 +2792,14 @@ public class WallpaperManager {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return a list of paths to the system default wallpapers, in order of priority:
|
|
|
|
|
* if the file exists for the first path of this list, the first path should be used.
|
|
|
|
|
*/
|
|
|
|
|
private static List<String> getDefaultSystemWallpaperPaths() {
|
|
|
|
|
return List.of(SystemProperties.get(PROP_WALLPAPER), getCmfWallpaperPath());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static String getCmfWallpaperPath() {
|
|
|
|
|
return Environment.getProductDirectory() + WALLPAPER_CMF_PATH + "default_wallpaper_"
|
|
|
|
|
+ VALUE_CMF_COLOR;
|
|
|
|
|
|