Skip to content

Commit 722b808

Browse files
committed
Handle media button events during phone calls and when ringing
Add functionality in AudioManager/AudioService to register a media button receiver for telephony that, when registered, gets priority for media button key events during a phone call or when ringing. Bug 6484717 Change-Id: I0835fc02cb24d06ca59af5a32c3ba0ae93e54442
1 parent c1c1406 commit 722b808

File tree

3 files changed

+95
-5
lines changed

3 files changed

+95
-5
lines changed

media/java/android/media/AudioManager.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1999,6 +1999,37 @@ public void registerMediaButtonIntent(PendingIntent pi, ComponentName eventRecei
19991999
}
20002000
}
20012001

2002+
/**
2003+
* @hide
2004+
* Used internally by telephony package to register an intent receiver for ACTION_MEDIA_BUTTON.
2005+
* @param eventReceiver the component that will receive the media button key events,
2006+
* no-op if eventReceiver is null
2007+
*/
2008+
public void registerMediaButtonEventReceiverForCalls(ComponentName eventReceiver) {
2009+
if (eventReceiver == null) {
2010+
return;
2011+
}
2012+
IAudioService service = getService();
2013+
try {
2014+
// eventReceiver != null
2015+
service.registerMediaButtonEventReceiverForCalls(eventReceiver);
2016+
} catch (RemoteException e) {
2017+
Log.e(TAG, "Dead object in registerMediaButtonEventReceiverForCalls", e);
2018+
}
2019+
}
2020+
2021+
/**
2022+
* @hide
2023+
*/
2024+
public void unregisterMediaButtonEventReceiverForCalls() {
2025+
IAudioService service = getService();
2026+
try {
2027+
service.unregisterMediaButtonEventReceiverForCalls();
2028+
} catch (RemoteException e) {
2029+
Log.e(TAG, "Dead object in unregisterMediaButtonEventReceiverForCalls", e);
2030+
}
2031+
}
2032+
20022033
/**
20032034
* Unregister the receiver of MEDIA_BUTTON intents.
20042035
* @param eventReceiver identifier of a {@link android.content.BroadcastReceiver}

media/java/android/media/AudioService.java

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3625,12 +3625,14 @@ private void filterMediaKeyEvent(KeyEvent keyEvent, boolean needWakeLock) {
36253625
Log.e(TAG, "not dispatching invalid media key event " + keyEvent);
36263626
return;
36273627
}
3628-
// event filtering based on audio mode
3628+
// event filtering for telephony
36293629
synchronized(mRingingLock) {
3630-
if (mIsRinging || (getMode() == AudioSystem.MODE_IN_CALL) ||
3631-
(getMode() == AudioSystem.MODE_IN_COMMUNICATION) ||
3632-
(getMode() == AudioSystem.MODE_RINGTONE) ) {
3633-
return;
3630+
synchronized(mRCStack) {
3631+
if ((mMediaReceiverForCalls != null) &&
3632+
(mIsRinging || (getMode() == AudioSystem.MODE_IN_CALL))) {
3633+
dispatchMediaKeyEventForCalls(keyEvent, needWakeLock);
3634+
return;
3635+
}
36343636
}
36353637
}
36363638
// event filtering based on voice-based interactions
@@ -3641,6 +3643,25 @@ private void filterMediaKeyEvent(KeyEvent keyEvent, boolean needWakeLock) {
36413643
}
36423644
}
36433645

3646+
/**
3647+
* Handles the dispatching of the media button events to the telephony package.
3648+
* Precondition: mMediaReceiverForCalls != null
3649+
* @param keyEvent a non-null KeyEvent whose key code is one of the supported media buttons
3650+
* @param needWakeLock true if a PARTIAL_WAKE_LOCK needs to be held while this key event
3651+
* is dispatched.
3652+
*/
3653+
private void dispatchMediaKeyEventForCalls(KeyEvent keyEvent, boolean needWakeLock) {
3654+
Intent keyIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
3655+
keyIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
3656+
keyIntent.setPackage(mMediaReceiverForCalls.getPackageName());
3657+
if (needWakeLock) {
3658+
mMediaEventWakeLock.acquire();
3659+
keyIntent.putExtra(EXTRA_WAKELOCK_ACQUIRED, WAKELOCK_RELEASE_ON_FINISHED);
3660+
}
3661+
mContext.sendOrderedBroadcast(keyIntent, null, mKeyEventDone,
3662+
mAudioHandler, Activity.RESULT_OK, null, null);
3663+
}
3664+
36443665
/**
36453666
* Handles the dispatching of the media button events to one of the registered listeners,
36463667
* or if there was none, broadcast an ACTION_MEDIA_BUTTON intent to the rest of the system.
@@ -4027,6 +4048,12 @@ protected void finalize() throws Throwable {
40274048
*/
40284049
private final Stack<RemoteControlStackEntry> mRCStack = new Stack<RemoteControlStackEntry>();
40294050

4051+
/**
4052+
* The component the telephony package can register so telephony calls have priority to
4053+
* handle media button events
4054+
*/
4055+
private ComponentName mMediaReceiverForCalls = null;
4056+
40304057
/**
40314058
* Helper function:
40324059
* Display in the log the current entries in the remote control focus stack
@@ -4380,6 +4407,35 @@ public void unregisterMediaButtonIntent(PendingIntent mediaIntent, ComponentName
43804407
}
43814408
}
43824409

4410+
/**
4411+
* see AudioManager.registerMediaButtonEventReceiverForCalls(ComponentName c)
4412+
* precondition: c != null
4413+
*/
4414+
public void registerMediaButtonEventReceiverForCalls(ComponentName c) {
4415+
if (mContext.checkCallingPermission("android.permission.MODIFY_PHONE_STATE")
4416+
!= PackageManager.PERMISSION_GRANTED) {
4417+
Log.e(TAG, "Invalid permissions to register media button receiver for calls");
4418+
return;
4419+
}
4420+
synchronized(mRCStack) {
4421+
mMediaReceiverForCalls = c;
4422+
}
4423+
}
4424+
4425+
/**
4426+
* see AudioManager.unregisterMediaButtonEventReceiverForCalls()
4427+
*/
4428+
public void unregisterMediaButtonEventReceiverForCalls() {
4429+
if (mContext.checkCallingPermission("android.permission.MODIFY_PHONE_STATE")
4430+
!= PackageManager.PERMISSION_GRANTED) {
4431+
Log.e(TAG, "Invalid permissions to unregister media button receiver for calls");
4432+
return;
4433+
}
4434+
synchronized(mRCStack) {
4435+
mMediaReceiverForCalls = null;
4436+
}
4437+
}
4438+
43834439
/**
43844440
* see AudioManager.registerRemoteControlClient(ComponentName eventReceiver, ...)
43854441
* Note: using this method with rcClient == null is a way to "disable" the IRemoteControlClient

media/java/android/media/IAudioService.aidl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ interface IAudioService {
109109
oneway void registerMediaButtonIntent(in PendingIntent pi, in ComponentName c);
110110
oneway void unregisterMediaButtonIntent(in PendingIntent pi, in ComponentName c);
111111

112+
oneway void registerMediaButtonEventReceiverForCalls(in ComponentName c);
113+
oneway void unregisterMediaButtonEventReceiverForCalls();
114+
112115
oneway void registerRemoteControlClient(in PendingIntent mediaIntent,
113116
in IRemoteControlClient rcClient, in String callingPackageName);
114117
oneway void unregisterRemoteControlClient(in PendingIntent mediaIntent,

0 commit comments

Comments
 (0)