InCallUI: clean up prox speaker code and improve usability

Addresses a rare bug or two, relating to proximity speaker behavior
during the beginning of an outgoing phone call.

Change-Id: I4aff0c393a9803d648538c2e268a2c3d446f536d
diff --git a/src/com/android/incallui/ProximitySensor.java b/src/com/android/incallui/ProximitySensor.java
index cab08e6..0d382ba 100644
--- a/src/com/android/incallui/ProximitySensor.java
+++ b/src/com/android/incallui/ProximitySensor.java
@@ -64,12 +64,13 @@
     private boolean mIsPhoneOffhook = false;
     private boolean mIsPhoneOutgoing = false;
     private boolean mProximitySpeaker = false;
+    private boolean mIsProxSensorFar = true;
     private int mProxSpeakerDelay = 100;
     private boolean mDialpadVisible;
     private Context mContext;
 
     private final Handler mHandler = new Handler();
-    private final Runnable mRunnable = new Runnable() {
+    private final Runnable mActivateSpeaker = new Runnable() {
         @Override
         public void run() {
             TelecomAdapter.getInstance().setAudioRoute(AudioMode.SPEAKER);
@@ -123,6 +124,9 @@
         if (mSensor != null) {
             mSensor.unregisterListener(this);
         }
+
+        // remove any pending audio changes scheduled
+        mHandler.removeCallbacks(mActivateSpeaker);
     }
 
     /**
@@ -144,25 +148,21 @@
         // can also put the in-call screen in the INCALL state.
         boolean hasOngoingCall = InCallState.INCALL == newState && callList.hasLiveCall();
         boolean isOffhook = (InCallState.OUTGOING == newState) || hasOngoingCall;
-        boolean isOutgoing = (InCallState.OUTGOING == newState);
         mHasIncomingCall = (InCallState.INCOMING == newState);
-
-        // remove any pending audio changes scheduled
-        mHandler.removeCallbacks(mRunnable);
+        mIsPhoneOutgoing = (InCallState.OUTGOING == newState);
 
         if (isOffhook != mIsPhoneOffhook) {
             mIsPhoneOffhook = isOffhook;
-            mIsPhoneOutgoing = isOutgoing;
 
             mOrientation = AccelerometerListener.ORIENTATION_UNKNOWN;
             mAccelerometerListener.enable(mIsPhoneOffhook);
 
             updateProxSpeaker();
             updateProximitySensorMode();
-        } else if (isOutgoing != mIsPhoneOutgoing) {
-            mIsPhoneOutgoing = isOutgoing;
-            updateProxSpeaker();
-            updateProximitySensorMode();
+        }
+
+        if (hasOngoingCall && InCallState.OUTGOING == oldState) {
+            setProxSpeaker(mIsProxSensorFar);
         }
 
         if (mHasIncomingCall) {
@@ -192,10 +192,11 @@
     @Override
     public void onSensorChanged(SensorEvent event) {
         if (event.values[0] != mProxSensor.getMaximumRange()) {
-            setProxSpeaker(false);
+            mIsProxSensorFar = false;
         } else {
-            setProxSpeaker(true);
+            mIsProxSensorFar = true;
         }
+        setProxSpeaker(mIsProxSensorFar);
     }
 
     @Override
@@ -353,8 +354,13 @@
     }
 
     private void setProxSpeaker(final boolean speaker) {
-        final int audioMode = mAudioModeProvider.getAudioMode();
+        // remove any pending audio changes scheduled
+        mHandler.removeCallbacks(mActivateSpeaker);
 
+        final int audioMode = mAudioModeProvider.getAudioMode();
+        final boolean proxSpeakerIncallOnlyPref =
+                (Settings.System.getInt(mContext.getContentResolver(),
+                Settings.System.PROXIMITY_AUTO_SPEAKER_INCALL_ONLY, 0) == 1);
         mProxSpeakerDelay = Settings.System.getInt(mContext.getContentResolver(),
                 Settings.System.PROXIMITY_AUTO_SPEAKER_DELAY, 100);
 
@@ -371,20 +377,14 @@
 
                 // if prox incall only is off, we set to speaker as long as phone
                 // is off hook, ignoring whether or not the call state is outgoing
-                if (Settings.System.getInt(mContext.getContentResolver(),
-                        Settings.System.PROXIMITY_AUTO_SPEAKER_INCALL_ONLY, 0) == 0
+                if (!proxSpeakerIncallOnlyPref
                         // or if prox incall only is on, we have to check the call
                         // state to decide if AudioMode should be speaker
-                        || (Settings.System.getInt(mContext.getContentResolver(),
-                        Settings.System.PROXIMITY_AUTO_SPEAKER_INCALL_ONLY, 0) == 1
-                        && !mIsPhoneOutgoing)) {
-                    mHandler.removeCallbacks(mRunnable);
-                    mHandler.postDelayed(mRunnable, mProxSpeakerDelay);
+                        || (proxSpeakerIncallOnlyPref && !mIsPhoneOutgoing)) {
+                    mHandler.postDelayed(mActivateSpeaker, mProxSpeakerDelay);
                 }
             } else if (!speaker) {
-                mHandler.removeCallbacks(mRunnable);
                 TelecomAdapter.getInstance().setAudioRoute(AudioMode.EARPIECE);
-                updateProximitySensorMode();
             }
         }
     }