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

Commit 53d2dcbb authored by Yujing Gu's avatar Yujing Gu Committed by Luca Stefani
Browse files

SimPhoneBook: Add ANR/EMAIL support for USIM phonebook.

1. Add multi-EF_ANR/EF_EMAIL support for each ADN record.
2. Add the related interfaces for getting count of ADN,ANR,EMAIL
    - getAdnRecordsCapacity
3. Use updateIccRecordInEf for all update/insert/delete operations.
    - add updateAdnRecordsWithContentValuesInEfBySearchUsingSubId for
      updating IccRecord
4.Move main thread in IccPhoneBookInterfaceManager to other thread to
fix deadlock issue.

Change-Id: I282650251b98317a4a2bf59d61adad66a30cc9c9
parent 01bf521c
Loading
Loading
Loading
Loading
+53 −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,39 @@ interface IIccPhoneBook {
     */
    int[] getAdnRecordsSizeForSubscriber(int subId, int efid);

    /**
     * Get the capacity of ADN records
     *
     * @return  int[10] array
     *            capacity[0]  is the max count of ADN
     *            capacity[1]  is the used count of ADN
     *            capacity[2]  is the max count of EMAIL
     *            capacity[3]  is the used count of EMAIL
     *            capacity[4]  is the max count of ANR
     *            capacity[5]  is the used count of ANR
     *            capacity[6]  is the max length of name
     *            capacity[7]  is the max length of number
     *            capacity[8]  is the max length of email
     *            capacity[9]  is the max length of anr
     */
    int[] getAdnRecordsCapacity();

    /**
     * Get the capacity of ADN records
     *
     * @param subId user preferred subId
     * @return  int[10] array
     *            capacity[0]  is the max count of ADN
     *            capacity[1]  is the used count of ADN
     *            capacity[2]  is the max count of EMAIL
     *            capacity[3]  is the used count of EMAIL
     *            capacity[4]  is the max count of ANR
     *            capacity[5]  is the used count of ANR
     *            capacity[6]  is the max length of name
     *            capacity[7]  is the max length of number
     *            capacity[8]  is the max length of email
     *            capacity[9]  is the max length of anr
     */
    int[] getAdnRecordsCapacityForSubscriber(int subId);

}
+119 −3
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.HandlerThread;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.telephony.Rlog;
import android.text.TextUtils;

