Move PhoneUtils.setAudioMode().

As different audio modes need to be applied for different phone types, (for example,
SIP call needs to be in MODE_NORMAL while GSM call in MODE_IN_CALL,) we move the
logic to CallManager. A side benefit is that since CallManager knows the current
phone state, PhoneUtils does not need to keep the audio control state (sAudioBehaviourState)
anymore.

The companion CL is at https://android-git/g/#change,61553

Change-Id: Ibb40e1853f2e5818b4b28c976f5756f567b3de41
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index 7cf4587..717da01 100755
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -458,7 +458,6 @@
         // - don't ring for call waiting connections
         // - do this before showing the incoming call panel
         if (PhoneUtils.isRealIncomingCall(state)) {
-            PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_RINGING);
             startIncomingCallQuery(c);
         } else {
             if (VDBG) log("- starting call waiting tone...");
@@ -734,18 +733,9 @@
                 mCallWaitingTonePlayer = null;
             }
 
-            PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_OFFHOOK);
             if (VDBG) log("onPhoneStateChanged: OFF HOOK");
-            // If Audio Mode is not In Call, then set the Audio Mode.  This
-            // changes is needed because for one of the carrier specific test case,
-            // call is originated from the lower layer without using the UI, and
-            // since calling does not go through DIALING state, it skips the steps
-            // of setting the Audio Mode
-            if (mPhone.getPhoneType() == Phone.PHONE_TYPE_CDMA) {
-                if (mAudioManager.getMode() != AudioManager.MODE_IN_CALL) {
-                    PhoneUtils.setAudioMode(mPhoneContext, AudioManager.MODE_IN_CALL);
-                }
-            }
+            // make sure audio is in in-call mode now
+            PhoneUtils.setAudioMode(mCM);
 
             // if the call screen is showing, let it handle the event,
             // otherwise handle it here.
@@ -920,10 +910,6 @@
                     getContentResolver(),android.provider.Settings.System.CALL_AUTO_RETRY, 0);
         }
 
-        if (mCM.getState() == Phone.State.IDLE) {
-            PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_IDLE);
-        }
-
         if (mPhone.getPhoneType() == Phone.PHONE_TYPE_CDMA) {
             // Stop any signalInfo tone being played when a call gets ended
             stopSignalInfoTone();
@@ -1199,7 +1185,7 @@
         // is already off to reset user requested speaker state.
         PhoneUtils.turnOnSpeaker(mPhoneContext, false, true);
 
-        PhoneUtils.setAudioMode(mPhoneContext, AudioManager.MODE_NORMAL);
+        PhoneUtils.setAudioMode(mCM);
     }
 
     private void onMwiChanged(boolean visible) {
diff --git a/src/com/android/phone/InCallScreen.java b/src/com/android/phone/InCallScreen.java
index 5d616f7..1d2c114 100755
--- a/src/com/android/phone/InCallScreen.java
+++ b/src/com/android/phone/InCallScreen.java
@@ -1555,7 +1555,6 @@
                     final CallNotifier notifier = PhoneApp.getInstance().notifier;
                     if (notifier.isRinging()) {
                         // ringer is actually playing, so silence it.
-                        PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_IDLE);
                         if (DBG) log("VOLUME key: silence ringer");
                         notifier.silenceRinger();
                     }
diff --git a/src/com/android/phone/PhoneApp.java b/src/com/android/phone/PhoneApp.java
index 14765fe..eaf1f60 100644
--- a/src/com/android/phone/PhoneApp.java
+++ b/src/com/android/phone/PhoneApp.java
@@ -426,7 +426,7 @@
                 mBtHandsfree = null;
             }
 
-            ringer = new Ringer(phone);
+            ringer = new Ringer(this);
 
             // before registering for phone state changes
             PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
@@ -517,23 +517,7 @@
             // Make sure the audio mode (along with some
             // audio-mode-related state of our own) is initialized
             // correctly, given the current state of the phone.
