Merge "Adding the ability for carrier app to override SPN and carrier name." into lmp-dev
diff --git a/src/java/android/telephony/SmsManager.java b/src/java/android/telephony/SmsManager.java
index 9a6d24a..ff6e46c 100644
--- a/src/java/android/telephony/SmsManager.java
+++ b/src/java/android/telephony/SmsManager.java
@@ -1037,7 +1037,6 @@
      * @param sentIntent if not NULL this <code>PendingIntent</code> is
      *  broadcast when the message is successfully sent, or failed
      * @throws IllegalArgumentException if pdu is empty
-     * {@hide}
      */
     public void sendMultimediaMessage(long subId, byte[] pdu, String locationUrl,
             PendingIntent sentIntent) {
@@ -1078,7 +1077,6 @@
      * @param downloadedIntent if not NULL this <code>PendingIntent</code> is
      *  broadcast when the message is downloaded, or the download is failed
      * @throws IllegalArgumentException if locationUrl is empty
-     * {@hide}
      */
     public void downloadMultimediaMessage(long subId, String locationUrl,
             PendingIntent downloadedIntent) {
@@ -1396,7 +1394,6 @@
      *  raw pdu of the status report is in the extended data ("pdu").
      *
      * @throws IllegalArgumentException if messageUri is empty
-     * {@hide}
      */
     public void sendStoredTextMessage(long subId, Uri messageUri, String scAddress,
             PendingIntent sentIntent, PendingIntent deliveryIntent) {
@@ -1483,7 +1480,6 @@
      *   extended data ("pdu").
      *
      * @throws IllegalArgumentException if messageUri is empty
-     * {@hide}
      */
     public void sendStoredMultipartTextMessage(long subId, Uri messageUri, String scAddress,
             ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
@@ -1525,7 +1521,6 @@
      * @param sentIntent if not NULL this <code>PendingIntent</code> is
      *  broadcast when the message is successfully sent, or failed
      * @throws IllegalArgumentException if messageUri is empty
-     * {@hide}
      */
     public void sendStoredMultimediaMessage(long subId, Uri messageUri, PendingIntent sentIntent) {
         if (messageUri == null) {
diff --git a/src/java/com/android/internal/telephony/CallManager.java b/src/java/com/android/internal/telephony/CallManager.java
index 0f30a4c..75227ad 100644
--- a/src/java/com/android/internal/telephony/CallManager.java
+++ b/src/java/com/android/internal/telephony/CallManager.java
@@ -26,6 +26,7 @@
 import android.os.Message;
 import android.os.RegistrantList;
 import android.os.Registrant;
+import android.telecomm.VideoCallProfile;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -707,7 +708,8 @@
             }
         }
 
-        ringingPhone.acceptCall();
+        // We only support the AUDIO_ONLY video state in this scenario.
+        ringingPhone.acceptCall(VideoCallProfile.VIDEO_STATE_AUDIO_ONLY);
 
         if (VDBG) {
             Rlog.d(LOG_TAG, "End acceptCall(" +ringingCall + ")");
diff --git a/src/java/com/android/internal/telephony/CommandsInterface.java b/src/java/com/android/internal/telephony/CommandsInterface.java
index e75de0b..3d14b86 100644
--- a/src/java/com/android/internal/telephony/CommandsInterface.java
+++ b/src/java/com/android/internal/telephony/CommandsInterface.java
@@ -1655,10 +1655,14 @@
      * Base64 encoded Strings.
      * Can support EAP-SIM, EAP-AKA with results encoded per 3GPP TS 31.102.
      *
+     * @param authContext is the P2 parameter that specifies the authentication context per 3GPP TS
+     *                    31.102 (Section 7.1.2)
      * @param data authentication challenge data
+     * @param aid used to determine which application/slot to send the auth command to. See ETSI
+     *            102.221 8.1 and 101.220 4
      * @param response a callback message with the String response in the obj field
      */
-    public void requestIccSimAuthentication(String data, Message response);
+    public void requestIccSimAuthentication(int authContext, String data, String aid, Message response);
 
     /**
      * Get the current Voice Radio Technology.
diff --git a/src/java/com/android/internal/telephony/Connection.java b/src/java/com/android/internal/telephony/Connection.java
index e1ef562..3d096cf 100644
--- a/src/java/com/android/internal/telephony/Connection.java
+++ b/src/java/com/android/internal/telephony/Connection.java
@@ -21,25 +21,52 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
 
 /**
  * {@hide}
  */
 public abstract class Connection {
-
     public interface PostDialListener {
         void onPostDialWait();
     }
 
+    /**
+     * Listener interface for events related to the connection which should be reported to the
+     * {@link android.telecomm.Connection}.
+     */
+    public interface Listener {
+        public void onVideoStateChanged(int videoState);
+        public void onLocalVideoCapabilityChanged(boolean capable);
+        public void onRemoteVideoCapabilityChanged(boolean capable);
+    }
+
+    /**
+     * Base listener implementation.
+     */
+    public abstract static class ListenerBase implements Listener {
+        @Override
+        public void onVideoStateChanged(int videoState) {}
+        @Override
+        public void onLocalVideoCapabilityChanged(boolean capable) {}
+        @Override
+        public void onRemoteVideoCapabilityChanged(boolean capable) {}
+    }
+
     //Caller Name Display
     protected String mCnapName;
     protected int mCnapNamePresentation  = PhoneConstants.PRESENTATION_ALLOWED;
 
     private List<PostDialListener> mPostDialListeners = new ArrayList<>();
+    private final Set<Listener> mListeners = new CopyOnWriteArraySet<>();
 
     private static String LOG_TAG = "Connection";
 
     Object mUserData;
+    private int mVideoState;
+    private boolean mLocalVideoCapable;
+    private boolean mRemoteVideoCapable;
 
     /* Instance Methods */
 
@@ -310,6 +337,89 @@
     public abstract boolean isMultiparty();
 
     /**
+     * Assign a listener to be notified of state changes.
+     *
+     * @param listener A listener.
+     */
+    public final void addListener(Listener listener) {
+        mListeners.add(listener);
+    }
+
+    /**
+     * Removes a listener.
+     *
+     * @param listener A listener.
+     */
+    public final void removeListener(Listener listener) {
+        mListeners.remove(listener);
+    }
+
+    /**
+     * Returns the current video state of the connection.
+     *
+     * @return The video state of the connection.
+     */
+    public int getVideoState() {
+        return mVideoState;
+    }
+
+    /**
+     * Returns the local video capability state for the connection.
+     *
+     * @return {@code True} if the connection has local video capabilities.
+     */
+    public boolean isLocalVideoCapable() {
+        return mLocalVideoCapable;
+    }
+
+    /**
+     * Returns the remote video capability state for the connection.
+     *
+     * @return {@code True} if the connection has remote video capabilities.
+     */
+    public boolean isRemoteVideoCapable() {
+        return mRemoteVideoCapable;
+    }
+
+
+    /**
+     * Sets the videoState for the current connection and reports the changes to all listeners.
+     * Valid video states are defined in {@link VideoCallProfile}.
+     *
+     * @return The video state.
+     */
+    public void setVideoState(int videoState) {
+        mVideoState = videoState;
+        for (Listener l : mListeners) {
+            l.onVideoStateChanged(mVideoState);
+        }
+    }
+
+    /**
+     * Sets whether video capability is present locally.
+     *
+     * @param capable {@code True} if video capable.
+     */
+    public void setLocalVideoCapable(boolean capable) {
+        mLocalVideoCapable = capable;
+        for (Listener l : mListeners) {
+            l.onLocalVideoCapabilityChanged(mLocalVideoCapable);
+        }
+    }
+
+    /**
+     * Sets whether video capability is present remotely.
+     *
+     * @param capable {@code True} if video capable.
+     */
+    public void setRemoteVideoCapable(boolean capable) {
+        mRemoteVideoCapable = capable;
+        for (Listener l : mListeners) {
+            l.onRemoteVideoCapabilityChanged(mRemoteVideoCapable);
+        }
+    }
+
+    /**
      * Build a human representation of a connection instance, suitable for debugging.
      * Don't log personal stuff unless in debug mode.
      * @return a string representing the internal state of this connection.
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index 6a5a82d..517557c 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -647,9 +647,10 @@
      * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
      * java.lang.Object) registerForPreciseCallStateChanged()}.
      *
+     * @param videoState The video state in which to answer the call.
      * @exception CallStateException when no call is ringing or waiting
      */
-    void acceptCall() throws CallStateException;
+    void acceptCall(int videoState) throws CallStateException;
 
     /**
      * Reject (ignore) a ringing call. In GSM, this means UDUB
diff --git a/src/java/com/android/internal/telephony/PhoneProxy.java b/src/java/com/android/internal/telephony/PhoneProxy.java
index e043bf9..e78db0d 100644
--- a/src/java/com/android/internal/telephony/PhoneProxy.java
+++ b/src/java/com/android/internal/telephony/PhoneProxy.java
@@ -610,8 +610,8 @@
     }
 
     @Override
-    public void acceptCall() throws CallStateException {
-        mActivePhone.acceptCall();
+    public void acceptCall(int videoState) throws CallStateException {
+        mActivePhone.acceptCall(videoState);
     }
 
     @Override
diff --git a/src/java/com/android/internal/telephony/PhoneSubInfo.java b/src/java/com/android/internal/telephony/PhoneSubInfo.java
index 4da8e9e..0e5dffd 100755
--- a/src/java/com/android/internal/telephony/PhoneSubInfo.java
+++ b/src/java/com/android/internal/telephony/PhoneSubInfo.java
@@ -279,7 +279,15 @@
             return null;
         }
 
-        return uiccApp.getIccRecords().getIccSimChallengeResponse(data);
+        int authContext = uiccApp.getAuthContext();
+
+        if(authContext == UiccCardApplication.AUTH_CONTEXT_UNDEFINED) {
+            Rlog.e(LOG_TAG, "getIccSimChallengeResponse() authContext undefined for app type " +
+                    appType);
+            return null;
+        }
+
+        return uiccApp.getIccRecords().getIccSimChallengeResponse(authContext, data);
     }
 
     private void log(String s) {
diff --git a/src/java/com/android/internal/telephony/RIL.java b/src/java/com/android/internal/telephony/RIL.java
index 3b3c245..6089690 100644
--- a/src/java/com/android/internal/telephony/RIL.java
+++ b/src/java/com/android/internal/telephony/RIL.java
@@ -2496,7 +2496,7 @@
             case RIL_REQUEST_SET_UICC_SUBSCRIPTION: ret = responseVoid(p); break;
             case RIL_REQUEST_ALLOW_DATA: ret = responseVoid(p); break;
             case RIL_REQUEST_GET_HARDWARE_CONFIG: ret = responseHardwareConfig(p); break;
-            case RIL_REQUEST_SIM_AUTHENTICATION: ret =  responseString(p); break;
+            case RIL_REQUEST_SIM_AUTHENTICATION: ret =  responseICC_IO(p); break;
             default:
                 throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
             //break;
@@ -4198,10 +4198,13 @@
     }
 
     @Override
-    public void requestIccSimAuthentication(String data, Message response) {
+    public void requestIccSimAuthentication(int authContext, String data, String aid,
+                                            Message response) {
         RILRequest rr = RILRequest.obtain(RIL_REQUEST_SIM_AUTHENTICATION, response);
 
+        rr.mParcel.writeInt(authContext);
         rr.mParcel.writeString(data);
+        rr.mParcel.writeString(aid);
 
         if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
diff --git a/src/java/com/android/internal/telephony/cdma/CDMAPhone.java b/src/java/com/android/internal/telephony/cdma/CDMAPhone.java
index d4fb7e3..8d6757b 100644
--- a/src/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/src/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -43,6 +43,7 @@
 import android.text.TextUtils;
 import android.telephony.Rlog;
 
+import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallStateException;
 import com.android.internal.telephony.CallTracker;
 import com.android.internal.telephony.CommandException;
@@ -316,7 +317,12 @@
     }
 
     @Override
-    public CdmaCall getRingingCall() {
+    public Call getRingingCall() {
+        if ( mCT.mRingingCall != null && mCT.mRingingCall.isRinging() ) {
+            return mCT.mRingingCall;
+        } else if ( mImsPhone != null ) {
+            return mImsPhone.getRingingCall();
+        }
         return mCT.mRingingCall;
     }
 
@@ -466,8 +472,12 @@
 
     @Override
     public void
-    acceptCall() throws CallStateException {
-        mCT.acceptCall();
+    acceptCall(int videoState) throws CallStateException {
+        if ( mImsPhone != null && mImsPhone.getRingingCall().isRinging() ) {
+            mImsPhone.acceptCall(videoState);
+        } else {
+            mCT.acceptCall();
+        }
     }
 
     @Override
@@ -971,8 +981,7 @@
          mNotifier.notifyCellLocation(this);
      }
 
-    /*package*/ void notifyNewRingingConnection(Connection c) {
-        /* we'd love it if this was package-scoped*/
+    public void notifyNewRingingConnection(Connection c) {
         super.notifyNewRingingConnectionP(c);
     }
 
diff --git a/src/java/com/android/internal/telephony/gsm/GSMPhone.java b/src/java/com/android/internal/telephony/gsm/GSMPhone.java
index 6d2a8ad..7f73edb 100644
--- a/src/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/src/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -435,9 +435,7 @@
         super.notifyPreciseCallStateChangedP();
     }
 
-    /*package*/ void
-    notifyNewRingingConnection(Connection c) {
-        /* we'd love it if this was package-scoped*/
+    public void notifyNewRingingConnection(Connection c) {
         super.notifyNewRingingConnectionP(c);
     }
 
@@ -507,8 +505,12 @@
 
     @Override
     public void
-    acceptCall() throws CallStateException {
-        mCT.acceptCall();
+    acceptCall(int videoState) throws CallStateException {
+        if ( mImsPhone != null && mImsPhone.getRingingCall().isRinging() ) {
+            mImsPhone.acceptCall(videoState);
+        } else {
+            mCT.acceptCall();
+        }
     }
 
     @Override
@@ -565,8 +567,12 @@
     }
 
     @Override
-    public GsmCall
-    getRingingCall() {
+    public Call getRingingCall() {
+        if ( mCT.mRingingCall != null && mCT.mRingingCall.isRinging() ) {
+            return mCT.mRingingCall;
+        } else if ( mImsPhone != null ) {
+            return mImsPhone.getRingingCall();
+        }
         return mCT.mRingingCall;
     }
 
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
index ea0def6..fabe022 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
@@ -174,7 +174,7 @@
 
     @Override
     public void
-    acceptCall() throws CallStateException {
+    acceptCall(int videoState) throws CallStateException {
         mCT.acceptCall();
     }
 
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
index b2b6155..6efc153 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
@@ -34,10 +34,14 @@
 import com.android.internal.telephony.CallStateException;
 import com.android.internal.telephony.Connection;
 import com.android.internal.telephony.dataconnection.DataConnection;
+import com.android.internal.telephony.cdma.CDMAPhone;
+import com.android.internal.telephony.gsm.GSMPhone;
+import com.android.internal.telephony.CallManager;
 import com.android.internal.telephony.IccCard;
 import com.android.internal.telephony.IccPhoneBookInterfaceManager;
 import com.android.internal.telephony.MmiCode;
 import com.android.internal.telephony.OperatorInfo;
+import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneBase;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneNotifier;
@@ -213,7 +217,13 @@
     }
 
     void notifyNewRingingConnection(Connection c) {
-        super.notifyNewRingingConnectionP(c);
+        Phone defaultPhone = CallManager.getInstance().getDefaultPhone();
+        if ( defaultPhone != null && defaultPhone.getPhoneType() ==
+                PhoneConstants.PHONE_TYPE_GSM ) {
+           ((GSMPhone) defaultPhone).notifyNewRingingConnection(c);
+        } else { // Should be CDMA - also go here by default
+            ((CDMAPhone) defaultPhone).notifyNewRingingConnection(c);
+        }
     }
 
     void notifyDisconnect(Connection cn) {
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java
index a6cab1e..0665300 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java
@@ -32,7 +32,7 @@
 /**
  * {@hide}
  */
-class ImsPhoneCall extends Call {
+public class ImsPhoneCall extends Call {
     /*************************** Instance Variables **************************/
 
     private static final String LOG_TAG = "ImsPhoneCall";
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index 07e4f8f..5dfa43b 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -330,7 +330,9 @@
         setMute(false);
         int serviceType = PhoneNumberUtils.isEmergencyNumber(conn.getAddress()) ?
                 ImsCallProfile.SERVICE_TYPE_EMERGENCY : ImsCallProfile.SERVICE_TYPE_NORMAL;
-        int callType = getCallType(videoState);
+        int callType = ImsCallProfile.getCallTypeFromVideoState(videoState);
+        //TODO(vt): Is this sufficient?  At what point do we know the video state of the call?
+        conn.setVideoState(videoState);
 
         try {
             String[] callees = new String[] { conn.getAddress() };
@@ -348,40 +350,6 @@
         }
     }
 
-    /**
-     * Converts from the video state values defined in {@link VideoCallProfile} to the call types
-     * defined in {@link ImsCallProfile}.
-     *
-     * @param videoState The video state.
-     * @return The call type.
-     */
-    private int getCallType(int videoState) {
-        boolean videoTx = isVideoStateSet(videoState, VideoCallProfile.VIDEO_STATE_TX_ENABLED);
-        boolean videoRx = isVideoStateSet(videoState, VideoCallProfile.VIDEO_STATE_RX_ENABLED);
-        boolean isPaused = isVideoStateSet(videoState, VideoCallProfile.VIDEO_STATE_PAUSED);
-        if (isPaused) {
-            return ImsCallProfile.CALL_TYPE_VT_NODIR;
-        } else if (videoTx && !videoRx) {
-            return ImsCallProfile.CALL_TYPE_VT_TX;
-        } else if (!videoTx && videoRx) {
-            return ImsCallProfile.CALL_TYPE_VT_RX;
-        } else if (videoTx && videoRx) {
-            return ImsCallProfile.CALL_TYPE_VT;
-        }
-        return ImsCallProfile.CALL_TYPE_VOICE;
-    }
-
-    /**
-     * Determines if a video state is set in a video state bit-mask.
-     *
-     * @param videoState The video state bit mask.
-     * @param videoStateToCheck The particular video state to check.
-     * @return True if the video state is set in the bit-mask.
-     */
-    private boolean isVideoStateSet(int videoState, int videoStateToCheck) {
-        return (videoState & videoStateToCheck) == videoStateToCheck;
-    }
-
     void
     acceptCall () throws CallStateException {
         if (DBG) log("acceptCall");
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCommandInterface.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCommandInterface.java
index d59d4a1..b804075 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCommandInterface.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCommandInterface.java
@@ -538,7 +538,7 @@
     }
 
     @Override
-    public void requestIccSimAuthentication(String data, Message response) {
+    public void requestIccSimAuthentication(int authContext, String data, String aid, Message response) {
     }
 
     @Override
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
index 77ae57d..6603cbe 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
@@ -24,6 +24,7 @@
 import android.os.PowerManager;
 import android.os.Registrant;
 import android.os.SystemClock;
+import android.telecomm.VideoCallProfile;
 import android.telephony.DisconnectCause;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.Rlog;
@@ -143,6 +144,15 @@
                     imsCall.getCallProfile().getCallExtraInt(ImsCallProfile.EXTRA_OIR));
             mCnapNamePresentation = presentationFromOir(
                     imsCall.getCallProfile().getCallExtraInt(ImsCallProfile.EXTRA_CNAP));
+
+            ImsCallProfile imsCallProfile = imsCall.getCallProfile();
+            if (imsCallProfile != null) {
+                int callType = imsCall.getCallProfile().mCallType;
+                setVideoState(ImsCallProfile.getVideoStateFromCallType(callType));
+            }
+            //TODO(vt): Set the local and remote video capabilities appropriately.
+            setLocalVideoCapable(true);
+            setRemoteVideoCapable(true);
         } else {
             mNumberPresentation = PhoneConstants.PRESENTATION_UNKNOWN;
             mCnapNamePresentation = PhoneConstants.PRESENTATION_UNKNOWN;
@@ -641,3 +651,4 @@
         }
     }
 }
+
diff --git a/src/java/com/android/internal/telephony/sip/SipCommandInterface.java b/src/java/com/android/internal/telephony/sip/SipCommandInterface.java
index 6223e48..83f95fb 100644
--- a/src/java/com/android/internal/telephony/sip/SipCommandInterface.java
+++ b/src/java/com/android/internal/telephony/sip/SipCommandInterface.java
@@ -540,7 +540,7 @@
     }
 
     @Override
-    public void requestIccSimAuthentication(String data, Message response) {
+    public void requestIccSimAuthentication(int authContext, String data, String aid, Message response) {
     }
 
     @Override
diff --git a/src/java/com/android/internal/telephony/sip/SipPhone.java b/src/java/com/android/internal/telephony/sip/SipPhone.java
index 4ecfe58..6edee55 100644
--- a/src/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/src/java/com/android/internal/telephony/sip/SipPhone.java
@@ -144,7 +144,7 @@
     }
 
     @Override
-    public void acceptCall() throws CallStateException {
+    public void acceptCall(int videoState) throws CallStateException {
         synchronized (SipPhone.class) {
             if ((mRingingCall.getState() == Call.State.INCOMING) ||
                     (mRingingCall.getState() == Call.State.WAITING)) {
diff --git a/src/java/com/android/internal/telephony/test/SimulatedCommands.java b/src/java/com/android/internal/telephony/test/SimulatedCommands.java
index 250e507..0aef631 100644
--- a/src/java/com/android/internal/telephony/test/SimulatedCommands.java
+++ b/src/java/com/android/internal/telephony/test/SimulatedCommands.java
@@ -1643,7 +1643,7 @@
     }
 
     @Override
-    public void requestIccSimAuthentication(String data, Message response) {
+    public void requestIccSimAuthentication(int authContext, String data, String aid, Message response) {
         unimplemented(response);
     }
 
diff --git a/src/java/com/android/internal/telephony/uicc/IccRecords.java b/src/java/com/android/internal/telephony/uicc/IccRecords.java
index e54dfa4..6c68dae 100644
--- a/src/java/com/android/internal/telephony/uicc/IccRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/IccRecords.java
@@ -67,7 +67,7 @@
     protected boolean mIsVoiceMailFixed = false;
     protected int mCountVoiceMessages = 0;
     protected String mImsi;
-    private String auth_rsp;
+    private IccIoResult auth_rsp;
 
     protected int mMncLength = UNINITIALIZED;
     protected int mMailboxIndex = 0; // 0 is no mailbox dailing number associated
@@ -432,7 +432,7 @@
                     loge("Exception ICC SIM AKA: " + ar.exception);
                 } else {
                     try {
-                        auth_rsp = (String)ar.result;
+                        auth_rsp = (IccIoResult)ar.result;
                         if (DBG) log("ICC SIM AKA: auth_rsp = " + auth_rsp);
                     } catch (Exception e) {
                         loge("Failed to parse ICC SIM AKA contents: " + e);
@@ -543,19 +543,17 @@
      * Base64 encoded Strings.
      * Can support EAP-SIM, EAP-AKA with results encoded per 3GPP TS 31.102.
      *
+     * @param authContext parameter P2 that specifies the authentication context per 3GPP TS 31.102 (Section 7.1.2)
      * @param data authentication challenge data
      * @return challenge response
      */
-    public String getIccSimChallengeResponse(String data) {
-        if (DBG) log("getIccSimChallengeResponse-data: (original) " + data);
-
-        data = data + mParentApp.getAid();
-
-        if (DBG) log("getIccSimChallengeResponse-data: (with AID) " + data);
+    public String getIccSimChallengeResponse(int authContext, String data) {
+        if (DBG) log("getIccSimChallengeResponse-data: " + data);
 
         try {
             synchronized(mLock) {
-                mCi.requestIccSimAuthentication(data, obtainMessage(EVENT_AKA_AUTHENTICATE_DONE));
+                mCi.requestIccSimAuthentication(authContext, data, mParentApp.getAid(),
+                        obtainMessage(EVENT_AKA_AUTHENTICATE_DONE));
                 try {
                     mLock.wait();
                 } catch (InterruptedException e) {
@@ -569,7 +567,7 @@
 
         if (DBG) log("getIccSimChallengeResponse-auth_rsp" + auth_rsp);
 
-        return auth_rsp;
+        return IccUtils.bytesToHexString(auth_rsp.payload);
     }
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java b/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
index 94efb98..72bb02f 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
@@ -25,6 +25,7 @@
 import android.telephony.Rlog;
 
 import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState;
@@ -49,10 +50,18 @@
     private static final int EVENT_CHANGE_FACILITY_LOCK_DONE = 7;
     private static final int EVENT_PIN2_PUK2_DONE = 8;
 
+    /**
+     * These values are for authContext (parameter P2) per 3GPP TS 31.102 (Section 7.1.2)
+     */
+    public static final int AUTH_CONTEXT_EAP_SIM = 128;
+    public static final int AUTH_CONTEXT_EAP_AKA = 129;
+    public static final int AUTH_CONTEXT_UNDEFINED = -1;
+
     private final Object  mLock = new Object();
     private UiccCard      mUiccCard; //parent
     private AppState      mAppState;
     private AppType       mAppType;
+    private int           mAuthContext;
     private PersoSubState mPersoSubState;
     private String        mAid;
     private String        mAppLabel;
@@ -84,6 +93,7 @@
         mUiccCard = uiccCard;
         mAppState = as.app_state;
         mAppType = as.app_type;
+        mAuthContext = getAuthContext(mAppType);
         mPersoSubState = as.perso_substate;
         mAid = as.aid;
         mAppLabel = as.app_label;
@@ -116,6 +126,7 @@
             AppState oldAppState = mAppState;
             PersoSubState oldPersoSubState = mPersoSubState;
             mAppType = as.app_type;
+            mAuthContext = getAuthContext(mAppType);
             mAppState = as.app_state;
             mPersoSubState = as.perso_substate;
             mAid = as.aid;
@@ -536,6 +547,39 @@
         }
     }
 
+    public int getAuthContext() {
+        synchronized (mLock) {
+            return mAuthContext;
+        }
+    }
+
+    /**
+     * Returns the authContext based on the type of UiccCard.
+     *
+     * @param appType the app type
+     * @return authContext corresponding to the type or AUTH_CONTEXT_UNDEFINED if appType not
+     * supported
+     */
+    private static int getAuthContext(AppType appType) {
+        int authContext;
+
+        switch (appType) {
+            case APPTYPE_SIM:
+                authContext = AUTH_CONTEXT_EAP_SIM;
+                break;
+
+            case APPTYPE_USIM:
+                authContext = AUTH_CONTEXT_EAP_AKA;
+                break;
+
+            default:
+                authContext = AUTH_CONTEXT_UNDEFINED;
+                break;
+        }
+
+        return authContext;
+    }
+
     public PersoSubState getPersoSubState() {
         synchronized (mLock) {
             return mPersoSubState;
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
index 3a0d01c..55ddef8 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
@@ -52,7 +52,10 @@
  * after the UICC can be read. And it should be deleted when a UICC is changed.
  *
  * The spec for the rules:
- *     TODO: Put link here.
+ *     GP Secure Element Access Control:
+ *     http://www.globalplatform.org/specifications/review/GPD_SE_Access_Control_v1.0.20.pdf
+ *     Extension spec:
+ *     https://code.google.com/p/seek-for-android/
  *
  *
  * TODO: Notifications.
@@ -62,7 +65,7 @@
 public class UiccCarrierPrivilegeRules extends Handler {
     private static final String LOG_TAG = "UiccCarrierPrivilegeRules";
 
-    private static final String AID = "A0000000015141434C00";
+    private static final String AID = "A00000015141434C00";
     private static final int CLA = 0x80;
     private static final int COMMAND = 0xB0;
     private static final int P1 = 0x00;