1c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/*
2c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Copyright (C) 2006 The Android Open Source Project
3c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
4c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Licensed under the Apache License, Version 2.0 (the "License");
5c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * you may not use this file except in compliance with the License.
6c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * You may obtain a copy of the License at
7c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
8c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *      http://www.apache.org/licenses/LICENSE-2.0
9c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
10c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Unless required by applicable law or agreed to in writing, software
11c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * distributed under the License is distributed on an "AS IS" BASIS,
12c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * See the License for the specific language governing permissions and
14c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * limitations under the License.
15c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
16c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
17c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepackage com.android.internal.telephony;
18c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
19c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.pm.PackageManager;
20c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.AsyncResult;
21c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Handler;
22c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Looper;
23c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Message;
241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport android.telephony.Rlog;
25c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
26d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.AdnRecord;
27d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.AdnRecordCache;
28d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
29d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccConstants;
301a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yuimport com.android.internal.telephony.uicc.IccFileHandler;
31d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccRecords;
32a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.uicc.UiccCardApplication;
33e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
34c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.List;
35c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.concurrent.atomic.AtomicBoolean;
36c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
37c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/**
38c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * SimPhoneBookInterfaceManager to provide an inter-process communication to
39c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * access ADN-like SIM records.
40c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yupublic class IccPhoneBookInterfaceManager {
421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    static final String LOG_TAG = "IccPhoneBookIM";
43c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final boolean DBG = true;
44c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    protected Phone mPhone;
46a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private   UiccCardApplication mCurrentApp = null;
4722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected AdnRecordCache mAdnCache;
48c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected final Object mLock = new Object();
4922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected int mRecordSize[];
5022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected boolean mSuccess;
51a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private   boolean mIs3gCard = false;  // flag to determine if card is 3G or 2G
5222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected List<AdnRecord> mRecords;
53c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
54a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
55c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final boolean ALLOW_SIM_OP_IN_UI_THREAD = false;
56c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
57c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int EVENT_GET_SIZE_DONE = 1;
58c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int EVENT_LOAD_DONE = 2;
59c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int EVENT_UPDATE_DONE = 3;
60c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
61c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected Handler mBaseHandler = new Handler() {
62c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        @Override
63c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        public void handleMessage(Message msg) {
64c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AsyncResult ar;
65c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
66c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            switch (msg.what) {
67c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                case EVENT_GET_SIZE_DONE:
68c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ar = (AsyncResult) msg.obj;
69c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    synchronized (mLock) {
70c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        if (ar.exception == null) {
7122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            mRecordSize = (int[])ar.result;
72c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            // recordSize[0]  is the record length
73c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            // recordSize[1]  is the total length of the EF file
74c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            // recordSize[2]  is the number of records in the EF file
7522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            logd("GET_RECORD_SIZE Size " + mRecordSize[0] +
7622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                                    " total " + mRecordSize[1] +
7722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                                    " #record " + mRecordSize[2]);
78c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
79c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        notifyPending(ar);
80c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
81c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
82c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                case EVENT_UPDATE_DONE:
83c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ar = (AsyncResult) msg.obj;
84c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    synchronized (mLock) {
8522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mSuccess = (ar.exception == null);
86c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        notifyPending(ar);
87c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
88c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
89c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                case EVENT_LOAD_DONE:
90c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ar = (AsyncResult)msg.obj;
91c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    synchronized (mLock) {
92c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        if (ar.exception == null) {
9322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            mRecords = (List<AdnRecord>) ar.result;
94c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        } else {
95c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            if(DBG) logd("Cannot load ADN records");
963be9fb032307d7586b32dc57ddd486e8e9d43bd2fionaxu                            mRecords = null;
97c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
98c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        notifyPending(ar);
99c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
101c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
102c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
103c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
104c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        private void notifyPending(AsyncResult ar) {
105145c68db12c0fba4c6e1ff67329f02f29fc683e2Amit Mahajan            if (ar.userObj != null) {
106145c68db12c0fba4c6e1ff67329f02f29fc683e2Amit Mahajan                AtomicBoolean status = (AtomicBoolean) ar.userObj;
107145c68db12c0fba4c6e1ff67329f02f29fc683e2Amit Mahajan                status.set(true);
108c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            mLock.notifyAll();
110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
111c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    };
112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1131a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public IccPhoneBookInterfaceManager(Phone phone) {
11422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        this.mPhone = phone;
115ce000ddfbb615f873e9fc0a4c68f992b12d3f82ffionaxu        IccRecords r = phone.getIccRecords();
116bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        if (r != null) {
11722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mAdnCache = r.getAdnCache();
118bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        }
119c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
120c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dispose() {
122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
124bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka    public void updateIccRecords(IccRecords iccRecords) {
125bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        if (iccRecords != null) {
12622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mAdnCache = iccRecords.getAdnCache();
127bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        } else {
12822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mAdnCache = null;
129bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        }
130bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka    }
131bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka
1321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    protected void logd(String msg) {
1331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Rlog.d(LOG_TAG, "[IccPbInterfaceManager] " + msg);
1341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
135c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    protected void loge(String msg) {
1371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        Rlog.e(LOG_TAG, "[IccPbInterfaceManager] " + msg);
1381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
140c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Replace oldAdn with newAdn in ADN-like record in EF
142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
143c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * getAdnRecordsInEf must be called at least once before this function,
144c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * otherwise an error will be returned. Currently the email field
145c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * if set in the ADN record is ignored.
146c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * throws SecurityException if no WRITE_CONTACTS permission
147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param oldTag adn tag to be replaced
150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param oldPhoneNumber adn number to be replaced
151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        Set both oldTag and oldPhoneNubmer to "" means to replace an
152c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        empty record, aka, insert new record
153c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param newTag adn tag to be stored
154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param newPhoneNumber adn number ot be stored
155c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        Set both newTag and newPhoneNubmer to "" means to replace the old
156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        record with empty one, aka, delete old record
157c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param pin2 required to update EF_FDN, otherwise must be null
158c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return true for success
159c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
160c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean
161c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    updateAdnRecordsInEfBySearch (int efid,
162c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String oldTag, String oldPhoneNumber,
163c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String newTag, String newPhoneNumber, String pin2) {
164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
165c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
16622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPhone.getContext().checkCallingOrSelfPermission(
167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                android.Manifest.permission.WRITE_CONTACTS)
168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            != PackageManager.PERMISSION_GRANTED) {
169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            throw new SecurityException(
170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    "Requires android.permission.WRITE_CONTACTS permission");
171c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
173c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) logd("updateAdnRecordsInEfBySearch: efid=0x" +
17577a1f167b962ceaf7972d246f4c23e17772d1c69fionaxu                Integer.toHexString(efid).toUpperCase() + " ("+ Rlog.pii(LOG_TAG, oldTag) + "," +
17677a1f167b962ceaf7972d246f4c23e17772d1c69fionaxu                Rlog.pii(LOG_TAG, oldPhoneNumber) + ")" + "==>" + " ("+ Rlog.pii(LOG_TAG, newTag) +
17777a1f167b962ceaf7972d246f4c23e17772d1c69fionaxu                "," + Rlog.pii(LOG_TAG, newPhoneNumber) + ")"+ " pin2=" + Rlog.pii(LOG_TAG, pin2));
178c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
179c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        efid = updateEfForIccType(efid);
180c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
181c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        synchronized(mLock) {
182c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            checkThread();
18322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mSuccess = false;
184c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AtomicBoolean status = new AtomicBoolean(false);
185c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, status);
186c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AdnRecord oldAdn = new AdnRecord(oldTag, oldPhoneNumber);
187c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
188f16c95f5e7e34e7e3a51a012d172902365a3682eAlex Yakavenka            if (mAdnCache != null) {
189f16c95f5e7e34e7e3a51a012d172902365a3682eAlex Yakavenka                mAdnCache.updateAdnBySearch(efid, oldAdn, newAdn, pin2, response);
19098437235fc30d809992c32410f02d22cc89fac8cAlex Yakavenka                waitForResult(status);
19198437235fc30d809992c32410f02d22cc89fac8cAlex Yakavenka            } else {
19298437235fc30d809992c32410f02d22cc89fac8cAlex Yakavenka                loge("Failure while trying to update by search due to uninitialised adncache");
19398437235fc30d809992c32410f02d22cc89fac8cAlex Yakavenka            }
194c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
19522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mSuccess;
196c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
198c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
199c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Update an ADN-like EF record by record index
200c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
201c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * This is useful for iteration the whole ADN file, such as write the whole
202c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * phone book or erase/format the whole phonebook. Currently the email field
203c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * if set in the ADN record is ignored.
204c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * throws SecurityException if no WRITE_CONTACTS permission
205c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
206c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
207c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param newTag adn tag to be stored
208c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param newPhoneNumber adn number to be stored
209c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        Set both newTag and newPhoneNubmer to "" means to replace the old
210c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        record with empty one, aka, delete old record
211c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param index is 1-based adn record index to be updated
212c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param pin2 required to update EF_FDN, otherwise must be null
213c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return true for success
214c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
215c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean
216c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    updateAdnRecordsInEfByIndex(int efid, String newTag,
217c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String newPhoneNumber, int index, String pin2) {
218c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
21922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPhone.getContext().checkCallingOrSelfPermission(
220c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                android.Manifest.permission.WRITE_CONTACTS)
221c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                != PackageManager.PERMISSION_GRANTED) {
222c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            throw new SecurityException(
223c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    "Requires android.permission.WRITE_CONTACTS permission");
224c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
225c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
2261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) logd("updateAdnRecordsInEfByIndex: efid=0x" +
22777a1f167b962ceaf7972d246f4c23e17772d1c69fionaxu                Integer.toHexString(efid).toUpperCase() + " Index=" + index + " ==> " + "(" +
22877a1f167b962ceaf7972d246f4c23e17772d1c69fionaxu                Rlog.pii(LOG_TAG, newTag) + "," + Rlog.pii(LOG_TAG, newPhoneNumber) + ")" +
22977a1f167b962ceaf7972d246f4c23e17772d1c69fionaxu                " pin2=" + Rlog.pii(LOG_TAG, pin2));
230c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        synchronized(mLock) {
231c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            checkThread();
23222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mSuccess = false;
233c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AtomicBoolean status = new AtomicBoolean(false);
234c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, status);
235c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
236f16c95f5e7e34e7e3a51a012d172902365a3682eAlex Yakavenka            if (mAdnCache != null) {
237f16c95f5e7e34e7e3a51a012d172902365a3682eAlex Yakavenka                mAdnCache.updateAdnByIndex(efid, newAdn, index, pin2, response);
23898437235fc30d809992c32410f02d22cc89fac8cAlex Yakavenka                waitForResult(status);
23998437235fc30d809992c32410f02d22cc89fac8cAlex Yakavenka            } else {
24098437235fc30d809992c32410f02d22cc89fac8cAlex Yakavenka                loge("Failure while trying to update by index due to uninitialised adncache");
24198437235fc30d809992c32410f02d22cc89fac8cAlex Yakavenka            }
242c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
24322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mSuccess;
244c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
245c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
246c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
247c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Get the capacity of records in efid
248c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
249c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param efid the EF id of a ADN-like ICC
250c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return  int[3] array
251c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *            recordSizes[0]  is the single record length
252c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *            recordSizes[1]  is the total length of the EF file
253c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *            recordSizes[2]  is the number of records in the EF file
254c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
2551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    public int[] getAdnRecordsSize(int efid) {
2561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) logd("getAdnRecordsSize: efid=" + efid);
2571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        synchronized(mLock) {
2581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            checkThread();
2591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            mRecordSize = new int[3];
2601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            //Using mBaseHandler, no difference in EVENT_GET_SIZE_DONE handling
2621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            AtomicBoolean status = new AtomicBoolean(false);
2631a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE, status);
2641a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            IccFileHandler fh = mPhone.getIccFileHandler();
2661a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            if (fh != null) {
2671a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                fh.getEFLinearRecordSize(efid, response);
2681a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu                waitForResult(status);
2691a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu            }
2701a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        }
2711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        return mRecordSize;
2731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    }
2741a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
275c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
276c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
277c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Loads the AdnRecords in efid and returns them as a
278c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * List of AdnRecords
279c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
280c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * throws SecurityException if no READ_CONTACTS permission
281c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
282c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param efid the EF id of a ADN-like ICC
283c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return List of AdnRecord
284c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
285c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public List<AdnRecord> getAdnRecordsInEf(int efid) {
286c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
28722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPhone.getContext().checkCallingOrSelfPermission(
288c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                android.Manifest.permission.READ_CONTACTS)
289c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                != PackageManager.PERMISSION_GRANTED) {
290c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            throw new SecurityException(
291c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    "Requires android.permission.READ_CONTACTS permission");
292c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
293c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
294c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        efid = updateEfForIccType(efid);
2951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu        if (DBG) logd("getAdnRecordsInEF: efid=0x" + Integer.toHexString(efid).toUpperCase());
296c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
297c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        synchronized(mLock) {
298c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            checkThread();
299c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AtomicBoolean status = new AtomicBoolean(false);
300c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Message response = mBaseHandler.obtainMessage(EVENT_LOAD_DONE, status);
301f16c95f5e7e34e7e3a51a012d172902365a3682eAlex Yakavenka            if (mAdnCache != null) {
302f16c95f5e7e34e7e3a51a012d172902365a3682eAlex Yakavenka                mAdnCache.requestLoadAllAdnLike(efid, mAdnCache.extensionEfForEf(efid), response);
30398437235fc30d809992c32410f02d22cc89fac8cAlex Yakavenka                waitForResult(status);
30498437235fc30d809992c32410f02d22cc89fac8cAlex Yakavenka            } else {
30598437235fc30d809992c32410f02d22cc89fac8cAlex Yakavenka                loge("Failure while trying to load from SIM due to uninitialised adncache");
30698437235fc30d809992c32410f02d22cc89fac8cAlex Yakavenka            }
307c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
30822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mRecords;
309c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
310c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
311c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void checkThread() {
312c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (!ALLOW_SIM_OP_IN_UI_THREAD) {
313c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Make sure this isn't the UI thread, since it will block
314c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (mBaseHandler.getLooper().equals(Looper.myLooper())) {
315c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                loge("query() called on the main UI thread!");
316c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                throw new IllegalStateException(
317c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        "You cannot call query on this provder from the main UI thread.");
318c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
319c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
320c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
321c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
322c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void waitForResult(AtomicBoolean status) {
323c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        while (!status.get()) {
324c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            try {
325c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mLock.wait();
326c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } catch (InterruptedException e) {
327c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                logd("interrupted while trying to update by search");
328c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
329c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
330c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
331c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
332c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private int updateEfForIccType(int efid) {
333c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Check if we are trying to read ADN records
334c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (efid == IccConstants.EF_ADN) {
33522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (mPhone.getCurrentUiccAppType() == AppType.APPTYPE_USIM) {
336c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                return IccConstants.EF_PBR;
337c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
338c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
339c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return efid;
340c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
341c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
342c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
343