Merge "Report data status from ApnContext even if data is detached" into honeycomb-LTE
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index ce8a9397..1ed5ad7 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -3940,7 +3940,11 @@
                         // approches 1.0.  Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2).
                         PointerGesture::Delta& delta1 = mPointerGesture.referenceDeltas[id1];
                         PointerGesture::Delta& delta2 = mPointerGesture.referenceDeltas[id2];
-                        float dot = delta1.dx * delta2.dx + delta1.dy * delta2.dy;
+                        float dx1 = delta1.dx * mLocked.pointerGestureXZoomScale;
+                        float dy1 = delta1.dy * mLocked.pointerGestureYZoomScale;
+                        float dx2 = delta2.dx * mLocked.pointerGestureXZoomScale;
+                        float dy2 = delta2.dy * mLocked.pointerGestureYZoomScale;
+                        float dot = dx1 * dx2 + dy1 * dy2;
                         float cosine = dot / (dist1 * dist2); // denominator always > 0
                         if (cosine >= mConfig->pointerGestureSwipeTransitionAngleCosine) {
                             // Pointers are moving in the same direction.  Switch to SWIPE.
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index 82faf7d..fa3239c 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -143,7 +143,7 @@
             pointerGestureTapSlop(10.0f), // 10 pixels
             pointerGestureMultitouchSettleInterval(100 * 1000000LL), // 100 ms
             pointerGestureMultitouchMinDistance(15), // 15 pixels
-            pointerGestureSwipeTransitionAngleCosine(0.5f), // cosine of 45degrees
+            pointerGestureSwipeTransitionAngleCosine(0.2588f), // cosine of 75 degrees
             pointerGestureSwipeMaxWidthRatio(0.25f),
             pointerGestureMovementSpeedRatio(0.8f),
             pointerGestureZoomSpeedRatio(0.3f) { }
diff --git a/telephony/java/com/android/internal/telephony/IccConstants.java b/telephony/java/com/android/internal/telephony/IccConstants.java
index cafc79b..1ba6dfe 100644
--- a/telephony/java/com/android/internal/telephony/IccConstants.java
+++ b/telephony/java/com/android/internal/telephony/IccConstants.java
@@ -63,6 +63,10 @@
     // 3GPP2 C.S0065
     static final int EF_CSIM_LI = 0x6F3A;
     static final int EF_CSIM_SPN =0x6F41;
+    static final int EF_CSIM_MDN = 0x6F44;
+    static final int EF_CSIM_IMSIM = 0x6F22;
+    static final int EF_CSIM_CDMAHOME = 0x6F28;
+    static final int EF_CSIM_EPRL = 0x6F5A;
 
     //ISIM access
     static final int EF_IMPU = 0x6f04;
diff --git a/telephony/java/com/android/internal/telephony/IccRecords.java b/telephony/java/com/android/internal/telephony/IccRecords.java
index 10a3b69..3a27901 100644
--- a/telephony/java/com/android/internal/telephony/IccRecords.java
+++ b/telephony/java/com/android/internal/telephony/IccRecords.java
@@ -288,6 +288,16 @@
     }
 
     /**
+     * Indicates wether SIM is in provisioned state or not.
+     * Overridden only if SIM can be dynamically provisioned via OTA.
+     *
+     * @return true if provisioned
+     */
+    public boolean isProvisioned () {
+        return true;
+    }
+
+    /**
      * Write string to log file
      *
      * @param s is the string to write
diff --git a/telephony/java/com/android/internal/telephony/IccUtils.java b/telephony/java/com/android/internal/telephony/IccUtils.java
index df579b0..8e60e6e 100644
--- a/telephony/java/com/android/internal/telephony/IccUtils.java
+++ b/telephony/java/com/android/internal/telephony/IccUtils.java
@@ -63,6 +63,29 @@
         return ret.toString();
     }
 
+    /**
+     * Decode cdma byte into String.
+     */
+    public static String
+    cdmaBcdToString(byte[] data, int offset, int length) {
+        StringBuilder ret = new StringBuilder(length);
+
+        int count = 0;
+        for (int i = offset; count < length; i++) {
+            int v;
+            v = data[i] & 0xf;
+            if (v > 9)  v = 0;
+            ret.append((char)('0' + v));
+
+            if (++count == length) break;
+
+            v = (data[i] >> 4) & 0xf;
+            if (v > 9)  v = 0;
+            ret.append((char)('0' + v));
+            ++count;
+        }
+        return ret.toString();
+    }
 
     /**
      * Decodes a GSM-style BCD byte, returning an int ranging from 0-99.
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
index faae622..318cf37 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
@@ -67,11 +67,24 @@
         case EVENT_SIM_READY:
             if (DBG) log("handleMessage EVENT_SIM_READY");
             isSubscriptionFromRuim = false;
-            cm.getCDMASubscription( obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION));
+            // Register SIM_RECORDS_LOADED dynamically.
+            // This is to avoid confilct with RUIM_READY scenario)
+            phone.mIccRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
             pollState();
             // Signal strength polling stops when radio is off.
             queueNextSignalStrengthPoll();
             break;
+        case EVENT_SIM_RECORDS_LOADED:
+            CdmaLteUiccRecords sim = (CdmaLteUiccRecords)phone.mIccRecords;
+            if ((sim != null) && sim.isProvisioned()) {
+                mMdn = sim.getMdn();
+                mMin = sim.getMin();
+                parseSidNid(sim.getSid(), sim.getNid());
+                mPrlVersion = sim.getPrlVersion();;
+                mIsMinInfoReady = true;
+                updateOtaspState();
+            }
+            break;
         default:
             super.handleMessage(msg);
         }
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java
index 2aede29..b9d7c46 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java
@@ -19,6 +19,7 @@
 import android.util.Log;
 import com.android.internal.telephony.IccConstants;
 import com.android.internal.telephony.IccFileHandler;
+import android.os.Message;
 
 /**
  * {@hide}
@@ -34,6 +35,10 @@
         switch(efid) {
         case EF_CSIM_SPN:
         case EF_CSIM_LI:
+        case EF_CSIM_MDN:
+        case EF_CSIM_IMSIM:
+        case EF_CSIM_CDMAHOME:
+        case EF_CSIM_EPRL:
             return MF_SIM + DF_CDMA;
         case EF_AD:
             return MF_SIM + DF_GSM;
@@ -41,6 +46,21 @@
         return getCommonIccEFPath(efid);
     }
 
+    @Override
+    public void loadEFTransparent(int fileid, Message onLoaded) {
+        if (fileid == EF_CSIM_EPRL) {
+            // Entire PRL could be huge. We are only interested in
+            // the first 4 bytes of the record.
+            phone.mCM.iccIO(COMMAND_READ_BINARY, fileid, getEFPath(fileid),
+                            0, 0, 4, null, null,
+                            obtainMessage(EVENT_READ_BINARY_DONE,
+                                          fileid, 0, onLoaded));
+        } else {
+            super.loadEFTransparent(fileid, onLoaded);
+        }
+    }
+
+
     protected void logd(String msg) {
         Log.d(LOG_TAG, "[CdmaLteUiccFileHandler] " + msg);
     }
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
index 78879d6..ac77f9a 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
@@ -26,7 +26,8 @@
 import android.os.Message;
 import android.os.SystemProperties;
 import android.util.Log;
-
+import java.util.Locale;
+import java.util.ArrayList;
 
 /**
  * {@hide}
@@ -36,10 +37,19 @@
     private byte[] mEFpl = null;
     private byte[] mEFli = null;
     boolean csimSpnDisplayCondition = false;
+    private String mMdn;
+    private String mMin;
+    private String mPrlVersion;
+    private String mHomeSystemId;
+    private String mHomeNetworkId;
 
     private static final int EVENT_GET_PL_DONE = CSIM_EVENT_BASE;
     private static final int EVENT_GET_CSIM_LI_DONE = CSIM_EVENT_BASE + 1;
     private static final int EVENT_GET_CSIM_SPN_DONE = CSIM_EVENT_BASE + 2;
+    private static final int EVENT_GET_CSIM_MDN_DONE = CSIM_EVENT_BASE + 3;
+    private static final int EVENT_GET_CSIM_IMSIM_DONE = CSIM_EVENT_BASE + 4;
+    private static final int EVENT_GET_CSIM_CDMAHOME_DONE = CSIM_EVENT_BASE + 5;
+    private static final int EVENT_GET_CSIM_EPRL_DONE = CSIM_EVENT_BASE + 6;
 
     public CdmaLteUiccRecords(PhoneBase p) {
         super(p);
@@ -109,6 +119,46 @@
                 }
                 onGetCSimSpnDone(ar);
                 break;
+            case EVENT_GET_CSIM_MDN_DONE:
+                if (DBG) log("EVENT_GET_CSIM_MDN_DONE");
+                isCsimRecordLoadResponse = true;
+                ar = (AsyncResult) msg.obj;
+                if (ar.exception != null) {
+                    Log.e(LOG_TAG, "ar.exception=" + ar.exception);
+                    break;
+                }
+                onGetCSimMdnDone(ar);
+                break;
+            case EVENT_GET_CSIM_IMSIM_DONE:
+                if (DBG) log("EVENT_GET_CSIM_IMSIM_DONE");
+                isCsimRecordLoadResponse = true;
+                ar = (AsyncResult) msg.obj;
+                if (ar.exception != null) {
+                    Log.e(LOG_TAG, "ar.exception=" + ar.exception);
+                    break;
+                }
+                onGetCSimImsimDone(ar);
+                break;
+            case EVENT_GET_CSIM_CDMAHOME_DONE:
+                if (DBG) log("EVENT_GET_CSIM_CDMAHOME_DONE");
+                isCsimRecordLoadResponse = true;
+                ar = (AsyncResult) msg.obj;
+                if (ar.exception != null) {
+                    Log.e(LOG_TAG, "ar.exception=" + ar.exception);
+                    break;
+                }
+                onGetCSimCdmaHomeDone(ar);
+                break;
+            case EVENT_GET_CSIM_EPRL_DONE:
+                if (DBG) log("EVENT_GET_CSIM_EPRL_DONE");
+                isCsimRecordLoadResponse = true;
+                ar = (AsyncResult) msg.obj;
+                if (ar.exception != null) {
+                    Log.e(LOG_TAG, "ar.exception=" + ar.exception);
+                    break;
+                }
+                onGetCSimEprlDone(ar);
+                break;
             default:
                 super.handleMessage(msg);
         }}catch (RuntimeException exc) {
@@ -156,6 +206,19 @@
 
         iccFh.loadEFTransparent(EF_CSIM_SPN, obtainMessage(EVENT_GET_CSIM_SPN_DONE));
         recordsToLoad++;
+
+        iccFh.loadEFLinearFixed(EF_CSIM_MDN, 1, obtainMessage(EVENT_GET_CSIM_MDN_DONE));
+        recordsToLoad++;
+
+        iccFh.loadEFTransparent(EF_CSIM_IMSIM, obtainMessage(EVENT_GET_CSIM_IMSIM_DONE));
+        recordsToLoad++;
+
+        iccFh.loadEFLinearFixedAll(EF_CSIM_CDMAHOME,
+                                   obtainMessage(EVENT_GET_CSIM_CDMAHOME_DONE));
+        recordsToLoad++;
+
+        iccFh.loadEFTransparent(EF_CSIM_EPRL, obtainMessage(EVENT_GET_CSIM_EPRL_DONE));
+        recordsToLoad++;
     }
 
     private void onGetCSimSpnDone(AsyncResult ar) {
@@ -205,6 +268,93 @@
         phone.setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, spn);
     }
 
+    private void onGetCSimMdnDone(AsyncResult ar) {
+        byte[] data = (byte[]) ar.result;
+        if (DBG) log("CSIM_MDN=" + IccUtils.bytesToHexString(data));
+        int mdnDigitsNum = 0x0F & data[0];
+        mMdn = IccUtils.cdmaBcdToString(data, 1, mdnDigitsNum);
+        if (DBG) log("CSIM MDN=" + mMdn);
+    }
+
+    private void onGetCSimImsimDone(AsyncResult ar) {
+        byte[] data = (byte[]) ar.result;
+        if (DBG) log("CSIM_IMSIM=" + IccUtils.bytesToHexString(data));
+        // C.S0065 section 5.2.2 for IMSI_M encoding
+        // C.S0005 section 2.3.1 for MIN encoding in IMSI_M.
+        boolean provisioned = ((data[7] & 0x80) == 0x80);
+
+        if (provisioned) {
+            int first3digits = ((0x03 & data[2]) << 8) + (0xFF & data[1]);
+            int second3digits = (((0xFF & data[5]) << 8) | (0xFF & data[4])) >> 6;
+            int digit7 = 0x0F & (data[4] >> 2);
+            if (digit7 > 0x09) digit7 = 0;
+            int last3digits = ((0x03 & data[4]) << 8) | (0xFF & data[3]);
+            first3digits = adjstMinDigits(first3digits);
+            second3digits = adjstMinDigits(second3digits);
+            last3digits = adjstMinDigits(last3digits);
+
+            StringBuilder builder = new StringBuilder();
+            builder.append(String.format(Locale.US, "%03d", first3digits));
+            builder.append(String.format(Locale.US, "%03d", second3digits));
+            builder.append(String.format(Locale.US, "%d", digit7));
+            builder.append(String.format(Locale.US, "%03d", last3digits));
+            if (DBG) log("min present=" + builder.toString());
+
+            mMin = builder.toString();
+        } else {
+            if (DBG) log("min not present");
+        }
+    }
+
+    private int adjstMinDigits (int digits) {
+        // Per C.S0005 section 2.3.1.
+        digits += 111;
+        digits = (digits % 10 == 0)?(digits - 10):digits;
+        digits = ((digits / 10) % 10 == 0)?(digits - 100):digits;
+        digits = ((digits / 100) % 10 == 0)?(digits - 1000):digits;
+        return digits;
+    }
+
+    private void onGetCSimCdmaHomeDone(AsyncResult ar) {
+        // Per C.S0065 section 5.2.8
+        ArrayList<byte[]> dataList = (ArrayList<byte[]>) ar.result;
+        if (DBG) log("CSIM_CDMAHOME data size=" + dataList.size());
+        if (dataList.isEmpty()) {
+            return;
+        }
+        StringBuilder sidBuf = new StringBuilder();
+        StringBuilder nidBuf = new StringBuilder();
+
+        for (byte[] data : dataList) {
+            if (data.length == 5) {
+                int sid = ((data[1] & 0xFF) << 8) | (data[0] & 0xFF);
+                int nid = ((data[3] & 0xFF) << 8) | (data[2] & 0xFF);
+                sidBuf.append(sid).append(",");
+                nidBuf.append(nid).append(",");
+            }
+        }
+        // remove trailing ","
+        sidBuf.setLength(sidBuf.length()-1);
+        nidBuf.setLength(nidBuf.length()-1);
+
+        mHomeSystemId = sidBuf.toString();
+        mHomeNetworkId = nidBuf.toString();
+    }
+
+    private void onGetCSimEprlDone(AsyncResult ar) {
+        // C.S0065 section 5.2.57 for EFeprl encoding
+        // C.S0016 section 3.5.5 for PRL format.
+        byte[] data = (byte[]) ar.result;
+        if (DBG) log("CSIM_EPRL=" + IccUtils.bytesToHexString(data));
+
+        // Only need the first 4 bytes of record
+        if (data.length > 3) {
+            int prlId = ((data[2] & 0xFF) << 8) | (data[3] & 0xFF);
+            mPrlVersion = Integer.toString(prlId);
+        }
+        if (DBG) log("CSIM PRL version=" + mPrlVersion);
+    }
+
     public byte[] getPreferredLanguage() {
         return mEFpl;
     }
@@ -212,4 +362,32 @@
     public byte[] getLanguageIndication() {
         return mEFli;
     }
+
+    public String getMdn() {
+        return mMdn;
+    }
+
+    public String getMin() {
+        return mMin;
+    }
+
+    public String getSid() {
+        return mHomeSystemId;
+    }
+
+    public String getNid() {
+        return mHomeNetworkId;
+    }
+
+    public String getPrlVersion() {
+        return mPrlVersion;
+    }
+
+    @Override
+    public boolean isProvisioned() {
+        // Look for MDN and MIN field to determine if the SIM is provisioned.
+        if ((mMdn != null) && (mMin != null)) return true;
+
+        return false;
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 805ee49..5ebdd22 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -129,12 +129,12 @@
     /** Contains the name of the registered network in CDMA (either ONS or ERI text). */
     private String curPlmn = null;
 
