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

Commit 71931a53 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Reland: Change input injection security model" into tm-dev am: d0f6ad2f

parents d756f11f d0f6ad2f
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -568,14 +568,15 @@ public abstract class ActivityManagerInternal {
    public abstract void unregisterProcessObserver(IProcessObserver processObserver);

    /**
     * Checks if there is an unfinished instrumentation that targets the given uid.
     * Gets the uid of the instrumentation source if there is an unfinished instrumentation that
     * targets the given uid.
     *
     * @param uid The uid to be checked for
     *
     * @return True, if there is an instrumentation whose target application uid matches the given
     * uid, false otherwise
     * @return the uid of the instrumentation source, if there is an instrumentation whose target
     * application uid matches the given uid, and {@link android.os.Process#INVALID_UID} otherwise.
     */
    public abstract boolean isUidCurrentlyInstrumented(int uid);
    public abstract int getInstrumentationSourceUid(int uid);

    /** Is this a device owner app? */
    public abstract boolean isDeviceOwner(int uid);
+50 −37
Original line number Diff line number Diff line
@@ -1058,10 +1058,11 @@ public class Instrumentation {
    }
    
    /**
     * Sends the key events corresponding to the text to the app being
     * instrumented.
     * Sends the key events that result in the given text being typed into the currently focused
     * window, and waits for it to be processed.
     *
     * @param text The text to be sent.
     * @see #sendKeySync(KeyEvent)
     */
    public void sendStringSync(String text) {
        if (text == null) {
@@ -1084,11 +1085,12 @@ public class Instrumentation {
    }

    /**
     * Send a key event to the currently focused window/view and wait for it to
     * be processed.  Finished at some point after the recipient has returned
     * from its event processing, though it may <em>not</em> have completely
     * finished reacting from the event -- for example, if it needs to update
     * its display as a result, it may still be in the process of doing that.
     * Sends a key event to the currently focused window, and waits for it to be processed.
     * <p>
     * This method blocks until the recipient has finished handling the event. Note that the
     * recipient may <em>not</em> have completely finished reacting from the event when this method
     * returns. For example, it may still be in the process of updating its display or UI contents
     * upon reacting to the injected event.
     *
     * @param event The event to send to the current focus.
     */
@@ -1116,34 +1118,42 @@ public class Instrumentation {
    }

    /**
     * Sends an up and down key event sync to the currently focused window.
     * Sends up and down key events with the given key code to the currently focused window, and
     * waits for it to be processed.
     * 
     * @param key The integer keycode for the event.
     * @param keyCode The key code for the events to send.
     * @see #sendKeySync(KeyEvent)
     */
    public void sendKeyDownUpSync(int key) {        
        sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, key));
        sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, key));
    public void sendKeyDownUpSync(int keyCode) {
        sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
        sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, keyCode));
    }

    /**
     * Higher-level method for sending both the down and up key events for a
     * particular character key code.  Equivalent to creating both KeyEvent
     * objects by hand and calling {@link #sendKeySync}.  The event appears
     * as if it came from keyboard 0, the built in one.
     * Sends up and down key events with the given key code to the currently focused window, and
     * waits for it to be processed.
     * <p>
     * Equivalent to {@link #sendKeyDownUpSync(int)}.
     *
     * @param keyCode The key code of the character to send.
     * @see #sendKeySync(KeyEvent)
     */
    public void sendCharacterSync(int keyCode) {
        sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
        sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, keyCode));
        sendKeyDownUpSync(keyCode);
    }

    /**
     * Dispatch a pointer event. Finished at some point after the recipient has
     * returned from its event processing, though it may <em>not</em> have
     * completely finished reacting from the event -- for example, if it needs
     * to update its display as a result, it may still be in the process of
     * doing that.
     * Dispatches a pointer event into a window owned by the instrumented application, and waits for
     * it to be processed.
     * <p>
     * If the motion event being injected is targeted at a window that is not owned by the
     * instrumented application, the input injection will fail. See {@link #getUiAutomation()} for
     * injecting events into all windows.
     * <p>
     * This method blocks until the recipient has finished handling the event. Note that the
     * recipient may <em>not</em> have completely finished reacting from the event when this method
     * returns. For example, it may still be in the process of updating its display or UI contents
     * upon reacting to the injected event.
     * 
     * @param event A motion event describing the pointer action.  (As noted in 
     * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use 
@@ -1155,10 +1165,10 @@ public class Instrumentation {
            event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
        }

        syncInputTransactionsAndInjectEvent(event);
        syncInputTransactionsAndInjectEventIntoSelf(event);
    }

    private void syncInputTransactionsAndInjectEvent(MotionEvent event) {
    private void syncInputTransactionsAndInjectEventIntoSelf(MotionEvent event) {
        final boolean syncBefore = event.getAction() == MotionEvent.ACTION_DOWN
                || event.isFromSource(InputDevice.SOURCE_MOUSE);
        final boolean syncAfter = event.getAction() == MotionEvent.ACTION_UP;
@@ -1169,8 +1179,9 @@ public class Instrumentation {
                        .syncInputTransactions(true /*waitForAnimations*/);
            }

            // Direct the injected event into windows owned by the instrumentation target.
            InputManager.getInstance().injectInputEvent(
                    event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
                    event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH, Process.myUid());

            if (syncAfter) {
                WindowManagerGlobal.getWindowManagerService()
@@ -1182,11 +1193,13 @@ public class Instrumentation {
    }

    /**
     * Dispatch a trackball event. Finished at some point after the recipient has
     * returned from its event processing, though it may <em>not</em> have
     * completely finished reacting from the event -- for example, if it needs
     * to update its display as a result, it may still be in the process of
     * doing that.
     * Dispatches a trackball event into the currently focused window, and waits for it to be
     * processed.
     * <p>
     * This method blocks until the recipient has finished handling the event. Note that the
     * recipient may <em>not</em> have completely finished reacting from the event when this method
     * returns. For example, it may still be in the process of updating its display or UI contents
     * upon reacting to the injected event.
     *
     * @param event A motion event describing the trackball action.  (As noted in 
     * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use 
@@ -1194,7 +1207,7 @@ public class Instrumentation {
     */
    public void sendTrackballEventSync(MotionEvent event) {
        validateNotAppThread();
        if ((event.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
        if (!event.isFromSource(InputDevice.SOURCE_CLASS_TRACKBALL)) {
            event.setSource(InputDevice.SOURCE_TRACKBALL);
        }
        InputManager.getInstance().injectInputEvent(event,
+7 −2
Original line number Diff line number Diff line
@@ -57,11 +57,16 @@ interface IInputManager {
    // Temporarily changes the pointer speed.
    void tryPointerSpeed(int speed);

    // Injects an input event into the system.  To inject into windows owned by other
    // applications, the caller must have the INJECT_EVENTS permission.
    // Injects an input event into the system. The caller must have the INJECT_EVENTS permssion.
    // This method exists only for compatibility purposes and may be removed in a future release.
    @UnsupportedAppUsage
    boolean injectInputEvent(in InputEvent ev, int mode);

    // Injects an input event into the system. The caller must have the INJECT_EVENTS permission.
    // The caller can target windows owned by a certain UID by providing a valid UID, or by
    // providing {@link android.os.Process#INVALID_UID} to target all windows.
    boolean injectInputEventToTarget(in InputEvent ev, int mode, int targetUid);

    VerifiedInputEvent verifyInputEvent(in InputEvent ev);

    // Calibrate input device position
+40 −7
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import android.os.IVibratorStateListener;
import android.os.InputEventInjectionSync;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
@@ -1107,14 +1108,18 @@ public final class InputManager {
        }
    }


    /**
     * Injects an input event into the event system on behalf of an application.
     * Injects an input event into the event system, targeting windows owned by the provided uid.
     *
     * If a valid targetUid is provided, the system will only consider injecting the input event
     * into windows owned by the provided uid. If the input event is targeted at a window that is
     * not owned by the provided uid, input injection will fail and a RemoteException will be
     * thrown.
     *
     * The synchronization mode determines whether the method blocks while waiting for
     * input injection to proceed.
     * <p>
     * Requires {@link android.Manifest.permission.INJECT_EVENTS} to inject into
     * windows that are owned by other applications.
     * Requires the {@link android.Manifest.permission.INJECT_EVENTS} permission.
     * </p><p>
     * Make sure you correctly set the event time and input source of the event
     * before calling this method.
@@ -1125,12 +1130,14 @@ public final class InputManager {
     * {@link android.os.InputEventInjectionSync.NONE},
     * {@link android.os.InputEventInjectionSync.WAIT_FOR_RESULT}, or
     * {@link android.os.InputEventInjectionSync.WAIT_FOR_FINISHED}.
     * @param targetUid The uid to target, or {@link android.os.Process#INVALID_UID} to target all
     *                 windows.
     * @return True if input event injection succeeded.
     *
     * @hide
     */
    @UnsupportedAppUsage
    public boolean injectInputEvent(InputEvent event, int mode) {
    @RequiresPermission(Manifest.permission.INJECT_EVENTS)
    public boolean injectInputEvent(InputEvent event, int mode, int targetUid) {
        if (event == null) {
            throw new IllegalArgumentException("event must not be null");
        }
@@ -1141,12 +1148,38 @@ public final class InputManager {
        }

        try {
            return mIm.injectInputEvent(event, mode);
            return mIm.injectInputEventToTarget(event, mode, targetUid);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }

    /**
     * Injects an input event into the event system on behalf of an application.
     * The synchronization mode determines whether the method blocks while waiting for
     * input injection to proceed.
     * <p>
     * Requires the {@link android.Manifest.permission.INJECT_EVENTS} permission.
     * </p><p>
     * Make sure you correctly set the event time and input source of the event
     * before calling this method.
     * </p>
     *
     * @param event The event to inject.
     * @param mode The synchronization mode.  One of:
     * {@link android.os.InputEventInjectionSync.NONE},
     * {@link android.os.InputEventInjectionSync.WAIT_FOR_RESULT}, or
     * {@link android.os.InputEventInjectionSync.WAIT_FOR_FINISHED}.
     * @return True if input event injection succeeded.
     *
     * @hide
     */
    @RequiresPermission(Manifest.permission.INJECT_EVENTS)
    @UnsupportedAppUsage
    public boolean injectInputEvent(InputEvent event, int mode) {
        return injectInputEvent(event, mode, Process.INVALID_UID);
    }

    /**
     * Verify the details of an {@link android.view.InputEvent} that came from the system.
     * If the event did not come from the system, or its details could not be verified, then this
+3 −3
Original line number Diff line number Diff line
@@ -17195,17 +17195,17 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
        @Override
        public boolean isUidCurrentlyInstrumented(int uid) {
        public int getInstrumentationSourceUid(int uid) {
            synchronized (mProcLock) {
                for (int i = mActiveInstrumentation.size() - 1; i >= 0; i--) {
                    ActiveInstrumentation activeInst = mActiveInstrumentation.get(i);
                    if (!activeInst.mFinished && activeInst.mTargetInfo != null
                            && activeInst.mTargetInfo.uid == uid) {
                        return true;
                        return activeInst.mSourceUid;
                    }
                }
            }
            return false;
            return INVALID_UID;
        }
        @Override
Loading