Merge "Save call forwarding flag in SharedPreference." into mnc-dr-dev
diff --git a/src/java/com/android/internal/telephony/PhoneBase.java b/src/java/com/android/internal/telephony/PhoneBase.java
index e037005..16a1843 100644
--- a/src/java/com/android/internal/telephony/PhoneBase.java
+++ b/src/java/com/android/internal/telephony/PhoneBase.java
@@ -190,6 +190,11 @@
     // Key used to read/write the ID for storing the voice mail
     public static final String VM_ID = "vm_id_key";
 
+    // Key used for storing call forwarding status
+    public static final String CF_STATUS = "cf_status_key";
+    // Key used to read/write the ID for storing the call forwarding status
+    public static final String CF_ID = "cf_id_key";
+
     // Key used to read/write "disable DNS server check" pref (used for testing)
     public static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key";
 
@@ -1447,10 +1452,58 @@
         return mVmCount != 0;
     }
 
+    private int getCallForwardingIndicatorFromSharedPref() {
+        int status = IccRecords.CALL_FORWARDING_STATUS_DISABLED;
+        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+        String subscriberId = sp.getString(CF_ID, null);
+        String currentSubscriberId = getSubscriberId();
+
+        if (currentSubscriberId != null && currentSubscriberId.equals(subscriberId)) {
+            // get call forwarding status from preferences
+            status = sp.getInt(CF_STATUS, IccRecords.CALL_FORWARDING_STATUS_DISABLED);
+            Rlog.d(LOG_TAG, "Call forwarding status from preference = " + status);
+        } else {
+            Rlog.d(LOG_TAG, "Call forwarding status retrieval returning DISABLED as status for " +
+                    "matching subscriberId not found");
+
+        }
+        return status;
+    }
+
+    private void setCallForwardingIndicatorInSharedPref(boolean enable) {
+        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+        SharedPreferences.Editor editor = sp.edit();
+
+        String imsi = getSubscriberId();
+
+        editor.putInt(CF_STATUS, enable ? IccRecords.CALL_FORWARDING_STATUS_ENABLED :
+                IccRecords.CALL_FORWARDING_STATUS_DISABLED);
+        editor.putString(CF_ID, imsi);
+        editor.apply();
+    }
+
+    public void setVoiceCallForwardingFlag(int line, boolean enable, String number) {
+        setCallForwardingIndicatorInSharedPref(enable);
+        mIccRecords.get().setVoiceCallForwardingFlag(line, enable, number);
+    }
+
+    protected void setVoiceCallForwardingFlag(IccRecords r, int line, boolean enable,
+                                              String number) {
+        setCallForwardingIndicatorInSharedPref(enable);
+        r.setVoiceCallForwardingFlag(line, enable, number);
+    }
+
     @Override
     public boolean getCallForwardingIndicator() {
         IccRecords r = mIccRecords.get();
-        return (r != null) ? r.getVoiceCallForwardingFlag() : false;
+        int callForwardingIndicator = IccRecords.CALL_FORWARDING_STATUS_UNKNOWN;
+        if (r != null) {
+            callForwardingIndicator = r.getVoiceCallForwardingFlag();
+        }
+        if (callForwardingIndicator == IccRecords.CALL_FORWARDING_STATUS_UNKNOWN) {
+            callForwardingIndicator = getCallForwardingIndicatorFromSharedPref();
+        }
+        return (callForwardingIndicator == IccRecords.CALL_FORWARDING_STATUS_ENABLED);
     }
 
     /**
@@ -1722,8 +1775,7 @@
         String subscriberId = sp.getString(VM_ID, null);
         String currentSubscriberId = getSubscriberId();
 
-        if ((subscriberId != null) && (currentSubscriberId != null)
-                && (currentSubscriberId.equals(subscriberId))) {
+        if (currentSubscriberId != null && currentSubscriberId.equals(subscriberId)) {
             // get voice mail count from preferences
             countVoiceMessages = sp.getInt(VM_COUNT, 0);
             Rlog.d(LOG_TAG, "Voice Mail Count from preference = " + countVoiceMessages);
diff --git a/src/java/com/android/internal/telephony/gsm/GSMPhone.java b/src/java/com/android/internal/telephony/gsm/GSMPhone.java
index 3a3c963..3174b90 100755
--- a/src/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/src/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -1582,7 +1582,7 @@
                 IccRecords r = mIccRecords.get();
                 Cfu cfu = (Cfu) ar.userObj;
                 if (ar.exception == null && r != null) {
-                    r.setVoiceCallForwardingFlag(1, msg.arg1 == 1, cfu.mSetCfNumber);
+                    setVoiceCallForwardingFlag(1, msg.arg1 == 1, cfu.mSetCfNumber);
                 }
                 if (cfu.mOnComplete != null) {
                     AsyncResult.forMessage(cfu.mOnComplete, ar.result, ar.exception);
@@ -1744,11 +1744,11 @@
             if (infos == null || infos.length == 0) {
                 // Assume the default is not active
                 // Set unconditional CFF in SIM to false
-                r.setVoiceCallForwardingFlag(1, false, null);
+                setVoiceCallForwardingFlag(1, false, null);
             } else {
                 for (int i = 0, s = infos.length; i < s; i++) {
                     if ((infos[i].serviceClass & SERVICE_CLASS_VOICE) != 0) {
-                        r.setVoiceCallForwardingFlag(1, (infos[i].status == 1),
+                        setVoiceCallForwardingFlag(1, (infos[i].status == 1),
                             infos[i].number);
                         // should only have the one
                         break;
diff --git a/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java
index 8bd1ec7..a3f1036 100644
--- a/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java
+++ b/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java
@@ -307,7 +307,7 @@
 
                     Rlog.d(LOG_TAG, "setVoiceCallForwardingFlag cffEnabled: " + cffEnabled);
                     if (mIccRecords != null) {
-                        mIccRecords.setVoiceCallForwardingFlag(1, cffEnabled, null);
+                        mPhone.setVoiceCallForwardingFlag(1, cffEnabled, null);
                         Rlog.d(LOG_TAG, "setVoiceCallForwardingFlag done from SS Info.");
                     } else {
                         Rlog.e(LOG_TAG, "setVoiceCallForwardingFlag aborted. sim records is null.");
@@ -1090,7 +1090,7 @@
                 if ((ar.exception == null) && (msg.arg1 == 1)) {
                     boolean cffEnabled = (msg.arg2 == 1);
                     if (mIccRecords != null) {
-                        mIccRecords.setVoiceCallForwardingFlag(1, cffEnabled, mDialingNumber);
+                        mPhone.setVoiceCallForwardingFlag(1, cffEnabled, mDialingNumber);
                     }
                 }
 
@@ -1449,7 +1449,7 @@
                         == CommandsInterface.SERVICE_CLASS_VOICE) {
             boolean cffEnabled = (info.status == 1);
             if (mIccRecords != null) {
-                mIccRecords.setVoiceCallForwardingFlag(1, cffEnabled, info.number);
+                mPhone.setVoiceCallForwardingFlag(1, cffEnabled, info.number);
             }
         }
 
@@ -1483,7 +1483,7 @@
 
                 // Set unconditional CFF in SIM to false
                 if (mIccRecords != null) {
-                    mIccRecords.setVoiceCallForwardingFlag(1, false, null);
+                    mPhone.setVoiceCallForwardingFlag(1, false, null);
                 }
             } else {
 
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
index 755d1b9..3d0fe27 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
@@ -1154,13 +1154,13 @@
             if (r != null) {
                 // Assume the default is not active
                 // Set unconditional CFF in SIM to false
-                r.setVoiceCallForwardingFlag(1, false, null);
+                setVoiceCallForwardingFlag(r, 1, false, null);
             }
         } else {
             for (int i = 0, s = infos.length; i < s; i++) {
                 if (infos[i].mCondition == ImsUtInterface.CDIV_CF_UNCONDITIONAL) {
                     if (r != null) {
-                        r.setVoiceCallForwardingFlag(1, (infos[i].mStatus == 1),
+                        setVoiceCallForwardingFlag(r, 1, (infos[i].mStatus == 1),
                             infos[i].mNumber);
                     }
                 }
@@ -1230,7 +1230,7 @@
                 IccRecords r = getIccRecords();
                 Cf cf = (Cf) ar.userObj;
                 if (cf.mIsCfu && ar.exception == null && r != null) {
-                    r.setVoiceCallForwardingFlag(1, msg.arg1 == 1, cf.mSetCfNumber);
+                    setVoiceCallForwardingFlag(r, 1, msg.arg1 == 1, cf.mSetCfNumber);
                 }
                 sendResponse(cf.mOnComplete, null, ar.exception);
                 break;
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
index 09c2d0f..d2fa2c6 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
@@ -1049,7 +1049,7 @@
                 if ((ar.exception == null) && (msg.arg1 == 1)) {
                     boolean cffEnabled = (msg.arg2 == 1);
                     if (mIccRecords != null) {
-                        mIccRecords.setVoiceCallForwardingFlag(1, cffEnabled, mDialingNumber);
+                        mPhone.setVoiceCallForwardingFlag(1, cffEnabled, mDialingNumber);
                     }
                 }
 
@@ -1300,7 +1300,7 @@
                         == CommandsInterface.SERVICE_CLASS_VOICE) {
             boolean cffEnabled = (info.status == 1);
             if (mIccRecords != null) {
-                mIccRecords.setVoiceCallForwardingFlag(1, cffEnabled, info.number);
+                mPhone.setVoiceCallForwardingFlag(1, cffEnabled, info.number);
             }
         }
 
@@ -1338,7 +1338,7 @@
 
                 // Set unconditional CFF in SIM to false
                 if (mIccRecords != null) {
-                    mIccRecords.setVoiceCallForwardingFlag(1, false, null);
+                    mPhone.setVoiceCallForwardingFlag(1, false, null);
                 }
             } else {
 
diff --git a/src/java/com/android/internal/telephony/uicc/IccRecords.java b/src/java/com/android/internal/telephony/uicc/IccRecords.java
index 1e814a6..7bbf324 100644
--- a/src/java/com/android/internal/telephony/uicc/IccRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/IccRecords.java
@@ -109,6 +109,10 @@
     protected static final int EVENT_APP_READY = 1;
     private static final int EVENT_AKA_AUTHENTICATE_DONE          = 90;
 
+    public static final int CALL_FORWARDING_STATUS_DISABLED = 0;
+    public static final int CALL_FORWARDING_STATUS_ENABLED = 1;
+    public static final int CALL_FORWARDING_STATUS_UNKNOWN = -1;
+
     @Override
     public String toString() {
         String iccIdToPrint = mIccId != null ? mIccId.substring(0, 9) + "XXXXXXXXXXX" : null;
@@ -577,10 +581,10 @@
     /**
      * Get the current Voice call forwarding flag for GSM/UMTS and the like SIMs
      *
-     * @return true if enabled
+     * @return CALL_FORWARDING_STATUS_XXX (DISABLED/ENABLED/UNKNOWN)
      */
