Limit UI context verification to UI related APIs

This CL relaxed the UI context checks to only apply on UI related
APIs in WallpaperManager.

Test: build & run
Bug: 176958992

Change-Id: I390e865e31fde48bad6bbddb4203e4c997a1400a
This commit is contained in:
Charles Chen
2020-12-28 15:16:13 +08:00
parent f749076910
commit 9ca5f902ca
3 changed files with 44 additions and 2 deletions

View File

@@ -1996,8 +1996,7 @@ class ContextImpl extends Context {
}
private static boolean isUiComponent(String name) {
return WINDOW_SERVICE.equals(name) || LAYOUT_INFLATER_SERVICE.equals(name)
|| WALLPAPER_SERVICE.equals(name);
return WINDOW_SERVICE.equals(name) || LAYOUT_INFLATER_SERVICE.equals(name);
}
@Override

View File

@@ -63,6 +63,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.StrictMode;
import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.Log;
@@ -606,6 +607,7 @@ public class WallpaperManager {
* is not able to access the wallpaper.
*/
public Drawable getDrawable() {
assertUiContext("getDrawable");
final ColorManagementProxy cmProxy = getColorManagementProxy();
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true, FLAG_SYSTEM, cmProxy);
if (bm != null) {
@@ -673,6 +675,7 @@ public class WallpaperManager {
*/
public Drawable getBuiltInDrawable(int outWidth, int outHeight, boolean scaleToFit,
float horizontalAlignment, float verticalAlignment, @SetWallpaperFlags int which) {
assertUiContext("getBuiltInDrawable");
if (sGlobals.mService == null) {
Log.w(TAG, "WallpaperService not running");
throw new RuntimeException(new DeadSystemException());
@@ -838,6 +841,7 @@ public class WallpaperManager {
* null pointer if these is none.
*/
public Drawable peekDrawable() {
assertUiContext("peekDrawable");
final ColorManagementProxy cmProxy = getColorManagementProxy();
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false, FLAG_SYSTEM, cmProxy);
if (bm != null) {
@@ -880,6 +884,7 @@ public class WallpaperManager {
*/
@RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
public Drawable peekFastDrawable() {
assertUiContext("peekFastDrawable");
final ColorManagementProxy cmProxy = getColorManagementProxy();
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false, FLAG_SYSTEM, cmProxy);
if (bm != null) {
@@ -1046,6 +1051,7 @@ public class WallpaperManager {
*/
@UnsupportedAppUsage
public @Nullable WallpaperColors getWallpaperColors(int which, int userId) {
assertUiContext("getWallpaperColors");
return sGlobals.getWallpaperColors(which, userId, mContext.getDisplayId());
}
@@ -1261,6 +1267,7 @@ public class WallpaperManager {
@RequiresPermission(android.Manifest.permission.SET_WALLPAPER)
public int setResource(@RawRes int resid, @SetWallpaperFlags int which)
throws IOException {
assertUiContext("setResource");
if (sGlobals.mService == null) {
Log.w(TAG, "WallpaperService not running");
throw new RuntimeException(new DeadSystemException());
@@ -1581,6 +1588,7 @@ public class WallpaperManager {
* @see #getDesiredMinimumHeight()
*/
public int getDesiredMinimumWidth() {
assertUiContext("getDesiredMinimumWidth");
if (sGlobals.mService == null) {
Log.w(TAG, "WallpaperService not running");
throw new RuntimeException(new DeadSystemException());
@@ -1609,6 +1617,7 @@ public class WallpaperManager {
* @see #getDesiredMinimumWidth()
*/
public int getDesiredMinimumHeight() {
assertUiContext("getDesiredMinimumHeight");
if (sGlobals.mService == null) {
Log.w(TAG, "WallpaperService not running");
throw new RuntimeException(new DeadSystemException());
@@ -1639,6 +1648,7 @@ public class WallpaperManager {
* @param minimumHeight Desired minimum height
*/
public void suggestDesiredDimensions(int minimumWidth, int minimumHeight) {
assertUiContext("suggestDesiredDimensions");
try {
/**
* The framework makes no attempt to limit the window size
@@ -1694,6 +1704,7 @@ public class WallpaperManager {
*/
@RequiresPermission(android.Manifest.permission.SET_WALLPAPER_HINTS)
public void setDisplayPadding(Rect padding) {
assertUiContext("setDisplayPadding");
try {
if (sGlobals.mService == null) {
Log.w(TAG, "WallpaperService not running");
@@ -1946,6 +1957,7 @@ public class WallpaperManager {
*/
@RequiresPermission(android.Manifest.permission.SET_WALLPAPER)
public void clear() throws IOException {
assertUiContext("clear");
setStream(openDefaultWallpaper(mContext, FLAG_SYSTEM), null, false);
}
@@ -2094,6 +2106,10 @@ public class WallpaperManager {
return mCmProxy;
}
private void assertUiContext(final String methodName) {
StrictMode.assertUiContext(mContext, methodName);
}
/**
* A hidden class to help {@link Globals#getCurrentWallpaperLocked} handle color management.
* @hide

View File

@@ -2194,6 +2194,33 @@ public final class StrictMode {
onVmPolicyViolation(new IncorrectContextUseViolation(message, originStack));
}
/**
* A helper method to verify if the {@code context} is a UI context and throw
* {@link IncorrectContextUseViolation} if the {@code context} is not a UI context.
*
* @param context The context to verify if it is a UI context
* @param methodName The asserted method name
*
* @see Context#isUiContext()
* @see IncorrectContextUseViolation
*
* @hide
*/
public static void assertUiContext(@NonNull Context context, @NonNull String methodName) {
if (vmIncorrectContextUseEnabled() && !context.isUiContext()) {
final String errorMessage = "Tried to access UI related API" + methodName
+ " from a non-UI Context:" + context;
final String message = "UI-related services, such as WindowManager, WallpaperService "
+ "or LayoutInflater should be accessed from Activity or other UI "
+ "Contexts. Use an Activity or a Context created with "
+ "Context#createWindowContext(int, Bundle), which are adjusted to "
+ "the configuration and visual bounds of an area on screen.";
final Exception exception = new IllegalAccessException(errorMessage);
StrictMode.onIncorrectContextUsed(message, exception);
Log.e(TAG, errorMessage + " " + message, exception);
}
}
/** Assume locked until we hear otherwise */
private static volatile boolean sUserKeyUnlocked = false;