-    private String mMdn;
+    protected String mMdn;
     private int mHomeSystemId[] = null;
     private int mHomeNetworkId[] = null;
-    private String mMin;
-    private String mPrlVersion;
-    private boolean mIsMinInfoReady = false;
+    protected String mMin;
+    protected String mPrlVersion;
+    protected boolean mIsMinInfoReady = false;
 
     private boolean isEriTextLoaded = false;
     protected boolean isSubscriptionFromRuim = false;
@@ -373,53 +373,15 @@
                 String cdmaSubscription[] = (String[])ar.result;
                 if (cdmaSubscription != null && cdmaSubscription.length >= 5) {
                     mMdn = cdmaSubscription[0];
-                    if (cdmaSubscription[1] != null) {
-                        String[] sid = cdmaSubscription[1].split(",");
-                        mHomeSystemId = new int[sid.length];
-                        for (int i = 0; i < sid.length; i++) {
-                            try {
-                                mHomeSystemId[i] = Integer.parseInt(sid[i]);
-                            } catch (NumberFormatException ex) {
-                                loge("error parsing system id: " + ex);
-                            }
-                        }
-                    }
-                    if (DBG) log("GET_CDMA_SUBSCRIPTION: SID=" + cdmaSubscription[1] );
+                    parseSidNid(cdmaSubscription[1], cdmaSubscription[2]);
 
-                    if (cdmaSubscription[2] != null) {
-                        String[] nid = cdmaSubscription[2].split(",");
-                        mHomeNetworkId = new int[nid.length];
-                        for (int i = 0; i < nid.length; i++) {
-                            try {
-                                mHomeNetworkId[i] = Integer.parseInt(nid[i]);
-                            } catch (NumberFormatException ex) {
-                                loge("GET_CDMA_SUBSCRIPTION: error parsing network id: " + ex);
-                            }
-                        }
-                    }
-                    if (DBG) log("GET_CDMA_SUBSCRIPTION: NID=" + cdmaSubscription[2]);
                     mMin = cdmaSubscription[3];
                     mPrlVersion = cdmaSubscription[4];
                     if (DBG) log("GET_CDMA_SUBSCRIPTION: MDN=" + mMdn);
 
                     mIsMinInfoReady = true;
 
-                    int otaspMode = getOtasp();
-                    int oldOtaspMode = mCurrentOtaspMode;
-                    mCurrentOtaspMode = otaspMode;
-
-                    // Notify apps subscription info is ready
-                    if (cdmaForSubscriptionInfoReadyRegistrants != null) {
-                        if (DBG) log("GET_CDMA_SUBSCRIPTION: call notifyRegistrants()");
-                        cdmaForSubscriptionInfoReadyRegistrants.notifyRegistrants();
-                    }
-                    if (oldOtaspMode != mCurrentOtaspMode) {
-                        if (DBG) {
-                            log("GET_CDMA_SUBSCRIPTION: call notifyOtaspChanged old otaspMode=" +
-                                oldOtaspMode + " new otaspMode=" + mCurrentOtaspMode);
-                        }
-                        phone.notifyOtaspChanged(mCurrentOtaspMode);
-                    }
+                    updateOtaspState();
                     phone.getIccCard().broadcastIccStateChangedIntent(IccCard.INTENT_VALUE_ICC_IMSI,
                             null);
                 } else {
@@ -1622,6 +1584,53 @@
         cm.setRadioPower(false, null);
     }
 
