Merge "Remove un-needed code in NotificationManager." into klp-dev
diff --git a/common/src/com/android/services/telephony/common/ICallHandlerService.aidl b/common/src/com/android/services/telephony/common/ICallHandlerService.aidl
index 0cbd9b9..c4f0961 100644
--- a/common/src/com/android/services/telephony/common/ICallHandlerService.aidl
+++ b/common/src/com/android/services/telephony/common/ICallHandlerService.aidl
@@ -67,7 +67,7 @@
     /**
      * Called when the system wants to bring the in-call UI into the foreground.
      */
-    void bringToForeground();
+    void bringToForeground(boolean showDialpad);
 
     void onPostDialWait(int callId, String remainingChars);
 }
diff --git a/src/com/android/phone/CallHandlerServiceProxy.java b/src/com/android/phone/CallHandlerServiceProxy.java
index 4426fed..1d43fe8 100644
--- a/src/com/android/phone/CallHandlerServiceProxy.java
+++ b/src/com/android/phone/CallHandlerServiceProxy.java
@@ -294,13 +294,13 @@
         }
     }
 
-    public void bringToForeground() {
+    public void bringToForeground(boolean showDialpad) {
         // only support this call if the service is already connected.
         synchronized (mServiceAndQueueLock) {
             if (mCallHandlerServiceGuarded != null && mCallModeler.hasLiveCall()) {
                 try {
-                    if (DBG) Log.d(TAG, "bringToForeground");
-                    mCallHandlerServiceGuarded.bringToForeground();
+                    if (DBG) Log.d(TAG, "bringToForeground: " + showDialpad);
+                    mCallHandlerServiceGuarded.bringToForeground(showDialpad);
                 } catch (RemoteException e) {
                     Log.e(TAG, "Exception handling bringToForeground", e);
                 }
diff --git a/src/com/android/phone/CallModeler.java b/src/com/android/phone/CallModeler.java
index ae0ac48..f3e0d36 100644
--- a/src/com/android/phone/CallModeler.java
+++ b/src/com/android/phone/CallModeler.java
@@ -28,6 +28,8 @@
 import com.android.internal.telephony.Connection;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.TelephonyCapabilities;
+import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
 import com.android.phone.CallGatewayManager.RawGatewayInfo;
 import com.android.services.telephony.common.Call;
 import com.android.services.telephony.common.Call.Capabilities;
@@ -89,6 +91,7 @@
     private final AtomicInteger mNextCallId = new AtomicInteger(CALL_ID_START_VALUE);
     private final ArrayList<Listener> mListeners = new ArrayList<Listener>();
     private RejectWithTextMessageManager mRejectWithTextMessageManager;
+    private Connection mCdmaIncomingConnection;
 
     public CallModeler(CallStateMonitor callStateMonitor, CallManager callManager,
             RejectWithTextMessageManager rejectWithTextMessageManager,
@@ -105,10 +108,10 @@
     public void handleMessage(Message msg) {
         switch(msg.what) {
             case CallStateMonitor.PHONE_NEW_RINGING_CONNECTION:
-                onNewRingingConnection((AsyncResult) msg.obj);
+                onNewRingingConnection((Connection) ((AsyncResult) msg.obj).result);
                 break;
             case CallStateMonitor.PHONE_DISCONNECT:
-                onDisconnect((AsyncResult) msg.obj);
+                onDisconnect((Connection) ((AsyncResult) msg.obj).result);
                 break;
             case CallStateMonitor.PHONE_STATE_CHANGED:
                 onPhoneStateChanged((AsyncResult) msg.obj);
@@ -156,6 +159,39 @@
             hasLiveCallInternal(mConfCallMap);
     }
 
+    public void onCdmaCallWaiting(CdmaCallWaitingNotification callWaitingInfo) {
+        // We dont get the traditional onIncomingCall notification for cdma call waiting,
+        // but the Connection does actually exist.  We need to find it in the set of ringing calls
+        // and pass it through our normal incoming logic.
+        final com.android.internal.telephony.Call teleCall =
+            mCallManager.getFirstActiveRingingCall();
+
+        if (teleCall.getState() == com.android.internal.telephony.Call.State.WAITING) {
+            Connection connection = teleCall.getLatestConnection();
+
+            if (connection != null) {
+                String number = connection.getAddress();
+                if (number != null && number.equals(callWaitingInfo.number)) {
+                    Call call = onNewRingingConnection(connection);
+                    mCdmaIncomingConnection = connection;
+                    return;
+                }
+            }
+        }
+
+        Log.e(TAG, "CDMA Call waiting notification without a matching connection.");
+    }
+
+    public void onCdmaCallWaitingReject() {
+        // Cdma call was rejected...
+        if (mCdmaIncomingConnection != null) {
+            onDisconnect(mCdmaIncomingConnection);
+            mCdmaIncomingConnection = null;
+        } else {
+            Log.e(TAG, "CDMA Call waiting rejection without an incoming call.");
+        }
+    }
+
     private boolean hasLiveCallInternal(HashMap<Connection, Call> map) {
         for (Call call : map.values()) {
             final int state = call.getState();
@@ -224,9 +260,8 @@
         }
     }
 
-    private void onNewRingingConnection(AsyncResult r) {
+    private Call onNewRingingConnection(Connection conn) {
         Log.i(TAG, "onNewRingingConnection");
-        final Connection conn = (Connection) r.result;
         final Call call = getCallFromMap(mCallMap, conn, true);
 
         updateCallFromConnection(call, conn, false);
@@ -236,11 +271,12 @@
               mListeners.get(i).onIncoming(call);
             }
         }
+
+        return call;
     }
 
-    private void onDisconnect(AsyncResult r) {
+    private void onDisconnect(Connection conn) {
         Log.i(TAG, "onDisconnect");
-        final Connection conn = (Connection) r.result;
         final Call call = getCallFromMap(mCallMap, conn, false);
 
         if (call != null) {
@@ -296,6 +332,8 @@
         for (com.android.internal.telephony.Call telephonyCall : telephonyCalls) {
 
             for (Connection connection : telephonyCall.getConnections()) {
+                if (DBG) Log.d(TAG, "connection: " + connection);
+
                 // We only send updates for live calls which are not incoming (ringing).
                 // Disconnected and incoming calls are handled by onDisconnect and
                 // onNewRingingConnection.
@@ -308,6 +346,7 @@
                 final Call call = getCallFromMap(mCallMap, connection, shouldUpdate /* create */);
 
                 if (call == null || !shouldUpdate) {
+                    if (DBG) Log.d(TAG, "update skipped");
                     continue;
                 }
 
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index d2c9d8b..c7db763 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -140,6 +140,7 @@
     private Ringer mRinger;
     private BluetoothHeadset mBluetoothHeadset;
     private CallLogger mCallLogger;
+    private CallModeler mCallModeler;
     private boolean mSilentRingerRequested;
 
     // ToneGenerator instance for playing SignalInfo tones
@@ -174,11 +175,11 @@
      */
     /* package */ static CallNotifier init(PhoneGlobals app, Phone phone, Ringer ringer,
             CallLogger callLogger, CallStateMonitor callStateMonitor,
-            BluetoothManager bluetoothManager) {
+            BluetoothManager bluetoothManager, CallModeler callModeler) {
         synchronized (CallNotifier.class) {
             if (sInstance == null) {
                 sInstance = new CallNotifier(app, phone, ringer, callLogger, callStateMonitor,
-                        bluetoothManager);
+                        bluetoothManager, callModeler);
             } else {
                 Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);
             }
@@ -188,11 +189,13 @@
 
     /** Private constructor; @see init() */
     private CallNotifier(PhoneGlobals app, Phone phone, Ringer ringer, CallLogger callLogger,
-            CallStateMonitor callStateMonitor, BluetoothManager bluetoothManager) {
+            CallStateMonitor callStateMonitor, BluetoothManager bluetoothManager,
+            CallModeler callModeler) {
         mApplication = app;
         mCM = app.mCM;
         mCallLogger = callLogger;
         mBluetoothManager = bluetoothManager;
+        mCallModeler = callModeler;
 
         mAudioManager = (AudioManager) mApplication.getSystemService(Context.AUDIO_SERVICE);
 
@@ -1678,6 +1681,8 @@
             //Create the SignalInfo tone player and pass the ToneID
             new SignalInfoTonePlayer(toneID).start();
         }
+
+        mCallModeler.onCdmaCallWaiting(infoCW);
     }
 
     /**
@@ -1731,6 +1736,10 @@
             //Reset the mCallWaitingTimeOut boolean
             mCallWaitingTimeOut = false;
         }
+
+        // Call modeler needs to know about this event regardless of the
+        // state conditionals in the previous code.
+        mCallModeler.onCdmaCallWaitingReject();
     }
 
     /**
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 45ffd33..214402d 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -531,7 +531,7 @@
             // launching the incoming-call UI when an incoming call comes
             // in.)
             notifier = CallNotifier.init(this, phone, ringer, callLogger, callStateMonitor,
-                    bluetoothManager);
+                    bluetoothManager, callModeler);
 
             // register for ICC status
             IccCard sim = phone.getIccCard();
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index c37fe07..1ce46b2 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -297,7 +297,7 @@
     }
 
     private boolean showCallScreenInternal(boolean specifyInitialDialpadState,
-                                           boolean initialDialpadState) {
+                                           boolean showDialpad) {
         if (!PhoneGlobals.sVoiceCapable) {
             // Never allow the InCallScreen to appear on data-only devices.
             return false;
@@ -308,7 +308,7 @@
         // If the phone isn't idle then go to the in-call screen
         long callingId = Binder.clearCallingIdentity();
 
-        mCallHandlerService.bringToForeground();
+        mCallHandlerService.bringToForeground(showDialpad);
 
         Binder.restoreCallingIdentity(callingId);
         return true;