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

Commit 85a31767 authored by Jeff Brown's avatar Jeff Brown
Browse files

Add support for secure views.

Added the MotionEvent.FLAG_WINDOW_IS_OBSCURED flag which is set by the
input manager whenever another visible window is partly or wholly obscured
the target of a touch event so that applications can filter touches
accordingly.

Added a "filterTouchesWhenObscured" attribute to View which can be used to
enable filtering of touches when the view's window is obscured.

Change-Id: I936d9c85013fd2d77fb296a600528d30a29027d2
parent c0b4f6d3
Loading
Loading
Loading
Loading
+94 −11
Original line number Diff line number Diff line
@@ -5861,17 +5861,6 @@
 visibility="public"
>
</field>
<field name="kraken_resource_pad61"
 type="int"
 transient="false"
 volatile="false"
 value="16843460"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="kraken_resource_pad7"
 type="int"
 transient="false"
@@ -8248,6 +8237,17 @@
 visibility="public"
>
</field>
<field name="securityMode"
 type="int"
 transient="false"
 volatile="false"
 value="16843460"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="seekBarStyle"
 type="int"
 transient="false"
@@ -181685,6 +181685,17 @@
 visibility="public"
>
</method>
<method name="getFlags"
 return="int"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="getHistoricalEventTime"
 return="long"
 abstract="false"
@@ -182322,6 +182333,8 @@
</parameter>
<parameter name="source" type="int">
</parameter>
<parameter name="flags" type="int">
</parameter>
</method>
<method name="obtain"
 return="android.view.MotionEvent"
@@ -182778,6 +182791,17 @@
 visibility="public"
>
</field>
<field name="FLAG_WINDOW_MAY_BE_OBSCURED"
 type="int"
 transient="false"
 volatile="false"
 value="1"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
</class>
<class name="MotionEvent.PointerCoords"
 extends="java.lang.Object"
@@ -185958,6 +185982,17 @@
 visibility="public"
>
</method>
<method name="getSecurityMode"
 return="int"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="getSolidColor"
 return="int"
 abstract="false"
@@ -186788,6 +186823,19 @@
<parameter name="canvas" type="android.graphics.Canvas">
</parameter>
</method>
<method name="onFilterTouchEventForSecurity"
 return="boolean"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="event" type="android.view.MotionEvent">
</parameter>
</method>
<method name="onFinishInflate"
 return="void"
 abstract="false"
@@ -188079,6 +188127,19 @@
<parameter name="fadeScrollbars" type="boolean">
</parameter>
</method>
<method name="setSecurityMode"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="securityMode" type="int">
</parameter>
</method>
<method name="setSelected"
 return="void"
 abstract="false"
@@ -188859,6 +188920,28 @@
 visibility="public"
>
</field>
<field name="SECURITY_MODE_FILTER_TOUCHES_WHEN_OBSCURED"
 type="int"
 transient="false"
 volatile="false"
 value="1"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="SECURITY_MODE_NORMAL"
 type="int"
 transient="false"
 volatile="false"
 value="0"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="SELECTED_STATE_SET"
 type="int[]"
 transient="false"
+34 −6
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.os.SystemClock;
 */
public final class MotionEvent extends InputEvent implements Parcelable {
    private static final long MS_PER_NS = 1000000;
    private static final boolean TRACK_RECYCLED_LOCATION = false;
    
    /**
     * Bit mask of the parts of the action code that are the action itself.
@@ -155,7 +156,17 @@ public final class MotionEvent extends InputEvent implements Parcelable {
    @Deprecated
    public static final int ACTION_POINTER_ID_SHIFT = 8;
    
    private static final boolean TRACK_RECYCLED_LOCATION = false;
    /**
     * This flag indicates that the window that received this motion event is partly
     * or wholly obscured by another visible window above it.  This flag is set to true
     * even if the event did not directly pass through the obscured area.
     * A security sensitive application can check this flag to identify situations in which
     * a malicious application may have covered up part of its content for the purpose
     * of misleading the user or hijacking touches.  An appropriate response might be
     * to drop the suspect touches or to take additional precautions to confirm the user's
     * actual intent.
     */
    public static final int FLAG_WINDOW_IS_OBSCURED = 0x1;

