@@ -158,7 +158,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
158158 static final boolean DEBUG = false ;
159159 static final boolean localLOGV = false ;
160160 static final boolean DEBUG_LAYOUT = false ;
161- static final boolean DEBUG_FALLBACK = false ;
161+ static final boolean DEBUG_INPUT = false ;
162162 static final boolean SHOW_STARTING_ANIMATIONS = true ;
163163 static final boolean SHOW_PROCESSES_ON_ALT_MENU = false ;
164164
@@ -504,13 +504,16 @@ public void onInputEvent(InputEvent event) {
504504
505505 ShortcutManager mShortcutManager ;
506506 PowerManager .WakeLock mBroadcastWakeLock ;
507+ boolean mHavePendingMediaKeyRepeatWithWakeLock ;
507508
508509 // Fallback actions by key code.
509510 private final SparseArray <KeyCharacterMap .FallbackAction > mFallbackActions =
510511 new SparseArray <KeyCharacterMap .FallbackAction >();
511512
512513 private static final int MSG_ENABLE_POINTER_LOCATION = 1 ;
513514 private static final int MSG_DISABLE_POINTER_LOCATION = 2 ;
515+ private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3 ;
516+ private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4 ;
514517
515518 private class PolicyHandler extends Handler {
516519 @ Override
@@ -522,6 +525,12 @@ public void handleMessage(Message msg) {
522525 case MSG_DISABLE_POINTER_LOCATION :
523526 disablePointerLocation ();
524527 break ;
528+ case MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK :
529+ dispatchMediaKeyWithWakeLock ((KeyEvent )msg .obj );
530+ break ;
531+ case MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK :
532+ dispatchMediaKeyRepeatWithWakeLock ((KeyEvent )msg .obj );
533+ break ;
525534 }
526535 }
527536 }
@@ -1692,7 +1701,7 @@ public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int p
16921701 final boolean down = event .getAction () == KeyEvent .ACTION_DOWN ;
16931702 final boolean canceled = event .isCanceled ();
16941703
1695- if (false ) {
1704+ if (DEBUG_INPUT ) {
16961705 Log .d (TAG , "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
16971706 + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed
16981707 + " canceled=" + canceled );
@@ -1942,7 +1951,7 @@ public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int p
19421951 @ Override
19431952 public KeyEvent dispatchUnhandledKey (WindowState win , KeyEvent event , int policyFlags ) {
19441953 // Note: This method is only called if the initial down was unhandled.
1945- if (DEBUG_FALLBACK ) {
1954+ if (DEBUG_INPUT ) {
19461955 Slog .d (TAG , "Unhandled key: win=" + win + ", action=" + event .getAction ()
19471956 + ", flags=" + event .getFlags ()
19481957 + ", keyCode=" + event .getKeyCode ()
@@ -1969,7 +1978,7 @@ public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policy
19691978 }
19701979
19711980 if (fallbackAction != null ) {
1972- if (DEBUG_FALLBACK ) {
1981+ if (DEBUG_INPUT ) {
19731982 Slog .d (TAG , "Fallback: keyCode=" + fallbackAction .keyCode
19741983 + " metaState=" + Integer .toHexString (fallbackAction .metaState ));
19751984 }
@@ -1996,7 +2005,7 @@ public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policy
19962005 }
19972006 }
19982007
1999- if (DEBUG_FALLBACK ) {
2008+ if (DEBUG_INPUT ) {
20002009 if (fallbackEvent == null ) {
20012010 Slog .d (TAG , "No fallback." );
20022011 } else {
@@ -3089,7 +3098,7 @@ public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean i
30893098 return 0 ;
30903099 }
30913100
3092- if (false ) {
3101+ if (DEBUG_INPUT ) {
30933102 Log .d (TAG , "interceptKeyTq keycode=" + keyCode
30943103 + " screenIsOn=" + isScreenOn + " keyguardActive=" + keyguardActive );
30953104 }
@@ -3311,8 +3320,13 @@ public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean i
33113320 // Only do this if we would otherwise not pass it to the user. In that
33123321 // case, the PhoneWindow class will do the same thing, except it will
33133322 // only do it if the showing app doesn't process the key on its own.
3323+ // Note that we need to make a copy of the key event here because the
3324+ // original key event will be recycled when we return.
33143325 mBroadcastWakeLock .acquire ();
3315- mHandler .post (new PassHeadsetKey (new KeyEvent (event )));
3326+ Message msg = mHandler .obtainMessage (MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK ,
3327+ new KeyEvent (event ));
3328+ msg .setAsynchronous (true );
3329+ msg .sendToTarget ();
33163330 }
33173331 break ;
33183332 }
@@ -3361,24 +3375,58 @@ public int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags) {
33613375 return result ;
33623376 }
33633377
3364- class PassHeadsetKey implements Runnable {
3365- KeyEvent mKeyEvent ;
3378+ void dispatchMediaKeyWithWakeLock (KeyEvent event ) {
3379+ if (DEBUG_INPUT ) {
3380+ Slog .d (TAG , "dispatchMediaKeyWithWakeLock: " + event );
3381+ }
3382+
3383+ if (mHavePendingMediaKeyRepeatWithWakeLock ) {
3384+ if (DEBUG_INPUT ) {
3385+ Slog .d (TAG , "dispatchMediaKeyWithWakeLock: canceled repeat" );
3386+ }
33663387
3367- PassHeadsetKey (KeyEvent keyEvent ) {
3368- mKeyEvent = keyEvent ;
3388+ mHandler .removeMessages (MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK );
3389+ mHavePendingMediaKeyRepeatWithWakeLock = false ;
3390+ mBroadcastWakeLock .release (); // pending repeat was holding onto the wake lock
33693391 }
33703392
3371- public void run () {
3372- if (ActivityManagerNative .isSystemReady ()) {
3373- IAudioService audioService = getAudioService ();
3374- if (audioService != null ) {
3375- try {
3376- audioService .dispatchMediaKeyEventUnderWakelock (mKeyEvent );
3377- } catch (RemoteException e ) {
3378- Log .e (TAG , "dispatchMediaKeyEvent threw exception " + e );
3379- }
3393+ dispatchMediaKeyWithWakeLockToAudioService (event );
3394+
3395+ if (event .getAction () == KeyEvent .ACTION_DOWN
3396+ && event .getRepeatCount () == 0 ) {
3397+ mHavePendingMediaKeyRepeatWithWakeLock = true ;
3398+
3399+ Message msg = mHandler .obtainMessage (
3400+ MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK , event );
3401+ msg .setAsynchronous (true );
3402+ mHandler .sendMessageDelayed (msg , ViewConfiguration .getKeyRepeatTimeout ());
3403+ } else {
3404+ mBroadcastWakeLock .release ();
3405+ }
3406+ }
3407+
3408+ void dispatchMediaKeyRepeatWithWakeLock (KeyEvent event ) {
3409+ mHavePendingMediaKeyRepeatWithWakeLock = false ;
3410+
3411+ KeyEvent repeatEvent = KeyEvent .changeTimeRepeat (event ,
3412+ SystemClock .uptimeMillis (), 1 , event .getFlags () | KeyEvent .FLAG_LONG_PRESS );
3413+ if (DEBUG_INPUT ) {
3414+ Slog .d (TAG , "dispatchMediaKeyRepeatWithWakeLock: " + repeatEvent );
3415+ }
3416+
3417+ dispatchMediaKeyWithWakeLockToAudioService (repeatEvent );
3418+ mBroadcastWakeLock .release ();
3419+ }
3420+
3421+ void dispatchMediaKeyWithWakeLockToAudioService (KeyEvent event ) {
3422+ if (ActivityManagerNative .isSystemReady ()) {
3423+ IAudioService audioService = getAudioService ();
3424+ if (audioService != null ) {
3425+ try {
3426+ audioService .dispatchMediaKeyEventUnderWakelock (event );
3427+ } catch (RemoteException e ) {
3428+ Log .e (TAG , "dispatchMediaKeyEvent threw exception " + e );
33803429 }
3381- mBroadcastWakeLock .release ();
33823430 }
33833431 }
33843432 }
0 commit comments