-            switch (mCM.getState()) {
-                case IDLE:
-                    if (DBG) Log.d(LOG_TAG, "Resetting audio state/mode: IDLE");
-                    PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_IDLE);
-                    PhoneUtils.setAudioMode(this, AudioManager.MODE_NORMAL);
-                    break;
-                case RINGING:
-                    if (DBG) Log.d(LOG_TAG, "Resetting audio state/mode: RINGING");
-                    PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_RINGING);
-                    PhoneUtils.setAudioMode(this, AudioManager.MODE_RINGTONE);
-                    break;
-                case OFFHOOK:
-                    if (DBG) Log.d(LOG_TAG, "Resetting audio state/mode: OFFHOOK");
-                    PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_OFFHOOK);
-                    PhoneUtils.setAudioMode(this, AudioManager.MODE_IN_CALL);
-                    break;
-            }
+            PhoneUtils.setAudioMode(mCM);
         }
 
         boolean phoneIsCdma = (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA);
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 19d6ace..f3ee97c 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -366,7 +366,6 @@
             && mApp.notifier.isRinging()) {
             // Ringer is actually playing, so silence it.
             if (DBG) log("silenceRingerInternal: silencing...");
-            PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_IDLE);
             mApp.notifier.silenceRinger();
         }
     }
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index ca05c19..ffc2f7e 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -88,7 +88,6 @@
     static final int AUDIO_IDLE = 0;  /** audio behaviour at phone idle */
     static final int AUDIO_RINGING = 1;  /** audio behaviour while ringing */
     static final int AUDIO_OFFHOOK = 2;  /** audio behaviour while in call. */
-    private static int sAudioBehaviourState = AUDIO_IDLE;
 
     /** Speaker state, persisting between wired headset connection events */
     private static boolean sIsSpeakerEnabled = false;
@@ -218,11 +217,6 @@
     private PhoneUtils() {
     }
 
-    //static method to set the audio control state.
-    static void setAudioControlState(int newState) {
-        sAudioBehaviourState = newState;
-    }
-
     /**
      * Answer the currently-ringing call.
      *
@@ -239,8 +233,6 @@
         // right now (before actually answering the call.)
         PhoneApp.getInstance().getRinger().stopRing();
 
-        PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_OFFHOOK);
-
         boolean answered = false;
         PhoneApp app = PhoneApp.getInstance();
         Phone phone = ringing.getPhone();
@@ -292,7 +284,7 @@
                 // Always reset to "unmuted" for a freshly-answered call
                 setMute(phone, false);
 
-                setAudioMode(phone.getContext(), AudioManager.MODE_IN_CALL);
+                setAudioMode();
 
                 // Check is phone in any dock, and turn on speaker accordingly
                 activateSpeakerIfDocked(phone);
@@ -548,8 +540,6 @@
                     updateCdmaCallStateOnNewOutgoingCall(app);
                 }
 
-                PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_OFFHOOK);
-
                 // phone.dial() succeeded: we're now in a normal phone call.
                 // attach the URI to the CallerInfo Object if it is there,
                 // otherwise just attach the Uri Reference.
@@ -572,7 +562,7 @@
                         }
                     }
                 }
-                setAudioMode(phone.getContext(), AudioManager.MODE_IN_CALL);
+                setAudioMode();
 
                 // Check is phone in any dock, and turn on speaker accordingly
                 activateSpeakerIfDocked(phone);
@@ -644,7 +634,6 @@
         if (phoneIsCdma) {
             updateCdmaCallStateOnNewOutgoingCall(app);
         }
-        PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_OFFHOOK);
 
         // Clean up the number to be displayed.
         if (phoneIsCdma) {
@@ -672,7 +661,7 @@
         info.phoneNumber = number;
         connection.setUserData(info);
 
-        setAudioMode(phone.getContext(), AudioManager.MODE_IN_CALL);
+        setAudioMode();
         return CALL_STATUS_DIALED;
     }
 
@@ -706,6 +695,7 @@
                 // has particular heldCall, so to switch
                 cm.switchHoldingAndActive(heldCall);
             }
+            setAudioMode(cm);
         } catch (CallStateException ex) {
             Log.w(LOG_TAG, "switchHoldingAndActive: caught " + ex, ex);
         }
@@ -1786,43 +1776,29 @@
         }
     }
 
+    /* package */ static void setAudioMode() {
+        setAudioMode(PhoneApp.getInstance().mCM);
+    }
+
     /**
-     * A really simple wrapper around AudioManager.setMode(),
-     * with a bit of extra logging to help debug the exact
-     * timing (and call stacks) for all our setMode() calls.
-     *
-     * Also, add additional state monitoring to determine
-     * whether or not certain calls to change the audio mode
-     * are ignored.
+     * Sets the audio mode per current phone state.
      */
