Skip to content

Commit

Permalink
Report incorrect context usage in ViewConfiguration
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Chris Li committed Mar 27, 2020
1 parent 2279fd5 commit bfe1b70
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 8 deletions.
4 changes: 3 additions & 1 deletion core/java/android/app/ContextImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -1920,7 +1920,9 @@ public String getSystemServiceName(Class<?> serviceClass) {
return SystemServiceRegistry.getSystemServiceName(serviceClass);
}

private boolean isUiContext() {
/** @hide */
@Override
public boolean isUiContext() {
return mIsSystemOrSystemUiContext || mIsUiContext || isSystemOrSystemUI();
}

Expand Down
9 changes: 9 additions & 0 deletions core/java/android/content/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -6103,4 +6103,13 @@ public void assertRuntimeOverlayThemable() {
+ "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.");
}
}
8 changes: 8 additions & 0 deletions core/java/android/content/ContextWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -1145,4 +1145,12 @@ public void setContentCaptureOptions(ContentCaptureOptions options) {
mBase.setContentCaptureOptions(options);
}
}

/**
* @hide
*/
@Override
public boolean isUiContext() {
return mBase.isUiContext();
}
}
38 changes: 31 additions & 7 deletions core/java/android/view/ViewConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,33 @@

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;
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;

/**
* 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
Expand Down Expand Up @@ -372,11 +380,13 @@ public 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
Expand Down Expand Up @@ -480,13 +490,27 @@ private ViewConfiguration(Context context) {
}

/**
* 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);

Expand Down
6 changes: 6 additions & 0 deletions test-mock/src/android/test/mock/MockContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -928,4 +928,10 @@ public IApplicationThread getIApplicationThread() {
public Handler getMainThreadHandler() {
throw new UnsupportedOperationException();
}

/** {@hide} */
@Override
public boolean isUiContext() {
throw new UnsupportedOperationException();
}
}

0 comments on commit bfe1b70

Please sign in to comment.