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

Commit 1a67987c authored by Yujing Gu's avatar Yujing Gu Committed by Linux Build Service Account
Browse files

Add supports for SIM contacts

- Support to update/insert/delete SIM contacts
- Support to save anr and email for SIM contacts

Change-Id: Ic4645e1ef60137053f169ee1ff9c2b0b74ee47f0
parent 8164603b
Loading
Loading
Loading
Loading

res/values-zh-rCN/strings.xml

100644 → 100755
+14 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@
    <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"建议的联系人"</string>
    <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"所有联系人"</string>
    <string name="contactsJoinedMessage" msgid="7208148163607047389">"已合并联系人"</string>
    <string name="importConfirmation_title" msgid="1418215926447642260">"要导入联系人吗?"</string>
    <string name="menu_set_ring_tone" msgid="8728345772068064946">"设置铃声"</string>
    <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"所有来电转至语音信箱"</string>
    <string name="readOnlyContactWarning" msgid="7808825687289848259">"您无法删除只读帐户中的联系人,但可以在联系人列表中将他们隐藏。"</string>
@@ -90,7 +91,19 @@
    <string name="addPeopleToGroup" msgid="7879585947222263516">"要添加联系人,请修改该群组。"</string>
    <string name="savingContact" msgid="4075751076741924939">"正在保存联系人…"</string>
    <string name="contactSavedToast" msgid="7152589189385441091">"此联系人已保存。"</string>
    <string name="contactDeletedToast">"此联系人已删除。"</string>
    <string name="contactSavedErrorToast" msgid="3207250533172944892">"无法保存联系人更改。"</string>
    <string name="contactSavedToSimCardError">"发生错误,正在载入SIM卡联系人。"</string>
    <string name="airplane_mode_on">"发生错误,当前处于飞行模式。"</string>
    <string name="number_anr_too_long">"发生错误,电话号码过长。"</string>
    <string name="email_address_too_long">"发生错误,邮箱地址过长。"</string>
    <string name="sim_card_full">"发生错误,SIM卡已满。"</string>
    <string name="tag_too_long">"发生错误,联系人姓名过长。"</string>
    <string name="no_phone_number">请输入手机号码。</string>
    <string name="invalid_phone_number">"发生错误,电话号码不合法。"</string>
    <string name="invalid_number_type">"发生错误,号码类型不合法。"</string>
    <string name="no_phone_number_or_email">请输入手机号码或者邮箱地址。</string>
    <string name="memory_card_full">错误, 内存已满.</string>
    <string name="groupSavedToast" msgid="1168756874239833756">"群组已保存。"</string>
    <string name="groupSavedErrorToast" msgid="7984466936615304740">"无法保存所做的群组更改。"</string>
  <plurals name="listTotalPhoneContacts">
@@ -204,6 +217,7 @@
    <string name="copy_text" msgid="3257145021583508761">"复制到剪贴板"</string>
    <string name="set_default" msgid="4417505153468300351">"设置默认值"</string>
    <string name="clear_default" msgid="7193185801596678067">"清除默认值"</string>
    <string name="edit_before_call">"拨号前编辑号码"</string>
    <string name="toast_text_copied" msgid="5143776250008541719">"文本已复制"</string>
    <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"要舍弃您所做的更改吗?"</string>
    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>

res/values/strings.xml

100644 → 100755
+17 −2
Original line number Diff line number Diff line
@@ -162,6 +162,8 @@
    <!-- Toast shown after two contacts have been joined by a user action -->
    <string name="contactsJoinedMessage">Contacts joined</string>

    <string name="importConfirmation_title">Import contact?</string>

    <!-- Menu item that opens the Options activity for a given contact [CHAR LIMIT=15] -->
    <string name="menu_set_ring_tone">Set ringtone</string>

