Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5f2688d4 authored by Yujing Gu's avatar Yujing Gu Committed by Linux Build Service Account
Browse files

PhoneBook: add ANR/EMAIL support for sim card.

1. Add multi-EF_ANR/EF_EMAIL support for each ADN record.
2. Add the related interfaces for getting count of ADN,ANR,EMAIL
    - getAdnCountUsingSubId
    - getAnrCountUsingSubId
    - getEmailCountUsingSubId
    - getSpareAnrCountUsingSubId
    - getSpareEmailCountUsingSubId
3. Support loading part records in IccFileHandler.
4. Use updateIccRecordInEf for all update/insert/delete operations.
    - add updateAdnRecordsWithContentValuesInEfBySearchUsingSubId for
      updating IccRecord
5. Cleanup some unused codes.
6. Fix SIM contact email saving error.
7. Correct max len when build ANR data.
8. Fix phonebook records overwritten and email data lenth issues.
9. Fix exception when copying email data.
10.Fix email/anr issues of format of values is not standard.
11.Fix phonebook records overwritten and email data lenth issues.
12.Fix getting wrong adn count issue with CSIM/ISIM.
13.Move main thread in IPBIM to other thread to fix deadlock.
When thread A waits to get result A from main thread in
IccPhoneBookInterfaceManager (IPBIM), its lock in IPBIM is released.
So thread B holds this lock to query PB to post message to main
thread in UsimPhoneBookManager to get result B. Then result A
returns into main thread in IPBIM, it acquires lock in IPBIM to
notify thread A, but this lock in IPBIM is held by thread B.
Thread B also waits to get result B from main thread in
UsimPhoneBookManager, deadlock occurs.

CRs-Fixed: 611589 645605 739292 768920 778802 773847 774027 774290
CRs-Fixed: 596605 837202

cherry-pick from I282650251b98317a4a2bf59d61adad66a30cc9c9
cherry-pick from I4773d36b4bfd1a1e938bd084e7aa649797f0b76d
cherry-pick from Ic9b85b8cdf28891fbafe4609217fa57010c4a3bc
cherry-pick from Ic469cff4d6b83cfcda96a77f7a70ca542a198350
cherry-pick from I893555d282231700ee7cd94fe6cb61af9e14bd9a
cherry-pick from I833371a9280c51ad3823277510642ff9ef623e95
cherry-pick from I4773d36b4bfd1a1e938bd084e7aa649797f0b76d
cherry-pick from I0007e63c2b1126228384709e70af4fdff4d5be15

Change-Id: I282650251b98317a4a2bf59d61adad66a30cc9c9
parent 6ad5c9d4
Loading
Loading
Loading
Loading
+92 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.internal.telephony;

import android.content.ContentValues;

import com.android.internal.telephony.uicc.AdnRecord;


@@ -103,6 +105,22 @@ interface IIccPhoneBook {
            String oldTag, String oldPhoneNumber,
            String newTag, String newPhoneNumber,
            String pin2);

    /**
     * Replace oldAdn with newAdn in ADN-like record in EF
     *
     * getAdnRecordsInEf must be called at least once before this function,
     * otherwise an error will be returned
     *
     * @param subId user preferred subId
     * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
     * @param values including ADN,EMAIL,ANR to be updated
     * @param pin2 required to update EF_FDN, otherwise must be null
     * @return true for success
     */
    boolean updateAdnRecordsWithContentValuesInEfBySearchUsingSubId(int subId,
            int efid, in ContentValues values, String pin2);

    /**
     * Update an ADN-like EF record by record index
     *
@@ -165,4 +183,78 @@ interface IIccPhoneBook {
     */
    int[] getAdnRecordsSizeForSubscriber(int subId, int efid);

    /**
     * Get the adn count of sim card
     *
     * @return the adn count of sim card
     */
    int getAdnCount();

    /**
     * Get the adn count of sim card
     *
     * @param subId user preferred subId
     * @return the adn count of sim card
     */
    int getAdnCountUsingSubId(int subId);

    /**
     * Get the anr count of sim card
     *
     * @return the anr count of sim card
     */
    int getAnrCount();

    /**
     * Get the anr count of sim card
     *
     * @param subId user preferred subId
     * @return the anr count of sim card
     */
    int getAnrCountUsingSubId(int subId);

    /**
     * Get the email count of sim card
     *
     * @return the email count of sim card
     */
    int getEmailCount();

    /**
     * Get the email count of sim card
     *
     * @param subId user preferred subId
     * @return the email count of sim card
     */
    int getEmailCountUsingSubId(int subId);

    /**
     * Get the spare anr count of sim card
     *
     * @return the spare anr count of sim card
     */
    int getSpareAnrCount();

    /**
     * Get the spare anr count of sim card
     *
     * @param subId user preferred subId
     * @return the spare anr count of sim card
     */
    int getSpareAnrCountUsingSubId(int subId);

    /**
     * Get the spare email count of sim card
     *
     * @return the spare email count of sim card
     */
    int getSpareEmailCount();

    /**
     * Get the spare email count of sim card
     *
     * @param subId user preferred subId
     * @return the spare email count of sim card
     */
    int getSpareEmailCountUsingSubId(int subId);
}
+106 −0
Original line number Diff line number Diff line
@@ -16,12 +16,15 @@