    /**
     * Flag indicating the motion event intersected the top edge of the screen.
@@ -251,6 +262,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
    private float mYPrecision;
    private int mEdgeFlags;
    private int mMetaState;
    private int mFlags;
    
    private int mNumPointers;
    private int mNumSamples;
@@ -338,20 +350,22 @@ public final class MotionEvent extends InputEvent implements Parcelable {
     * @param deviceId The id for the device that this event came from.  An id of
     * zero indicates that the event didn't come from a physical device; other
     * numbers are arbitrary and you shouldn't depend on the values.
     * @param edgeFlags A bitfield indicating which edges, if any, where touched by this
     * @param edgeFlags A bitfield indicating which edges, if any, were touched by this
     * MotionEvent.
     * @param source The source of this event.
     * @param flags The motion event flags.
     */
    static public MotionEvent obtain(long downTime, long eventTime,
            int action, int pointers, int[] pointerIds, PointerCoords[] pointerCoords,
            int metaState, float xPrecision, float yPrecision, int deviceId,
            int edgeFlags, int source) {
            int edgeFlags, int source, int flags) {
        MotionEvent ev = obtain(pointers, 1);
        ev.mDeviceId = deviceId;
        ev.mSource = source;
        ev.mEdgeFlags = edgeFlags;
        ev.mDownTimeNano = downTime * MS_PER_NS;
        ev.mAction = action;
        ev.mFlags = flags;
        ev.mMetaState = metaState;
        ev.mXOffset = 0;
        ev.mYOffset = 0;
@@ -401,7 +415,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
     * @param deviceId The id for the device that this event came from.  An id of
     * zero indicates that the event didn't come from a physical device; other
     * numbers are arbitrary and you shouldn't depend on the values.
     * @param edgeFlags A bitfield indicating which edges, if any, where touched by this
     * @param edgeFlags A bitfield indicating which edges, if any, were touched by this
     * MotionEvent.
     */
    static public MotionEvent obtain(long downTime, long eventTime, int action,
@@ -413,6 +427,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
        ev.mEdgeFlags = edgeFlags;
        ev.mDownTimeNano = downTime * MS_PER_NS;
        ev.mAction = action;
        ev.mFlags = 0;
        ev.mMetaState = metaState;
        ev.mXOffset = 0;
        ev.mYOffset = 0;
@@ -462,7 +477,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
     * @param deviceId The id for the device that this event came from.  An id of
     * zero indicates that the event didn't come from a physical device; other
     * numbers are arbitrary and you shouldn't depend on the values.
     * @param edgeFlags A bitfield indicating which edges, if any, where touched by this
     * @param edgeFlags A bitfield indicating which edges, if any, were touched by this
     * MotionEvent.
     * 
     * @deprecated Use {@link #obtain(long, long, int, float, float, float, float, int, float, float, int, int)}
@@ -509,6 +524,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
        ev.mEdgeFlags = o.mEdgeFlags;
        ev.mDownTimeNano = o.mDownTimeNano;
        ev.mAction = o.mAction;
        ev.mFlags = o.mFlags;
        ev.mMetaState = o.mMetaState;
        ev.mXOffset = o.mXOffset;
        ev.mYOffset = o.mYOffset;
@@ -540,6 +556,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
        ev.mEdgeFlags = o.mEdgeFlags;
        ev.mDownTimeNano = o.mDownTimeNano;
        ev.mAction = o.mAction;
        o.mFlags = o.mFlags;
        ev.mMetaState = o.mMetaState;
        ev.mXOffset = o.mXOffset;
        ev.mYOffset = o.mYOffset;
@@ -650,6 +667,15 @@ public final class MotionEvent extends InputEvent implements Parcelable {
        return (mAction & ACTION_POINTER_INDEX_MASK) >> ACTION_POINTER_INDEX_SHIFT;
    }

    /**
     * Gets the motion event flags.
     *
     * @see #FLAG_WINDOW_IS_OBSCURED
     */
    public final int getFlags() {
        return mFlags;
    }

    /**
     * Returns the time (in ms) when the user originally pressed down to start
     * a stream of position events.
@@ -1285,7 +1311,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {


    /**
     * Sets the bitfield indicating which edges, if any, where touched by this
     * Sets the bitfield indicating which edges, if any, were touched by this
     * MotionEvent.
     *
     * @see #getEdgeFlags()
@@ -1480,6 +1506,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
        ev.mYPrecision = in.readFloat();
        ev.mEdgeFlags = in.readInt();
        ev.mMetaState = in.readInt();
        ev.mFlags = in.readInt();
        
        final int[] pointerIdentifiers = ev.mPointerIdentifiers;
        for (int i = 0; i < NP; i++) {
@@ -1521,6 +1548,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
        out.writeFloat(mYPrecision);
        out.writeInt(mEdgeFlags);
        out.writeInt(mMetaState);
        out.writeInt(mFlags);
        
        final int[] pointerIdentifiers = mPointerIdentifiers;
        for (int i = 0; i < NP; i++) {
+87 −1
Original line number Diff line number Diff line
@@ -542,6 +542,28 @@ import java.util.WeakHashMap;
 * take care of redrawing the appropriate views until the animation completes.
 * </p>
 *
 * <a name="Security"></a>
 * <h3>Security</h3>
 * <p>
 * Sometimes it is essential that an application be able to verify that an action
 * is being performed with the full knowledge and consent of the user, such as
 * granting a permission request, making a purchase or clicking on an advertisement.
 * Unfortunately, a malicious application could try to spoof the user into
 * performing these actions, unaware, by concealing the intended purpose of the view.
 * As a remedy, the framework offers a touch filtering mechanism that can be used to
 * improve the security of views that provide access to sensitive functionality.
 * </p><p>
 * To enable touch filtering, call {@link #setFilterTouchesWhenObscured} or set the
 * andoird:filterTouchesWhenObscured attribute to true.  When enabled, the framework
 * will discard touches that are received whenever the view's window is obscured by
 * another visible window.  As a result, the view will not receive touches whenever a
 * toast, dialog or other window appears above the view's window.
 * </p><p>
 * For more fine-grained control over security, consider overriding the
 * {@link #onFilterTouchEventForSecurity} method to implement your own security policy.
 * See also {@link MotionEvent#FLAG_WINDOW_IS_OBSCURED}.
 * </p>
 *
 * @attr ref android.R.styleable#View_background
 * @attr ref android.R.styleable#View_clickable
 * @attr ref android.R.styleable#View_contentDescription
@@ -550,6 +572,7 @@ import java.util.WeakHashMap;
 * @attr ref android.R.styleable#View_id
 * @attr ref android.R.styleable#View_fadingEdge
 * @attr ref android.R.styleable#View_fadingEdgeLength
 * @attr ref android.R.styleable#View_filterTouchesWhenObscured
 * @attr ref android.R.styleable#View_fitsSystemWindows
 * @attr ref android.R.styleable#View_isScrollContainer
 * @attr ref android.R.styleable#View_focusable
@@ -711,7 +734,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
     */
    static final int SCROLLBARS_MASK = 0x00000300;

    // note 0x00000400 and 0x00000800 are now available for next flags...
    /**
     * Indicates that the view should filter touches when its window is obscured.
     * Refer to the class comments for more information about this security feature.
     * {@hide}
     */
    static final int FILTER_TOUCHES_WHEN_OBSCURED = 0x00000400;

    // note flag value 0x00000800 is now available for next flags...

    /**
     * <p>This view doesn't show fading edges.</p>
@@ -2052,6 +2082,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
                        viewFlagMasks |= KEEP_SCREEN_ON;
                    }
                    break;
                case R.styleable.View_filterTouchesWhenObscured:
                    if (a.getBoolean(attr, false)) {
                        viewFlagValues |= FILTER_TOUCHES_WHEN_OBSCURED;
                        viewFlagMasks |= FILTER_TOUCHES_WHEN_OBSCURED;
                    }
                    break;
                case R.styleable.View_nextFocusLeft:
                    mNextFocusLeftId = a.getResourceId(attr, View.NO_ID);
                    break;
@@ -3389,6 +3425,35 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
        setFlags(enabled ? 0 : SAVE_DISABLED, SAVE_DISABLED_MASK);
    }

    /**
     * Gets whether the framework should discard touches when the view's
     * window is obscured by another visible window.
     * Refer to the {@link View} security documentation for more details.
     *
     * @return True if touch filtering is enabled.
     *
     * @see #setFilterTouchesWhenObscured(boolean)
     * @attr ref android.R.styleable#View_filterTouchesWhenObscured
     */
    @ViewDebug.ExportedProperty
    public boolean getFilterTouchesWhenObscured() {
        return (mViewFlags & FILTER_TOUCHES_WHEN_OBSCURED) != 0;
    }

    /**
     * Sets whether the framework should discard touches when the view's
     * window is obscured by another visible window.
     * Refer to the {@link View} security documentation for more details.
     *
     * @param enabled True if touch filtering should be enabled.
     *
     * @see #getFilterTouchesWhenObscured
     * @attr ref android.R.styleable#View_filterTouchesWhenObscured
     */
    public void setFilterTouchesWhenObscured(boolean enabled) {
        setFlags(enabled ? 0 : FILTER_TOUCHES_WHEN_OBSCURED,
                FILTER_TOUCHES_WHEN_OBSCURED);
    }

    /**
     * Returns whether this View is able to take focus.
@@ -3808,6 +3873,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
     * @return True if the event was handled by the view, false otherwise.
     */
    public boolean dispatchTouchEvent(MotionEvent event) {
        if (!onFilterTouchEventForSecurity(event)) {
            return false;
        }

        if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&
                mOnTouchListener.onTouch(this, event)) {
            return true;
@@ -3815,6 +3884,23 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
        return onTouchEvent(event);
    }

    /**
     * Filter the touch event to apply security policies.
     *
     * @param event The motion event to be filtered.
     * @return True if the event should be dispatched, false if the event should be dropped.
     * 
     * @see #getFilterTouchesWhenObscured
     */
    public boolean onFilterTouchEventForSecurity(MotionEvent event) {
        if ((mViewFlags & FILTER_TOUCHES_WHEN_OBSCURED) != 0
                && (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0) {
            // Window is obscured, drop this touch.
            return false;
        }
        return true;
    }

    /**
     * Pass a trackball motion event down to the focused view.
     *
+4 −0
Original line number Diff line number Diff line
@@ -822,6 +822,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (!onFilterTouchEventForSecurity(ev)) {
            return false;
        }

        final int action = ev.getAction();
        final float xf = ev.getX();
        final float yf = ev.getY();
+2 −0
Original line number Diff line number Diff line
@@ -74,6 +74,8 @@ public interface WindowManagerPolicy {
    public final static int FLAG_MENU = 0x00000040;
    public final static int FLAG_LAUNCHER = 0x00000080;

    public final static int FLAG_INJECTED = 0x01000000;

    public final static int FLAG_WOKE_HERE = 0x10000000;
    public final static int FLAG_BRIGHT_HERE = 0x20000000;

Loading