@@ -247,10 +249,24 @@

    <!-- Toast displayed when a contact is saved [CHAR LIMIT=NONE] -->
    <string name="contactSavedToast">Contact saved.</string>
    <!-- Toast displayed when a contact is deleted [CHAR LIMIT=NONE] -->
    <string name="contactDeletedToast">Contact deleted.</string>

    <!-- Toast displayed when saving a contact failed. [CHAR LIMIT=NONE] -->
    <string name="contactSavedErrorToast">Couldn\'t save contact changes.</string>

    <!-- Toast displayed when saving a contact to sim card failed -->
    <string name="contactSavedToSimCardError">Error, Loading Sim Contacts.</string>
    <string name="airplane_mode_on">Error, Airplane mode is on.</string>
    <string name="number_anr_too_long">Error, Number is too long.</string>
    <string name="email_address_too_long">Error, Email Address is too long.</string>
    <string name="sim_card_full">Error, Sim Card is full.</string>
    <string name="tag_too_long">Error, Contact name is too long.</string>
    <string name="no_phone_number">Please insert phone number.</string>
    <string name="invalid_phone_number">Error, Number is invalid.</string>
    <string name="invalid_number_type">Error, Number type is invalid.</string>
    <string name="no_phone_number_or_email">Please insert phone number or email address.</string>
    <string name="memory_card_full">Error, Memory is almost full.</string>
    <!-- Toast displayed when a group is saved [CHAR LIMIT=NONE] -->
    <string name="groupSavedToast">Group saved.</string>

@@ -311,7 +327,6 @@
         Used by AccessibilityService to announce the purpose of the button.
    -->
    <string name="description_plus_button">plus</string>

    <!-- Message in progress bar while exporting contact list to a file "(current number) of (total number) contacts" The order of "current number" and "total number" cannot be changed (like "total: (total number), current: (current number)")-->
    <string name="exporting_contact_list_progress"><xliff:g id="current_number">%s</xliff:g> of <xliff:g id="total_number">%s</xliff:g> contacts</string>

@@ -576,6 +591,7 @@
    <!-- Option displayed in context menu to clear long pressed item as default contact method [CHAR LIMIT=64] -->
    <string name="clear_default">Clear default</string>

    <string name="edit_before_call">Edit number before call</string>
    <!-- Toast shown when text is copied to the clipboard [CHAR LIMIT=64] -->
    <string name="toast_text_copied">Text copied</string>

@@ -643,7 +659,6 @@

    <!-- Button label to prompt the user to add another account (when there are already existing accounts on the device) [CHAR LIMIT=30] -->
    <string name="add_new_account">Add new account</string>

    <!-- Menu item shown only when the special debug mode is enabled, which is used to send all contacts database files via email.  [CHAR LIMI=NONE] -->
    <string name="menu_export_database">Export database files</string>

+252 −6
Original line number Diff line number Diff line
@@ -28,12 +28,14 @@ import android.content.Context;
import android.content.Intent;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.database.sqlite.SQLiteFullException;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.ContactsContract;
import android.provider.ContactsContract.AggregationExceptions;
import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
@@ -44,6 +46,10 @@ import android.provider.ContactsContract.PinnedPositions;
import android.provider.ContactsContract.Profile;
import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.RawContactsEntity;
import android.text.TextUtils;
import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
import android.telephony.SubscriptionManager;
import android.util.Log;
import android.widget.Toast;

@@ -53,8 +59,13 @@ import com.android.contacts.common.model.RawContactDelta;
import com.android.contacts.common.model.RawContactDeltaList;
import com.android.contacts.common.model.RawContactModifier;
import com.android.contacts.common.model.account.AccountWithDataSet;
import com.android.contacts.common.SimContactsConstants;
import com.android.contacts.common.SimContactsOperation;
import com.android.contacts.common.MoreContactUtils;
import com.android.contacts.util.ContactPhotoUtils;

import com.android.internal.telephony.uicc.AdnRecord;
import com.android.internal.telephony.uicc.IccConstants;
import com.android.internal.telephony.IIccPhoneBook;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