-    /* package */ static void setAudioMode(Context context, int mode) {
-        if (DBG) Log.d(LOG_TAG, "setAudioMode(" + audioModeToString(mode) + ")...");
+    /* package */ static void setAudioMode(CallManager cm) {
+        if (DBG) Log.d(LOG_TAG, "setAudioMode()..." + cm.getState());
 
-        //decide whether or not to ignore the audio setting
-        boolean ignore = false;
+        Context context = PhoneApp.getInstance();
+        AudioManager audioManager = (AudioManager)
+                context.getSystemService(Context.AUDIO_SERVICE);
+        int modeBefore = audioManager.getMode();
+        cm.setAudioMode();
+        int modeAfter = audioManager.getMode();
 
-        switch (sAudioBehaviourState) {
-            case AUDIO_RINGING:
-                ignore = ((mode == AudioManager.MODE_NORMAL) || (mode == AudioManager.MODE_IN_CALL));
-                break;
-            case AUDIO_OFFHOOK:
-                ignore = ((mode == AudioManager.MODE_NORMAL) || (mode == AudioManager.MODE_RINGTONE));
-                break;
-            case AUDIO_IDLE:
-            default:
-                ignore = (mode == AudioManager.MODE_IN_CALL);
-                break;
-        }
-
-        if (!ignore) {
-            AudioManager audioManager =
-                    (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        if (modeBefore != modeAfter) {
             // Enable stack dump only when actively debugging ("new Throwable()" is expensive!)
             if (DBG_SETAUDIOMODE_STACK) Log.d(LOG_TAG, "Stack:", new Throwable("stack dump"));
-            audioManager.setMode(mode);
         } else {
-            if (DBG) Log.d(LOG_TAG, "setAudioMode(), state is " + sAudioBehaviourState +
-                    " ignoring " + audioModeToString(mode) + " request");
+            if (DBG) Log.d(LOG_TAG, "setAudioMode() no change: "
+                    + audioModeToString(modeBefore));
         }
     }
     private static String audioModeToString(int mode) {
diff --git a/src/com/android/phone/Ringer.java b/src/com/android/phone/Ringer.java
index 8412f46..06a3637 100644
--- a/src/com/android/phone/Ringer.java
+++ b/src/com/android/phone/Ringer.java
@@ -61,8 +61,8 @@
     private long mFirstRingEventTime = -1;
     private long mFirstRingStartTime = -1;
 
-    Ringer(Phone phone) {
-        mContext = phone.getContext();
+    Ringer(Context context) {
+        mContext = context;
         mPowerManager = IPowerManager.Stub.asInterface(ServiceManager.getService(Context.POWER_SERVICE));
     }
 
@@ -198,7 +198,7 @@
                 Message msg = mRingHandler.obtainMessage(STOP_RING);
                 msg.obj = mRingtone;
                 mRingHandler.sendMessage(msg);
-                PhoneUtils.setAudioMode(mContext, AudioManager.MODE_NORMAL);
+                PhoneUtils.setAudioMode();
                 mRingThread = null;
                 mRingHandler = null;
                 mRingtone = null;
@@ -294,7 +294,7 @@
                             }
                             r = mRingtone;
                             if (r != null && !hasMessages(STOP_RING) && !r.isPlaying()) {
-                                PhoneUtils.setAudioMode(mContext, AudioManager.MODE_RINGTONE);
+                                PhoneUtils.setAudioMode();
                                 r.play();
                                 synchronized (Ringer.this) {
                                     if (mFirstRingStartTime < 0) {