分类: Android平台
2013-05-27 15:24:10
Android 2.3
frameworks/base/core/java/android/app/Instrumentation.java:
public void sendPointerSync(MotionEvent event){
IWindowManager.Stub.asInterface(ServiceManager.getService("window"))).injectPointerEvent(event, true)
frameworks/base/services/java/com/android/server/WindowManagerService.java:
final InputManager mInputManager;
public boolean injectPointerEvent(MotionEvent ev, boolean sync)
final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
: InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
INJECTION_TIMEOUT_MILLIS);
frameworks/base/services/java/com/android/server/InputManager.java:
public int injectInputEvent(InputEvent event, int injectorPid, int injectorUid, int syncMode, int timeoutMillis) {
if (event == null) {
throw new IllegalArgumentException("event must not be null");
}
if (injectorPid < 0 || injectorUid < 0) {
throw new IllegalArgumentException("injectorPid and injectorUid must not be negative.");
}
if (timeoutMillis <= 0) {
throw new IllegalArgumentException("timeoutMillis must be positive");
}
return nativeInjectInputEvent(event, injectorPid, injectorUid, syncMode, timeoutMillis);
}
frameworks/base/services/jni/com_android_server_InputManager.cpp:static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
frameworks/base/services/jni/com_android_server_InputManager.cpp: { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIII)I",
return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(& motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
mInputManager = new InputManager(eventHub, this, this);
Android 4.0:
\frameworks\base\core\java\android\app\Instrumentation.java
public void sendPointerSync(MotionEvent event) {
validateNotAppThread();
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
}
InputManager.getInstance().injectInputEvent(event,
InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
\frameworks\base\core\java\android\hardware\input\InputManager.java
private final IInputManager mIm;
public boolean injectInputEvent(InputEvent event, int mode) {
if (event == null) {
throw new IllegalArgumentException("event must not be null");
}
if (mode != INJECT_INPUT_EVENT_MODE_ASYNC
&& mode != INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH
&& mode != INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT) {
throw new IllegalArgumentException("mode is invalid");
}
try {
return mIm.injectInputEvent(event, mode);
} catch (RemoteException ex) {
return false;
}
}
\frameworks\base\services\java\com\android\server\input\InputManagerService.java
public boolean injectInputEvent(InputEvent event, int mode) {
if (event == null) {
throw new IllegalArgumentException("event must not be null");
}
if (mode != InputManager.INJECT_INPUT_EVENT_MODE_ASYNC
&& mode != InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH
&& mode != InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT) {
throw new IllegalArgumentException("mode is invalid");
}
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
final int result;
try {
result = nativeInjectInputEvent(mPtr, event, pid, uid, mode,
INJECTION_TIMEOUT_MILLIS, WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT);
} finally {
Binder.restoreCallingIdentity(ident);
}
switch (result) {
case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
Slog.w(TAG, "Input event injection from pid " + pid + " permission denied.");
throw new SecurityException(
"Injecting to another application requires INJECT_EVENTS permission");
case INPUT_EVENT_INJECTION_SUCCEEDED:
return true;
case INPUT_EVENT_INJECTION_TIMED_OUT:
Slog.w(TAG, "Input event injection from pid " + pid + " timed out.");
return false;
case INPUT_EVENT_INJECTION_FAILED:
default:
Slog.w(TAG, "Input event injection from pid " + pid + " failed.");
return false;
}
}
Note:Inject event to Android system need system permission.