@@ -66,6 +77,7 @@ import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.HashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
@@ -91,6 +103,7 @@ public class ContactSaveService extends IntentService {
    public static final String EXTRA_SAVE_IS_PROFILE = "saveIsProfile";
    public static final String EXTRA_SAVE_SUCCEEDED = "saveSucceeded";
    public static final String EXTRA_UPDATED_PHOTOS = "updatedPhotos";
    public static final String SAVE_CONTACT_RESULT = "saveResult";

    public static final String ACTION_CREATE_GROUP = "createGroup";
    public static final String ACTION_RENAME_GROUP = "renameGroup";
@@ -142,6 +155,33 @@ public class ContactSaveService extends IntentService {
    );

    private static final int PERSIST_TRIES = 3;
    private static int count = TelephonyManager.getDefault().getPhoneCount();
    private static int[] mSimMaxCount = new int[count];

    public static final int RESULT_UNCHANGED = 0;
    public static final int RESULT_SUCCESS = 1;
    public static final int RESULT_FAILURE = 2;
    public static final int RESULT_NO_NUMBER_AND_EMAIL = 3;
    public static final int RESULT_SIM_FAILURE = 4;   //only for sim operation failure
    public static final int RESULT_EMAIL_FAILURE = 5; // only for sim email operation failure
    // only for sim failure of number or anr is too long
    public static final int RESULT_NUMBER_ANR_FAILURE = 6;
    public static final int RESULT_SIM_FULL_FAILURE = 7; // only for sim card is full
    public static final int RESULT_TAG_FAILURE = 8; // only for sim failure of name is too long
    public static final int RESULT_NUMBER_INVALID = 9; // only for sim failure of number is valid

    public static final int RESULT_MEMORY_FULL_FAILURE = 11; //for memory full exception
    public static final int RESULT_NUMBER_TYPE_FAILURE =12;  //only for sim failure of number TYPE

    private final int MAX_NUM_LENGTH = 20;
    private final int MAX_EMAIL_LENGTH = 40;
    private final int MAX_EN_LENGTH = 14;
    private final int MAX_CH_LENGTH = 6;

    // Only for request accessing SIM card
    // when device is in the "AirPlane" mode.
    public static final int RESULT_AIR_PLANE_MODE = 10;
    public static SimContactsOperation mSimContactsOperation;

    public interface Listener {
        public void onServiceCompleted(Intent callbackIntent);
@@ -180,6 +220,40 @@ public class ContactSaveService extends IntentService {
        return getApplicationContext().getSystemService(name);
    }

    /**
     * when isMultiSimEnabled is true,get the maximum how many contacts can save to sim card
     */
    private int getMSimCardMaxCount(int subscription) {
        if (0 != mSimMaxCount[subscription]) {
            return mSimMaxCount[subscription];
        }
        long[] subId = SubscriptionManager.getSubId(subscription);
        try {
            IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
                ServiceManager.getService("simphonebook"));

            if (iccIpb != null) {
                if (subId != null 
                        && TelephonyManager.getDefault().isMultiSimEnabled()) {
                    List<AdnRecord> list = iccIpb.getAdnRecordsInEfForSubscriber(
                            subId[0], IccConstants.EF_ADN);
                    if (null != list) {
                        mSimMaxCount[subscription] = list.size();
                    }
                } else {
                    List<AdnRecord> list = iccIpb
                            .getAdnRecordsInEf(IccConstants.EF_ADN);
                    if (null != list) {
                        mSimMaxCount[subscription] = list.size();
                    }
                }
            }
        } catch (RemoteException ex) {
            Log.e(TAG, "Failed to IIccPhoneBookMSim", ex);
        }
        return mSimMaxCount[subscription];
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        // Call an appropriate method. If we're sure it affects how incoming phone calls are
@@ -347,8 +421,31 @@ public class ContactSaveService extends IntentService {
        long insertedRawContactId = -1;

        // Attempt to persist changes
        Integer result = RESULT_FAILURE;

        boolean isCardOperation = false;
        for (int i=0; i < state.size(); i++) {
            final RawContactDelta entity = state.get(i);
            final String accountType = entity.getValues().getAsString(RawContacts.ACCOUNT_TYPE);
            final String accountName = entity.getValues().getAsString(RawContacts.ACCOUNT_NAME);
            final int subscription = MoreContactUtils.getSubscription(
                accountType, accountName);
            isCardOperation = (subscription != SimContactsConstants.SUB_INVALID) ? true : false;
            if (isCardOperation) {
                result = doSaveToSimCard(entity, resolver, subscription);
                Log.d(TAG, "doSaveToSimCard result is  " + result);
                switch (result) {
                    case RESULT_SUCCESS:
                        result = RESULT_FAILURE;
                        break;
                    default:
                        break;
                }
            }
        }
        int tries = 0;
        while (tries++ < PERSIST_TRIES) {
            if (result == RESULT_FAILURE) {
            try {
                // Build operations and try applying
                final ArrayList<ContentProviderOperation> diff = state.buildDiff();
@@ -393,7 +490,13 @@ public class ContactSaveService extends IntentService {
                    lookupUri = RawContacts.getContactLookupUri(resolver, rawContactUri);
                }
                Log.v(TAG, "Saved contact. New URI: " + lookupUri);

                    if (lookupUri == null) {
                        resolver.delete(RawContacts.CONTENT_URI,
                            RawContacts._ID + "=?",
                            new String[] {
                                String.valueOf(rawContactId)
                            });
                    }
                // We can change this back to false later, if we fail to save the contact photo.
                succeeded = true;
                break;
@@ -402,13 +505,22 @@ public class ContactSaveService extends IntentService {
                // Something went wrong, bail without success
                Log.e(TAG, "Problem persisting user edits", e);
                break;

            } catch (IllegalArgumentException e) {
                // This is thrown by applyBatch on malformed requests
                Log.e(TAG, "Problem persisting user edits", e);
                showToast(R.string.contactSavedErrorToast);
                break;

            } catch (SQLiteFullException e) {
                // Memory is full. don't do any thing
                Log.e(TAG, "Memory is full", e);
                Intent callbackIntent = intent.getParcelableExtra(EXTRA_CALLBACK_INTENT);
                if (callbackIntent != null) {
                    callbackIntent.putExtra(EXTRA_SAVE_SUCCEEDED, false);
                    callbackIntent.setData(null);
                    callbackIntent.putExtra(SAVE_CONTACT_RESULT, RESULT_MEMORY_FULL_FAILURE);
                    deliverCallback(callbackIntent);
                }
                return;
            } catch (OperationApplicationException e) {
                // Version consistency failed, re-parent change and try again
                Log.w(TAG, "Version consistency failed, re-parenting: " + e.toString());
@@ -447,6 +559,7 @@ public class ContactSaveService extends IntentService {
                    }
                }
            }
        }

        // Now save any updated photos.  We do this at the end to ensure that
        // the ContactProvider already knows about newly-created contacts.
@@ -478,6 +591,8 @@ public class ContactSaveService extends IntentService {
                callbackIntent.putExtra(EXTRA_SAVE_SUCCEEDED, true);
            }
            callbackIntent.setData(lookupUri);
            callbackIntent.putExtra(SAVE_CONTACT_RESULT, result);

            deliverCallback(callbackIntent);
        }
    }
@@ -494,6 +609,123 @@ public class ContactSaveService extends IntentService {
        return ContactPhotoUtils.savePhotoFromUriToUri(this, photoUri, outputUri, true);
    }

    private Integer doSaveToSimCard(RawContactDelta entity, ContentResolver resolver,
        int subscription) {
        // Return Error code to indicate caller that device is in
        // the "AirPlane" mode and application can't access SIM card.
        if (MoreContactUtils.isAPMOnAndSIMPowerDown(this)) {
            return RESULT_AIR_PLANE_MODE;
        }

        boolean isInsert = entity.isContactInsert();
        Integer result = RESULT_SIM_FAILURE;
        mSimContactsOperation = new SimContactsOperation(this);

        ContentValues values = entity.buildSimDiff();
        String tag = null;
        String number = null;
        String anr = null;
        String email = null;

        if(entity.isContactInsert()){
            tag = values.getAsString(SimContactsConstants.STR_TAG);
            number = values.getAsString(SimContactsConstants.STR_NUMBER);
            anr = values.getAsString(SimContactsConstants.STR_ANRS);
            email = values.getAsString(SimContactsConstants.STR_EMAILS);
        } else {
            tag = values.getAsString(SimContactsConstants.STR_NEW_TAG);
            number = values.getAsString(SimContactsConstants.STR_NEW_NUMBER);
            anr = values.getAsString(SimContactsConstants.STR_NEW_ANRS);
            email = values.getAsString(SimContactsConstants.STR_NEW_EMAILS);
        }

        if (TextUtils.isEmpty(number) && TextUtils.isEmpty(anr) && TextUtils.isEmpty(email)) {
            return RESULT_NO_NUMBER_AND_EMAIL;
        }

        if (!TextUtils.isEmpty(number)) {
            if (number.length() > MAX_NUM_LENGTH) {
                return RESULT_NUMBER_ANR_FAILURE;
            } else if (number.contains(SimContactsConstants.STR_ANRS)) {
                return RESULT_NUMBER_TYPE_FAILURE;
            }
        }

        if (!TextUtils.isEmpty(anr)) {
            String[] anrs = anr.split(",");
            if (anrs != null) {
                if (anrs.length > MoreContactUtils
                        .getOneSimAnrCount(subscription)) {
                    return RESULT_NUMBER_TYPE_FAILURE;
                }
                for (String mAnr : anrs) {
                    if (mAnr.length() > MAX_NUM_LENGTH) {
                        return RESULT_NUMBER_ANR_FAILURE;
                    }
                }
            }
        }

        if (!TextUtils.isEmpty(number) && TextUtils.isEmpty(PhoneNumberUtils
                .stripSeparators(number))) {
            return RESULT_NUMBER_INVALID;
        }

        if (!TextUtils.isEmpty(email)) {
            String[] emails = email.split(",");
            for (String mEmail : emails) {
                if (mEmail != null && mEmail.length() > MAX_EMAIL_LENGTH) {
                    return RESULT_EMAIL_FAILURE;
                }
            }
        }

        if (!TextUtils.isEmpty(tag)) {
            if (tag.getBytes().length > MAX_EN_LENGTH) {
                return RESULT_TAG_FAILURE;
            }
        }

        if (entity.isContactInsert()) {
            int count = 0;
            Cursor c = null;
            Uri iccUri;
            long[] subId = SubscriptionManager.getSubId(subscription);
            if (!TelephonyManager.getDefault().isMultiSimEnabled()) {
                iccUri = Uri.parse(SimContactsConstants.SIM_URI);
            } else {
                iccUri = Uri.parse(SimContactsConstants.SIM_SUB_URI + subId[0]);
            }
            try {
                c = resolver.query(iccUri, null, null, null, null);
                if (c != null) {
                    count = c.getCount();
                }
            } finally {
                if (c != null) {
                    c.close();
                }
            }

            if (count == getMSimCardMaxCount(subscription)) {
                return RESULT_SIM_FULL_FAILURE;
            }
        }

        if (isInsert) {
            Uri resultUri = mSimContactsOperation.insert(values,
                    subscription);
            if (resultUri != null)
                result = RESULT_SUCCESS;
        } else {
            int resultInt = mSimContactsOperation.update(values,
                    subscription);
            if (resultInt == 1)
                result = RESULT_SUCCESS;
        }
        return result;
    }

     /**
     * Find the ID of an existing or newly-inserted raw-contact.  If none exists, return -1.
     */
@@ -942,13 +1174,27 @@ public class ContactSaveService extends IntentService {

    private void deleteContact(Intent intent) {
        Uri contactUri = intent.getParcelableExtra(EXTRA_CONTACT_URI);
        mSimContactsOperation = new SimContactsOperation(this);
        if (contactUri == null) {
            Log.e(TAG, "Invalid arguments for deleteContact request");
            return;
        }

        final List<String> segments = contactUri.getPathSegments();
        // Contains an Id.
        final long uriContactId = Long.parseLong(segments.get(3));
        int subscription = mSimContactsOperation.getSimSubscription(uriContactId);
        if (subscription != SimContactsConstants.SUB_INVALID) {
            ContentValues values =
                    mSimContactsOperation.getSimAccountValues(uriContactId);
            int result = mSimContactsOperation.delete(values, subscription);
            if (result == RESULT_SUCCESS) {
                getContentResolver().delete(contactUri, null, null);
            }
        } else {
            getContentResolver().delete(contactUri, null, null);
        }
    }

    /**
     * Creates an intent that can be sent to this service to join two contacts.
+4 −3
Original line number Diff line number Diff line
@@ -144,7 +144,8 @@ public class ContactEditorActivity extends ContactsActivity
            mFragment.onSaveCompleted(true,
                intent.getIntExtra(ContactEditorFragment.SAVE_MODE_EXTRA_KEY, SaveMode.CLOSE),
                intent.getBooleanExtra(ContactSaveService.EXTRA_SAVE_SUCCEEDED, false),
                    intent.getData());
                intent.getData(),
                intent.getIntExtra(ContactSaveService.SAVE_CONTACT_RESULT, 0));
        } else if (ACTION_JOIN_COMPLETED.equals(action)) {
            mFragment.onJoinCompleted(intent.getData());
        }
+90 −6

File changed.File mode changed from 100644 to 100755.

Preview size limit exceeded, changes collapsed.

Loading