Fix muting/notification issues on 3w/cw calls.
Paul Berman [Mon, 29 Jun 2009 23:22:20 +0000 (19:22 -0400)]
During various scenarios of making/receiving 3w/cw calls, the mute state
was not getting updated correctly, ex: being muted on a first call would still be
muted after receiving the second (cw) call which is incorrect.

Also resolved issue where missing an incoming cw call and trying to show
the notification in NotificationMgr would throw an exception.

src/com/android/phone/CallNotifier.java
src/com/android/phone/InCallScreen.java
src/com/android/phone/PhoneUtils.java

index d844a3b..94135b7 100755 (executable)
@@ -726,25 +726,7 @@ public class CallNotifier extends Handler
                 // Show the "Missed call" notification.
                 // (Note we *don't* do this if this was an incoming call that
                 // the user deliberately rejected.)
-
-                PhoneUtils.CallerInfoToken info =
-                        PhoneUtils.startGetCallerInfo(mApplication, c, this, Long.valueOf(date));
-                if (info != null) {
-                    // at this point, we've requested to start a query, but it makes no
-                    // sense to log this missed call until the query comes back.
-                    if (VDBG) log("onDisconnect: Querying for CallerInfo on missed call...");
-                    if (info.isFinal) {
-                        // it seems that the query we have actually is up to date.
-                        // send the notification then.
-                        CallerInfo ci = info.currentInfo;
-                        NotificationMgr.getDefault().notifyMissedCall(ci.name, ci.phoneNumber,
-                                ci.phoneLabel, date);
-                    }
-                } else {
-                    // getCallerInfo() can return null in rare cases, like if we weren't
-                    // able to get a valid phone number out of the specified Connection.
-                    Log.w(LOG_TAG, "onDisconnect: got null CallerInfo for Connection " + c);
-                }
+                showMissedCallNotification(c, date);
             }
 
             // Possibly play a "post-disconnect tone" thru the earpiece.
@@ -1136,30 +1118,36 @@ public class CallNotifier extends Handler
             Connection c = ringingCall.getLatestConnection();
 
             if (c != null) {
-                String number = c.getAddress();
-                int isPrivateNumber = c.getNumberPresentation();
-                long date = c.getCreateTime();
-                long duration = c.getDurationMillis();
-                int callLogType = mCallWaitingTimeOut ?
+                final String number = c.getAddress();
+                final int presentation = c.getNumberPresentation();
+                final long date = c.getCreateTime();
+                final long duration = c.getDurationMillis();
+                final int callLogType = mCallWaitingTimeOut ?
                         CallLog.Calls.MISSED_TYPE  : CallLog.Calls.INCOMING_TYPE;
 
                 // get the callerinfo object and then log the call with it.
                 Object o = c.getUserData();
-                CallerInfo ci;
+                final CallerInfo ci;
                 if ((o == null) || (o instanceof CallerInfo)) {
                     ci = (CallerInfo) o;
                 } else {
                     ci = ((PhoneUtils.CallerInfoToken) o).currentInfo;
                 }
 
-                // Add Call log
-                Calls.addCall(ci, mApplication, number, isPrivateNumber, callLogType,
-                        date, (int) duration / 1000);
+                // Watch out: Calls.addCall() hits the Contacts database,
+                // so we shouldn't call it from the main thread.
+                Thread t = new Thread() {
+                    public void run() {
+                        Calls.addCall(ci, mApplication, number, presentation,
+                                callLogType, date, (int) duration / 1000);
+                        if (DBG) log("onCdmaCallWaitingReject helper thread: Calls.addCall() done.");
+                    }
+                };
+                t.start();
 
                 if (callLogType == CallLog.Calls.MISSED_TYPE) {
                     // Add missed call notification
-                    NotificationMgr.getDefault().notifyMissedCall(ci.name,
-                            ci.phoneNumber, ci.phoneLabel, date);
+                    showMissedCallNotification(c, date);
                 }
 
                 // Set the Phone Call State to SINGLE_ACTIVE as there is only one connection
@@ -1175,6 +1163,30 @@ public class CallNotifier extends Handler
         }
     }
 
+    /**
+     * Helper function used to show a missed call notification.
+     */
+    private void showMissedCallNotification(Connection c, final long date) {
+        PhoneUtils.CallerInfoToken info =
+            PhoneUtils.startGetCallerInfo(mApplication, c, this, Long.valueOf(date));
+        if (info != null) {
+            // at this point, we've requested to start a query, but it makes no
+            // sense to log this missed call until the query comes back.
+            if (VDBG) log("showMissedCallNotification: Querying for CallerInfo on missed call...");
+            if (info.isFinal) {
+                // it seems that the query we have actually is up to date.
+                // send the notification then.
+                CallerInfo ci = info.currentInfo;
+                NotificationMgr.getDefault().notifyMissedCall(ci.name, ci.phoneNumber,
+                        ci.phoneLabel, date);
+            }
+        } else {
+            // getCallerInfo() can return null in rare cases, like if we weren't
+            // able to get a valid phone number out of the specified Connection.
+            Log.w(LOG_TAG, "showMissedCallNotification: got null CallerInfo for Connection " + c);
+        }
+    }
+
     private void log(String msg) {
         Log.d(LOG_TAG, msg);
     }
index 88e7fbc..0777886 100755 (executable)
@@ -2819,6 +2819,12 @@ public class InCallScreen extends Activity
         // if (DBG) PhoneUtils.dumpCallState(mPhone);
         PhoneUtils.answerCall(mPhone);  // Automatically holds the current active call,
                                         // if there is one
+        // Manually set the mute to false, especially in the case of an
+        // incoming call-waiting call
+        // TODO: would this need to be done for GSM also?
+        if (mPhone.getPhoneName().equals("CDMA")) {
+            PhoneUtils.setMute(mPhone, false);
+        }
     }
 
     /**
@@ -3409,12 +3415,15 @@ public class InCallScreen extends Activity
      */
     private void updateOnscreenAnswerUi() {
         if (mOnscreenAnswerUiContainer != null) {
+            if (DBG) log("onscreenAnswerUI: phone state is " + mPhone.getState().toString());
             if (mPhone.getState() == Phone.State.RINGING) {
                 // A phone call is ringing *or* call waiting.
                 mOnscreenAnswerUiContainer.setVisibility(View.VISIBLE);
             } else {
                 mOnscreenAnswerUiContainer.setVisibility(View.GONE);
             }
+            if (DBG) log("set onscreen answer UI visibility to " +
+                    mOnscreenAnswerUiContainer.getVisibility());
         }
     }
 
index 7268880..e17f210 100755 (executable)
@@ -440,8 +440,16 @@ public class PhoneUtils {
         if (c != null) {
 
             // retrieve the mute value.
-            Boolean shouldMute = sConnectionMuteTable.get(
-                    phone.getForegroundCall().getEarliestConnection());
+            Boolean shouldMute;
+            if (phone.getPhoneName().equals("CDMA") &&
+                    PhoneApp.getInstance().cdmaPhoneCallState.getCurrentCallState() ==
+                    CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
+                shouldMute = sConnectionMuteTable.get(
+                        phone.getForegroundCall().getLatestConnection());
+            } else {
+                shouldMute = sConnectionMuteTable.get(
+                        phone.getForegroundCall().getEarliestConnection());
+            }
             if (shouldMute == null) {
                 if (DBG) log("problem retrieving mute value for this connection.");
                 shouldMute = Boolean.FALSE;