diff options
Diffstat (limited to 'services/java/com/android/server/WindowManagerService.java')
-rw-r--r-- | services/java/com/android/server/WindowManagerService.java | 2093 |
1 files changed, 96 insertions, 1997 deletions
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 483f9eb..38f1e1f 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -48,7 +48,6 @@ import com.android.internal.view.IInputContext; import com.android.internal.view.IInputMethodClient; import com.android.internal.view.IInputMethodManager; import com.android.internal.view.WindowManagerPolicyThread; -import com.android.server.KeyInputQueue.QueuedEvent; import com.android.server.am.BatteryStatsService; import android.Manifest; @@ -95,6 +94,7 @@ import android.util.Slog; import android.util.SparseIntArray; import android.view.Display; import android.view.Gravity; +import android.view.HapticFeedbackConstants; import android.view.IApplicationToken; import android.view.IOnKeyguardExitResult; import android.view.IRotationWatcher; @@ -105,7 +105,6 @@ import android.view.InputChannel; import android.view.InputQueue; import android.view.KeyEvent; import android.view.MotionEvent; -import android.view.RawInputEvent; import android.view.Surface; import android.view.SurfaceSession; import android.view.View; @@ -137,7 +136,7 @@ import java.util.List; /** {@hide} */ public class WindowManagerService extends IWindowManager.Stub - implements Watchdog.Monitor, KeyInputQueue.HapticFeedbackCallback { + implements Watchdog.Monitor { static final String TAG = "WindowManager"; static final boolean DEBUG = false; static final boolean DEBUG_FOCUS = false; @@ -159,17 +158,12 @@ public class WindowManagerService extends IWindowManager.Stub static final boolean SHOW_TRANSACTIONS = false; static final boolean HIDE_STACK_CRAWLS = true; static final boolean MEASURE_LATENCY = false; - static final boolean ENABLE_NATIVE_INPUT_DISPATCH = - WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH; static private LatencyTimer lt; static final boolean PROFILE_ORIENTATION = false; static final boolean BLUR = true; static final boolean localLOGV = DEBUG; - /** How long to wait for subsequent key repeats, in milliseconds */ - static final int KEY_REPEAT_DELAY = 50; - /** How much to multiply the policy's type layer, to reserve room * for multiple windows of the same type and Z-ordering adjustment * with TYPE_LAYER_OFFSET. */ @@ -210,34 +204,11 @@ public class WindowManagerService extends IWindowManager.Stub // Default input dispatching timeout in nanoseconds. private static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L; - static final int INJECT_FAILED = 0; - static final int INJECT_SUCCEEDED = 1; - static final int INJECT_NO_PERMISSION = -1; - static final int UPDATE_FOCUS_NORMAL = 0; static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1; static final int UPDATE_FOCUS_PLACING_SURFACES = 2; static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3; - /** The minimum time between dispatching touch events. */ - int mMinWaitTimeBetweenTouchEvents = 1000 / 35; - - // Last touch event time - long mLastTouchEventTime = 0; - - // Last touch event type - int mLastTouchEventType = OTHER_EVENT; - - // Time to wait before calling useractivity again. This saves CPU usage - // when we get a flood of touch events. - static final int MIN_TIME_BETWEEN_USERACTIVITIES = 1000; - - // Last time we call user activity - long mLastUserActivityCallTime = 0; - - // Last time we updated battery stats - long mLastBatteryStatsCallTime = 0; - private static final String SYSTEM_SECURE = "ro.secure"; private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; @@ -486,7 +457,6 @@ public class WindowManagerService extends IWindowManager.Stub float mLastWallpaperY = -1; float mLastWallpaperXStep = -1; float mLastWallpaperYStep = -1; - boolean mSendingPointersToWallpaper = false; // This is set when we are waiting for a wallpaper to tell us it is done // changing its scroll position. WindowState mWaitingOnWallpaper; @@ -504,10 +474,7 @@ public class WindowManagerService extends IWindowManager.Stub float mWindowAnimationScale = 1.0f; float mTransitionAnimationScale = 1.0f; - final KeyWaiter mKeyWaiter = new KeyWaiter(); - final KeyQ mQueue; final InputManager mInputManager; - final InputDispatcherThread mInputThread; // Who is holding the screen on. Session mHoldingScreenOn; @@ -523,8 +490,6 @@ public class WindowManagerService extends IWindowManager.Stub private ViewServer mViewServer; - final Rect mTempRect = new Rect(); - final Configuration mTempConfiguration = new Configuration(); int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED; @@ -652,28 +617,11 @@ public class WindowManagerService extends IWindowManager.Stub filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); mContext.registerReceiver(mBroadcastReceiver, filter); - int max_events_per_sec = 35; - try { - max_events_per_sec = Integer.parseInt(SystemProperties - .get("windowsmgr.max_events_per_sec")); - if (max_events_per_sec < 1) { - max_events_per_sec = 35; - } - } catch (NumberFormatException e) { - } - mMinWaitTimeBetweenTouchEvents = 1000 / max_events_per_sec; - mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "KEEP_SCREEN_ON_FLAG"); mHoldingScreenWakeLock.setReferenceCounted(false); - if (ENABLE_NATIVE_INPUT_DISPATCH) { - mInputManager = new InputManager(context, this, mPolicy, pmc, mPowerManager); - } else { - mInputManager = null; - } - mQueue = new KeyQ(); - mInputThread = new InputDispatcherThread(); + mInputManager = new InputManager(context, this, pmc, mPowerManager); PolicyThread thr = new PolicyThread(mPolicy, this, context, pm); thr.start(); @@ -687,11 +635,7 @@ public class WindowManagerService extends IWindowManager.Stub } } - if (ENABLE_NATIVE_INPUT_DISPATCH) { - mInputManager.start(); - } else { - mInputThread.start(); - } + mInputManager.start(); // Add ourself to the Watchdog monitors. Watchdog.getInstance().addMonitor(this); @@ -1817,70 +1761,6 @@ public class WindowManagerService extends IWindowManager.Stub } } } - - void sendPointerToWallpaperLocked(WindowState srcWin, - MotionEvent pointer, long eventTime) { - int curTokenIndex = mWallpaperTokens.size(); - while (curTokenIndex > 0) { - curTokenIndex--; - WindowToken token = mWallpaperTokens.get(curTokenIndex); - int curWallpaperIndex = token.windows.size(); - while (curWallpaperIndex > 0) { - curWallpaperIndex--; - WindowState wallpaper = token.windows.get(curWallpaperIndex); - if ((wallpaper.mAttrs.flags & - WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) { - continue; - } - try { - MotionEvent ev = MotionEvent.obtainNoHistory(pointer); - if (srcWin != null) { - ev.offsetLocation(srcWin.mFrame.left-wallpaper.mFrame.left, - srcWin.mFrame.top-wallpaper.mFrame.top); - } else { - ev.offsetLocation(-wallpaper.mFrame.left, -wallpaper.mFrame.top); - } - switch (pointer.getAction()) { - case MotionEvent.ACTION_DOWN: - mSendingPointersToWallpaper = true; - break; - case MotionEvent.ACTION_UP: - mSendingPointersToWallpaper = false; - break; - } - wallpaper.mClient.dispatchPointer(ev, eventTime, false); - } catch (RemoteException e) { - Slog.w(TAG, "Failure sending pointer to wallpaper", e); - } - } - } - } - - void dispatchPointerElsewhereLocked(WindowState srcWin, WindowState relWin, - MotionEvent pointer, long eventTime, boolean skipped) { - if (relWin != null) { - mPolicy.dispatchedPointerEventLw(pointer, relWin.mFrame.left, relWin.mFrame.top); - } else { - mPolicy.dispatchedPointerEventLw(pointer, 0, 0); - } - - // If we sent an initial down to the wallpaper, then continue - // sending events until the final up. - if (mSendingPointersToWallpaper) { - if (skipped) { - Slog.i(TAG, "Sending skipped pointer to wallpaper!"); - } - sendPointerToWallpaperLocked(relWin, pointer, eventTime); - - // If we are on top of the wallpaper, then the wallpaper also - // gets to see this movement. - } else if (srcWin != null - && pointer.getAction() == MotionEvent.ACTION_DOWN - && mWallpaperTarget == srcWin - && srcWin.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD) { - sendPointerToWallpaperLocked(relWin, pointer, eventTime); - } - } public int addWindow(Session session, IWindow client, WindowManager.LayoutParams attrs, int viewVisibility, @@ -1903,12 +1783,7 @@ public class WindowManagerService extends IWindowManager.Stub mDisplay = wm.getDefaultDisplay(); mInitialDisplayWidth = mDisplay.getWidth(); mInitialDisplayHeight = mDisplay.getHeight(); - if (ENABLE_NATIVE_INPUT_DISPATCH) { - mInputManager.setDisplaySize(0, - mInitialDisplayWidth, mInitialDisplayHeight); - } else { - mQueue.setDisplay(mDisplay); - } + mInputManager.setDisplaySize(0, mInitialDisplayWidth, mInitialDisplayHeight); reportNewConfig = true; } @@ -2002,15 +1877,13 @@ public class WindowManagerService extends IWindowManager.Stub return res; } - if (ENABLE_NATIVE_INPUT_DISPATCH) { - if (outInputChannel != null) { - String name = win.makeInputChannelName(); - InputChannel[] inputChannels = InputChannel.openInputChannelPair(name); - win.mInputChannel = inputChannels[0]; - inputChannels[1].transferToBinderOutParameter(outInputChannel); - - mInputManager.registerInputChannel(win.mInputChannel); - } + if (outInputChannel != null) { + String name = win.makeInputChannelName(); + InputChannel[] inputChannels = InputChannel.openInputChannelPair(name); + win.mInputChannel = inputChannels[0]; + inputChannels[1].transferToBinderOutParameter(outInputChannel); + + mInputManager.registerInputChannel(win.mInputChannel); } // From now on, no exceptions or errors allowed! @@ -2186,14 +2059,7 @@ public class WindowManagerService extends IWindowManager.Stub } private void removeWindowInnerLocked(Session session, WindowState win) { - if (ENABLE_NATIVE_INPUT_DISPATCH) { - mInputMonitor.windowIsBeingRemovedLw(win); - } else { - mKeyWaiter.finishedKey(session, win.mClient, true, - KeyWaiter.RETURN_NOTHING); - mKeyWaiter.releasePendingPointerLocked(win.mSession); - mKeyWaiter.releasePendingTrackballLocked(win.mSession); - } + mInputMonitor.windowIsBeingRemovedLw(win); win.mRemoved = true; @@ -2561,12 +2427,7 @@ public class WindowManagerService extends IWindowManager.Stub applyAnimationLocked(win, transit, false)) { focusMayChange = true; win.mExiting = true; - if (ENABLE_NATIVE_INPUT_DISPATCH) { - mInputMonitor.windowIsBecomingInvisibleLw(win); - } else { - mKeyWaiter.finishedKey(session, client, true, - KeyWaiter.RETURN_NOTHING); - } + mInputMonitor.windowIsBecomingInvisibleLw(win); } else if (win.isAnimating()) { // Currently in a hide animation... turn this into // an exit. @@ -3027,12 +2888,7 @@ public class WindowManagerService extends IWindowManager.Stub if (win.isVisibleNow()) { applyAnimationLocked(win, WindowManagerPolicy.TRANSIT_EXIT, false); - if (ENABLE_NATIVE_INPUT_DISPATCH) { - mInputMonitor.windowIsBeingRemovedLw(win); - } else { - mKeyWaiter.finishedKey(win.mSession, win.mClient, true, - KeyWaiter.RETURN_NOTHING); - } + mInputMonitor.windowIsBeingRemovedLw(win); changed = true; } } @@ -3349,12 +3205,8 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp); changed = mFocusedApp != null; mFocusedApp = null; - if (ENABLE_NATIVE_INPUT_DISPATCH) { - if (changed) { - mInputMonitor.setFocusedAppLw(null); - } - } else { - mKeyWaiter.tickle(); + if (changed) { + mInputMonitor.setFocusedAppLw(null); } } else { AppWindowToken newFocus = findAppWindowToken(token); @@ -3365,12 +3217,8 @@ public class WindowManagerService extends IWindowManager.Stub changed = mFocusedApp != newFocus; mFocusedApp = newFocus; if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp); - if (ENABLE_NATIVE_INPUT_DISPATCH) { - if (changed) { - mInputMonitor.setFocusedAppLw(newFocus); - } - } else { - mKeyWaiter.tickle(); + if (changed) { + mInputMonitor.setFocusedAppLw(newFocus); } } @@ -3682,12 +3530,7 @@ public class WindowManagerService extends IWindowManager.Stub applyAnimationLocked(win, WindowManagerPolicy.TRANSIT_EXIT, false); } - if (ENABLE_NATIVE_INPUT_DISPATCH) { - mInputMonitor.windowIsBecomingInvisibleLw(win); - } else { - mKeyWaiter.finishedKey(win.mSession, win.mClient, true, - KeyWaiter.RETURN_NOTHING); - } + mInputMonitor.windowIsBecomingInvisibleLw(win); changed = true; } } @@ -3972,11 +3815,7 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken); mFocusedApp = null; updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL); - if (ENABLE_NATIVE_INPUT_DISPATCH) { - mInputMonitor.setFocusedAppLw(null); - } else { - mKeyWaiter.tickle(); - } + mInputMonitor.setFocusedAppLw(null); } } else { Slog.w(TAG, "Attempted to remove non-existing app token: " + token); @@ -4441,11 +4280,7 @@ public class WindowManagerService extends IWindowManager.Stub "getSwitchState()")) { throw new SecurityException("Requires READ_INPUT_STATE permission"); } - if (ENABLE_NATIVE_INPUT_DISPATCH) { - return mInputManager.getSwitchState(sw); - } else { - return KeyInputQueue.getSwitchState(sw); - } + return mInputManager.getSwitchState(sw); } public int getSwitchStateForDevice(int devid, int sw) { @@ -4453,11 +4288,7 @@ public class WindowManagerService extends IWindowManager.Stub "getSwitchStateForDevice()")) { throw new SecurityException("Requires READ_INPUT_STATE permission"); } - if (ENABLE_NATIVE_INPUT_DISPATCH) { - return mInputManager.getSwitchState(devid, sw); - } else { - return KeyInputQueue.getSwitchState(devid, sw); - } + return mInputManager.getSwitchState(devid, sw); } public int getScancodeState(int sw) { @@ -4465,11 +4296,7 @@ public class WindowManagerService extends IWindowManager.Stub "getScancodeState()")) { throw new SecurityException("Requires READ_INPUT_STATE permission"); } - if (ENABLE_NATIVE_INPUT_DISPATCH) { - return mInputManager.getScancodeState(sw); - } else { - return mQueue.getScancodeState(sw); - } + return mInputManager.getScancodeState(sw); } public int getScancodeStateForDevice(int devid, int sw) { @@ -4477,11 +4304,7 @@ public class WindowManagerService extends IWindowManager.Stub "getScancodeStateForDevice()")) { throw new SecurityException("Requires READ_INPUT_STATE permission"); } - if (ENABLE_NATIVE_INPUT_DISPATCH) { - return mInputManager.getScancodeState(devid, sw); - } else { - return mQueue.getScancodeState(devid, sw); - } + return mInputManager.getScancodeState(devid, sw); } public int getTrackballScancodeState(int sw) { @@ -4489,11 +4312,7 @@ public class WindowManagerService extends IWindowManager.Stub "getTrackballScancodeState()")) { throw new SecurityException("Requires READ_INPUT_STATE permission"); } - if (ENABLE_NATIVE_INPUT_DISPATCH) { - return mInputManager.getTrackballScancodeState(sw); - } else { - return mQueue.getTrackballScancodeState(sw); - } + return mInputManager.getTrackballScancodeState(sw); } public int getDPadScancodeState(int sw) { @@ -4501,11 +4320,7 @@ public class WindowManagerService extends IWindowManager.Stub "getDPadScancodeState()")) { throw new SecurityException("Requires READ_INPUT_STATE permission"); } - if (ENABLE_NATIVE_INPUT_DISPATCH) { - return mInputManager.getDPadScancodeState(sw); - } else { - return mQueue.getDPadScancodeState(sw); - } + return mInputManager.getDPadScancodeState(sw); } public int getKeycodeState(int sw) { @@ -4513,11 +4328,7 @@ public class WindowManagerService extends IWindowManager.Stub "getKeycodeState()")) { throw new SecurityException("Requires READ_INPUT_STATE permission"); } - if (ENABLE_NATIVE_INPUT_DISPATCH) { - return mInputManager.getKeycodeState(sw); - } else { - return mQueue.getKeycodeState(sw); - } + return mInputManager.getKeycodeState(sw); } public int getKeycodeStateForDevice(int devid, int sw) { @@ -4525,11 +4336,7 @@ public class WindowManagerService extends IWindowManager.Stub "getKeycodeStateForDevice()")) { throw new SecurityException("Requires READ_INPUT_STATE permission"); } - if (ENABLE_NATIVE_INPUT_DISPATCH) { - return mInputManager.getKeycodeState(devid, sw); - } else { - return mQueue.getKeycodeState(devid, sw); - } + return mInputManager.getKeycodeState(devid, sw); } public int getTrackballKeycodeState(int sw) { @@ -4537,11 +4344,7 @@ public class WindowManagerService extends IWindowManager.Stub "getTrackballKeycodeState()")) { throw new SecurityException("Requires READ_INPUT_STATE permission"); } - if (ENABLE_NATIVE_INPUT_DISPATCH) { - return mInputManager.getTrackballKeycodeState(sw); - } else { - return mQueue.getTrackballKeycodeState(sw); - } + return mInputManager.getTrackballKeycodeState(sw); } public int getDPadKeycodeState(int sw) { @@ -4549,19 +4352,11 @@ public class WindowManagerService extends IWindowManager.Stub "getDPadKeycodeState()")) { throw new SecurityException("Requires READ_INPUT_STATE permission"); } - if (ENABLE_NATIVE_INPUT_DISPATCH) { - return mInputManager.getDPadKeycodeState(sw); - } else { - return mQueue.getDPadKeycodeState(sw); - } + return mInputManager.getDPadKeycodeState(sw); } public boolean hasKeys(int[] keycodes, boolean[] keyExists) { - if (ENABLE_NATIVE_INPUT_DISPATCH) { - return mInputManager.hasKeys(keycodes, keyExists); - } else { - return KeyInputQueue.hasKeys(keycodes, keyExists); - } + return mInputManager.hasKeys(keycodes, keyExists); } public void enableScreenAfterBoot() { @@ -4706,11 +4501,7 @@ public class WindowManagerService extends IWindowManager.Stub mLayoutNeeded = true; startFreezingDisplayLocked(); Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags); - if (ENABLE_NATIVE_INPUT_DISPATCH) { - mInputManager.setDisplayOrientation(0, rotation); - } else { - mQueue.setOrientation(rotation); - } + mInputManager.setDisplayOrientation(0, rotation); if (mDisplayEnabled) { Surface.setOrientation(0, rotation, animFlags); } @@ -5041,11 +4832,8 @@ public class WindowManagerService extends IWindowManager.Stub if (mDisplay == null) { return false; } - if (ENABLE_NATIVE_INPUT_DISPATCH) { - mInputManager.getInputConfiguration(config); - } else { - mQueue.getInputConfiguration(config); - } + + mInputManager.getInputConfiguration(config); // Use the effective "visual" dimensions based on current rotation final boolean rotated = (mRotation == Surface.ROTATION_90 @@ -5326,6 +5114,13 @@ public class WindowManagerService extends IWindowManager.Stub mTempInputWindows.clear(); } + /* Provides feedback for a virtual key down. */ + public void virtualKeyDownFeedback() { + synchronized (mWindowMap) { + mPolicy.performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false); + } + } + /* Notifies that an app switch key (BACK / HOME) has just been pressed. * This essentially starts a .5 second timeout for the application to process * subsequent input events while waiting for the app switch to occur. If it takes longer @@ -5334,30 +5129,28 @@ public class WindowManagerService extends IWindowManager.Stub public void notifyAppSwitchComing() { // TODO Not implemented yet. Should go in the native side. } - + + /* Notifies that the lid switch changed state. */ + public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) { + mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen); + } + /* Provides an opportunity for the window manager policy to intercept early key * processing as soon as the key has been read from the device. */ - public int interceptKeyBeforeQueueing(int deviceId, int type, int scanCode, - int keyCode, int policyFlags, int value, long whenNanos, boolean isScreenOn) { - RawInputEvent event = new RawInputEvent(); - event.deviceId = deviceId; - event.type = type; - event.scancode = scanCode; - event.keycode = keyCode; - event.flags = policyFlags; - event.value = value; - event.when = whenNanos / 1000000; - - return mPolicy.interceptKeyTq(event, isScreenOn); + public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down, + int policyFlags, boolean isScreenOn) { + return mPolicy.interceptKeyBeforeQueueing(whenNanos, + keyCode, down, policyFlags, isScreenOn); } /* Provides an opportunity for the window manager policy to process a key before * ordinary dispatch. */ - public boolean interceptKeyBeforeDispatching(InputChannel focus, int keyCode, - int metaState, boolean down, int repeatCount, int policyFlags) { + public boolean interceptKeyBeforeDispatching(InputChannel focus, + int action, int flags, int keyCode, int metaState, int repeatCount, + int policyFlags) { WindowState windowState = getWindowStateForInputChannel(focus); - return mPolicy.interceptKeyTi(windowState, keyCode, metaState, down, repeatCount, - policyFlags); + return mPolicy.interceptKeyBeforeDispatching(windowState, action, flags, + keyCode, metaState, repeatCount, policyFlags); } /* Called when the current input focus changes. @@ -5496,450 +5289,6 @@ public class WindowManagerService extends IWindowManager.Stub } } - private final void wakeupIfNeeded(WindowState targetWin, int eventType) { - long curTime = SystemClock.uptimeMillis(); - - if (eventType == TOUCH_EVENT || eventType == LONG_TOUCH_EVENT || eventType == CHEEK_EVENT) { - if (mLastTouchEventType == eventType && - (curTime - mLastUserActivityCallTime) < MIN_TIME_BETWEEN_USERACTIVITIES) { - return; - } - mLastUserActivityCallTime = curTime; - mLastTouchEventType = eventType; - } - - if (targetWin == null - || targetWin.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD) { - mPowerManager.userActivity(curTime, false, eventType, false); - } - } - - // tells if it's a cheek event or not -- this function is stateful - private static final int EVENT_NONE = 0; - private static final int EVENT_UNKNOWN = 0; - private static final int EVENT_CHEEK = 0; - private static final int EVENT_IGNORE_DURATION = 300; // ms - private static final float CHEEK_THRESHOLD = 0.6f; - private int mEventState = EVENT_NONE; - private float mEventSize; - - private int eventType(MotionEvent ev) { - float size = ev.getSize(); - switch (ev.getAction()) { - case MotionEvent.ACTION_DOWN: - mEventSize = size; - return (mEventSize > CHEEK_THRESHOLD) ? CHEEK_EVENT : TOUCH_EVENT; - case MotionEvent.ACTION_UP: - if (size > mEventSize) mEventSize = size; - return (mEventSize > CHEEK_THRESHOLD) ? CHEEK_EVENT : TOUCH_UP_EVENT; - case MotionEvent.ACTION_MOVE: - final int N = ev.getHistorySize(); - if (size > mEventSize) mEventSize = size; - if (mEventSize > CHEEK_THRESHOLD) return CHEEK_EVENT; - for (int i=0; i<N; i++) { - size = ev.getHistoricalSize(i); - if (size > mEventSize) mEventSize = size; - if (mEventSize > CHEEK_THRESHOLD) return CHEEK_EVENT; - } - if (ev.getEventTime() < ev.getDownTime() + EVENT_IGNORE_DURATION) { - return TOUCH_EVENT; - } else { - return LONG_TOUCH_EVENT; - } - default: - // not good - return OTHER_EVENT; - } - } - - private boolean mFatTouch; // remove me together with dispatchPointer - - /** - * @return Returns true if event was dispatched, false if it was dropped for any reason - */ - private int dispatchPointer(QueuedEvent qev, MotionEvent ev, int pid, int uid) { - if (DEBUG_INPUT || WindowManagerPolicy.WATCH_POINTER) Slog.v(TAG, - "dispatchPointer " + ev); - - if (MEASURE_LATENCY) { - lt.sample("3 Wait for last dispatch ", System.nanoTime() - qev.whenNano); - } - - Object targetObj = mKeyWaiter.waitForNextEventTarget(null, qev, - ev, true, false, pid, uid); - - if (MEASURE_LATENCY) { - lt.sample("3 Last dispatch finished ", System.nanoTime() - qev.whenNano); - } - - int action = ev.getAction(); - - if (action == MotionEvent.ACTION_UP) { - // let go of our target - mKeyWaiter.mMotionTarget = null; - mPowerManager.logPointerUpEvent(); - } else if (action == MotionEvent.ACTION_DOWN) { - mPowerManager.logPointerDownEvent(); - } - - if (targetObj == null) { - // In this case we are either dropping the event, or have received - // a move or up without a down. It is common to receive move - // events in such a way, since this means the user is moving the - // pointer without actually pressing down. All other cases should - // be atypical, so let's log them. - if (action != MotionEvent.ACTION_MOVE) { - Slog.w(TAG, "No window to dispatch pointer action " + ev.getAction()); - } - synchronized (mWindowMap) { - dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), true); - } - if (qev != null) { - mQueue.recycleEvent(qev); - } - ev.recycle(); - return INJECT_FAILED; - } - if (targetObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) { - synchronized (mWindowMap) { - dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), true); - } - if (qev != null) { - mQueue.recycleEvent(qev); - } - ev.recycle(); - return INJECT_SUCCEEDED; - } - - WindowState target = (WindowState)targetObj; - - final long eventTime = ev.getEventTime(); - final long eventTimeNano = ev.getEventTimeNano(); - - //Slog.i(TAG, "Sending " + ev + " to " + target); - - if (uid != 0 && uid != target.mSession.mUid) { - if (mContext.checkPermission( - android.Manifest.permission.INJECT_EVENTS, pid, uid) - != PackageManager.PERMISSION_GRANTED) { - Slog.w(TAG, "Permission denied: injecting pointer event from pid " - + pid + " uid " + uid + " to window " + target - + " owned by uid " + target.mSession.mUid); - if (qev != null) { - mQueue.recycleEvent(qev); - } - ev.recycle(); - return INJECT_NO_PERMISSION; - } - } - - if (MEASURE_LATENCY) { - lt.sample("4 in dispatchPointer ", System.nanoTime() - eventTimeNano); - } - - if ((target.mAttrs.flags & - WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES) != 0) { - //target wants to ignore fat touch events - boolean cheekPress = mPolicy.isCheekPressedAgainstScreen(ev); - //explicit flag to return without processing event further - boolean returnFlag = false; - if((action == MotionEvent.ACTION_DOWN)) { - mFatTouch = false; - if(cheekPress) { - mFatTouch = true; - returnFlag = true; - } - } else { - if(action == MotionEvent.ACTION_UP) { - if(mFatTouch) { - //earlier even was invalid doesnt matter if current up is cheekpress or not - mFatTouch = false; - returnFlag = true; - } else if(cheekPress) { - //cancel the earlier event - ev.setAction(MotionEvent.ACTION_CANCEL); - action = MotionEvent.ACTION_CANCEL; - } - } else if(action == MotionEvent.ACTION_MOVE) { - if(mFatTouch) { - //two cases here - //an invalid down followed by 0 or moves(valid or invalid) - //a valid down, invalid move, more moves. want to ignore till up - returnFlag = true; - } else if(cheekPress) { - //valid down followed by invalid moves - //an invalid move have to cancel earlier action - ev.setAction(MotionEvent.ACTION_CANCEL); - action = MotionEvent.ACTION_CANCEL; - if (DEBUG_INPUT) Slog.v(TAG, "Sending cancel for invalid ACTION_MOVE"); - //note that the subsequent invalid moves will not get here - mFatTouch = true; - } - } - } //else if action - if(returnFlag) { - //recycle que, ev - if (qev != null) { - mQueue.recycleEvent(qev); - } - ev.recycle(); - return INJECT_FAILED; - } - } //end if target - - // Enable this for testing the "right" value - if (false && action == MotionEvent.ACTION_DOWN) { - int max_events_per_sec = 35; - try { - max_events_per_sec = Integer.parseInt(SystemProperties - .get("windowsmgr.max_events_per_sec")); - if (max_events_per_sec < 1) { - max_events_per_sec = 35; - } - } catch (NumberFormatException e) { - } - mMinWaitTimeBetweenTouchEvents = 1000 / max_events_per_sec; - } - - /* - * Throttle events to minimize CPU usage when there's a flood of events - * e.g. constant contact with the screen - */ - if (action == MotionEvent.ACTION_MOVE) { - long nextEventTime = mLastTouchEventTime + mMinWaitTimeBetweenTouchEvents; - long now = SystemClock.uptimeMillis(); - if (now < nextEventTime) { - try { - Thread.sleep(nextEventTime - now); - } catch (InterruptedException e) { - } - mLastTouchEventTime = nextEventTime; - } else { - mLastTouchEventTime = now; - } - } - - if (MEASURE_LATENCY) { - lt.sample("5 in dispatchPointer ", System.nanoTime() - eventTimeNano); - } - - synchronized(mWindowMap) { - if (!target.isVisibleLw()) { - // During this motion dispatch, the target window has become - // invisible. - dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), false); - if (qev != null) { - mQueue.recycleEvent(qev); - } - ev.recycle(); - return INJECT_SUCCEEDED; - } - - if (qev != null && action == MotionEvent.ACTION_MOVE) { - mKeyWaiter.bindTargetWindowLocked(target, - KeyWaiter.RETURN_PENDING_POINTER, qev); - ev = null; - } else { - if (action == MotionEvent.ACTION_DOWN) { - WindowState out = mKeyWaiter.mOutsideTouchTargets; - if (out != null) { - MotionEvent oev = MotionEvent.obtain(ev); - oev.setAction(MotionEvent.ACTION_OUTSIDE); - do { - final Rect frame = out.mFrame; - oev.offsetLocation(-(float)frame.left, -(float)frame.top); - try { - out.mClient.dispatchPointer(oev, eventTime, false); - } catch (android.os.RemoteException e) { - Slog.i(TAG, "WINDOW DIED during outside motion dispatch: " + out); - } - oev.offsetLocation((float)frame.left, (float)frame.top); - out = out.mNextOutsideTouch; - } while (out != null); - mKeyWaiter.mOutsideTouchTargets = null; - } - } - - dispatchPointerElsewhereLocked(target, null, ev, ev.getEventTime(), false); - - final Rect frame = target.mFrame; - ev.offsetLocation(-(float)frame.left, -(float)frame.top); - mKeyWaiter.bindTargetWindowLocked(target); - } - } - - // finally offset the event to the target's coordinate system and - // dispatch the event. - try { - if (DEBUG_INPUT || DEBUG_FOCUS || WindowManagerPolicy.WATCH_POINTER) { - Slog.v(TAG, "Delivering pointer " + qev + " to " + target); - } - - if (MEASURE_LATENCY) { - lt.sample("6 before svr->client ipc ", System.nanoTime() - eventTimeNano); - } - - target.mClient.dispatchPointer(ev, eventTime, true); - - if (MEASURE_LATENCY) { - lt.sample("7 after svr->client ipc ", System.nanoTime() - eventTimeNano); - } - return INJECT_SUCCEEDED; - } catch (android.os.RemoteException e) { - Slog.i(TAG, "WINDOW DIED during motion dispatch: " + target); - mKeyWaiter.mMotionTarget = null; - try { - removeWindow(target.mSession, target.mClient); - } catch (java.util.NoSuchElementException ex) { - // This will happen if the window has already been - // removed. - } - } - return INJECT_FAILED; - } - - /** - * @return Returns true if event was dispatched, false if it was dropped for any reason - */ - private int dispatchTrackball(QueuedEvent qev, MotionEvent ev, int pid, int uid) { - if (DEBUG_INPUT) Slog.v( - TAG, "dispatchTrackball [" + ev.getAction() +"] <" + ev.getX() + ", " + ev.getY() + ">"); - - Object focusObj = mKeyWaiter.waitForNextEventTarget(null, qev, - ev, false, false, pid, uid); - if (focusObj == null) { - Slog.w(TAG, "No focus window, dropping trackball: " + ev); - if (qev != null) { - mQueue.recycleEvent(qev); - } - ev.recycle(); - return INJECT_FAILED; - } - if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) { - if (qev != null) { - mQueue.recycleEvent(qev); - } - ev.recycle(); - return INJECT_SUCCEEDED; - } - - WindowState focus = (WindowState)focusObj; - - if (uid != 0 && uid != focus.mSession.mUid) { - if (mContext.checkPermission( - android.Manifest.permission.INJECT_EVENTS, pid, uid) - != PackageManager.PERMISSION_GRANTED) { - Slog.w(TAG, "Permission denied: injecting key event from pid " - + pid + " uid " + uid + " to window " + focus - + " owned by uid " + focus.mSession.mUid); - if (qev != null) { - mQueue.recycleEvent(qev); - } - ev.recycle(); - return INJECT_NO_PERMISSION; - } - } - - final long eventTime = ev.getEventTime(); - - synchronized(mWindowMap) { - if (qev != null && ev.getAction() == MotionEvent.ACTION_MOVE) { - mKeyWaiter.bindTargetWindowLocked(focus, - KeyWaiter.RETURN_PENDING_TRACKBALL, qev); - // We don't deliver movement events to the client, we hold - // them and wait for them to call back. - ev = null; - } else { - mKeyWaiter.bindTargetWindowLocked(focus); - } - } - - try { - focus.mClient.dispatchTrackball(ev, eventTime, true); - return INJECT_SUCCEEDED; - } catch (android.os.RemoteException e) { - Slog.i(TAG, "WINDOW DIED during key dispatch: " + focus); - try { - removeWindow(focus.mSession, focus.mClient); - } catch (java.util.NoSuchElementException ex) { - // This will happen if the window has already been - // removed. - } - } - - return INJECT_FAILED; - } - - /** - * @return Returns true if event was dispatched, false if it was dropped for any reason - */ - private int dispatchKey(KeyEvent event, int pid, int uid) { - if (DEBUG_INPUT) Slog.v(TAG, "Dispatch key: " + event); - - Object focusObj = mKeyWaiter.waitForNextEventTarget(event, null, - null, false, false, pid, uid); - if (focusObj == null) { - Slog.w(TAG, "No focus window, dropping: " + event); - return INJECT_FAILED; - } - if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) { - return INJECT_SUCCEEDED; - } - - // Okay we have finished waiting for the last event to be processed. - // First off, if this is a repeat event, check to see if there is - // a corresponding up event in the queue. If there is, we will - // just drop the repeat, because it makes no sense to repeat after - // the user has released a key. (This is especially important for - // long presses.) - if (event.getRepeatCount() > 0 && mQueue.hasKeyUpEvent(event)) { - return INJECT_SUCCEEDED; - } - - WindowState focus = (WindowState)focusObj; - - if (DEBUG_INPUT) Slog.v( - TAG, "Dispatching to " + focus + ": " + event); - - if (uid != 0 && uid != focus.mSession.mUid) { - if (mContext.checkPermission( - android.Manifest.permission.INJECT_EVENTS, pid, uid) - != PackageManager.PERMISSION_GRANTED) { - Slog.w(TAG, "Permission denied: injecting key event from pid " - + pid + " uid " + uid + " to window " + focus - + " owned by uid " + focus.mSession.mUid); - return INJECT_NO_PERMISSION; - } - } - - synchronized(mWindowMap) { - mKeyWaiter.bindTargetWindowLocked(focus); - } - - // NOSHIP extra state logging - mKeyWaiter.recordDispatchState(event, focus); - // END NOSHIP - - try { - if (DEBUG_INPUT || DEBUG_FOCUS) { - Slog.v(TAG, "Delivering key " + event.getKeyCode() - + " to " + focus); - } - focus.mClient.dispatchKey(event); - return INJECT_SUCCEEDED; - } catch (android.os.RemoteException e) { - Slog.i(TAG, "WINDOW DIED during key dispatch: " + focus); - try { - removeWindow(focus.mSession, focus.mClient); - } catch (java.util.NoSuchElementException ex) { - // This will happen if the window has already been - // removed. - } - } - - return INJECT_FAILED; - } - public void pauseKeyDispatching(IBinder _token) { if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, "pauseKeyDispatching()")) { @@ -5949,11 +5298,7 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mWindowMap) { WindowToken token = mTokenMap.get(_token); if (token != null) { - if (ENABLE_NATIVE_INPUT_DISPATCH) { - mInputMonitor.pauseDispatchingLw(token); - } else { - mKeyWaiter.pauseDispatchingLocked(token); - } + mInputMonitor.pauseDispatchingLw(token); } } } @@ -5967,11 +5312,7 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mWindowMap) { WindowToken token = mTokenMap.get(_token); if (token != null) { - if (ENABLE_NATIVE_INPUT_DISPATCH) { - mInputMonitor.resumeDispatchingLw(token); - } else { - mKeyWaiter.resumeDispatchingLocked(token); - } + mInputMonitor.resumeDispatchingLw(token); } } } @@ -5983,11 +5324,7 @@ public class WindowManagerService extends IWindowManager.Stub } synchronized (mWindowMap) { - if (ENABLE_NATIVE_INPUT_DISPATCH) { - mInputMonitor.setEventDispatchingLw(enabled); - } else { - mKeyWaiter.setEventDispatchingLocked(enabled); - } + mInputMonitor.setEventDispatchingLw(enabled); } } @@ -6020,16 +5357,8 @@ public class WindowManagerService extends IWindowManager.Stub final int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); - final int result; - if (ENABLE_NATIVE_INPUT_DISPATCH) { - result = mInputManager.injectKeyEvent(newEvent, InputQueue.INPUT_EVENT_NATURE_KEY, - pid, uid, sync, INJECTION_TIMEOUT_MILLIS); - } else { - result = dispatchKey(newEvent, pid, uid); - if (sync) { - mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid); - } - } + final int result = mInputManager.injectKeyEvent(newEvent, + InputQueue.INPUT_EVENT_NATURE_KEY, pid, uid, sync, INJECTION_TIMEOUT_MILLIS); Binder.restoreCallingIdentity(ident); return reportInjectionResult(result); @@ -6049,16 +5378,8 @@ public class WindowManagerService extends IWindowManager.Stub final int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); - final int result; - if (ENABLE_NATIVE_INPUT_DISPATCH) { - result = mInputManager.injectMotionEvent(ev, InputQueue.INPUT_EVENT_NATURE_TOUCH, - pid, uid, sync, INJECTION_TIMEOUT_MILLIS); - } else { - result = dispatchPointer(null, ev, pid, uid); - if (sync) { - mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid); - } - } + final int result = mInputManager.injectMotionEvent(ev, + InputQueue.INPUT_EVENT_NATURE_TOUCH, pid, uid, sync, INJECTION_TIMEOUT_MILLIS); Binder.restoreCallingIdentity(ident); return reportInjectionResult(result); @@ -6078,48 +5399,29 @@ public class WindowManagerService extends IWindowManager.Stub final int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); - final int result; - if (ENABLE_NATIVE_INPUT_DISPATCH) { - result = mInputManager.injectMotionEvent(ev, InputQueue.INPUT_EVENT_NATURE_TRACKBALL, - pid, uid, sync, INJECTION_TIMEOUT_MILLIS); - } else { - result = dispatchTrackball(null, ev, pid, uid); - if (sync) { - mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid); - } - } + final int result = mInputManager.injectMotionEvent(ev, + InputQueue.INPUT_EVENT_NATURE_TRACKBALL, pid, uid, sync, INJECTION_TIMEOUT_MILLIS); Binder.restoreCallingIdentity(ident); return reportInjectionResult(result); } private boolean reportInjectionResult(int result) { - if (ENABLE_NATIVE_INPUT_DISPATCH) { - switch (result) { - case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED: - Slog.w(TAG, "Input event injection permission denied."); - throw new SecurityException( - "Injecting to another application requires INJECT_EVENTS permission"); - case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED: - Slog.v(TAG, "Input event injection succeeded."); - return true; - case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT: - Slog.w(TAG, "Input event injection timed out."); - return false; - case InputManager.INPUT_EVENT_INJECTION_FAILED: - default: - Slog.w(TAG, "Input event injection failed."); - return false; - } - } else { - switch (result) { - case INJECT_NO_PERMISSION: - throw new SecurityException( - "Injecting to another application requires INJECT_EVENTS permission"); - case INJECT_SUCCEEDED: - return true; - } - return false; + switch (result) { + case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED: + Slog.w(TAG, "Input event injection permission denied."); + throw new SecurityException( + "Injecting to another application requires INJECT_EVENTS permission"); + case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED: + Slog.v(TAG, "Input event injection succeeded."); + return true; + case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT: + Slog.w(TAG, "Input event injection timed out."); + return false; + case InputManager.INPUT_EVENT_INJECTION_FAILED: + default: + Slog.w(TAG, "Input event injection failed."); + return false; } } @@ -6133,867 +5435,6 @@ public class WindowManagerService extends IWindowManager.Stub return mCurrentFocus; } - /** - * This class holds the state for dispatching key events. This state - * is protected by the KeyWaiter instance, NOT by the window lock. You - * can be holding the main window lock while acquire the KeyWaiter lock, - * but not the other way around. - */ - final class KeyWaiter { - // NOSHIP debugging - public class DispatchState { - private KeyEvent event; - private WindowState focus; - private long time; - private WindowState lastWin; - private IBinder lastBinder; - private boolean finished; - private boolean gotFirstWindow; - private boolean eventDispatching; - private long timeToSwitch; - private boolean wasFrozen; - private boolean focusPaused; - private WindowState curFocus; - - DispatchState(KeyEvent theEvent, WindowState theFocus) { - focus = theFocus; - event = theEvent; - time = System.currentTimeMillis(); - // snapshot KeyWaiter state - lastWin = mLastWin; - lastBinder = mLastBinder; - finished = mFinished; - gotFirstWindow = mGotFirstWindow; - eventDispatching = mEventDispatching; - timeToSwitch = mTimeToSwitch; - wasFrozen = mWasFrozen; - curFocus = mCurrentFocus; - // cache the paused state at ctor time as well - if (theFocus == null || theFocus.mToken == null) { - focusPaused = false; - } else { - focusPaused = theFocus.mToken.paused; - } - } - - public String toString() { - return "{{" + event + " to " + focus + " @ " + time - + " lw=" + lastWin + " lb=" + lastBinder - + " fin=" + finished + " gfw=" + gotFirstWindow - + " ed=" + eventDispatching + " tts=" + timeToSwitch - + " wf=" + wasFrozen + " fp=" + focusPaused - + " mcf=" + curFocus + "}}"; - } - }; - private DispatchState mDispatchState = null; - public void recordDispatchState(KeyEvent theEvent, WindowState theFocus) { - mDispatchState = new DispatchState(theEvent, theFocus); - } - // END NOSHIP - - public static final int RETURN_NOTHING = 0; - public static final int RETURN_PENDING_POINTER = 1; - public static final int RETURN_PENDING_TRACKBALL = 2; - - final Object SKIP_TARGET_TOKEN = new Object(); - final Object CONSUMED_EVENT_TOKEN = new Object(); - - private WindowState mLastWin = null; - private IBinder mLastBinder = null; - private boolean mFinished = true; - private boolean mGotFirstWindow = false; - private boolean mEventDispatching = true; - private long mTimeToSwitch = 0; - /* package */ boolean mWasFrozen = false; - - // Target of Motion events - WindowState mMotionTarget; - - // Windows above the target who would like to receive an "outside" - // touch event for any down events outside of them. - WindowState mOutsideTouchTargets; - - /** - * Wait for the last event dispatch to complete, then find the next - * target that should receive the given event and wait for that one - * to be ready to receive it. - */ - Object waitForNextEventTarget(KeyEvent nextKey, QueuedEvent qev, - MotionEvent nextMotion, boolean isPointerEvent, - boolean failIfTimeout, int callingPid, int callingUid) { - long startTime = SystemClock.uptimeMillis(); - long keyDispatchingTimeout = 5 * 1000; - long waitedFor = 0; - - while (true) { - // Figure out which window we care about. It is either the - // last window we are waiting to have process the event or, - // if none, then the next window we think the event should go - // to. Note: we retrieve mLastWin outside of the lock, so - // it may change before we lock. Thus we must check it again. - WindowState targetWin = mLastWin; - boolean targetIsNew = targetWin == null; - if (DEBUG_INPUT) Slog.v( - TAG, "waitForLastKey: mFinished=" + mFinished + - ", mLastWin=" + mLastWin); - if (targetIsNew) { - Object target = findTargetWindow(nextKey, qev, nextMotion, - isPointerEvent, callingPid, callingUid); - if (target == SKIP_TARGET_TOKEN) { - // The user has pressed a special key, and we are - // dropping all pending events before it. - if (DEBUG_INPUT) Slog.v(TAG, "Skipping: " + nextKey - + " " + nextMotion); - return null; - } - if (target == CONSUMED_EVENT_TOKEN) { - if (DEBUG_INPUT) Slog.v(TAG, "Consumed: " + nextKey - + " " + nextMotion); - return target; - } - targetWin = (WindowState)target; - } - - AppWindowToken targetApp = null; - - // Now: is it okay to send the next event to this window? - synchronized (this) { - // First: did we come here based on the last window not - // being null, but it changed by the time we got here? - // If so, try again. - if (!targetIsNew && mLastWin == null) { - continue; - } - - // We never dispatch events if not finished with the - // last one, or the display is frozen. - if (mFinished && !mDisplayFrozen) { - // If event dispatching is disabled, then we - // just consume the events. - if (!mEventDispatching) { - if (DEBUG_INPUT) Slog.v(TAG, - "Skipping event; dispatching disabled: " - + nextKey + " " + nextMotion); - return null; - } - if (targetWin != null) { - // If this is a new target, and that target is not - // paused or unresponsive, then all looks good to - // handle the event. - if (targetIsNew && !targetWin.mToken.paused) { - return targetWin; - } - - // If we didn't find a target window, and there is no - // focused app window, then just eat the events. - } else if (mFocusedApp == null) { - if (DEBUG_INPUT) Slog.v(TAG, - "Skipping event; no focused app: " - + nextKey + " " + nextMotion); - return null; - } - } - - if (DEBUG_INPUT) Slog.v( - TAG, "Waiting for last key in " + mLastBinder - + " target=" + targetWin - + " mFinished=" + mFinished - + " mDisplayFrozen=" + mDisplayFrozen - + " targetIsNew=" + targetIsNew - + " paused=" - + (targetWin != null ? targetWin.mToken.paused : false) - + " mFocusedApp=" + mFocusedApp - + " mCurrentFocus=" + mCurrentFocus); - - targetApp = targetWin != null - ? targetWin.mAppToken : mFocusedApp; - - long curTimeout = keyDispatchingTimeout; - if (mTimeToSwitch != 0) { - long now = SystemClock.uptimeMillis(); - if (mTimeToSwitch <= now) { - // If an app switch key has been pressed, and we have - // waited too long for the current app to finish - // processing keys, then wait no more! - doFinishedKeyLocked(false); - continue; - } - long switchTimeout = mTimeToSwitch - now; - if (curTimeout > switchTimeout) { - curTimeout = switchTimeout; - } - } - - try { - // after that continue - // processing keys, so we don't get stuck. - if (DEBUG_INPUT) Slog.v( - TAG, "Waiting for key dispatch: " + curTimeout); - wait(curTimeout); - if (DEBUG_INPUT) Slog.v(TAG, "Finished waiting @" - + SystemClock.uptimeMillis() + " startTime=" - + startTime + " switchTime=" + mTimeToSwitch - + " target=" + targetWin + " mLW=" + mLastWin - + " mLB=" + mLastBinder + " fin=" + mFinished - + " mCurrentFocus=" + mCurrentFocus); - } catch (InterruptedException e) { - } - } - - // If we were frozen during configuration change, restart the - // timeout checks from now; otherwise look at whether we timed - // out before awakening. - if (mWasFrozen) { - waitedFor = 0; - mWasFrozen = false; - } else { - waitedFor = SystemClock.uptimeMillis() - startTime; - } - - if (waitedFor >= keyDispatchingTimeout && mTimeToSwitch == 0) { - IApplicationToken at = null; - synchronized (this) { - Slog.w(TAG, "Key dispatching timed out sending to " + - (targetWin != null ? targetWin.mAttrs.getTitle() - : "<null>: no window ready for key dispatch")); - // NOSHIP debugging - Slog.w(TAG, "Previous dispatch state: " + mDispatchState); - Slog.w(TAG, "Current dispatch state: " + - new DispatchState(nextKey, targetWin)); - // END NOSHIP - //dump(); - if (targetWin != null) { - at = targetWin.getAppToken(); - } else if (targetApp != null) { - at = targetApp.appToken; - } - } - - boolean abort = true; - if (at != null) { - try { - long timeout = at.getKeyDispatchingTimeout(); - if (timeout > waitedFor) { - // we did not wait the proper amount of time for this application. - // set the timeout to be the real timeout and wait again. - keyDispatchingTimeout = timeout - waitedFor; - continue; - } else { - abort = at.keyDispatchingTimedOut(); - } - } catch (RemoteException ex) { - } - } - - synchronized (this) { - if (abort && (mLastWin == targetWin || targetWin == null)) { - mFinished = true; - if (mLastWin != null) { - if (DEBUG_INPUT) Slog.v(TAG, - "Window " + mLastWin + - " timed out on key input"); - if (mLastWin.mToken.paused) { - Slog.w(TAG, "Un-pausing dispatching to this window"); - mLastWin.mToken.paused = false; - } - } - if (mMotionTarget == targetWin) { - mMotionTarget = null; - } - mLastWin = null; - mLastBinder = null; - if (failIfTimeout || targetWin == null) { - return null; - } - } else { - Slog.w(TAG, "Continuing to wait for key to be dispatched"); - startTime = SystemClock.uptimeMillis(); - } - } - } - } - } - - Object findTargetWindow(KeyEvent nextKey, QueuedEvent qev, - MotionEvent nextMotion, boolean isPointerEvent, - int callingPid, int callingUid) { - mOutsideTouchTargets = null; - - if (nextKey != null) { - // Find the target window for a normal key event. - final int keycode = nextKey.getKeyCode(); - final int repeatCount = nextKey.getRepeatCount(); - final boolean down = nextKey.getAction() != KeyEvent.ACTION_UP; - boolean dispatch = mKeyWaiter.checkShouldDispatchKey(keycode); - - if (!dispatch) { - if (callingUid == 0 || - mContext.checkPermission( - android.Manifest.permission.INJECT_EVENTS, - callingPid, callingUid) - == PackageManager.PERMISSION_GRANTED) { - mPolicy.interceptKeyTi(null, keycode, - nextKey.getMetaState(), down, repeatCount, - nextKey.getFlags()); - } - Slog.w(TAG, "Event timeout during app switch: dropping " - + nextKey); - return SKIP_TARGET_TOKEN; - } - - // System.out.println("##### [" + SystemClock.uptimeMillis() + "] WindowManagerService.dispatchKey(" + keycode + ", " + down + ", " + repeatCount + ")"); - - WindowState focus = null; - synchronized(mWindowMap) { - focus = getFocusedWindowLocked(); - } - - wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT); - - if (callingUid == 0 || - (focus != null && callingUid == focus.mSession.mUid) || - mContext.checkPermission( - android.Manifest.permission.INJECT_EVENTS, - callingPid, callingUid) - == PackageManager.PERMISSION_GRANTED) { - if (mPolicy.interceptKeyTi(focus, - keycode, nextKey.getMetaState(), down, repeatCount, - nextKey.getFlags())) { - return CONSUMED_EVENT_TOKEN; - } - } - - return focus; - - } else if (!isPointerEvent) { - boolean dispatch = mKeyWaiter.checkShouldDispatchKey(-1); - if (!dispatch) { - Slog.w(TAG, "Event timeout during app switch: dropping trackball " - + nextMotion); - return SKIP_TARGET_TOKEN; - } - - WindowState focus = null; - synchronized(mWindowMap) { - focus = getFocusedWindowLocked(); - } - - wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT); - return focus; - } - - if (nextMotion == null) { - return SKIP_TARGET_TOKEN; - } - - boolean dispatch = mKeyWaiter.checkShouldDispatchKey( - KeyEvent.KEYCODE_UNKNOWN); - if (!dispatch) { - Slog.w(TAG, "Event timeout during app switch: dropping pointer " - + nextMotion); - return SKIP_TARGET_TOKEN; - } - - // Find the target window for a pointer event. - int action = nextMotion.getAction(); - final float xf = nextMotion.getX(); - final float yf = nextMotion.getY(); - final long eventTime = nextMotion.getEventTime(); - - final boolean screenWasOff = qev != null - && (qev.flags&WindowManagerPolicy.FLAG_BRIGHT_HERE) != 0; - - WindowState target = null; - - synchronized(mWindowMap) { - synchronized (this) { - if (action == MotionEvent.ACTION_DOWN) { - if (mMotionTarget != null) { - // this is weird, we got a pen down, but we thought it was - // already down! - // XXX: We should probably send an ACTION_UP to the current - // target. - Slog.w(TAG, "Pointer down received while already down in: " - + mMotionTarget); - mMotionTarget = null; - } - - // ACTION_DOWN is special, because we need to lock next events to - // the window we'll land onto. - final int x = (int)xf; - final int y = (int)yf; - - final ArrayList windows = mWindows; - final int N = windows.size(); - WindowState topErrWindow = null; - final Rect tmpRect = mTempRect; - for (int i=N-1; i>=0; i--) { - WindowState child = (WindowState)windows.get(i); - //Slog.i(TAG, "Checking dispatch to: " + child); - final int flags = child.mAttrs.flags; - if ((flags & WindowManager.LayoutParams.FLAG_SYSTEM_ERROR) != 0) { - if (topErrWindow == null) { - topErrWindow = child; - } - } - if (!child.isVisibleLw()) { - //Slog.i(TAG, "Not visible!"); - continue; - } - if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) { - //Slog.i(TAG, "Not touchable!"); - if ((flags & WindowManager.LayoutParams - .FLAG_WATCH_OUTSIDE_TOUCH) != 0) { - child.mNextOutsideTouch = mOutsideTouchTargets; - mOutsideTouchTargets = child; - } - continue; - } - tmpRect.set(child.mFrame); - if (child.mTouchableInsets == ViewTreeObserver - .InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT) { - // The touch is inside of the window if it is - // inside the frame, AND the content part of that - // frame that was given by the application. - tmpRect.left += child.mGivenContentInsets.left; - tmpRect.top += child.mGivenContentInsets.top; - tmpRect.right -= child.mGivenContentInsets.right; - tmpRect.bottom -= child.mGivenContentInsets.bottom; - } else if (child.mTouchableInsets == ViewTreeObserver - .InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE) { - // The touch is inside of the window if it is - // inside the frame, AND the visible part of that - // frame that was given by the application. - tmpRect.left += child.mGivenVisibleInsets.left; - tmpRect.top += child.mGivenVisibleInsets.top; - tmpRect.right -= child.mGivenVisibleInsets.right; - tmpRect.bottom -= child.mGivenVisibleInsets.bottom; - } - final int touchFlags = flags & - (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE - |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); - if (tmpRect.contains(x, y) || touchFlags == 0) { - //Slog.i(TAG, "Using this target!"); - if (!screenWasOff || (flags & - WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING) != 0) { - mMotionTarget = child; - } else { - //Slog.i(TAG, "Waking, skip!"); - mMotionTarget = null; - } - break; - } - - if ((flags & WindowManager.LayoutParams - .FLAG_WATCH_OUTSIDE_TOUCH) != 0) { - child.mNextOutsideTouch = mOutsideTouchTargets; - mOutsideTouchTargets = child; - //Slog.i(TAG, "Adding to outside target list: " + child); - } - } - - // if there's an error window but it's not accepting - // focus (typically because it is not yet visible) just - // wait for it -- any other focused window may in fact - // be in ANR state. - if (topErrWindow != null && mMotionTarget != topErrWindow) { - mMotionTarget = null; - } - } - - target = mMotionTarget; - } - } - - wakeupIfNeeded(target, eventType(nextMotion)); - - // Pointer events are a little different -- if there isn't a - // target found for any event, then just drop it. - return target != null ? target : SKIP_TARGET_TOKEN; - } - - boolean checkShouldDispatchKey(int keycode) { - synchronized (this) { - if (mPolicy.isAppSwitchKeyTqTiLwLi(keycode)) { - mTimeToSwitch = 0; - return true; - } - if (mTimeToSwitch != 0 - && mTimeToSwitch < SystemClock.uptimeMillis()) { - return false; - } - return true; - } - } - - void bindTargetWindowLocked(WindowState win, - int pendingWhat, QueuedEvent pendingMotion) { - synchronized (this) { - bindTargetWindowLockedLocked(win, pendingWhat, pendingMotion); - } - } - - void bindTargetWindowLocked(WindowState win) { - synchronized (this) { - bindTargetWindowLockedLocked(win, RETURN_NOTHING, null); - } - } - - void bindTargetWindowLockedLocked(WindowState win, - int pendingWhat, QueuedEvent pendingMotion) { - mLastWin = win; - mLastBinder = win.mClient.asBinder(); - mFinished = false; - if (pendingMotion != null) { - final Session s = win.mSession; - if (pendingWhat == RETURN_PENDING_POINTER) { - releasePendingPointerLocked(s); - s.mPendingPointerMove = pendingMotion; - s.mPendingPointerWindow = win; - if (DEBUG_INPUT) Slog.v(TAG, - "bindTargetToWindow " + s.mPendingPointerMove); - } else if (pendingWhat == RETURN_PENDING_TRACKBALL) { - releasePendingTrackballLocked(s); - s.mPendingTrackballMove = pendingMotion; - s.mPendingTrackballWindow = win; - } - } - } - - void releasePendingPointerLocked(Session s) { - if (DEBUG_INPUT) Slog.v(TAG, - "releasePendingPointer " + s.mPendingPointerMove); - if (s.mPendingPointerMove != null) { - mQueue.recycleEvent(s.mPendingPointerMove); - s.mPendingPointerMove = null; - } - } - - void releasePendingTrackballLocked(Session s) { - if (s.mPendingTrackballMove != null) { - mQueue.recycleEvent(s.mPendingTrackballMove); - s.mPendingTrackballMove = null; - } - } - - MotionEvent finishedKey(Session session, IWindow client, boolean force, - int returnWhat) { - if (DEBUG_INPUT) Slog.v( - TAG, "finishedKey: client=" + client + ", force=" + force); - - if (client == null) { - return null; - } - - MotionEvent res = null; - QueuedEvent qev = null; - WindowState win = null; - - synchronized (this) { - if (DEBUG_INPUT) Slog.v( - TAG, "finishedKey: client=" + client.asBinder() - + ", force=" + force + ", last=" + mLastBinder - + " (token=" + (mLastWin != null ? mLastWin.mToken : null) + ")"); - - if (returnWhat == RETURN_PENDING_POINTER) { - qev = session.mPendingPointerMove; - win = session.mPendingPointerWindow; - session.mPendingPointerMove = null; - session.mPendingPointerWindow = null; - } else if (returnWhat == RETURN_PENDING_TRACKBALL) { - qev = session.mPendingTrackballMove; - win = session.mPendingTrackballWindow; - session.mPendingTrackballMove = null; - session.mPendingTrackballWindow = null; - } - - if (mLastBinder == client.asBinder()) { - if (DEBUG_INPUT) Slog.v( - TAG, "finishedKey: last paused=" - + ((mLastWin != null) ? mLastWin.mToken.paused : "null")); - if (mLastWin != null && (!mLastWin.mToken.paused || force - || !mEventDispatching)) { - doFinishedKeyLocked(true); - } else { - // Make sure to wake up anyone currently waiting to - // dispatch a key, so they can re-evaluate their - // current situation. - mFinished = true; - notifyAll(); - } - } - - if (qev != null) { - res = (MotionEvent)qev.event; - if (DEBUG_INPUT) Slog.v(TAG, - "Returning pending motion: " + res); - mQueue.recycleEvent(qev); - if (win != null && returnWhat == RETURN_PENDING_POINTER) { - res.offsetLocation(-win.mFrame.left, -win.mFrame.top); - } - } - } - - if (res != null && returnWhat == RETURN_PENDING_POINTER) { - synchronized (mWindowMap) { - dispatchPointerElsewhereLocked(win, win, res, res.getEventTime(), false); - } - } - - return res; - } - - void tickle() { - synchronized (this) { - notifyAll(); - } - } - - void handleNewWindowLocked(WindowState newWindow) { - if (!newWindow.canReceiveKeys()) { - return; - } - synchronized (this) { - if (DEBUG_INPUT) Slog.v( - TAG, "New key dispatch window: win=" - + newWindow.mClient.asBinder() - + ", last=" + mLastBinder - + " (token=" + (mLastWin != null ? mLastWin.mToken : null) - + "), finished=" + mFinished + ", paused=" - + newWindow.mToken.paused); - - // Displaying a window implicitly causes dispatching to - // be unpaused. (This is to protect against bugs if someone - // pauses dispatching but forgets to resume.) - newWindow.mToken.paused = false; - - mGotFirstWindow = true; - - if ((newWindow.mAttrs.flags & FLAG_SYSTEM_ERROR) != 0) { - if (DEBUG_INPUT) Slog.v(TAG, - "New SYSTEM_ERROR window; resetting state"); - mLastWin = null; - mLastBinder = null; - mMotionTarget = null; - mFinished = true; - } else if (mLastWin != null) { - // If the new window is above the window we are - // waiting on, then stop waiting and let key dispatching - // start on the new guy. - if (DEBUG_INPUT) Slog.v( - TAG, "Last win layer=" + mLastWin.mLayer - + ", new win layer=" + newWindow.mLayer); - if (newWindow.mLayer >= mLastWin.mLayer) { - // The new window is above the old; finish pending input to the last - // window and start directing it to the new one. - mLastWin.mToken.paused = false; - doFinishedKeyLocked(false); // does a notifyAll() - return; - } - } - - // Now that we've put a new window state in place, make the event waiter - // take notice and retarget its attentions. - notifyAll(); - } - } - - void pauseDispatchingLocked(WindowToken token) { - synchronized (this) - { - if (DEBUG_INPUT) Slog.v(TAG, "Pausing WindowToken " + token); - token.paused = true; - - /* - if (mLastWin != null && !mFinished && mLastWin.mBaseLayer <= layer) { - mPaused = true; - } else { - if (mLastWin == null) { - Slog.i(TAG, "Key dispatching not paused: no last window."); - } else if (mFinished) { - Slog.i(TAG, "Key dispatching not paused: finished last key."); - } else { - Slog.i(TAG, "Key dispatching not paused: window in higher layer."); - } - } - */ - } - } - - void resumeDispatchingLocked(WindowToken token) { - synchronized (this) { - if (token.paused) { - if (DEBUG_INPUT) Slog.v( - TAG, "Resuming WindowToken " + token - + ", last=" + mLastBinder - + " (token=" + (mLastWin != null ? mLastWin.mToken : null) - + "), finished=" + mFinished + ", paused=" - + token.paused); - token.paused = false; - if (mLastWin != null && mLastWin.mToken == token && mFinished) { - doFinishedKeyLocked(false); - } else { - notifyAll(); - } - } - } - } - - void setEventDispatchingLocked(boolean enabled) { - synchronized (this) { - mEventDispatching = enabled; - notifyAll(); - } - } - - void appSwitchComing() { - synchronized (this) { - // Don't wait for more than .5 seconds for app to finish - // processing the pending events. - long now = SystemClock.uptimeMillis() + 500; - if (DEBUG_INPUT) Slog.v(TAG, "appSwitchComing: " + now); - if (mTimeToSwitch == 0 || now < mTimeToSwitch) { - mTimeToSwitch = now; - } - notifyAll(); - } - } - - private final void doFinishedKeyLocked(boolean force) { - if (mLastWin != null) { - releasePendingPointerLocked(mLastWin.mSession); - releasePendingTrackballLocked(mLastWin.mSession); - } - - if (force || mLastWin == null || !mLastWin.mToken.paused - || !mLastWin.isVisibleLw()) { - // If the current window has been paused, we aren't -really- - // finished... so let the waiters still wait. - mLastWin = null; - mLastBinder = null; - } - mFinished = true; - notifyAll(); - } - } - - private class KeyQ extends KeyInputQueue - implements KeyInputQueue.FilterCallback { - KeyQ() { - super(mContext, WindowManagerService.this); - } - - @Override - boolean preprocessEvent(InputDevice device, RawInputEvent event) { - if (mPolicy.preprocessInputEventTq(event)) { - return true; - } - - switch (event.type) { - case RawInputEvent.EV_KEY: { - // XXX begin hack - if (DEBUG) { - if (event.keycode == KeyEvent.KEYCODE_G) { - if (event.value != 0) { - // G down - mPolicy.screenTurnedOff(WindowManagerPolicy.OFF_BECAUSE_OF_USER); - } - return false; - } - if (event.keycode == KeyEvent.KEYCODE_D) { - if (event.value != 0) { - //dump(); - } - return false; - } - } - // XXX end hack - - boolean screenIsOff = !mPowerManager.isScreenOn(); - boolean screenIsDim = !mPowerManager.isScreenBright(); - int actions = mPolicy.interceptKeyTq(event, !screenIsOff); - - if ((actions & WindowManagerPolicy.ACTION_GO_TO_SLEEP) != 0) { - mPowerManager.goToSleep(event.when); - } - - if (screenIsOff) { - event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE; - } - if (screenIsDim) { - event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE; - } - if ((actions & WindowManagerPolicy.ACTION_POKE_USER_ACTIVITY) != 0) { - mPowerManager.userActivity(event.when, false, - LocalPowerManager.BUTTON_EVENT, false); - } - - if ((actions & WindowManagerPolicy.ACTION_PASS_TO_USER) != 0) { - if (event.value != 0 && mPolicy.isAppSwitchKeyTqTiLwLi(event.keycode)) { - filterQueue(this); - mKeyWaiter.appSwitchComing(); - } - return true; - } else { - return false; - } - } - - case RawInputEvent.EV_REL: { - boolean screenIsOff = !mPowerManager.isScreenOn(); - boolean screenIsDim = !mPowerManager.isScreenBright(); - if (screenIsOff) { - if (!mPolicy.isWakeRelMovementTq(event.deviceId, - device.classes, event)) { - //Slog.i(TAG, "dropping because screenIsOff and !isWakeKey"); - return false; - } - event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE; - } - if (screenIsDim) { - event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE; - } - return true; - } - - case RawInputEvent.EV_ABS: { - boolean screenIsOff = !mPowerManager.isScreenOn(); - boolean screenIsDim = !mPowerManager.isScreenBright(); - if (screenIsOff) { - if (!mPolicy.isWakeAbsMovementTq(event.deviceId, - device.classes, event)) { - //Slog.i(TAG, "dropping because screenIsOff and !isWakeKey"); - return false; - } - event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE; - } - if (screenIsDim) { - event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE; - } - return true; - } - - default: - return true; - } - } - - public int filterEvent(QueuedEvent ev) { - switch (ev.classType) { - case RawInputEvent.CLASS_KEYBOARD: - KeyEvent ke = (KeyEvent)ev.event; - if (mPolicy.isMovementKeyTi(ke.getKeyCode())) { - Slog.w(TAG, "Dropping movement key during app switch: " - + ke.getKeyCode() + ", action=" + ke.getAction()); - return FILTER_REMOVE; - } - return FILTER_ABORT; - default: - return FILTER_KEEP; - } - } - } - public boolean detectSafeMode() { mSafeMode = mPolicy.detectSafeMode(); return mSafeMode; @@ -7003,219 +5444,6 @@ public class WindowManagerService extends IWindowManager.Stub mPolicy.systemReady(); } - private final class InputDispatcherThread extends Thread { - // Time to wait when there is nothing to do: 9999 seconds. - static final int LONG_WAIT=9999*1000; - - public InputDispatcherThread() { - super("InputDispatcher"); - } - - @Override - public void run() { - while (true) { - try { - process(); - } catch (Exception e) { - Slog.e(TAG, "Exception in input dispatcher", e); - } - } - } - - private void process() { - android.os.Process.setThreadPriority( - android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY); - - // The last key event we saw - KeyEvent lastKey = null; - - // Last keydown time for auto-repeating keys - long lastKeyTime = SystemClock.uptimeMillis(); - long nextKeyTime = lastKeyTime+LONG_WAIT; - long downTime = 0; - - // How many successive repeats we generated - int keyRepeatCount = 0; - - // Need to report that configuration has changed? - boolean configChanged = false; - - while (true) { - long curTime = SystemClock.uptimeMillis(); - - if (DEBUG_INPUT) Slog.v( - TAG, "Waiting for next key: now=" + curTime - + ", repeat @ " + nextKeyTime); - - // Retrieve next event, waiting only as long as the next - // repeat timeout. If the configuration has changed, then - // don't wait at all -- we'll report the change as soon as - // we have processed all events. - QueuedEvent ev = mQueue.getEvent( - (int)((!configChanged && curTime < nextKeyTime) - ? (nextKeyTime-curTime) : 0)); - - if (DEBUG_INPUT && ev != null) Slog.v( - TAG, "Event: type=" + ev.classType + " data=" + ev.event); - - if (MEASURE_LATENCY) { - lt.sample("2 got event ", System.nanoTime() - ev.whenNano); - } - - if (lastKey != null && !mPolicy.allowKeyRepeat()) { - // cancel key repeat at the request of the policy. - lastKey = null; - downTime = 0; - lastKeyTime = curTime; - nextKeyTime = curTime + LONG_WAIT; - } - try { - if (ev != null) { - curTime = SystemClock.uptimeMillis(); - int eventType; - if (ev.classType == RawInputEvent.CLASS_TOUCHSCREEN) { - eventType = eventType((MotionEvent)ev.event); - } else if (ev.classType == RawInputEvent.CLASS_KEYBOARD || - ev.classType == RawInputEvent.CLASS_TRACKBALL) { - eventType = LocalPowerManager.BUTTON_EVENT; - } else { - eventType = LocalPowerManager.OTHER_EVENT; - } - try { - if ((curTime - mLastBatteryStatsCallTime) - >= MIN_TIME_BETWEEN_USERACTIVITIES) { - mLastBatteryStatsCallTime = curTime; - mBatteryStats.noteInputEvent(); - } - } catch (RemoteException e) { - // Ignore - } - - if (ev.classType == RawInputEvent.CLASS_CONFIGURATION_CHANGED) { - // do not wake screen in this case - } else if (eventType != TOUCH_EVENT - && eventType != LONG_TOUCH_EVENT - && eventType != CHEEK_EVENT) { - mPowerManager.userActivity(curTime, false, - eventType, false); - } else if (mLastTouchEventType != eventType - || (curTime - mLastUserActivityCallTime) - >= MIN_TIME_BETWEEN_USERACTIVITIES) { - mLastUserActivityCallTime = curTime; - mLastTouchEventType = eventType; - mPowerManager.userActivity(curTime, false, - eventType, false); - } - - switch (ev.classType) { - case RawInputEvent.CLASS_KEYBOARD: - KeyEvent ke = (KeyEvent)ev.event; - if (ke.isDown()) { - lastKeyTime = curTime; - if (lastKey != null && - ke.getKeyCode() == lastKey.getKeyCode()) { - keyRepeatCount++; - // Arbitrary long timeout to block - // repeating here since we know that - // the device driver takes care of it. - nextKeyTime = lastKeyTime + LONG_WAIT; - if (DEBUG_INPUT) Slog.v( - TAG, "Received repeated key down"); - } else { - downTime = curTime; - keyRepeatCount = 0; - nextKeyTime = lastKeyTime - + ViewConfiguration.getLongPressTimeout(); - if (DEBUG_INPUT) Slog.v( - TAG, "Received key down: first repeat @ " - + nextKeyTime); - } - lastKey = ke; - } else { - lastKey = null; - downTime = 0; - keyRepeatCount = 0; - // Arbitrary long timeout. - lastKeyTime = curTime; - nextKeyTime = curTime + LONG_WAIT; - if (DEBUG_INPUT) Slog.v( - TAG, "Received key up: ignore repeat @ " - + nextKeyTime); - } - if (keyRepeatCount > 0) { - dispatchKey(KeyEvent.changeTimeRepeat(ke, - ke.getEventTime(), keyRepeatCount), 0, 0); - } else { - dispatchKey(ke, 0, 0); - } - mQueue.recycleEvent(ev); - break; - case RawInputEvent.CLASS_TOUCHSCREEN: - //Slog.i(TAG, "Read next event " + ev); - dispatchPointer(ev, (MotionEvent)ev.event, 0, 0); - break; - case RawInputEvent.CLASS_TRACKBALL: - dispatchTrackball(ev, (MotionEvent)ev.event, 0, 0); - break; - case RawInputEvent.CLASS_CONFIGURATION_CHANGED: - configChanged = true; - break; - default: - mQueue.recycleEvent(ev); - break; - } - - } else if (configChanged) { - configChanged = false; - sendNewConfiguration(); - - } else if (lastKey != null) { - curTime = SystemClock.uptimeMillis(); - - // Timeout occurred while key was down. If it is at or - // past the key repeat time, dispatch the repeat. - if (DEBUG_INPUT) Slog.v( - TAG, "Key timeout: repeat=" + nextKeyTime - + ", now=" + curTime); - if (curTime < nextKeyTime) { - continue; - } - - lastKeyTime = nextKeyTime; - nextKeyTime = nextKeyTime + KEY_REPEAT_DELAY; - keyRepeatCount++; - if (DEBUG_INPUT) Slog.v( - TAG, "Key repeat: count=" + keyRepeatCount - + ", next @ " + nextKeyTime); - KeyEvent newEvent; - if (downTime != 0 && (downTime - + ViewConfiguration.getLongPressTimeout()) - <= curTime) { - newEvent = KeyEvent.changeTimeRepeat(lastKey, - curTime, keyRepeatCount, - lastKey.getFlags() | KeyEvent.FLAG_LONG_PRESS); - downTime = 0; - } else { - newEvent = KeyEvent.changeTimeRepeat(lastKey, - curTime, keyRepeatCount); - } - dispatchKey(newEvent, 0, 0); - - } else { - curTime = SystemClock.uptimeMillis(); - - lastKeyTime = curTime; - nextKeyTime = curTime + LONG_WAIT; - } - - } catch (Exception e) { - Slog.e(TAG, - "Input thread received uncaught exception: " + e, e); - } - } - } - } - // ------------------------------------------------------------- // Client Session State // ------------------------------------------------------------- @@ -7231,20 +5459,6 @@ public class WindowManagerService extends IWindowManager.Stub int mNumWindow = 0; boolean mClientDead = false; - /** - * Current pointer move event being dispatched to client window... must - * hold key lock to access. - */ - QueuedEvent mPendingPointerMove; - WindowState mPendingPointerWindow; - - /** - * Current trackball move event being dispatched to client window... must - * hold key lock to access. - */ - QueuedEvent mPendingTrackballMove; - WindowState mPendingTrackballWindow; - public Session(IInputMethodClient client, IInputContext inputContext) { mClient = client; mInputContext = inputContext; @@ -7363,36 +5577,6 @@ public class WindowManagerService extends IWindowManager.Stub finishDrawingWindow(this, window); } - public void finishKey(IWindow window) { - if (localLOGV) Slog.v( - TAG, "IWindow finishKey called for " + window); - if (ENABLE_NATIVE_INPUT_DISPATCH) { - throw new IllegalStateException("Should not be called anymore."); - } - mKeyWaiter.finishedKey(this, window, false, - KeyWaiter.RETURN_NOTHING); - } - - public MotionEvent getPendingPointerMove(IWindow window) { - if (localLOGV) Slog.v( - TAG, "IWindow getPendingMotionEvent called for " + window); - if (ENABLE_NATIVE_INPUT_DISPATCH) { - throw new IllegalStateException("Should not be called anymore."); - } - return mKeyWaiter.finishedKey(this, window, false, - KeyWaiter.RETURN_PENDING_POINTER); - } - - public MotionEvent getPendingTrackballMove(IWindow window) { - if (localLOGV) Slog.v( - TAG, "IWindow getPendingMotionEvent called for " + window); - if (ENABLE_NATIVE_INPUT_DISPATCH) { - throw new IllegalStateException("Should not be called anymore."); - } - return mKeyWaiter.finishedKey(this, window, false, - KeyWaiter.RETURN_PENDING_TRACKBALL); - } - public void setInTouchMode(boolean mode) { synchronized(mWindowMap) { mInTouchMode = mode; @@ -7496,16 +5680,6 @@ public class WindowManagerService extends IWindowManager.Stub pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow); pw.print(" mClientDead="); pw.print(mClientDead); pw.print(" mSurfaceSession="); pw.println(mSurfaceSession); - if (mPendingPointerWindow != null || mPendingPointerMove != null) { - pw.print(prefix); - pw.print("mPendingPointerWindow="); pw.print(mPendingPointerWindow); - pw.print(" mPendingPointerMove="); pw.println(mPendingPointerMove); - } - if (mPendingTrackballWindow != null || mPendingTrackballMove != null) { - pw.print(prefix); - pw.print("mPendingTrackballWindow="); pw.print(mPendingTrackballWindow); - pw.print(" mPendingTrackballMove="); pw.println(mPendingTrackballMove); - } } @Override @@ -7556,8 +5730,6 @@ public class WindowManagerService extends IWindowManager.Stub boolean mObscured; boolean mTurnOnScreen; - WindowState mNextOutsideTouch; - int mLayoutSeq = -1; Configuration mConfiguration = null; @@ -8074,16 +6246,6 @@ public class WindowManagerService extends IWindowManager.Stub } void destroySurfaceLocked() { - // Window is no longer on-screen, so can no longer receive - // key events... if we were waiting for it to finish - // handling a key event, the wait is over! - if (! ENABLE_NATIVE_INPUT_DISPATCH) { - mKeyWaiter.finishedKey(mSession, mClient, true, - KeyWaiter.RETURN_NOTHING); - mKeyWaiter.releasePendingPointerLocked(mSession); - mKeyWaiter.releasePendingTrackballLocked(mSession); - } - if (mAppToken != null && this == mAppToken.startingWindow) { mAppToken.startingDisplayed = false; } @@ -8099,9 +6261,7 @@ public class WindowManagerService extends IWindowManager.Stub WindowState c = (WindowState)mChildWindows.get(i); c.mAttachedHidden = true; - if (ENABLE_NATIVE_INPUT_DISPATCH) { - mInputMonitor.windowIsBecomingInvisibleLw(c); - } + mInputMonitor.windowIsBecomingInvisibleLw(c); } if (mReportDestroySurface) { @@ -8410,12 +6570,8 @@ public class WindowManagerService extends IWindowManager.Stub } mLastHidden = true; - if (ENABLE_NATIVE_INPUT_DISPATCH) { - for (int i=0; i<N; i++) { - mInputMonitor.windowIsBecomingInvisibleLw((WindowState)mChildWindows.get(i)); - } - } else { - mKeyWaiter.releasePendingPointerLocked(mSession); + for (int i=0; i<N; i++) { + mInputMonitor.windowIsBecomingInvisibleLw((WindowState)mChildWindows.get(i)); } } mExiting = false; @@ -8752,13 +6908,11 @@ public class WindowManagerService extends IWindowManager.Stub // we are doing this as part of processing a death note.) } - if (ENABLE_NATIVE_INPUT_DISPATCH) { - if (mInputChannel != null) { - mInputManager.unregisterInputChannel(mInputChannel); - - mInputChannel.dispose(); - mInputChannel = null; - } + if (mInputChannel != null) { + mInputManager.unregisterInputChannel(mInputChannel); + + mInputChannel.dispose(); + mInputChannel = null; } } @@ -10174,9 +8328,7 @@ public class WindowManagerService extends IWindowManager.Stub } // Window frames may have changed. Tell the input dispatcher about it. - if (ENABLE_NATIVE_INPUT_DISPATCH) { - mInputMonitor.updateInputWindowsLw(); - } + mInputMonitor.updateInputWindowsLw(); return mPolicy.finishLayoutLw(); } @@ -10977,11 +9129,7 @@ public class WindowManagerService extends IWindowManager.Stub Slog.w(TAG, "Exception hiding surface in " + w); } } - if (ENABLE_NATIVE_INPUT_DISPATCH) { - mInputMonitor.windowIsBecomingInvisibleLw(w); - } else { - mKeyWaiter.releasePendingPointerLocked(w.mSession); - } + mInputMonitor.windowIsBecomingInvisibleLw(w); } // If we are waiting for this window to handle an // orientation change, well, it is hidden, so @@ -11583,13 +9731,7 @@ public class WindowManagerService extends IWindowManager.Stub } private void finishUpdateFocusedWindowAfterAssignLayersLocked() { - if (ENABLE_NATIVE_INPUT_DISPATCH) { - mInputMonitor.setInputFocusLw(mCurrentFocus); - } else { - if (mCurrentFocus != null) { - mKeyWaiter.handleNewWindowLocked(mCurrentFocus); - } - } + mInputMonitor.setInputFocusLw(mCurrentFocus); } private WindowState computeFocusedWindowLocked() { @@ -11663,17 +9805,6 @@ public class WindowManagerService extends IWindowManager.Stub private void startFreezingDisplayLocked() { if (mDisplayFrozen) { - // Freezing the display also suspends key event delivery, to - // keep events from going astray while the display is reconfigured. - // If someone has changed orientation again while the screen is - // still frozen, the events will continue to be blocked while the - // successive orientation change is processed. To prevent spurious - // ANRs, we reset the event dispatch timeout in this case. - if (! ENABLE_NATIVE_INPUT_DISPATCH) { - synchronized (mKeyWaiter) { - mKeyWaiter.mWasFrozen = true; - } - } return; } @@ -11696,9 +9827,7 @@ public class WindowManagerService extends IWindowManager.Stub mDisplayFrozen = true; - if (ENABLE_NATIVE_INPUT_DISPATCH) { - mInputMonitor.freezeInputDispatchingLw(); - } + mInputMonitor.freezeInputDispatchingLw(); if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) { mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET; @@ -11731,16 +9860,7 @@ public class WindowManagerService extends IWindowManager.Stub } Surface.unfreezeDisplay(0); - // Reset the key delivery timeout on unfreeze, too. We force a wakeup here - // too because regular key delivery processing should resume immediately. - if (ENABLE_NATIVE_INPUT_DISPATCH) { - mInputMonitor.thawInputDispatchingLw(); - } else { - synchronized (mKeyWaiter) { - mKeyWaiter.mWasFrozen = true; - mKeyWaiter.notifyAll(); - } - } + mInputMonitor.thawInputDispatchingLw(); // While the display is frozen we don't re-compute the orientation // to avoid inconsistent states. However, something interesting @@ -11772,13 +9892,8 @@ public class WindowManagerService extends IWindowManager.Stub return; } - if (ENABLE_NATIVE_INPUT_DISPATCH) { - pw.println("Input Dispatcher State:"); - mInputManager.dump(pw); - } else { - pw.println("Input State:"); - mQueue.dump(pw, " "); - } + pw.println("Input Dispatcher State:"); + mInputManager.dump(pw); pw.println(" "); synchronized(mWindowMap) { @@ -11995,16 +10110,6 @@ public class WindowManagerService extends IWindowManager.Stub } pw.print(" DisplayWidth="); pw.print(mDisplay.getWidth()); pw.print(" DisplayHeight="); pw.println(mDisplay.getHeight()); - - if (! ENABLE_NATIVE_INPUT_DISPATCH) { - pw.println(" KeyWaiter state:"); - pw.print(" mLastWin="); pw.print(mKeyWaiter.mLastWin); - pw.print(" mLastBinder="); pw.println(mKeyWaiter.mLastBinder); - pw.print(" mFinished="); pw.print(mKeyWaiter.mFinished); - pw.print(" mGotFirstWindow="); pw.print(mKeyWaiter.mGotFirstWindow); - pw.print(" mEventDispatching="); pw.print(mKeyWaiter.mEventDispatching); - pw.print(" mTimeToSwitch="); pw.println(mKeyWaiter.mTimeToSwitch); - } } } @@ -12012,12 +10117,6 @@ public class WindowManagerService extends IWindowManager.Stub public void monitor() { synchronized (mWindowMap) { } synchronized (mKeyguardTokenWatcher) { } - synchronized (mKeyWaiter) { } - synchronized (mInputMonitor) { } - } - - public void virtualKeyFeedback(KeyEvent event) { - mPolicy.keyFeedbackFromInput(event); } /** |