+    protected void parseSidNid (String sidStr, String nidStr) {
+        if (sidStr != null) {
+            String[] sid = sidStr.split(",");
+            mHomeSystemId = new int[sid.length];
+            for (int i = 0; i < sid.length; i++) {
+                try {
+                    mHomeSystemId[i] = Integer.parseInt(sid[i]);
+                } catch (NumberFormatException ex) {
+                    loge("error parsing system id: " + ex);
+                }
+            }
+        }
+        if (DBG) log("CDMA_SUBSCRIPTION: SID=" + sidStr);
+
+        if (nidStr != null) {
+            String[] nid = nidStr.split(",");
+            mHomeNetworkId = new int[nid.length];
+            for (int i = 0; i < nid.length; i++) {
+                try {
+                    mHomeNetworkId[i] = Integer.parseInt(nid[i]);
+                } catch (NumberFormatException ex) {
+                    loge("CDMA_SUBSCRIPTION: error parsing network id: " + ex);
+                }
+            }
+        }
+        if (DBG) log("CDMA_SUBSCRIPTION: NID=" + nidStr);
+    }
+
+    protected void updateOtaspState() {
+        int otaspMode = getOtasp();
+        int oldOtaspMode = mCurrentOtaspMode;
+        mCurrentOtaspMode = otaspMode;
+
+        // Notify apps subscription info is ready
+        if (cdmaForSubscriptionInfoReadyRegistrants != null) {
+            if (DBG) log("CDMA_SUBSCRIPTION: call notifyRegistrants()");
+            cdmaForSubscriptionInfoReadyRegistrants.notifyRegistrants();
+        }
+        if (oldOtaspMode != mCurrentOtaspMode) {
+            if (DBG) {
+                log("CDMA_SUBSCRIPTION: call notifyOtaspChanged old otaspMode=" +
+                    oldOtaspMode + " new otaspMode=" + mCurrentOtaspMode);
+            }
+            phone.notifyOtaspChanged(mCurrentOtaspMode);
+        }
+    }
+
     @Override
     protected void log(String s) {
         Log.d(LOG_TAG, "[CdmaSST] " + s);
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index db2b490..dcde71a 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -561,6 +561,7 @@
         boolean allowed =
                     (gprsState == ServiceState.STATE_IN_SERVICE || mAutoAttachOnCreation) &&
                     mPhone.mIccRecords.getRecordsLoaded() &&
+                    mPhone.mIccRecords.isProvisioned() &&
                     mPhone.getState() == Phone.State.IDLE &&
                     mInternalDataEnabled &&
                     (!mPhone.getServiceState().getRoaming() || getDataOnRoamingEnabled()) &&
@@ -572,6 +573,7 @@
                 reason += " - gprs= " + gprsState;
             }
             if (!mPhone.mIccRecords.getRecordsLoaded()) reason += " - SIM not loaded";
+            if (!mPhone.mIccRecords.isProvisioned()) reason += " - SIM not provisioned";
             if (mPhone.getState() != Phone.State.IDLE) {
                 reason += " - PhoneState= " + mPhone.getState();
             }