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

Commit 31ad3207 authored by Oleg Blinnikov's avatar Oleg Blinnikov Committed by Android (Google) Code Review
Browse files

Merge "Per-app override sandboxing View API to Activity bounds"

parents 115587fd 2a276051
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -899,6 +899,7 @@ package android.content.pm {
    field public static final float OVERRIDE_MIN_ASPECT_RATIO_MEDIUM_VALUE = 1.5f;
    field public static final float OVERRIDE_MIN_ASPECT_RATIO_MEDIUM_VALUE = 1.5f;
    field public static final long OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY = 203647190L; // 0xc2368d6L
    field public static final long OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY = 203647190L; // 0xc2368d6L
    field public static final long OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN = 208648326L; // 0xc6fb886L
    field public static final long OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN = 208648326L; // 0xc6fb886L
    field public static final long OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS = 237531167L; // 0xe28701fL
    field public static final int RESIZE_MODE_RESIZEABLE = 2; // 0x2
    field public static final int RESIZE_MODE_RESIZEABLE = 2; // 0x2
  }
  }


@@ -3292,7 +3293,9 @@ package android.view {
  }
  }


  @UiThread public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback android.view.KeyEvent.Callback {
  @UiThread public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback android.view.KeyEvent.Callback {
    method public void getBoundsOnScreen(@NonNull android.graphics.Rect, boolean);
    method public android.view.View getTooltipView();
    method public android.view.View getTooltipView();
    method public void getWindowDisplayFrame(@NonNull android.graphics.Rect);
    method public boolean isAutofilled();
    method public boolean isAutofilled();
    method public static boolean isDefaultFocusHighlightEnabled();
    method public static boolean isDefaultFocusHighlightEnabled();
    method public boolean isDefaultFocusHighlightNeeded(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
    method public boolean isDefaultFocusHighlightNeeded(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
+28 −0
Original line number Original line Diff line number Diff line
@@ -1155,6 +1155,34 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
    public static final long OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE =
    public static final long OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE =
            264301586L; // buganizer id
            264301586L; // buganizer id


    /**
     * This change id forces the packages it is applied to sandbox {@link android.view.View} API to
     * an activity bounds for:
     *
     * <p>{@link android.view.View#getLocationOnScreen},
     * {@link android.view.View#getWindowVisibleDisplayFrame},
     * {@link android.view.View}#getWindowDisplayFrame,
     * {@link android.view.View}#getBoundsOnScreen.
     *
     * <p>For {@link android.view.View#getWindowVisibleDisplayFrame} and
     * {@link android.view.View}#getWindowDisplayFrame this sandboxing is happening indirectly
     * through
     * {@link android.view.ViewRootImpl}#getWindowVisibleDisplayFrame,
     * {@link android.view.ViewRootImpl}#getDisplayFrame respectively.
     *
     * <p>Some applications assume that they occupy the whole screen and therefore use the display
     * coordinates in their calculations as if an activity is  positioned in the top-left corner of
     * the screen, with left coordinate equal to 0. This may not be the case of applications in
     * multi-window and in letterbox modes. This can lead to shifted or out of bounds UI elements in
     * case the activity is Letterboxed or is in multi-window mode.
     * @hide
     */
    @ChangeId
    @Overridable
    @Disabled
    @TestApi
    public static final long OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS = 237531167L; // buganizer id

    /**
    /**
     * This change id is the gatekeeper for all treatments that force a given min aspect ratio.
     * This change id is the gatekeeper for all treatments that force a given min aspect ratio.
     * Enabling this change will allow the following min aspect ratio treatments to be applied:
     * Enabling this change will allow the following min aspect ratio treatments to be applied:
+10 −2
Original line number Original line Diff line number Diff line
@@ -8920,7 +8920,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     * @hide
     * @hide
     */
     */
    @UnsupportedAppUsage
    @UnsupportedAppUsage
    public void getBoundsOnScreen(Rect outRect, boolean clipToParent) {
    @TestApi
    public void getBoundsOnScreen(@NonNull Rect outRect, boolean clipToParent) {
        if (mAttachInfo == null) {
        if (mAttachInfo == null) {
            return;
            return;
        }
        }
@@ -8928,6 +8929,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        getBoundsToScreenInternal(position, clipToParent);
        getBoundsToScreenInternal(position, clipToParent);
        outRect.set(Math.round(position.left), Math.round(position.top),
        outRect.set(Math.round(position.left), Math.round(position.top),
                Math.round(position.right), Math.round(position.bottom));
                Math.round(position.right), Math.round(position.bottom));
        // If "Sandboxing View Bounds APIs" override is enabled, applyViewBoundsSandboxingIfNeeded
        // will sandbox outRect within window bounds.
        mAttachInfo.mViewRootImpl.applyViewBoundsSandboxingIfNeeded(outRect);
    }
    }
    /**
    /**
@@ -16159,7 +16163,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     * @hide
     * @hide
     */
     */
    @UnsupportedAppUsage
    @UnsupportedAppUsage
    public void getWindowDisplayFrame(Rect outRect) {
    @TestApi
    public void getWindowDisplayFrame(@NonNull Rect outRect) {
        if (mAttachInfo != null) {
        if (mAttachInfo != null) {
            mAttachInfo.mViewRootImpl.getDisplayFrame(outRect);
            mAttachInfo.mViewRootImpl.getDisplayFrame(outRect);
            return;
            return;
@@ -26375,6 +26380,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        if (info != null) {
        if (info != null) {
            outLocation[0] += info.mWindowLeft;
            outLocation[0] += info.mWindowLeft;
            outLocation[1] += info.mWindowTop;
            outLocation[1] += info.mWindowTop;
            // If OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS override is enabled,
            // applyViewLocationSandboxingIfNeeded sandboxes outLocation within window bounds.
            info.mViewRootImpl.applyViewLocationSandboxingIfNeeded(outLocation);
        }
        }
    }
    }
+81 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package android.view;
package android.view;


import static android.content.pm.ActivityInfo.OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS;
import static android.graphics.HardwareRenderer.SYNC_CONTEXT_IS_STOPPED;
import static android.graphics.HardwareRenderer.SYNC_CONTEXT_IS_STOPPED;
import static android.graphics.HardwareRenderer.SYNC_LOST_SURFACE_REWARD_IF_FOUND;
import static android.graphics.HardwareRenderer.SYNC_LOST_SURFACE_REWARD_IF_FOUND;
import static android.os.IInputConstants.INVALID_INPUT_EVENT_ID;
import static android.os.IInputConstants.INVALID_INPUT_EVENT_ID;
@@ -79,6 +80,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS;
import static android.view.WindowManagerGlobal.RELAYOUT_RES_CANCEL_AND_REDRAW;
import static android.view.WindowManagerGlobal.RELAYOUT_RES_CANCEL_AND_REDRAW;
import static android.view.WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS;
import static android.view.WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS;
import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
@@ -92,12 +94,14 @@ import android.animation.LayoutTransition;
import android.annotation.AnyThread;
import android.annotation.AnyThread;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.annotation.Size;
import android.annotation.UiContext;
import android.annotation.UiContext;
import android.app.ActivityManager;
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.ActivityThread;
import android.app.ICompatCameraControlCallback;
import android.app.ICompatCameraControlCallback;
import android.app.ResourcesManager;
import android.app.ResourcesManager;
import android.app.WindowConfiguration;
import android.app.WindowConfiguration;
import android.app.compat.CompatChanges;
import android.compat.annotation.UnsupportedAppUsage;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ClipData;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.ClipDescription;
@@ -895,6 +899,15 @@ public final class ViewRootImpl implements ViewParent,


    private boolean mRelayoutRequested;
    private boolean mRelayoutRequested;


    /**
     * Whether sandboxing of {@link android.view.View#getBoundsOnScreen},
     * {@link android.view.View#getLocationOnScreen(int[])},
     * {@link android.view.View#getWindowDisplayFrame} and
     * {@link android.view.View#getWindowVisibleDisplayFrame}
     * within Activity bounds is enabled for the current application.
     */
    private final boolean mViewBoundsSandboxingEnabled;

    private int mLastTransformHint = Integer.MIN_VALUE;
    private int mLastTransformHint = Integer.MIN_VALUE;


    private AccessibilityWindowAttributes mAccessibilityWindowAttributes;
    private AccessibilityWindowAttributes mAccessibilityWindowAttributes;
@@ -986,6 +999,8 @@ public final class ViewRootImpl implements ViewParent,
                mViewConfiguration,
                mViewConfiguration,
                mContext.getSystemService(InputMethodManager.class));
                mContext.getSystemService(InputMethodManager.class));


        mViewBoundsSandboxingEnabled = getViewBoundsSandboxingEnabled();

        String processorOverrideName = context.getResources().getString(
        String processorOverrideName = context.getResources().getString(
                                    R.string.config_inputEventCompatProcessorOverrideClassName);
                                    R.string.config_inputEventCompatProcessorOverrideClassName);
        if (processorOverrideName.isEmpty()) {
        if (processorOverrideName.isEmpty()) {
@@ -8598,6 +8613,9 @@ public final class ViewRootImpl implements ViewParent,
     */
     */
    void getDisplayFrame(Rect outFrame) {
    void getDisplayFrame(Rect outFrame) {
        outFrame.set(mTmpFrames.displayFrame);
        outFrame.set(mTmpFrames.displayFrame);
        // Apply sandboxing here (in getter) due to possible layout updates on the client after
        // mTmpFrames.displayFrame is received from the server.
        applyViewBoundsSandboxingIfNeeded(outFrame);
    }
    }


    /**
    /**
@@ -8614,6 +8632,69 @@ public final class ViewRootImpl implements ViewParent,
        outFrame.top += insets.top;
        outFrame.top += insets.top;
        outFrame.right -= insets.right;
        outFrame.right -= insets.right;
        outFrame.bottom -= insets.bottom;
        outFrame.bottom -= insets.bottom;
        // Apply sandboxing here (in getter) due to possible layout updates on the client after
        // mTmpFrames.displayFrame is received from the server.
        applyViewBoundsSandboxingIfNeeded(outFrame);
    }

    /**
     * Offset outRect to make it sandboxed within Window's bounds.
     *
     * <p>This is used by {@link android.view.View#getBoundsOnScreen},
     * {@link android.view.ViewRootImpl#getDisplayFrame} and
     * {@link android.view.ViewRootImpl#getWindowVisibleDisplayFrame}, which are invoked by
     * {@link android.view.View#getWindowDisplayFrame} and
     * {@link android.view.View#getWindowVisibleDisplayFrame}, as well as
     * {@link android.view.ViewDebug#captureLayers} for debugging.
     */
    void applyViewBoundsSandboxingIfNeeded(final Rect inOutRect) {
        if (mViewBoundsSandboxingEnabled) {
            final Rect bounds = getConfiguration().windowConfiguration.getBounds();
            inOutRect.offset(-bounds.left, -bounds.top);
        }
    }

    /**
     * Offset outLocation to make it sandboxed within Window's bounds.
     *
     * <p>This is used by {@link android.view.View#getLocationOnScreen(int[])}
     */
    public void applyViewLocationSandboxingIfNeeded(@Size(2) int[] outLocation) {
        if (mViewBoundsSandboxingEnabled) {
            final Rect bounds = getConfiguration().windowConfiguration.getBounds();
            outLocation[0] -= bounds.left;
            outLocation[1] -= bounds.top;
        }
    }

    private boolean getViewBoundsSandboxingEnabled() {
        // System dialogs (e.g. ANR) can be created within System process, so handleBindApplication
        // may be never called. This results into all app compat changes being enabled
        // (see b/268007823) because AppCompatCallbacks.install() is never called with non-empty
        // array.
        // With ActivityThread.isSystem we verify that it is not the system process,
        // then this CompatChange can take effect.
        if (ActivityThread.isSystem()
                || !CompatChanges.isChangeEnabled(OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS)) {
            // It is a system process or OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS change-id is disabled.
            return false;
        }

        // OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS is enabled by the device manufacturer.
        try {
            final List<PackageManager.Property> properties = mContext.getPackageManager()
                    .queryApplicationProperty(PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS);

            final boolean isOptedOut = !properties.isEmpty() && !properties.get(0).getBoolean();
            if (isOptedOut) {
                // PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS is disabled by the app devs.
                return false;
            }
        } catch (RuntimeException e) {
            // remote exception.
        }

        return true;
    }
    }


    /**
    /**
+36 −0
Original line number Original line Diff line number Diff line
@@ -870,6 +870,42 @@ public interface WindowManager extends ViewManager {
    String PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION =
    String PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION =
            "android.window.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION";
            "android.window.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION";


    /**
     * Application level {@link android.content.pm.PackageManager.Property PackageManager
     * .Property} for an app to inform the system that it needs to be opted-out from the
     * compatibility treatment that sandboxes {@link android.view.View} API.
     *
     * <p>The treatment can be enabled by device manufacturers for applications which misuse
     * {@link android.view.View} APIs by expecting that
     * {@link android.view.View#getLocationOnScreen},
     * {@link android.view.View#getBoundsOnScreen},
     * {@link android.view.View#getWindowVisibleDisplayFrame},
     * {@link android.view.View#getWindowDisplayFrame}
     * return coordinates as if an activity is positioned in the top-left corner of the screen, with
     * left coordinate equal to 0. This may not be the case for applications in multi-window and in
     * letterbox modes.
     *
     * <p>Setting this property to {@code false} informs the system that the application must be
     * opted-out from the "Sandbox {@link android.view.View} API to Activity bounds" treatment even
     * if the device manufacturer has opted the app into the treatment.
     *
     * <p>Not setting this property at all, or setting this property to {@code true} has no effect.
     *
     * <p><b>Syntax:</b>
     * <pre>
     * &lt;application&gt;
     *   &lt;property
     *     android:name="android.window.PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS"
     *     android:value="false"/&gt;
     * &lt;/application&gt;
     * </pre>
     *
     * @hide
     */
    // TODO(b/263984287): Make this public API.
    String PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS =
            "android.window.PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS";

    /**
    /**
     * Application level {@link android.content.pm.PackageManager.Property PackageManager
     * Application level {@link android.content.pm.PackageManager.Property PackageManager
     * .Property} for an app to inform the system that the application can be opted-in or opted-out
     * .Property} for an app to inform the system that the application can be opted-in or opted-out