summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2010-08-11 16:18:36 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2010-08-11 16:18:36 -0700
commitf66f8a58cc4412bd258e1d5b11cac17a617bdc58 (patch)
treeddd39a7b221d8c863fe5d5fdf648abe8d29ea5fa
parent2d8b9fe0f9fe44c17ccc4d041f726df490548984 (diff)
parent95af0c14a64ef264d2b362ded4ca2b5a169d1066 (diff)
downloadframeworks_base-f66f8a58cc4412bd258e1d5b11cac17a617bdc58.zip
frameworks_base-f66f8a58cc4412bd258e1d5b11cac17a617bdc58.tar.gz
frameworks_base-f66f8a58cc4412bd258e1d5b11cac17a617bdc58.tar.bz2
am 95af0c14: Merge "Add support for the PointerLocation overlay." into gingerbread
Merge commit '95af0c14a64ef264d2b362ded4ca2b5a169d1066' into gingerbread-plus-aosp * commit '95af0c14a64ef264d2b362ded4ca2b5a169d1066': Add support for the PointerLocation overlay.
-rw-r--r--core/java/android/os/Looper.java5
-rw-r--r--core/java/android/view/IWindowManager.aidl2
-rw-r--r--core/java/android/view/WindowManagerPolicy.java5
-rw-r--r--include/utils/String8.h3
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java49
-rw-r--r--services/java/com/android/server/InputManager.java29
-rw-r--r--services/java/com/android/server/WindowManagerService.java10
-rw-r--r--services/jni/com_android_server_InputManager.cpp78
8 files changed, 150 insertions, 31 deletions
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index 69b3540..a9d7342 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -180,6 +180,11 @@ public class Looper {
return mThread;
}
+ /** @hide */
+ public MessageQueue getQueue() {
+ return mQueue;
+ }
+
public void dump(Printer pw, String prefix) {
pw.println(prefix + this);
pw.println(prefix + "mRun=" + mRun);
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index d6b9212..e86e3bf 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -28,6 +28,7 @@ import android.view.IWindowSession;
import android.view.KeyEvent;
import android.view.InputEvent;
import android.view.MotionEvent;
+import android.view.InputChannel;
/**
* System private interface to the window manager.
@@ -119,6 +120,7 @@ interface IWindowManager
int getKeycodeStateForDevice(int devid, int sw);
int getTrackballKeycodeState(int sw);
int getDPadKeycodeState(int sw);
+ InputChannel monitorInput(String inputChannelName);
// Report whether the hardware supports the given keys; returns true if successful
boolean hasKeys(in int[] keycodes, inout boolean[] keyExists);
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 33757f0..659f9cd 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -779,11 +779,6 @@ public interface WindowManagerPolicy {
*/
public void enableScreenAfterBoot();
- /**
- * Called every time the window manager is dispatching a pointer event.
- */
- public void dispatchedPointerEventLw(MotionEvent ev, int targetX, int targetY);
-
public void setCurrentOrientationLw(int newOrientation);
/**
diff --git a/include/utils/String8.h b/include/utils/String8.h
index 4e41410..ef0b51a 100644
--- a/include/utils/String8.h
+++ b/include/utils/String8.h
@@ -171,7 +171,8 @@ public:
status_t append(const char* other);
status_t append(const char* other, size_t numChars);
- status_t appendFormat(const char* fmt, ...);
+ status_t appendFormat(const char* fmt, ...)
+ __attribute__((format (printf, 2, 3)));
// Note that this function takes O(N) time to calculate the value.
// No cache value is stored.
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 83d9c47..e2e6f1a 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -37,6 +37,7 @@ import android.graphics.Rect;
import android.os.Handler;
import android.os.IBinder;
import android.os.LocalPowerManager;
+import android.os.Looper;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -48,15 +49,20 @@ import android.provider.Settings;
import com.android.internal.policy.PolicyManager;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.telephony.ITelephony;
+import com.android.internal.view.BaseInputHandler;
import com.android.internal.widget.PointerLocationView;
import android.util.Config;
import android.util.EventLog;
import android.util.Log;
+import android.util.Slog;
import android.view.Display;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.IWindowManager;
+import android.view.InputChannel;
+import android.view.InputQueue;
+import android.view.InputHandler;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.WindowOrientationListener;
@@ -220,6 +226,17 @@ public class PhoneWindowManager implements WindowManagerPolicy {
int mPointerLocationMode = 0;
PointerLocationView mPointerLocationView = null;
+ InputChannel mPointerLocationInputChannel;
+
+ private final InputHandler mPointerLocationInputHandler = new BaseInputHandler() {
+ @Override
+ public void handleMotion(MotionEvent event, Runnable finishedCallback) {
+ finishedCallback.run();
+ synchronized (mLock) {
+ mPointerLocationView.addTouchEvent(event);
+ }
+ }
+ };
// The current size of the screen.
int mW, mH;
@@ -613,8 +630,26 @@ public class PhoneWindowManager implements WindowManagerPolicy {
WindowManagerImpl wm = (WindowManagerImpl)
mContext.getSystemService(Context.WINDOW_SERVICE);
wm.addView(addView, lp);
+
+ if (mPointerLocationInputChannel == null) {
+ try {
+ mPointerLocationInputChannel =
+ mWindowManager.monitorInput("PointerLocationView");
+ InputQueue.registerInputChannel(mPointerLocationInputChannel,
+ mPointerLocationInputHandler, mHandler.getLooper().getQueue());
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "Could not set up input monitoring channel for PointerLocation.",
+ ex);
+ }
+ }
}
if (removeView != null) {
+ if (mPointerLocationInputChannel != null) {
+ InputQueue.unregisterInputChannel(mPointerLocationInputChannel);
+ mPointerLocationInputChannel.dispose();
+ mPointerLocationInputChannel = null;
+ }
+
WindowManagerImpl wm = (WindowManagerImpl)
mContext.getSystemService(Context.WINDOW_SERVICE);
wm.removeView(removeView);
@@ -728,20 +763,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
: Configuration.KEYBOARDHIDDEN_YES;
}
- public void dispatchedPointerEventLw(MotionEvent ev, int targetX, int targetY) {
- if (mPointerLocationView == null) {
- return;
- }
- synchronized (mLock) {
- if (mPointerLocationView == null) {
- return;
- }
- ev.offsetLocation(targetX, targetY);
- mPointerLocationView.addTouchEvent(ev);
- ev.offsetLocation(-targetX, -targetY);
- }
- }
-
/** {@inheritDoc} */
public int windowTypeToLayerLw(int type) {
if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/InputManager.java
index 9195123..c2c799b 100644
--- a/services/java/com/android/server/InputManager.java
+++ b/services/java/com/android/server/InputManager.java
@@ -75,7 +75,8 @@ public class InputManager {
int sw);
private static native boolean nativeHasKeys(int deviceId, int sourceMask,
int[] keyCodes, boolean[] keyExists);
- private static native void nativeRegisterInputChannel(InputChannel inputChannel);
+ private static native void nativeRegisterInputChannel(InputChannel inputChannel,
+ boolean monitor);
private static native void nativeUnregisterInputChannel(InputChannel inputChannel);
private static native int nativeInjectInputEvent(InputEvent event,
int injectorPid, int injectorUid, int syncMode, int timeoutMillis);
@@ -225,14 +226,38 @@ public class InputManager {
return nativeHasKeys(deviceId, sourceMask, keyCodes, keyExists);
}
+ /**
+ * Creates an input channel that will receive all input from the input dispatcher.
+ * @param inputChannelName The input channel name.
+ * @return The input channel.
+ */
+ public InputChannel monitorInput(String inputChannelName) {
+ if (inputChannelName == null) {
+ throw new IllegalArgumentException("inputChannelName must not be null.");
+ }
+
+ InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName);
+ nativeRegisterInputChannel(inputChannels[0], true);
+ inputChannels[0].dispose(); // don't need to retain the Java object reference
+ return inputChannels[1];
+ }
+
+ /**
+ * Registers an input channel so that it can be used as an input event target.
+ * @param inputChannel The input channel to register.
+ */
public void registerInputChannel(InputChannel inputChannel) {
if (inputChannel == null) {
throw new IllegalArgumentException("inputChannel must not be null.");
}
- nativeRegisterInputChannel(inputChannel);
+ nativeRegisterInputChannel(inputChannel, false);
}
+ /**
+ * Unregisters an input channel.
+ * @param inputChannel The input channel to unregister.
+ */
public void unregisterInputChannel(InputChannel inputChannel) {
if (inputChannel == null) {
throw new IllegalArgumentException("inputChannel must not be null.");
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 0def5f2..11fcca8 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -4382,11 +4382,19 @@ public class WindowManagerService extends IWindowManager.Stub
}
return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD, sw);
}
-
+
public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
return mInputManager.hasKeys(-1, InputDevice.SOURCE_ANY, keycodes, keyExists);
}
+ public InputChannel monitorInput(String inputChannelName) {
+ if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
+ "monitorInput()")) {
+ throw new SecurityException("Requires READ_INPUT_STATE permission");
+ }
+ return mInputManager.monitorInput(inputChannelName);
+ }
+
public void enableScreenAfterBoot() {
synchronized(mWindowMap) {
if (mSystemBooted) {
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index 0982b32..ebe71ab 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -213,7 +213,7 @@ public:
void setDisplayOrientation(int32_t displayId, int32_t orientation);
status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
- jweak inputChannelObjWeak);
+ jweak inputChannelObjWeak, bool monitor);
status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
@@ -334,6 +334,7 @@ private:
bool mWindowsReady;
Vector<InputWindow> mWindows;
Vector<InputWindow*> mWallpaperWindows;
+ Vector<sp<InputChannel> > mMonitoringChannels;
// Focus tracking for keys, trackball, etc.
InputWindow* mFocusedWindow;
@@ -382,6 +383,10 @@ private:
static void addTarget(const InputWindow* window, int32_t targetFlags,
nsecs_t timeSpentWaitingForApplication, Vector<InputTarget>& outTargets);
+ void registerMonitoringChannel(const sp<InputChannel>& inputChannel);
+ void unregisterMonitoringChannel(const sp<InputChannel>& inputChannel);
+ void addMonitoringTargetsLd(Vector<InputTarget>& outTargets);
+
static inline JNIEnv* jniEnv() {
return AndroidRuntime::getJNIEnv();
}
@@ -492,7 +497,7 @@ void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orient
}
status_t NativeInputManager::registerInputChannel(JNIEnv* env,
- const sp<InputChannel>& inputChannel, jobject inputChannelObj) {
+ const sp<InputChannel>& inputChannel, jobject inputChannelObj, bool monitor) {
jweak inputChannelObjWeak = env->NewWeakGlobalRef(inputChannelObj);
if (! inputChannelObjWeak) {
LOGE("Could not create weak reference for input channel.");
@@ -519,9 +524,14 @@ status_t NativeInputManager::registerInputChannel(JNIEnv* env,
status = mInputManager->registerInputChannel(inputChannel);
if (! status) {
+ // Success.
+ if (monitor) {
+ registerMonitoringChannel(inputChannel);
+ }
return OK;
}
+ // Failed!
{
AutoMutex _l(mInputChannelRegistryLock);
mInputChannelObjWeakByReceiveFd.removeItem(inputChannel->getReceivePipeFd());
@@ -552,6 +562,8 @@ status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
env->DeleteWeakGlobalRef(inputChannelObjWeak);
+ unregisterMonitoringChannel(inputChannel);
+
return mInputManager->unregisterInputChannel(inputChannel);
}
@@ -829,6 +841,8 @@ void NativeInputManager::notifyInputChannelBroken(const sp<InputChannel>& inputC
env->DeleteLocalRef(inputChannelObjLocal);
}
+
+ unregisterMonitoringChannel(inputChannel);
}
bool NativeInputManager::notifyInputChannelANR(const sp<InputChannel>& inputChannel,
@@ -1429,7 +1443,9 @@ int32_t NativeInputManager::waitForTouchedWindowLd(MotionEvent* motionEvent, uin
// If there is no currently touched window then fail.
if (! mTouchedWindow) {
- LOGW("Dropping event because there is no touched window to receive it.");
+#if DEBUG_INPUT_DISPATCHER_POLICY
+ LOGD("Dropping event because there is no touched window to receive it.");
+#endif
injectionResult = INPUT_EVENT_INJECTION_FAILED;
injectionPermission = INJECTION_PERMISSION_GRANTED;
break; // failed, exit wait loop
@@ -1587,6 +1603,8 @@ int32_t NativeInputManager::waitForKeyEventTargets(KeyEvent* keyEvent, uint32_t
outTargets.clear();
return INPUT_EVENT_INJECTION_SUCCEEDED;
}
+
+ addMonitoringTargetsLd(outTargets);
}
pokeUserActivityIfNeeded(windowType, POWER_MANAGER_BUTTON_EVENT);
@@ -1631,6 +1649,8 @@ int32_t NativeInputManager::waitForNonTouchEventTargets(MotionEvent* motionEvent
}
windowType = focusedWindow->layoutParamsType;
+
+ addMonitoringTargetsLd(outTargets);
} // release lock
pokeUserActivityIfNeeded(windowType, POWER_MANAGER_BUTTON_EVENT);
@@ -1657,6 +1677,8 @@ int32_t NativeInputManager::waitForTouchEventTargets(MotionEvent* motionEvent,
}
windowType = touchedWindow->layoutParamsType;
+
+ addMonitoringTargetsLd(outTargets);
} // release lock
int32_t eventType;
@@ -1714,6 +1736,39 @@ void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType)
android_server_PowerManagerService_userActivity(eventTime, eventType);
}
+void NativeInputManager::registerMonitoringChannel(const sp<InputChannel>& inputChannel) {
+ { // acquire lock
+ AutoMutex _l(mDispatchLock);
+ mMonitoringChannels.push(inputChannel);
+ } // release lock
+}
+
+void NativeInputManager::unregisterMonitoringChannel(const sp<InputChannel>& inputChannel) {
+ { // acquire lock
+ AutoMutex _l(mDispatchLock);
+
+ for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
+ if (mMonitoringChannels[i] == inputChannel) {
+ mMonitoringChannels.removeAt(i);
+ break;
+ }
+ }
+ } // release lock
+}
+
+void NativeInputManager::addMonitoringTargetsLd(Vector<InputTarget>& outTargets) {
+ for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
+ outTargets.push();
+
+ InputTarget& target = outTargets.editTop();
+ target.inputChannel = mMonitoringChannels[i];
+ target.flags = 0;
+ target.timeout = -1;
+ target.xOffset = 0;
+ target.yOffset = 0;
+ }
+}
+
static void dumpMotionRange(String8& dump,
const char* name, const InputDeviceInfo::MotionRange* range) {
if (range) {
@@ -1805,6 +1860,11 @@ void NativeInputManager::dumpDispatchStateLd(String8& dump) {
mWindows[i].ownerPid, mWindows[i].ownerUid,
mWindows[i].dispatchingTimeout / 1000000.0);
}
+
+ for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
+ dump.appendFormat(" monitoringChannel[%d]: '%s'\n",
+ i, mMonitoringChannels[i]->getName().string());
+ }
}
// ----------------------------------------------------------------------------
@@ -2012,7 +2072,7 @@ static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
}
static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
- jobject inputChannelObj) {
+ jobject inputChannelObj, jboolean monitor) {
if (checkInputManagerUnitialized(env)) {
return;
}
@@ -2026,15 +2086,17 @@ static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env,
status_t status = gNativeInputManager->registerInputChannel(
- env, inputChannel, inputChannelObj);
+ env, inputChannel, inputChannelObj, monitor);
if (status) {
jniThrowRuntimeException(env, "Failed to register input channel. "
"Check logs for details.");
return;
}
- android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
- android_server_InputManager_handleInputChannelDisposed, NULL);
+ if (! monitor) {
+ android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
+ android_server_InputManager_handleInputChannelDisposed, NULL);
+ }
}
static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
@@ -2149,7 +2211,7 @@ static JNINativeMethod gInputManagerMethods[] = {
(void*) android_server_InputManager_nativeGetSwitchState },
{ "nativeHasKeys", "(II[I[Z)Z",
(void*) android_server_InputManager_nativeHasKeys },
- { "nativeRegisterInputChannel", "(Landroid/view/InputChannel;)V",
+ { "nativeRegisterInputChannel", "(Landroid/view/InputChannel;Z)V",
(void*) android_server_InputManager_nativeRegisterInputChannel },
{ "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
(void*) android_server_InputManager_nativeUnregisterInputChannel },