Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bfe1b70f authored by Chris Li's avatar Chris Li
Browse files

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
parent 2279fd5f
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -1920,7 +1920,9 @@ class ContextImpl extends Context {
        return SystemServiceRegistry.getSystemServiceName(serviceClass);
        return SystemServiceRegistry.getSystemServiceName(serviceClass);
    }
    }


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


+9 −0
Original line number Original line Diff line number Diff line
@@ -6103,4 +6103,13 @@ public abstract class Context {
                    + "get a UI context from ActivityThread#getSystemUiContext()");
                    + "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 −0
Original line number Original line Diff line number Diff line
@@ -1145,4 +1145,12 @@ public class ContextWrapper extends Context {
            mBase.setContentCaptureOptions(options);
            mBase.setContentCaptureOptions(options);
        }
        }
    }
    }

    /**
     * @hide
     */
    @Override
    public boolean isUiContext() {
        return mBase.isUiContext();
    }
}
}
+31 −7
Original line number Original line Diff line number Diff line
@@ -16,8 +16,11 @@


package android.view;
package android.view;


import static android.os.StrictMode.vmIncorrectContextUseEnabled;

import android.annotation.FloatRange;
import android.annotation.FloatRange;
import android.annotation.TestApi;
import android.annotation.TestApi;
import android.app.Activity;
import android.app.AppGlobals;
import android.app.AppGlobals;
import android.compat.annotation.UnsupportedAppUsage;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.Context;
@@ -25,9 +28,12 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.Resources;
import android.graphics.Rect;
import android.graphics.Rect;
import android.os.Build;
import android.os.Build;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.StrictMode;
import android.provider.Settings;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseArray;
import android.util.TypedValue;
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.
 * Contains methods to standard constants used in the UI for timeouts, sizes, and distances.
 */
 */
public class ViewConfiguration {
public class ViewConfiguration {
    private static final String TAG = "ViewConfiguration";

    /**
    /**
     * Defines the width of the horizontal scrollbar and the height of the vertical scrollbar in
     * Defines the width of the horizontal scrollbar and the height of the vertical scrollbar in
     * dips
     * dips
@@ -372,11 +380,13 @@ public class ViewConfiguration {
    }
    }


    /**
    /**
     * Creates a new configuration for the specified context. The configuration depends on
     * Creates a new configuration for the specified visual {@link Context}. The configuration
     * various parameters of the context, like the dimension of the display or the density
     * depends on various parameters of the {@link Context}, like the dimension of the display or
     * of the display.
     * 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 #get(android.content.Context)
     * @see android.util.DisplayMetrics
     * @see android.util.DisplayMetrics
@@ -480,13 +490,27 @@ public class ViewConfiguration {
    }
    }


    /**
    /**
     * Returns a configuration for the specified context. The configuration depends on
     * Returns a configuration for the specified visual {@link Context}. The configuration depends
     * various parameters of the context, like the dimension of the display or the
     * on various parameters of the {@link Context}, like the dimension of the display or the
     * density of the display.
     * 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) {
    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 DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        final int density = (int) (100.0f * metrics.density);
        final int density = (int) (100.0f * metrics.density);


+6 −0
Original line number Original line Diff line number Diff line
@@ -928,4 +928,10 @@ public class MockContext extends Context {
    public Handler getMainThreadHandler() {
    public Handler getMainThreadHandler() {
        throw new UnsupportedOperationException();
        throw new UnsupportedOperationException();
    }
    }

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