Skip to content

Commit 4001365

Browse files
author
Jeff Brown
committed
Support long-press on media keys with screen off.
Bug: 3204066 Change-Id: I3ea4b6ceb853483b9e103de62b2ef0cf48b3dff1
1 parent 1b283b4 commit 4001365

File tree

1 file changed

+69
-21
lines changed

1 file changed

+69
-21
lines changed

policy/src/com/android/internal/policy/impl/PhoneWindowManager.java

Lines changed: 69 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)