Merge "Handle media button events during phone calls and when ringing" into jb-dev

This commit is contained in:
Jean-Michel Trivi
2012-05-17 11:14:56 -07:00
committed by Android (Google) Code Review
3 changed files with 95 additions and 5 deletions

View File

@@ -1999,6 +1999,37 @@ public class AudioManager {
}
}
/**
* @hide
* Used internally by telephony package to register an intent receiver for ACTION_MEDIA_BUTTON.
* @param eventReceiver the component that will receive the media button key events,
* no-op if eventReceiver is null
*/
public void registerMediaButtonEventReceiverForCalls(ComponentName eventReceiver) {
if (eventReceiver == null) {
return;
}
IAudioService service = getService();
try {
// eventReceiver != null
service.registerMediaButtonEventReceiverForCalls(eventReceiver);
} catch (RemoteException e) {
Log.e(TAG, "Dead object in registerMediaButtonEventReceiverForCalls", e);
}
}
/**
* @hide
*/
public void unregisterMediaButtonEventReceiverForCalls() {
IAudioService service = getService();
try {
service.unregisterMediaButtonEventReceiverForCalls();
} catch (RemoteException e) {
Log.e(TAG, "Dead object in unregisterMediaButtonEventReceiverForCalls", e);
}
}
/**
* Unregister the receiver of MEDIA_BUTTON intents.
* @param eventReceiver identifier of a {@link android.content.BroadcastReceiver}

View File

@@ -3625,12 +3625,14 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
Log.e(TAG, "not dispatching invalid media key event " + keyEvent);
return;
}
// event filtering based on audio mode
// event filtering for telephony
synchronized(mRingingLock) {
if (mIsRinging || (getMode() == AudioSystem.MODE_IN_CALL) ||
(getMode() == AudioSystem.MODE_IN_COMMUNICATION) ||
(getMode() == AudioSystem.MODE_RINGTONE) ) {
return;
synchronized(mRCStack) {
if ((mMediaReceiverForCalls != null) &&
(mIsRinging || (getMode() == AudioSystem.MODE_IN_CALL))) {
dispatchMediaKeyEventForCalls(keyEvent, needWakeLock);
return;
}
}
}
// event filtering based on voice-based interactions
@@ -3641,6 +3643,25 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
}
}
/**
* Handles the dispatching of the media button events to the telephony package.
* Precondition: mMediaReceiverForCalls != null
* @param keyEvent a non-null KeyEvent whose key code is one of the supported media buttons
* @param needWakeLock true if a PARTIAL_WAKE_LOCK needs to be held while this key event
* is dispatched.
*/
private void dispatchMediaKeyEventForCalls(KeyEvent keyEvent, boolean needWakeLock) {
Intent keyIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
keyIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
keyIntent.setPackage(mMediaReceiverForCalls.getPackageName());
if (needWakeLock) {
mMediaEventWakeLock.acquire();
keyIntent.putExtra(EXTRA_WAKELOCK_ACQUIRED, WAKELOCK_RELEASE_ON_FINISHED);
}
mContext.sendOrderedBroadcast(keyIntent, null, mKeyEventDone,
mAudioHandler, Activity.RESULT_OK, null, null);
}
/**
* Handles the dispatching of the media button events to one of the registered listeners,
* or if there was none, broadcast an ACTION_MEDIA_BUTTON intent to the rest of the system.
@@ -4027,6 +4048,12 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
*/
private final Stack<RemoteControlStackEntry> mRCStack = new Stack<RemoteControlStackEntry>();
/**
* The component the telephony package can register so telephony calls have priority to
* handle media button events
*/
private ComponentName mMediaReceiverForCalls = null;
/**
* Helper function:
* Display in the log the current entries in the remote control focus stack
@@ -4380,6 +4407,35 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
}
}
/**
* see AudioManager.registerMediaButtonEventReceiverForCalls(ComponentName c)
* precondition: c != null
*/
public void registerMediaButtonEventReceiverForCalls(ComponentName c) {
if (mContext.checkCallingPermission("android.permission.MODIFY_PHONE_STATE")
!= PackageManager.PERMISSION_GRANTED) {
Log.e(TAG, "Invalid permissions to register media button receiver for calls");
return;
}
synchronized(mRCStack) {
mMediaReceiverForCalls = c;
}
}
/**
* see AudioManager.unregisterMediaButtonEventReceiverForCalls()
*/
public void unregisterMediaButtonEventReceiverForCalls() {
if (mContext.checkCallingPermission("android.permission.MODIFY_PHONE_STATE")
!= PackageManager.PERMISSION_GRANTED) {
Log.e(TAG, "Invalid permissions to unregister media button receiver for calls");
return;
}
synchronized(mRCStack) {
mMediaReceiverForCalls = null;
}
}
/**
* see AudioManager.registerRemoteControlClient(ComponentName eventReceiver, ...)
* Note: using this method with rcClient == null is a way to "disable" the IRemoteControlClient

View File

@@ -109,6 +109,9 @@ interface IAudioService {
oneway void registerMediaButtonIntent(in PendingIntent pi, in ComponentName c);
oneway void unregisterMediaButtonIntent(in PendingIntent pi, in ComponentName c);
oneway void registerMediaButtonEventReceiverForCalls(in ComponentName c);
oneway void unregisterMediaButtonEventReceiverForCalls();
oneway void registerRemoteControlClient(in PendingIntent mediaIntent,
in IRemoteControlClient rcClient, in String callingPackageName);
oneway void unregisterRemoteControlClient(in PendingIntent mediaIntent,