Loading core/java/android/app/ActivityManagerInternal.java +5 −4 Original line number Diff line number Diff line Loading @@ -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); Loading core/java/android/app/Instrumentation.java +50 −37 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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. */ Loading Loading @@ -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 Loading @@ -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; Loading @@ -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() Loading @@ -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 Loading @@ -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, Loading core/java/android/hardware/input/IInputManager.aidl +7 −2 Original line number Diff line number Diff line Loading @@ -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 Loading core/java/android/hardware/input/InputManager.java +40 −7 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading @@ -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"); } Loading @@ -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 Loading services/core/java/com/android/server/am/ActivityManagerService.java +3 −3 Original line number Diff line number Diff line Loading @@ -17185,17 +17185,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
core/java/android/app/ActivityManagerInternal.java +5 −4 Original line number Diff line number Diff line Loading @@ -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); Loading
core/java/android/app/Instrumentation.java +50 −37 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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. */ Loading Loading @@ -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 Loading @@ -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; Loading @@ -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() Loading @@ -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 Loading @@ -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, Loading
core/java/android/hardware/input/IInputManager.aidl +7 −2 Original line number Diff line number Diff line Loading @@ -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 Loading
core/java/android/hardware/input/InputManager.java +40 −7 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading @@ -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"); } Loading @@ -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 Loading
services/core/java/com/android/server/am/ActivityManagerService.java +3 −3 Original line number Diff line number Diff line Loading @@ -17185,17 +17185,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