Report incorrect context usage in ViewConfiguration
Before, the documentation said that the passed context is an application context, which is incorrect to get the density, window metrics, and window manager. We should use visual context to get these instead. Bug: 151474461 Test: StrictModeTest#testIncorrectContextUse_GetViewConfiguration Change-Id: Iea28d727cafbb3ec8536742c6a0e594f73fe5a51
This commit is contained in:
@@ -1920,7 +1920,9 @@ class ContextImpl extends Context {
|
||||
return SystemServiceRegistry.getSystemServiceName(serviceClass);
|
||||
}
|
||||
|
||||
private boolean isUiContext() {
|
||||
/** @hide */
|
||||
@Override
|
||||
public boolean isUiContext() {
|
||||
return mIsSystemOrSystemUiContext || mIsUiContext || isSystemOrSystemUI();
|
||||
}
|
||||
|
||||
|
||||
@@ -6103,4 +6103,13 @@ public abstract class Context {
|
||||
+ "get a UI context from ActivityThread#getSystemUiContext()");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this context is a visual context such as {@link android.app.Activity} or
|
||||
* a context created from {@link #createWindowContext(int, Bundle)}.
|
||||
* @hide
|
||||
*/
|
||||
public boolean isUiContext() {
|
||||
throw new RuntimeException("Not implemented. Must override in a subclass.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1145,4 +1145,12 @@ public class ContextWrapper extends Context {
|
||||
mBase.setContentCaptureOptions(options);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public boolean isUiContext() {
|
||||
return mBase.isUiContext();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,11 @@
|
||||
|
||||
package android.view;
|
||||
|
||||
import static android.os.StrictMode.vmIncorrectContextUseEnabled;
|
||||
|
||||
import android.annotation.FloatRange;
|
||||
import android.annotation.TestApi;
|
||||
import android.app.Activity;
|
||||
import android.app.AppGlobals;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.Context;
|
||||
@@ -25,9 +28,12 @@ import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.StrictMode;
|
||||
import android.provider.Settings;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.util.TypedValue;
|
||||
|
||||
@@ -35,6 +41,8 @@ import android.util.TypedValue;
|
||||
* Contains methods to standard constants used in the UI for timeouts, sizes, and distances.
|
||||
*/
|
||||
public class ViewConfiguration {
|
||||
private static final String TAG = "ViewConfiguration";
|
||||
|
||||
/**
|
||||
* Defines the width of the horizontal scrollbar and the height of the vertical scrollbar in
|
||||
* dips
|
||||
@@ -372,11 +380,13 @@ public class ViewConfiguration {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new configuration for the specified context. The configuration depends on
|
||||
* various parameters of the context, like the dimension of the display or the density
|
||||
* of the display.
|
||||
* Creates a new configuration for the specified visual {@link Context}. The configuration
|
||||
* depends on various parameters of the {@link Context}, like the dimension of the display or
|
||||
* the density of the display.
|
||||
*
|
||||
* @param context The application context used to initialize this view configuration.
|
||||
* @param context A visual {@link Context} used to initialize the view configuration. It must
|
||||
* be {@link Activity} or other {@link Context} created with
|
||||
* {@link Context#createWindowContext(int, Bundle)}.
|
||||
*
|
||||
* @see #get(android.content.Context)
|
||||
* @see android.util.DisplayMetrics
|
||||
@@ -480,13 +490,27 @@ public class ViewConfiguration {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a configuration for the specified context. The configuration depends on
|
||||
* various parameters of the context, like the dimension of the display or the
|
||||
* Returns a configuration for the specified visual {@link Context}. The configuration depends
|
||||
* on various parameters of the {@link Context}, like the dimension of the display or the
|
||||
* density of the display.
|
||||
*
|
||||
* @param context The application context used to initialize the view configuration.
|
||||
* @param context A visual {@link Context} used to initialize the view configuration. It must
|
||||
* be {@link Activity} or other {@link Context} created with
|
||||
* {@link Context#createWindowContext(int, Bundle)}.
|
||||
*/
|
||||
public static ViewConfiguration get(Context context) {
|
||||
if (!context.isUiContext() && vmIncorrectContextUseEnabled()) {
|
||||
final String errorMessage = "Tried to access UI constants from a non-visual Context.";
|
||||
final String message = "UI constants, such as display metrics or window metrics, "
|
||||
+ "must be accessed from Activity or other visual Context. "
|
||||
+ "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 IllegalArgumentException(errorMessage);
|
||||
StrictMode.onIncorrectContextUsed(message, exception);
|
||||
Log.e(TAG, errorMessage + message, exception);
|
||||
}
|
||||
|
||||
final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
|
||||
final int density = (int) (100.0f * metrics.density);
|
||||
|
||||
|
||||
@@ -928,4 +928,10 @@ public class MockContext extends Context {
|
||||
public Handler getMainThreadHandler() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
@Override
|
||||
public boolean isUiContext() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user