import com.android.internal.telephony.uicc.AdnRecord;
import com.android.internal.telephony.uicc.AdnRecordCache;
@@ -58,7 +61,18 @@ public class IccPhoneBookInterfaceManager {
    protected static final int EVENT_LOAD_DONE = 2;
    protected static final int EVENT_UPDATE_DONE = 3;

    protected Handler mBaseHandler = new Handler() {
    protected final IccPbHandler mBaseHandler;

    private static final HandlerThread  mHandlerThread  = new HandlerThread("IccPbHandlerLoader");
    static {
        mHandlerThread.start();
    }

    protected class IccPbHandler extends Handler {
        public IccPbHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            AsyncResult ar;
@@ -81,6 +95,9 @@ public class IccPhoneBookInterfaceManager {
                    break;
                case EVENT_UPDATE_DONE:
                    ar = (AsyncResult) msg.obj;
                    if (ar.exception != null) {
                        if(DBG) logd("exception of EVENT_UPDATE_DONE is" + ar.exception );
                    }
                    synchronized (mLock) {
                        mSuccess = (ar.exception == null);
                        notifyPending(ar);
@@ -90,6 +107,7 @@ public class IccPhoneBookInterfaceManager {
                    ar = (AsyncResult)msg.obj;
                    synchronized (mLock) {
                        if (ar.exception == null) {
                            if(DBG) logd("Load ADN records done");
                            mRecords = (List<AdnRecord>) ar.result;
                        } else {
                            if(DBG) logd("Cannot load ADN records");
@@ -116,6 +134,7 @@ public class IccPhoneBookInterfaceManager {
        if (r != null) {
            mAdnCache = r.getAdnCache();
        }
        mBaseHandler = new IccPbHandler(mHandlerThread.getLooper());
    }

    public void dispose() {
@@ -195,6 +214,67 @@ public class IccPhoneBookInterfaceManager {
        return mSuccess;
    }

    /**
     * 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.
     * throws SecurityException if no WRITE_CONTACTS permission
     *
     * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
     * @param values old adn tag,  phone number, email and anr to be replaced
     *        new adn tag,  phone number, email and anr to be stored
     * @param newPhoneNumber adn number ot be stored
     * @param oldPhoneNumber adn number to be replaced
     *        Set both oldTag, oldPhoneNubmer, oldEmail and oldAnr to ""
     *        means to replace an empty record, aka, insert new record
     *        Set both newTag, newPhoneNubmer, newEmail and newAnr ""
     *        means to replace the old record with empty one, aka, delete old record
     * @param pin2 required to update EF_FDN, otherwise must be null
     * @return true for success
     */
    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 : getAnrStringArray(oldAnr);
        String[] newAnrArray = TextUtils.isEmpty(newAnr) ? null : getAnrStringArray(newAnr);
        efid = updateEfForIccType(efid);

        if (DBG)
            logd("updateAdnRecordsWithContentValuesInEfBySearch: 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
     *
@@ -311,7 +391,7 @@ public class IccPhoneBookInterfaceManager {
    protected void checkThread() {
        if (!ALLOW_SIM_OP_IN_UI_THREAD) {
            // Make sure this isn't the UI thread, since it will block
            if (mBaseHandler.getLooper().equals(Looper.myLooper())) {
            if (Looper.getMainLooper().equals(Looper.myLooper())) {
                loge("query() called on the main UI thread!");
                throw new IllegalStateException(
                        "You cannot call query on this provder from the main UI thread.");
@@ -329,7 +409,7 @@ public class IccPhoneBookInterfaceManager {
        }
    }

    private int updateEfForIccType(int efid) {
    protected int updateEfForIccType(int efid) {
        // Check if we are trying to read ADN records
        if (efid == IccConstants.EF_ADN) {
            if (mPhone.getCurrentUiccAppType() == AppType.APPTYPE_USIM) {
@@ -338,5 +418,41 @@ public class IccPhoneBookInterfaceManager {
        }
        return efid;
    }

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

    protected String[] getAnrStringArray(String str) {
        if (str != null) {
            return str.split(":");
        }
        return null;
    }

    /**
     * Get the capacity of ADN records
     *
     * @return  int[6] array
     *            capacity[0]  is the max count of ADN
     *            capacity[1]  is the used count of ADN
     *            capacity[2]  is the max count of EMAIL
     *            capacity[3]  is the used count of EMAIL
     *            capacity[4]  is the max count of ANR
     *            capacity[5]  is the used count of ANR
     *            capacity[6]  is the max length of name
     *            capacity[7]  is the max length of number
     *            capacity[8]  is the max length of email
     *            capacity[9]  is the max length of anr
     */
    public int[] getAdnRecordsCapacity() {
        if (DBG) logd("getAdnRecordsCapacity" );
        int capacity[] = new int[10];

        return capacity;
    }
}
+62 −27
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ public class IccProvider extends ContentProvider {
        "name",
        "number",
        "emails",
        "anrs",
        "_id"
    };

@@ -59,10 +60,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);
@@ -197,8 +203,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;
@@ -291,7 +308,8 @@ public class IccProvider extends ContentProvider {
        // 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");
@@ -315,18 +333,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;
        }
@@ -379,8 +408,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;
@@ -411,7 +439,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);
            }
@@ -454,21 +482,18 @@ public class IccProvider extends ContentProvider {
    }

    private boolean
    updateIccRecordInEf(int efType, String oldName, String oldNumber,
            String newName, String newNumber, String pin2, int subId) {
        if (DBG) log("updateIccRecordInEf: efType=0x" + Integer.toHexString(efType).toUpperCase() +
                ", oldname=" + Rlog.pii(TAG, oldName) + ", oldnumber=" + Rlog.pii(TAG, oldNumber) +
                ", newname=" + Rlog.pii(TAG, newName) + ", newnumber=" + Rlog.pii(TAG, newName) +
                ", subscription=" + subId);

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

        if (DBG) log("updateIccRecordInEf: efType=" + efType +
                    ", 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
@@ -479,7 +504,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=0x" +
@@ -513,10 +537,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 + ", " + Rlog.pii(TAG, number));
            contact[0] = alphaTag;
            contact[1] = number;
@@ -531,7 +555,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);
        }
    }
+43 −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.telephony.Rlog;

@@ -127,6 +128,48 @@ public class UiccPhoneBookController extends IIccPhoneBook.Stub {
        }
    }

    @Override
    public int[] getAdnRecordsCapacity() throws android.os.RemoteException {
        return getAdnRecordsCapacityForSubscriber(getDefaultSubscription());
    }

    @Override
    public int[] getAdnRecordsCapacityForSubscriber(int subId)
           throws android.os.RemoteException {
        IccPhoneBookInterfaceManager iccPbkIntMgr =
                             getIccPhoneBookInterfaceManager(subId);
        if (iccPbkIntMgr != null) {
            return iccPbkIntMgr.getAdnRecordsCapacity();
        } else {
            Rlog.e(TAG,"getAdnRecordsCapacity iccPbkIntMgr is" +
                      " null for Subscription:"+subId);
            return null;
        }
    }

    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 {
        IccPhoneBookInterfaceManager iccPbkIntMgr =
                             getIccPhoneBookInterfaceManager(subId);
        if (iccPbkIntMgr != null) {
            return iccPbkIntMgr.updateAdnRecordsWithContentValuesInEfBySearch(
                efid, values, pin2);
        } else {
            Rlog.e(TAG,"updateAdnRecordsWithContentValuesInEfBySearchUsingSubId " +
                "iccPbkIntMgr is null for Subscription:"+subId);
            return false;
        }
    }

    /**
     * get phone book interface manager object based on subscription.
     **/
+97 −11
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ public class AdnRecord implements Parcelable {
    String mAlphaTag = null;
    String mNumber = null;
    String[] mEmails;
    String[] mAdditionalNumbers = null;
    int mExtRecord = 0xff;
    int mEfid;                   // or 0 if none
    int mRecordNumber;           // or 0 if none
@@ -80,14 +81,15 @@ public class AdnRecord implements Parcelable {
            String alphaTag;
            String number;
            String[] emails;

            String[] additionalNumbers;
            efid = source.readInt();
            recordNumber = source.readInt();
            alphaTag = source.readString();
            number = source.readString();
            emails = source.readStringArray();
            additionalNumbers = source.readStringArray();

            return new AdnRecord(efid, recordNumber, alphaTag, number, emails);
            return new AdnRecord(efid, recordNumber, alphaTag, number, emails, additionalNumbers);
        }

        @Override
@@ -116,12 +118,27 @@ public class AdnRecord implements Parcelable {
        this(0, 0, alphaTag, number, emails);
    }

    public AdnRecord(String alphaTag, String number, String[] emails, String[] additionalNumbers) {
        this(0, 0, alphaTag, number, emails, additionalNumbers);
    }

    public AdnRecord (int efid, int recordNumber, String alphaTag, String number, String[] emails) {
        this.mEfid = efid;
        this.mRecordNumber = recordNumber;
        this.mAlphaTag = alphaTag;
        this.mNumber = number;
        this.mEmails = emails;
        this.mAdditionalNumbers = null;
    }

    public AdnRecord(int efid, int recordNumber, String alphaTag, String number, String[] emails,
            String[] additionalNumbers) {
        this.mEfid = efid;
        this.mRecordNumber = recordNumber;
        this.mAlphaTag = alphaTag;
        this.mNumber = number;
        this.mEmails = emails;
        this.mAdditionalNumbers = additionalNumbers;
    }

    public AdnRecord(int efid, int recordNumber, String alphaTag, String number) {
@@ -130,6 +147,7 @@ public class AdnRecord implements Parcelable {
        this.mAlphaTag = alphaTag;
        this.mNumber = number;
        this.mEmails = null;
        this.mAdditionalNumbers = null;
    }

    //***** Instance Methods
@@ -162,14 +180,32 @@ public class AdnRecord implements Parcelable {
        this.mEmails = emails;
    }

    public String[] getAdditionalNumbers() {
        return mAdditionalNumbers;
    }

    public void setAdditionalNumbers(String[] additionalNumbers) {
        this.mAdditionalNumbers = additionalNumbers;
    }

    public int getRecordNumber() {
        return mRecordNumber;
    }

    public void setRecordNumber(int recNumber) {
        mRecordNumber = recNumber;
    }

    @Override
    public String toString() {
        return "ADN Record '" + mAlphaTag + "' '" + Rlog.pii(LOG_TAG, mNumber) + " "
                + Rlog.pii(LOG_TAG, mEmails) + "'";
                + Rlog.pii(LOG_TAG, mEmails) + " "
                + Rlog.pii(LOG_TAG, mAdditionalNumbers) + "'";
    }

    public boolean isEmpty() {
        return TextUtils.isEmpty(mAlphaTag) && TextUtils.isEmpty(mNumber) && mEmails == null;
        return TextUtils.isEmpty(mAlphaTag) && TextUtils.isEmpty(mNumber) && mEmails == null
                && mAdditionalNumbers == null;
    }

    public boolean hasExtendedRecord() {
@@ -190,11 +226,56 @@ public class AdnRecord implements Parcelable {
        return (s1.equals(s2));
    }

    /** Help function for ANR/EMAIL array compare. */
    private static boolean arrayCompareNullEqualsEmpty(String s1[], String s2[]) {
        if (s1 == s2) {
            return true;
        }

        if (s1 == null) {
            s1 = new String[1];
            s1[0] = "";
        }

        if (s2 == null) {
            s2 = new String[1];
            s2[0] = "";
        }

        for (String str:s1) {
            if (TextUtils.isEmpty(str)) {
                continue;
            } else {
                if (Arrays.asList(s2).contains(str)) {
                    continue;
                } else {
                    return false;
                }
            }
        }

        for (String str:s2) {
            if (TextUtils.isEmpty(str)) {
                continue;
            } else {
                if (Arrays.asList(s1).contains(str)) {
                    continue;
                } else {
                    return false;
                }
            }
        }

        return true;
    }

    public boolean isEqual(AdnRecord adn) {
        return ( stringCompareNullEqualsEmpty(mAlphaTag, adn.mAlphaTag) &&
                stringCompareNullEqualsEmpty(mNumber, adn.mNumber) &&
                Arrays.equals(mEmails, adn.mEmails));
                arrayCompareNullEqualsEmpty(mEmails, adn.mEmails)
                && arrayCompareNullEqualsEmpty(mAdditionalNumbers, adn.mAdditionalNumbers));
    }

    //***** Parcelable Implementation

    @Override
@@ -209,6 +290,7 @@ public class AdnRecord implements Parcelable {
        dest.writeString(mAlphaTag);
        dest.writeString(mNumber);
        dest.writeStringArray(mEmails);
        dest.writeStringArray(mAdditionalNumbers);
    }

    /**
@@ -231,11 +313,11 @@ public class AdnRecord implements Parcelable {
            adnString[i] = (byte) 0xFF;
        }

        if (TextUtils.isEmpty(mNumber)) {
        if ((TextUtils.isEmpty(mNumber)) && (TextUtils.isEmpty(mAlphaTag))) {
            Rlog.w(LOG_TAG, "[buildAdnString] Empty dialing number");
            return adnString;   // return the empty record (for delete)
        } else if (mNumber.length()
                > (ADN_DIALING_NUMBER_END - ADN_DIALING_NUMBER_START + 1) * 2) {
        } else if ((mNumber != null) && (mNumber.length()
                > (ADN_DIALING_NUMBER_END - ADN_DIALING_NUMBER_START + 1) * 2)) {
            Rlog.w(LOG_TAG,
                    "[buildAdnString] Max length of dialing number is 20");
            return null;
@@ -248,6 +330,7 @@ public class AdnRecord implements Parcelable {
            Rlog.w(LOG_TAG, "[buildAdnString] Max length of tag is " + footerOffset);
            return null;
        } else {
            if (!(TextUtils.isEmpty(mNumber))) {
                bcdNumber = PhoneNumberUtils.numberToCalledPartyBCD(mNumber);

            System.arraycopy(bcdNumber, 0, adnString,
@@ -255,6 +338,7 @@ public class AdnRecord implements Parcelable {

                adnString[footerOffset + ADN_BCD_NUMBER_LENGTH]
                        = (byte) (bcdNumber.length);
            }
            adnString[footerOffset + ADN_CAPABILITY_ID]
                    = (byte) 0xFF; // Capability Id
            adnString[footerOffset + ADN_EXTENSION_ID]
@@ -333,12 +417,14 @@ public class AdnRecord implements Parcelable {
            mExtRecord = 0xff & record[record.length - 1];

            mEmails = null;
            mAdditionalNumbers = null;

        } catch (RuntimeException ex) {
            Rlog.w(LOG_TAG, "Error parsing AdnRecord", ex);
            mNumber = "";
            mAlphaTag = "";
            mEmails = null;
            mAdditionalNumbers = null;
        }
    }
}
Loading