-    public boolean getVoiceCallForwardingFlag() {
-        return false;
+    public int getVoiceCallForwardingFlag() {
+        return CALL_FORWARDING_STATUS_UNKNOWN;
     }
 
     /**
diff --git a/src/java/com/android/internal/telephony/uicc/SIMRecords.java b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
index 4cf4880..4c93b21 100644
--- a/src/java/com/android/internal/telephony/uicc/SIMRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
@@ -19,8 +19,6 @@
 import android.content.Context;
 import android.os.AsyncResult;
 import android.os.Message;
-import android.os.SystemProperties;
-import android.telephony.TelephonyManager;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.SmsMessage;
 import android.text.TextUtils;
@@ -57,7 +55,7 @@
 
     // ***** Cached SIM State; cleared on channel close
 
-    private boolean mCallForwardingEnabled;
+    private int mCallForwardingStatus;
 
 
     /**
@@ -94,7 +92,7 @@
         return "SimRecords: " + super.toString()
                 + " mVmConfig" + mVmConfig
                 + " mSpnOverride=" + "mSpnOverride"
-                + " callForwardingEnabled=" + mCallForwardingEnabled
+                + " callForwardingEnabled=" + mCallForwardingStatus
                 + " spnState=" + mSpnState
                 + " mCphsInfo=" + mCphsInfo
                 + " mCspPlmnEnabled=" + mCspPlmnEnabled
@@ -504,8 +502,8 @@
      * {@inheritDoc}
      */
     @Override
-    public boolean getVoiceCallForwardingFlag() {
-        return mCallForwardingEnabled;
+    public int getVoiceCallForwardingFlag() {
+        return mCallForwardingStatus;
     }
 
     /**
@@ -516,7 +514,8 @@
 
         if (line != 1) return; // only line 1 is supported
 
-        mCallForwardingEnabled = enable;
+        mCallForwardingStatus = enable ? CALL_FORWARDING_STATUS_ENABLED :
+                CALL_FORWARDING_STATUS_DISABLED;
 
         mRecordsEventsRegistrants.notifyResult(EVENT_CFI);
 
@@ -959,21 +958,12 @@
                 data = (byte[]) ar.result;
 
                 if (ar.exception != null) {
-                    break;
-                }
-
-                log("EF_CFF_CPHS: " + IccUtils.bytesToHexString(data));
-                mEfCff = data;
-
-                // if EF_CFIS is valid, prefer it to EF_CFF_CPHS
-                if (!validEfCfis(mEfCfis)) {
-                    mCallForwardingEnabled =
-                        ((data[0] & CFF_LINE1_MASK) == CFF_UNCONDITIONAL_ACTIVE);
-
-                    mRecordsEventsRegistrants.notifyResult(EVENT_CFI);
+                    mEfCff = null;
                 } else {
-                    log("EVENT_GET_CFF_DONE: EF_CFIS is valid, ignoring EF_CFF_CPHS");
+                    log("EF_CFF_CPHS: " + IccUtils.bytesToHexString(data));
+                    mEfCff = data;
                 }
+
                 break;
 
             case EVENT_GET_SPDI_DONE:
@@ -1172,22 +1162,12 @@
                 data = (byte[])ar.result;
 
                 if (ar.exception != null) {
-                    break;
-                }
-
-                log("EF_CFIS: " + IccUtils.bytesToHexString(data));
-
-                if (validEfCfis(data)) {
-                    mEfCfis = data;
-
-                    // Refer TS 51.011 Section 10.3.46 for the content description
-                    mCallForwardingEnabled = ((data[1] & 0x01) != 0);
-                    log("EF_CFIS: callForwardingEnabled=" + mCallForwardingEnabled);
-
-                    mRecordsEventsRegistrants.notifyResult(EVENT_CFI);
+                    mEfCfis = null;
                 } else {
-                    log("EF_CFIS: invalid data=" + IccUtils.bytesToHexString(data));
+                    log("EF_CFIS: " + IccUtils.bytesToHexString(data));
+                    mEfCfis = data;
                 }
+
                 break;
 
             case EVENT_GET_CSP_CPHS_DONE:
@@ -1303,16 +1283,9 @@
                         obtainMessage(EVENT_GET_MSISDN_DONE));
                 break;
             case EF_CFIS:
-                mRecordsToLoad++;
-                log("SIM Refresh called for EF_CFIS");
-                mFh.loadEFLinearFixed(EF_CFIS,
-                        1, obtainMessage(EVENT_GET_CFIS_DONE));
-                break;
             case EF_CFF_CPHS:
-                mRecordsToLoad++;
-                log("SIM Refresh called for EF_CFF_CPHS");
-                mFh.loadEFTransparent(EF_CFF_CPHS,
-                        obtainMessage(EVENT_GET_CFF_DONE));
+                log("SIM Refresh called for EF_CFIS or EF_CFF_CPHS");
+                loadCallForwardingRecords();
                 break;
             default:
                 // For now, fetch all records if this is not a
@@ -1437,6 +1410,22 @@
         }
     }
 
+    private void setVoiceCallForwardingFlagFromSimRecords() {
+        if (validEfCfis(mEfCfis)) {
+            // Refer TS 51.011 Section 10.3.46 for the content description
+            mCallForwardingStatus = (mEfCfis[1] & 0x01);
+            log("EF_CFIS: callForwardingEnabled=" + mCallForwardingStatus);
+        } else if (mEfCff != null) {
+            mCallForwardingStatus =
+                    ((mEfCff[0] & CFF_LINE1_MASK) == CFF_UNCONDITIONAL_ACTIVE) ?
+                            CALL_FORWARDING_STATUS_ENABLED : CALL_FORWARDING_STATUS_DISABLED;
+            log("EF_CFF: callForwardingEnabled=" + mCallForwardingStatus);
+        } else {
+            mCallForwardingStatus = CALL_FORWARDING_STATUS_UNKNOWN;
+            log("EF_CFIS and EF_CFF not valid. callForwardingEnabled=" + mCallForwardingStatus);
+        }
+    }
+
     @Override
     protected void onAllRecordsLoaded() {
         if (DBG) log("record load complete");
@@ -1448,6 +1437,8 @@
             if (DBG) log ("Not using EF LI/EF PL");
         }
 
+        setVoiceCallForwardingFlagFromSimRecords();
+
         if (mParentApp.getState() == AppState.APPSTATE_PIN ||
                mParentApp.getState() == AppState.APPSTATE_PUK) {
             // reset recordsRequested, since sim is not loaded really
@@ -1529,6 +1520,14 @@
         }
     }
 
+    private void loadCallForwardingRecords() {
+        mRecordsRequested = true;
+        mFh.loadEFLinearFixed(EF_CFIS, 1, obtainMessage(EVENT_GET_CFIS_DONE));
+        mRecordsToLoad++;
+        mFh.loadEFTransparent(EF_CFF_CPHS, obtainMessage(EVENT_GET_CFF_DONE));
+        mRecordsToLoad++;
+    }
+
     protected void fetchSimRecords() {
         mRecordsRequested = true;
 
@@ -1569,11 +1568,7 @@
 
         // Same goes for Call Forward Status indicator: fetch both
         // EF[CFIS] and CPHS-EF, with EF[CFIS] preferred.
-        mFh.loadEFLinearFixed(EF_CFIS, 1, obtainMessage(EVENT_GET_CFIS_DONE));
-        mRecordsToLoad++;
-        mFh.loadEFTransparent(EF_CFF_CPHS, obtainMessage(EVENT_GET_CFF_DONE));
-        mRecordsToLoad++;
-
+        loadCallForwardingRecords();
 
         getSpnFsm(true, null);
 
@@ -1919,7 +1914,7 @@
         super.dump(fd, pw, args);
         pw.println(" mVmConfig=" + mVmConfig);
         pw.println(" mSpnOverride=" + mSpnOverride);
-        pw.println(" mCallForwardingEnabled=" + mCallForwardingEnabled);
+        pw.println(" mCallForwardingStatus=" + mCallForwardingStatus);
         pw.println(" mSpnState=" + mSpnState);
         pw.println(" mCphsInfo=" + mCphsInfo);
         pw.println(" mCspPlmnEnabled=" + mCspPlmnEnabled);