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

Commit fbf09773 authored by Jeff Brown's avatar Jeff Brown
Browse files

Support non-rectangular input regions.

This enables the system bar to carve out a region through which
events will be sent to the IME behind it.

Bug: 3238092
Change-Id: I69b855a8d9b5b3ee525266c0861826e53e5b5028
parent 115ad165
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -95568,6 +95568,17 @@
 visibility="public"
>
</field>
<field name="TOUCHABLE_INSETS_REGION"
 type="int"
 transient="false"
 volatile="false"
 value="3"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="TOUCHABLE_INSETS_VISIBLE"
 type="int"
 transient="false"
@@ -95599,6 +95610,16 @@
 visibility="public"
>
</field>
<field name="touchableRegion"
 type="android.graphics.Region"
 transient="false"
 volatile="false"
 static="false"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="visibleTopInsets"
 type="int"
 transient="false"
+14 −2
Original line number Diff line number Diff line
@@ -283,6 +283,7 @@ public class CompatibilityInfo {
        
        private Rect mContentInsetsBuffer = null;
        private Rect mVisibleInsetsBuffer = null;
        private Region mTouchableAreaBuffer = null;
        
        Translator(float applicationScale, float applicationInvertedScale) {
            this.applicationScale = applicationScale;
@@ -395,14 +396,25 @@ public class CompatibilityInfo {

        /**
         * Translate the visible insets in application window to Screen. This uses
         * the internal buffer for content insets to avoid extra object allocation.
         * the internal buffer for visible insets to avoid extra object allocation.
         */
        public Rect getTranslatedVisbileInsets(Rect visibleInsets) {
        public Rect getTranslatedVisibleInsets(Rect visibleInsets) {
            if (mVisibleInsetsBuffer == null) mVisibleInsetsBuffer = new Rect();
            mVisibleInsetsBuffer.set(visibleInsets);
            translateRectInAppWindowToScreen(mVisibleInsetsBuffer);
            return mVisibleInsetsBuffer;
        }

        /**
         * Translate the touchable area in application window to Screen. This uses
         * the internal buffer for touchable area to avoid extra object allocation.
         */
        public Region getTranslatedTouchableArea(Region touchableArea) {
            if (mTouchableAreaBuffer == null) mTouchableAreaBuffer = new Region();
            mTouchableAreaBuffer.set(touchableArea);
            mTouchableAreaBuffer.scale(applicationScale);
            return mTouchableAreaBuffer;
        }
    }

    /**
+24 −4
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ResultReceiver;
@@ -283,11 +284,13 @@ public class InputMethodService extends AbstractInputMethodService {
                View decor = getWindow().getWindow().getDecorView();
                info.contentInsets.top = info.visibleInsets.top
                        = decor.getHeight();
                info.touchableRegion.setEmpty();
                info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
            } else {
                onComputeInsets(mTmpInsets);
                info.contentInsets.top = mTmpInsets.contentTopInsets;
                info.visibleInsets.top = mTmpInsets.visibleTopInsets;
                info.touchableRegion.set(mTmpInsets.touchableRegion);
                info.setTouchableInsets(mTmpInsets.touchableInsets);
            }
        }
@@ -511,6 +514,13 @@ public class InputMethodService extends AbstractInputMethodService {
         */
        public int visibleTopInsets;

        /**
         * This is the region of the UI that is touchable.  It is used when
         * {@link #touchableInsets} is set to {@link #TOUCHABLE_INSETS_REGION}.
         * The region should be specified relative to the origin of the window frame.
         */
        public final Region touchableRegion = new Region();

        /**
         * Option for {@link #touchableInsets}: the entire window frame
         * can be touched.
@@ -532,10 +542,18 @@ public class InputMethodService extends AbstractInputMethodService {
        public static final int TOUCHABLE_INSETS_VISIBLE
                = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE;

        /**
         * Option for {@link #touchableInsets}: the region specified by
         * {@link #touchableRegion} can be touched.
         */
        public static final int TOUCHABLE_INSETS_REGION
                = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;

        /**
         * Determine which area of the window is touchable by the user.  May
         * be one of: {@link #TOUCHABLE_INSETS_FRAME},
         * {@link #TOUCHABLE_INSETS_CONTENT}, or {@link #TOUCHABLE_INSETS_VISIBLE}. 
         * {@link #TOUCHABLE_INSETS_CONTENT}, {@link #TOUCHABLE_INSETS_VISIBLE},
         * or {@link #TOUCHABLE_INSETS_REGION}.
         */
        public int touchableInsets;
    }
@@ -950,6 +968,7 @@ public class InputMethodService extends AbstractInputMethodService {
        }
        outInsets.visibleTopInsets = loc[1];
        outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_VISIBLE;
        outInsets.touchableRegion.setEmpty();
    }
    
    /**
@@ -2153,6 +2172,7 @@ public class InputMethodService extends AbstractInputMethodService {
        p.println("Last computed insets:");
        p.println("  contentTopInsets=" + mTmpInsets.contentTopInsets
                + " visibleTopInsets=" + mTmpInsets.visibleTopInsets
                + " touchableInsets=" + mTmpInsets.touchableInsets);
                + " touchableInsets=" + mTmpInsets.touchableInsets
                + " touchableRegion=" + mTmpInsets.touchableRegion);
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -101,7 +101,7 @@ interface IWindowSession {
     * {@link android.view.ViewTreeObserver.InternalInsetsInfo}.
     */
    void setInsets(IWindow window, int touchableInsets, in Rect contentInsets,
            in Rect visibleInsets);
            in Rect visibleInsets, in Region touchableRegion);
    
    /**
     * Return the current display size in which the window is being laid out,
+23 −13
Original line number Diff line number Diff line
@@ -1229,24 +1229,34 @@ public final class ViewRoot extends Handler implements ViewParent,
        }

        if (computesInternalInsets) {
            ViewTreeObserver.InternalInsetsInfo insets = attachInfo.mGivenInternalInsets;
            final Rect givenContent = attachInfo.mGivenInternalInsets.contentInsets;
            final Rect givenVisible = attachInfo.mGivenInternalInsets.visibleInsets;
            givenContent.left = givenContent.top = givenContent.right
                    = givenContent.bottom = givenVisible.left = givenVisible.top
                    = givenVisible.right = givenVisible.bottom = 0;
            // Clear the original insets.
            final ViewTreeObserver.InternalInsetsInfo insets = attachInfo.mGivenInternalInsets;
            insets.reset();

            // Compute new insets in place.
            attachInfo.mTreeObserver.dispatchOnComputeInternalInsets(insets);
            Rect contentInsets = insets.contentInsets;
            Rect visibleInsets = insets.visibleInsets;
            if (mTranslator != null) {
                contentInsets = mTranslator.getTranslatedContentInsets(contentInsets);
                visibleInsets = mTranslator.getTranslatedVisbileInsets(visibleInsets);
            }

            // Tell the window manager.
            if (insetsPending || !mLastGivenInsets.equals(insets)) {
                mLastGivenInsets.set(insets);

                // Translate insets to screen coordinates if needed.
                final Rect contentInsets;
                final Rect visibleInsets;
                final Region touchableRegion;
                if (mTranslator != null) {
                    contentInsets = mTranslator.getTranslatedContentInsets(insets.contentInsets);
                    visibleInsets = mTranslator.getTranslatedVisibleInsets(insets.visibleInsets);
                    touchableRegion = mTranslator.getTranslatedTouchableArea(insets.touchableRegion);
                } else {
                    contentInsets = insets.contentInsets;
                    visibleInsets = insets.visibleInsets;
                    touchableRegion = insets.touchableRegion;
                }

                try {
                    sWindowSession.setInsets(mWindow, insets.mTouchableInsets,
                            contentInsets, visibleInsets);
                            contentInsets, visibleInsets, touchableRegion);
                } catch (RemoteException e) {
                }
            }
Loading