Bug 1290467 - part10 : update audio focus related control operations. draft
authorAlastor Wu <alwu@mozilla.com>
Fri, 09 Sep 2016 09:51:12 +0800
changeset 411972 e02dc2201ce54239daedb42eeabf9825aec4c0c6
parent 411971 47fee053e1f72da6d1811a62e713f1ef10d82ffc
child 530849 ccfac92cf61683e4aefc40a295692f2871308619
push id29020
push useralwu@mozilla.com
push dateFri, 09 Sep 2016 01:50:40 +0000
bugs1290467
milestone51.0a1
Bug 1290467 - part10 : update audio focus related control operations. Except controlling audio focus from gecko, the MediaControlService can also decide whether needs to request or abandon audio focus. MozReview-Commit-ID: G3iSYwd24JZ
mobile/android/base/java/org/mozilla/gecko/media/AudioFocusAgent.java
mobile/android/base/java/org/mozilla/gecko/media/MediaControlService.java
--- a/mobile/android/base/java/org/mozilla/gecko/media/AudioFocusAgent.java
+++ b/mobile/android/base/java/org/mozilla/gecko/media/AudioFocusAgent.java
@@ -51,32 +51,32 @@ public class AudioFocusAgent {
         mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
 
         mAfChangeListener = new OnAudioFocusChangeListener() {
             public void onAudioFocusChange(int focusChange) {
                 switch (focusChange) {
                     case AudioManager.AUDIOFOCUS_LOSS:
                         Log.d(LOGTAG, "onAudioFocusChange, AUDIOFOCUS_LOSS");
                         notifyObservers("AudioFocusChanged", "lostAudioFocus");
-                        notifyMediaControlService(MediaControlService.ACTION_PAUSE);
+                        notifyMediaControlService(MediaControlService.ACTION_PAUSE_BY_AUDIO_FOCUS);
                         mAudioFocusState = LOST_FOCUS;
                         break;
                     case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                         Log.d(LOGTAG, "onAudioFocusChange, AUDIOFOCUS_LOSS_TRANSIENT");
                         notifyObservers("AudioFocusChanged", "lostAudioFocusTransiently");
-                        notifyMediaControlService(MediaControlService.ACTION_PAUSE);
+                        notifyMediaControlService(MediaControlService.ACTION_PAUSE_BY_AUDIO_FOCUS);
                         mAudioFocusState = LOST_FOCUS_TRANSIENT;
                         break;
                     case AudioManager.AUDIOFOCUS_GAIN:
                         if (!mAudioFocusState.equals(LOST_FOCUS_TRANSIENT)) {
                             return;
                         }
                         Log.d(LOGTAG, "onAudioFocusChange, AUDIOFOCUS_GAIN");
                         notifyObservers("AudioFocusChanged", "gainAudioFocus");
-                        notifyMediaControlService(MediaControlService.ACTION_RESUME);
+                        notifyMediaControlService(MediaControlService.ACTION_RESUME_BY_AUDIO_FOCUS);
                         mAudioFocusState = OWN_FOCUS;
                         break;
                     default:
                 }
             }
         };
         notifyMediaControlService(MediaControlService.ACTION_INIT);
     }
--- a/mobile/android/base/java/org/mozilla/gecko/media/MediaControlService.java
+++ b/mobile/android/base/java/org/mozilla/gecko/media/MediaControlService.java
@@ -32,16 +32,18 @@ import java.lang.ref.WeakReference;
 public class MediaControlService extends Service implements Tabs.OnTabsChangedListener {
     private static final String LOGTAG = "MediaControlService";
 
     public static final String ACTION_INIT           = "action_init";
     public static final String ACTION_START          = "action_start";
     public static final String ACTION_RESUME         = "action_resume";
     public static final String ACTION_PAUSE          = "action_pause";
     public static final String ACTION_STOP           = "action_stop";
+    public static final String ACTION_RESUME_BY_AUDIO_FOCUS = "action_resume_audio_focus";
+    public static final String ACTION_PAUSE_BY_AUDIO_FOCUS  = "action_pause_audio_focus";
 
     private static final int MEDIA_CONTROL_ID = 1;
     private static final String MEDIA_CONTROL_PREF = "dom.audiochannel.mediaControl";
 
     private String mActionState = ACTION_STOP;
 
     private MediaSession mSession;
     private MediaController mController;
@@ -166,16 +168,22 @@ public class MediaControlService extends
                 mController.getTransportControls().play();
                 break;
             case ACTION_PAUSE :
                 mController.getTransportControls().pause();
                 break;
             case ACTION_STOP :
                 mController.getTransportControls().stop();
                 break;
+            case ACTION_PAUSE_BY_AUDIO_FOCUS :
+                mController.getTransportControls().sendCustomAction(ACTION_PAUSE_BY_AUDIO_FOCUS, null);
+                break;
+            case ACTION_RESUME_BY_AUDIO_FOCUS :
+                mController.getTransportControls().sendCustomAction(ACTION_RESUME_BY_AUDIO_FOCUS, null);
+                break;
         }
     }
 
     private void getGeckoPreference() {
         mPrefsObserver = new PrefsHelper.PrefHandlerBase() {
             @Override
             public void prefValue(String pref, boolean value) {
                 if (pref.equals(MEDIA_CONTROL_PREF)) {
@@ -212,35 +220,46 @@ public class MediaControlService extends
 
         mSession.setCallback(new MediaSession.Callback() {
             @Override
             public void onCustomAction(String action, Bundle extras) {
                 if (action.equals(ACTION_START)) {
                     Log.d(LOGTAG, "Controller, onStart");
                     notifyControlInterfaceChanged(ACTION_PAUSE);
                     mActionState = ACTION_RESUME;
+                } else if (action.equals(ACTION_PAUSE_BY_AUDIO_FOCUS)) {
+                    Log.d(LOGTAG, "Controller, pause by audio focus changed");
+                    notifyControlInterfaceChanged(ACTION_RESUME);
+                    mActionState = ACTION_PAUSE_BY_AUDIO_FOCUS;
+                } else if (action.equals(ACTION_RESUME_BY_AUDIO_FOCUS)) {
+                    Log.d(LOGTAG, "Controller, resume by audio focus changed");
+                    notifyControlInterfaceChanged(ACTION_PAUSE);
+                    mActionState = ACTION_RESUME_BY_AUDIO_FOCUS;
                 }
             }
 
             @Override
             public void onPlay() {
                 Log.d(LOGTAG, "Controller, onPlay");
                 super.onPlay();
                 notifyControlInterfaceChanged(ACTION_PAUSE);
                 notifyObservers("MediaControl", "resumeMedia");
                 mActionState = ACTION_RESUME;
+                // To make sure we always own audio focus during playing.
+                AudioFocusAgent.notifyStartedPlaying();
             }
 
             @Override
             public void onPause() {
                 Log.d(LOGTAG, "Controller, onPause");
                 super.onPause();
                 notifyControlInterfaceChanged(ACTION_RESUME);
                 notifyObservers("MediaControl", "mediaControlPaused");
                 mActionState = ACTION_PAUSE;
+                AudioFocusAgent.notifyStoppedPlaying();
             }
 
             @Override
             public void onStop() {
                 Log.d(LOGTAG, "Controller, onStop");
                 super.onStop();
                 notifyControlInterfaceChanged(ACTION_STOP);
                 notifyObservers("MediaControl", "mediaControlStopped");