package com.android.internal.telephony;

import android.content.ContentValues;
import android.content.pm.PackageManager;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.ServiceManager;
import android.telephony.Rlog;
import android.text.TextUtils;

import com.android.internal.telephony.uicc.AdnRecord;
import com.android.internal.telephony.uicc.AdnRecordCache;
@@ -194,6 +197,48 @@ public abstract class IccPhoneBookInterfaceManager {
        return mSuccess;
    }

    public boolean updateAdnRecordsWithContentValuesInEfBySearch(int efid, ContentValues values,
            String pin2) {

        if (mPhone.getContext().checkCallingOrSelfPermission(
                android.Manifest.permission.WRITE_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Requires android.permission.WRITE_CONTACTS permission");
        }

        String oldTag = values.getAsString(IccProvider.STR_TAG);
        String newTag = values.getAsString(IccProvider.STR_NEW_TAG);
        String oldPhoneNumber = values.getAsString(IccProvider.STR_NUMBER);
        String newPhoneNumber = values.getAsString(IccProvider.STR_NEW_NUMBER);
        String oldEmail = values.getAsString(IccProvider.STR_EMAILS);
        String newEmail = values.getAsString(IccProvider.STR_NEW_EMAILS);
        String oldAnr = values.getAsString(IccProvider.STR_ANRS);
        String newAnr = values.getAsString(IccProvider.STR_NEW_ANRS);
        String[] oldEmailArray = TextUtils.isEmpty(oldEmail) ? null : getStringArray(oldEmail);
        String[] newEmailArray = TextUtils.isEmpty(newEmail) ? null : getStringArray(newEmail);
        String[] oldAnrArray = TextUtils.isEmpty(oldAnr) ? null : getStringArray(oldAnr);
        String[] newAnrArray = TextUtils.isEmpty(newAnr) ? null : getStringArray(newAnr);
        efid = updateEfForIccType(efid);

        if (DBG)
            logd("updateAdnRecordsInEfBySearch: efid=" + efid + ", values = " + values + ", pin2="
                    + pin2);
        synchronized (mLock) {
            checkThread();
            mSuccess = false;
            AtomicBoolean status = new AtomicBoolean(false);
            Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, status);
            AdnRecord oldAdn = new AdnRecord(oldTag, oldPhoneNumber, oldEmailArray, oldAnrArray);
            AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber, newEmailArray, newAnrArray);
            if (mAdnCache != null) {
                mAdnCache.updateAdnBySearch(efid, oldAdn, newAdn, pin2, response);
                waitForResult(status);
            } else {
                loge("Failure while trying to update by search due to uninitialised adncache");
            }
        }
        return mSuccess;
    }

    /**
     * Update an ADN-like EF record by record index
     *
@@ -298,6 +343,13 @@ public abstract class IccPhoneBookInterfaceManager {
        }
    }

    private String[] getStringArray(String str) {
        if (str != null) {
            return str.split(",");
        }
        return null;
    }

    protected void waitForResult(AtomicBoolean status) {
        while (!status.get()) {
            try {
@@ -318,5 +370,59 @@ public abstract class IccPhoneBookInterfaceManager {
        }
        return efid;
    }

    public int getAdnCount() {
        int adnCount = 0;
        if (mAdnCache != null) {
            if (mIs3gCard) {
                adnCount = mAdnCache.getUsimAdnCount();
            } else {
                adnCount = mAdnCache.getAdnCount();
            }
        } else {
            loge("mAdnCache is NULL when getAdnCount.");
        }
        return adnCount;
    }

    public int getAnrCount() {
        int anrCount = 0;
        if (mAdnCache != null) {
            anrCount = mAdnCache.getAnrCount();
        } else {
            loge("mAdnCache is NULL when getAnrCount.");
        }
        return anrCount;
    }

    public int getEmailCount() {
        int emailCount = 0;
        if (mAdnCache != null) {
            emailCount = mAdnCache.getEmailCount();
        } else {
            loge("mAdnCache is NULL when getEmailCount.");
        }
        return emailCount;
    }

    public int getSpareAnrCount() {
        int spareAnrCount = 0;
        if (mAdnCache != null) {
            spareAnrCount = mAdnCache.getSpareAnrCount();
        } else {
            loge("mAdnCache is NULL when getSpareAnrCount.");
        }
        return spareAnrCount;
    }

    public int getSpareEmailCount() {
        int spareEmailCount = 0;
        if (mAdnCache != null) {
            spareEmailCount = mAdnCache.getSpareEmailCount();
        } else {
            loge("mAdnCache is NULL when getSpareEmailCount.");
        }
        return spareEmailCount;
    }
}
+28 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.internal.telephony;

import android.content.ContentValues;
import android.os.RemoteException;
import android.os.ServiceManager;
import com.android.internal.telephony.uicc.AdnRecord;

@@ -49,6 +51,12 @@ public class IccPhoneBookInterfaceManagerProxy {
                efid, oldTag, oldPhoneNumber, newTag, newPhoneNumber, pin2);
    }

    public boolean updateAdnRecordsWithContentValuesInEfBySearch(int efid, ContentValues values,
            String pin2) throws android.os.RemoteException {
        return mIccPhoneBookInterfaceManager.updateAdnRecordsWithContentValuesInEfBySearch(efid,
                values, pin2);
    }

    public boolean
    updateAdnRecordsInEfByIndex(int efid, String newTag,
            String newPhoneNumber, int index, String pin2) {
@@ -63,4 +71,24 @@ public class IccPhoneBookInterfaceManagerProxy {
    public List<AdnRecord> getAdnRecordsInEf(int efid) {
        return mIccPhoneBookInterfaceManager.getAdnRecordsInEf(efid);
    }

    public int getAdnCount() {
        return mIccPhoneBookInterfaceManager.getAdnCount();
    }

    public int getAnrCount() {
        return mIccPhoneBookInterfaceManager.getAnrCount();
    }

    public int getEmailCount() {
        return mIccPhoneBookInterfaceManager.getEmailCount();
    }

    public int getSpareAnrCount() {
        return mIccPhoneBookInterfaceManager.getSpareAnrCount();
    }

    public int getSpareEmailCount() {
        return mIccPhoneBookInterfaceManager.getSpareEmailCount();
    }
}
+62 −80
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ public class IccProvider extends ContentProvider {
        "name",
        "number",
        "emails",
        "anrs",
        "_id"
    };

@@ -60,10 +61,15 @@ public class IccProvider extends ContentProvider {
    protected static final int SDN_SUB = 6;
    protected static final int ADN_ALL = 7;

    protected static final String STR_TAG = "tag";
    protected static final String STR_NUMBER = "number";
    protected static final String STR_EMAILS = "emails";
    protected static final String STR_PIN2 = "pin2";
    public static final String STR_TAG = "tag";
    public static final String STR_NUMBER = "number";
    public static final String STR_EMAILS = "emails";
    public static final String STR_ANRS = "anrs";
    public static final String STR_NEW_TAG = "newTag";
    public static final String STR_NEW_NUMBER = "newNumber";
    public static final String STR_NEW_EMAILS = "newEmails";
    public static final String STR_NEW_ANRS = "newAnrs";
    public static final String STR_PIN2 = "pin2";

    private static final UriMatcher URL_MATCHER =
                            new UriMatcher(UriMatcher.NO_MATCH);
@@ -196,8 +202,19 @@ public class IccProvider extends ContentProvider {

        String tag = initialValues.getAsString("tag");
        String number = initialValues.getAsString("number");
        // TODO(): Read email instead of sending null.
        boolean success = addIccRecordToEf(efType, tag, number, null, pin2, subId);
        String emails = initialValues.getAsString("emails");
        String anrs = initialValues.getAsString("anrs");

        ContentValues values = new ContentValues();
        values.put(STR_TAG,"");
        values.put(STR_NUMBER,"");
        values.put(STR_EMAILS,"");
        values.put(STR_ANRS,"");
        values.put(STR_NEW_TAG,tag);
        values.put(STR_NEW_NUMBER,number);
        values.put(STR_NEW_EMAILS,emails);
        values.put(STR_NEW_ANRS,anrs);
        boolean success = updateIccRecordInEf(efType, values, pin2, subId);

        if (!success) {
            return null;
@@ -258,6 +275,7 @@ public class IccProvider extends ContentProvider {
        int efType;
        int subId;

        if (DBG) log("delete");
        int match = URL_MATCHER.match(url);
        switch (match) {
            case ADN:
@@ -285,12 +303,11 @@ public class IccProvider extends ContentProvider {
                        "Cannot insert into URL: " + url);
        }

        if (DBG) log("delete");

        // parse where clause
        String tag = null;
        String number = null;
        String[] emails = null;
        String emails = null;
        String anrs = null;
        String pin2 = null;

        String[] tokens = where.split("AND");
@@ -314,18 +331,29 @@ public class IccProvider extends ContentProvider {
            } else if (STR_NUMBER.equals(key)) {
                number = normalizeValue(val);
            } else if (STR_EMAILS.equals(key)) {
                //TODO(): Email is null.
                emails = null;
                emails = normalizeValue(val);
            } else if (STR_ANRS.equals(key)) {
                anrs = normalizeValue(val);
            } else if (STR_PIN2.equals(key)) {
                pin2 = normalizeValue(val);
            }
        }

        if (efType == FDN && TextUtils.isEmpty(pin2)) {
        ContentValues values = new ContentValues();
        values.put(STR_TAG,tag);
        values.put(STR_NUMBER,number);
        values.put(STR_EMAILS,emails);
        values.put(STR_ANRS,anrs);
        values.put(STR_NEW_TAG,"");
        values.put(STR_NEW_NUMBER,"");
        values.put(STR_NEW_EMAILS,"");
        values.put(STR_NEW_ANRS,"");
        if ((efType == FDN) && TextUtils.isEmpty(pin2)) {
            return 0;
        }

        boolean success = deleteIccRecordFromEf(efType, tag, number, emails, pin2, subId);
        if (DBG) log("delete mvalues= " + values);
        boolean success = updateIccRecordInEf(efType, values, pin2, subId);
        if (!success) {
            return 0;
        }
@@ -378,8 +406,7 @@ public class IccProvider extends ContentProvider {
        String newNumber = values.getAsString("newNumber");
        String[] newEmails = null;
        // TODO(): Update for email.
        boolean success = updateIccRecordInEf(efType, tag, number,
                newTag, newNumber, pin2, subId);
        boolean success = updateIccRecordInEf(efType, values, pin2, subId);

        if (!success) {
            return 0;
@@ -409,7 +436,7 @@ public class IccProvider extends ContentProvider {
            // Load the results
            final int N = adnRecords.size();
            final MatrixCursor cursor = new MatrixCursor(ADDRESS_BOOK_COLUMN_NAMES, N);
            if (DBG) log("adnRecords.size=" + N);
            log("adnRecords.size=" + N);
            for (int i = 0; i < N ; i++) {
                loadRecord(adnRecords.get(i), cursor, i);
            }
@@ -422,50 +449,19 @@ public class IccProvider extends ContentProvider {
    }

    private boolean
    addIccRecordToEf(int efType, String name, String number, String[] emails,
            String pin2, int subId) {
        if (DBG) log("addIccRecordToEf: efType=" + efType + ", name=" + name +
                ", number=" + number + ", emails=" + emails + ", subscription=" + subId);

    updateIccRecordInEf(int efType, ContentValues values, String pin2, int subId) {
        boolean success = false;

        // TODO: do we need to call getAdnRecordsInEf() before calling
        // updateAdnRecordsInEfBySearch()? In any case, we will leave
        // the UI level logic to fill that prereq if necessary. But
        // hopefully, we can remove this requirement.

        try {
            IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
                    ServiceManager.getService("simphonebook"));
            if (iccIpb != null) {
                success = iccIpb.updateAdnRecordsInEfBySearchForSubscriber(subId, efType,
                        "", "", name, number, pin2);
            }
        } catch (RemoteException ex) {
            // ignore it
        } catch (SecurityException ex) {
            if (DBG) log(ex.toString());
        }
        if (DBG) log("addIccRecordToEf: " + success);
        return success;
    }

    private boolean
    updateIccRecordInEf(int efType, String oldName, String oldNumber,
            String newName, String newNumber, String pin2, int subId) {
        if (DBG) log("updateIccRecordInEf: efType=" + efType +
                ", oldname=" + oldName + ", oldnumber=" + oldNumber +
                ", newname=" + newName + ", newnumber=" + newNumber +
                ", subscription=" + subId);

        boolean success = false;
                    ", values: [ "+ values + " ], subId:" + subId);

        try {
            IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
                    ServiceManager.getService("simphonebook"));
            if (iccIpb != null) {
                success = iccIpb.updateAdnRecordsInEfBySearchForSubscriber(subId, efType, oldName,
                        oldNumber, newName, newNumber, pin2);
                success = iccIpb
                        .updateAdnRecordsWithContentValuesInEfBySearchUsingSubId(
                            subId, efType, values, pin2);
            }
        } catch (RemoteException ex) {
            // ignore it
@@ -476,31 +472,6 @@ public class IccProvider extends ContentProvider {
        return success;
    }


    private boolean deleteIccRecordFromEf(int efType, String name, String number, String[] emails,
            String pin2, int subId) {
        if (DBG) log("deleteIccRecordFromEf: efType=" + efType +
                ", name=" + name + ", number=" + number + ", emails=" + emails +
                ", pin2=" + pin2 + ", subscription=" + subId);

        boolean success = false;

        try {
            IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
                    ServiceManager.getService("simphonebook"));
            if (iccIpb != null) {
                success = iccIpb.updateAdnRecordsInEfBySearchForSubscriber(subId, efType,
                          name, number, "", "", pin2);
            }
        } catch (RemoteException ex) {
            // ignore it
        } catch (SecurityException ex) {
            if (DBG) log(ex.toString());
        }
        if (DBG) log("deleteIccRecordFromEf: " + success);
        return success;
    }

    /**
     * Loads an AdnRecord into a MatrixCursor. Must be called with mLock held.
     *
@@ -509,10 +480,10 @@ public class IccProvider extends ContentProvider {
     */
    private void loadRecord(AdnRecord record, MatrixCursor cursor, int id) {
        if (!record.isEmpty()) {
            Object[] contact = new Object[4];
            Object[] contact = new Object[5];
            String alphaTag = record.getAlphaTag();
            String number = record.getNumber();

            String[] anrs =record.getAdditionalNumbers();
            if (DBG) log("loadRecord: " + alphaTag + ", " + number + ",");
            contact[0] = alphaTag;
            contact[1] = number;
@@ -527,7 +498,18 @@ public class IccProvider extends ContentProvider {
                }
                contact[2] = emailString.toString();
            }
            contact[3] = id;

            if (anrs != null) {
                StringBuilder anrString = new StringBuilder();
                for (String anr : anrs) {
                    if (DBG) log("Adding anr:" + anr);
                    anrString.append(anr);
                    anrString.append(",");
                }
                contact[3] = anrString.toString();
            }

            contact[4] = id;
            cursor.addRow(contact);
        }
    }
