summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ActivityView.java26
-rw-r--r--core/java/android/app/IActivityContainer.aidl2
-rw-r--r--core/java/android/hardware/input/InputManagerInternal.java3
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java29
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java16
-rw-r--r--services/core/jni/com_android_server_input_InputManagerService.cpp8
6 files changed, 74 insertions, 10 deletions
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 8acd19b..48ec420 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -27,6 +27,9 @@ import android.os.RemoteException;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
+import android.view.InputDevice;
+import android.view.InputEvent;
+import android.view.MotionEvent;
import android.view.Surface;
import android.view.TextureView;
import android.view.TextureView.SurfaceTextureListener;
@@ -112,6 +115,29 @@ public class ActivityView extends ViewGroup {
}
}
+ private boolean injectInputEvent(InputEvent event) {
+ try {
+ return mActivityContainer != null && mActivityContainer.injectEvent(event);
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ return injectInputEvent(event) || super.onTouchEvent(event);
+ }
+
+ @Override
+ public boolean onGenericMotionEvent(MotionEvent event) {
+ if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
+ if (injectInputEvent(event)) {
+ return true;
+ }
+ }
+ return super.onGenericMotionEvent(event);
+ }
+
public boolean isAttachedToDisplay() {
return mSurface != null;
}
diff --git a/core/java/android/app/IActivityContainer.aidl b/core/java/android/app/IActivityContainer.aidl
index abd296a..5b80e06 100644
--- a/core/java/android/app/IActivityContainer.aidl
+++ b/core/java/android/app/IActivityContainer.aidl
@@ -20,6 +20,7 @@ import android.app.IActivityContainerCallback;
import android.content.Intent;
import android.content.IIntentSender;
import android.os.IBinder;
+import android.view.InputEvent;
import android.view.Surface;
/** @hide */
@@ -30,4 +31,5 @@ interface IActivityContainer {
int startActivity(in Intent intent);
int startActivityIntentSender(in IIntentSender intentSender);
int getDisplayId();
+ boolean injectEvent(in InputEvent event);
}
diff --git a/core/java/android/hardware/input/InputManagerInternal.java b/core/java/android/hardware/input/InputManagerInternal.java
index ecd32ea..8be94d0 100644
--- a/core/java/android/hardware/input/InputManagerInternal.java
+++ b/core/java/android/hardware/input/InputManagerInternal.java
@@ -17,6 +17,7 @@
package android.hardware.input;
import android.hardware.display.DisplayViewport;
+import android.view.InputEvent;
/**
* Input manager local system service interface.
@@ -30,4 +31,6 @@ public abstract class InputManagerInternal {
*/
public abstract void setDisplayViewports(DisplayViewport defaultViewport,
DisplayViewport externalTouchViewport);
+
+ public abstract boolean injectInputEvent(InputEvent event, int displayId, int mode);
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 8f8b2a2..6ed30d9 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -61,6 +61,8 @@ import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.hardware.display.DisplayManagerGlobal;
import android.hardware.display.VirtualDisplay;
+import android.hardware.input.InputManager;
+import android.hardware.input.InputManagerInternal;
import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
@@ -81,9 +83,11 @@ import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.Display;
import android.view.DisplayInfo;
+import android.view.InputEvent;
import android.view.Surface;
import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.os.TransferPipe;
+import com.android.server.LocalServices;
import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
import com.android.server.am.ActivityStack.ActivityState;
import com.android.server.wm.WindowManagerService;
@@ -225,6 +229,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
/** Mapping from displayId to display current state */
private SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<ActivityDisplay>();
+ InputManagerInternal mInputManagerInternal;
+
public ActivityStackSupervisor(ActivityManagerService service) {
mService = service;
PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
@@ -255,6 +261,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
createStackOnDisplay(null, HOME_STACK_ID, Display.DEFAULT_DISPLAY);
mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);
+
+ mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
}
}
@@ -2941,7 +2949,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
@Override
- public void attachToDisplay(int displayId) throws RemoteException {
+ public void attachToDisplay(int displayId) {
synchronized (mService) {
ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
if (activityDisplay == null) {
@@ -2952,13 +2960,28 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
@Override
- public int getDisplayId() throws RemoteException {
+ public int getDisplayId() {
if (mActivityDisplay != null) {
return mActivityDisplay.mDisplayId;
}
return -1;
}
+ @Override
+ public boolean injectEvent(InputEvent event) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ if (mActivityDisplay != null) {
+ return mInputManagerInternal.injectInputEvent(event,
+ mActivityDisplay.mDisplayId,
+ InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
+ }
+ return false;
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
private void detachLocked() {
if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
+ mActivityDisplay + " Callers=" + Debug.getCallers(2));
@@ -2972,7 +2995,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
@Override
- public void detachFromDisplay() throws RemoteException {
+ public void detachFromDisplay() {
synchronized (mService) {
detachLocked();
}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 1522fd1..3aa3851 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -16,6 +16,7 @@
package com.android.server.input;
+import android.view.Display;
import com.android.internal.R;
import com.android.internal.util.XmlUtils;
import com.android.server.DisplayThread;
@@ -170,7 +171,7 @@ public class InputManagerService extends IInputManager.Stub
InputWindowHandle inputWindowHandle, boolean monitor);
private static native void nativeUnregisterInputChannel(long ptr, InputChannel inputChannel);
private static native void nativeSetInputFilterEnabled(long ptr, boolean enable);
- private static native int nativeInjectInputEvent(long ptr, InputEvent event,
+ private static native int nativeInjectInputEvent(long ptr, InputEvent event, int displayId,
int injectorPid, int injectorUid, int syncMode, int timeoutMillis,
int policyFlags);
private static native void nativeSetInputWindows(long ptr, InputWindowHandle[] windowHandles);
@@ -509,6 +510,10 @@ public class InputManagerService extends IInputManager.Stub
@Override // Binder call
public boolean injectInputEvent(InputEvent event, int mode) {
+ return injectInputEventInternal(event, Display.DEFAULT_DISPLAY, mode);
+ }
+
+ private boolean injectInputEventInternal(InputEvent event, int displayId, int mode) {
if (event == null) {
throw new IllegalArgumentException("event must not be null");
}
@@ -523,7 +528,7 @@ public class InputManagerService extends IInputManager.Stub
final long ident = Binder.clearCallingIdentity();
final int result;
try {
- result = nativeInjectInputEvent(mPtr, event, pid, uid, mode,
+ result = nativeInjectInputEvent(mPtr, event, displayId, pid, uid, mode,
INJECTION_TIMEOUT_MILLIS, WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT);
} finally {
Binder.restoreCallingIdentity(ident);
@@ -1588,7 +1593,7 @@ public class InputManagerService extends IInputManager.Stub
synchronized (mInputFilterLock) {
if (!mDisconnected) {
- nativeInjectInputEvent(mPtr, event, 0, 0,
+ nativeInjectInputEvent(mPtr, event, Display.DEFAULT_DISPLAY, 0, 0,
InputManager.INJECT_INPUT_EVENT_MODE_ASYNC, 0,
policyFlags | WindowManagerPolicy.FLAG_FILTERED);
}
@@ -1685,5 +1690,10 @@ public class InputManagerService extends IInputManager.Stub
DisplayViewport defaultViewport, DisplayViewport externalTouchViewport) {
setDisplayViewportsInternal(defaultViewport, externalTouchViewport);
}
+
+ @Override
+ public boolean injectInputEvent(InputEvent event, int displayId, int mode) {
+ return injectInputEventInternal(event, displayId, mode);
+ }
}
}
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 321776c..9fe0082 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -1153,7 +1153,7 @@ static void nativeSetInputFilterEnabled(JNIEnv* env, jclass clazz,
}
static jint nativeInjectInputEvent(JNIEnv* env, jclass clazz,
- jlong ptr, jobject inputEventObj, jint injectorPid, jint injectorUid,
+ jlong ptr, jobject inputEventObj, jint displayId, jint injectorPid, jint injectorUid,
jint syncMode, jint timeoutMillis, jint policyFlags) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
@@ -1166,7 +1166,7 @@ static jint nativeInjectInputEvent(JNIEnv* env, jclass clazz,
}
return (jint) im->getInputManager()->getDispatcher()->injectInputEvent(
- & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
+ & keyEvent, displayId, injectorPid, injectorUid, syncMode, timeoutMillis,
uint32_t(policyFlags));
} else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
@@ -1176,7 +1176,7 @@ static jint nativeInjectInputEvent(JNIEnv* env, jclass clazz,
}
return (jint) im->getInputManager()->getDispatcher()->injectInputEvent(
- motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
+ motionEvent, displayId, injectorPid, injectorUid, syncMode, timeoutMillis,
uint32_t(policyFlags));
} else {
jniThrowRuntimeException(env, "Invalid input event type.");
@@ -1336,7 +1336,7 @@ static JNINativeMethod gInputManagerMethods[] = {
(void*) nativeUnregisterInputChannel },
{ "nativeSetInputFilterEnabled", "(JZ)V",
(void*) nativeSetInputFilterEnabled },
- { "nativeInjectInputEvent", "(JLandroid/view/InputEvent;IIIII)I",
+ { "nativeInjectInputEvent", "(JLandroid/view/InputEvent;IIIIII)I",
(void*) nativeInjectInputEvent },
{ "nativeSetInputWindows", "(J[Lcom/android/server/input/InputWindowHandle;)V",
(void*) nativeSetInputWindows },