+105 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

package com.android.internal.telephony;

import android.content.ContentValues;
import android.os.ServiceManager;
import android.os.RemoteException;
import android.telephony.Rlog;
@@ -130,6 +131,110 @@ public class UiccPhoneBookController extends IIccPhoneBook.Stub {
        }
    }

    public boolean
    updateAdnRecordsWithContentValuesInEfBySearch(int efid, ContentValues values,
        String pin2) throws android.os.RemoteException {
            return updateAdnRecordsWithContentValuesInEfBySearchUsingSubId(
                getDefaultSubscription(), efid, values, pin2);
    }

    public boolean
    updateAdnRecordsWithContentValuesInEfBySearchUsingSubId(int subId, int efid,
        ContentValues values, String pin2)
        throws android.os.RemoteException {

        IccPhoneBookInterfaceManagerProxy iccPbkIntMgrProxy =
                             getIccPhoneBookInterfaceManagerProxy(subId);
        if (iccPbkIntMgrProxy != null) {
            return iccPbkIntMgrProxy.updateAdnRecordsWithContentValuesInEfBySearch(
                efid, values, pin2);
        } else {
            Rlog.e(TAG,"updateAdnRecordsWithContentValuesInEfBySearchUsingSubId " +
                "iccPbkIntMgrProxy is null for Subscription:"+subId);
            return false;
        }
    }

    public int getAdnCount() throws android.os.RemoteException {
        return getAdnCountUsingSubId(getDefaultSubscription());
    }

    public int getAdnCountUsingSubId(int subId) throws android.os.RemoteException {
        IccPhoneBookInterfaceManagerProxy iccPbkIntMgrProxy =
                             getIccPhoneBookInterfaceManagerProxy(subId);
        if (iccPbkIntMgrProxy != null) {
            return iccPbkIntMgrProxy.getAdnCount();
        } else {
            Rlog.e(TAG,"getAdnCount iccPbkIntMgrProxy is" +
                      "null for Subscription:"+subId);
            return 0;
        }
    }

    public int getAnrCount() throws android.os.RemoteException {
        return getAnrCountUsingSubId(getDefaultSubscription());
    }

    public int getAnrCountUsingSubId(int subId) throws android.os.RemoteException {
        IccPhoneBookInterfaceManagerProxy iccPbkIntMgrProxy =
                             getIccPhoneBookInterfaceManagerProxy(subId);
        if (iccPbkIntMgrProxy != null) {
            return iccPbkIntMgrProxy.getAnrCount();
        } else {
            Rlog.e(TAG,"getAnrCount iccPbkIntMgrProxy is" +
                      "null for Subscription:"+subId);
            return 0;
        }
    }

    public int getEmailCount() throws android.os.RemoteException {
        return getEmailCountUsingSubId(getDefaultSubscription());
    }

    public int getEmailCountUsingSubId(int subId) throws android.os.RemoteException {
        IccPhoneBookInterfaceManagerProxy iccPbkIntMgrProxy =
                             getIccPhoneBookInterfaceManagerProxy(subId);
        if (iccPbkIntMgrProxy != null) {
            return iccPbkIntMgrProxy.getEmailCount();
        } else {
            Rlog.e(TAG,"getEmailCount iccPbkIntMgrProxy is" +
                      "null for Subscription:"+subId);
            return 0;
        }
    }

    public int getSpareAnrCount() throws android.os.RemoteException {
        return getSpareAnrCountUsingSubId(getDefaultSubscription());
    }

    public int getSpareAnrCountUsingSubId(int subId) throws android.os.RemoteException {
        IccPhoneBookInterfaceManagerProxy iccPbkIntMgrProxy =
                             getIccPhoneBookInterfaceManagerProxy(subId);
        if (iccPbkIntMgrProxy != null) {
            return iccPbkIntMgrProxy.getSpareAnrCount();
        } else {
            Rlog.e(TAG,"getSpareAnrCount iccPbkIntMgrProxy is" +
                      "null for Subscription:"+subId);
            return 0;
        }
    }

    public int getSpareEmailCount() throws android.os.RemoteException {
        return getSpareEmailCountUsingSubId(getDefaultSubscription());
    }

    public int getSpareEmailCountUsingSubId(int subId) throws android.os.RemoteException {
        IccPhoneBookInterfaceManagerProxy iccPbkIntMgrProxy =
                             getIccPhoneBookInterfaceManagerProxy(subId);
        if (iccPbkIntMgrProxy != null) {
            return iccPbkIntMgrProxy.getSpareEmailCount();
        } else {
            Rlog.e(TAG,"getSpareEmailCount iccPbkIntMgrProxy is" +
                      "null for Subscription:"+subId);
            return 0;
        }
    }

    /**
     * get phone book interface manager proxy object based on subscription.
     **/
Loading