IccPhoneBookInterfaceManager.java revision 22d85a8e3a575a6d01d2c788587971657dfe20c6
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;
24c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.ServiceManager;
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;
30d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccRecords;
31e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
32c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.List;
33c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.concurrent.atomic.AtomicBoolean;
34c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
35c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/**
36c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * SimPhoneBookInterfaceManager to provide an inter-process communication to
37c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * access ADN-like SIM records.
38c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
39c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepublic abstract class IccPhoneBookInterfaceManager extends IIccPhoneBook.Stub {
40c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final boolean DBG = true;
41c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
4222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected PhoneBase mPhone;
4322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected AdnRecordCache mAdnCache;
44c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected final Object mLock = new Object();
4522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected int mRecordSize[];
4622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected boolean mSuccess;
4722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected List<AdnRecord> mRecords;
48c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
49c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final boolean ALLOW_SIM_OP_IN_UI_THREAD = false;
50c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
51c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int EVENT_GET_SIZE_DONE = 1;
52c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int EVENT_LOAD_DONE = 2;
53c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int EVENT_UPDATE_DONE = 3;
54c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
55c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected Handler mBaseHandler = new Handler() {
56c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        @Override
57c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        public void handleMessage(Message msg) {
58c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AsyncResult ar;
59c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
60c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            switch (msg.what) {
61c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                case EVENT_GET_SIZE_DONE:
62c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ar = (AsyncResult) msg.obj;
63c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    synchronized (mLock) {
64c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        if (ar.exception == null) {
6522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            mRecordSize = (int[])ar.result;
66c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            // recordSize[0]  is the record length
67c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            // recordSize[1]  is the total length of the EF file
68c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            // recordSize[2]  is the number of records in the EF file
6922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            logd("GET_RECORD_SIZE Size " + mRecordSize[0] +
7022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                                    " total " + mRecordSize[1] +
7122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                                    " #record " + mRecordSize[2]);
72c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
73c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        notifyPending(ar);
74c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
75c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
76c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                case EVENT_UPDATE_DONE:
77c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ar = (AsyncResult) msg.obj;
78c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    synchronized (mLock) {
7922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mSuccess = (ar.exception == null);
80c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        notifyPending(ar);
81c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
82c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
83c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                case EVENT_LOAD_DONE:
84c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ar = (AsyncResult)msg.obj;
85c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    synchronized (mLock) {
86c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        if (ar.exception == null) {
8722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            mRecords = (List<AdnRecord>) ar.result;
88c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        } else {
89c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            if(DBG) logd("Cannot load ADN records");
9022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            if (mRecords != null) {
9122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                                mRecords.clear();
92c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            }
93c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
94c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        notifyPending(ar);
95c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
96c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
97c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
98c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
99c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        private void notifyPending(AsyncResult ar) {
101c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (ar.userObj == null) {
102c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                return;
103c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
104c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AtomicBoolean status = (AtomicBoolean) ar.userObj;
105c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            status.set(true);
106c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            mLock.notifyAll();
107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
108c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    };
109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public IccPhoneBookInterfaceManager(PhoneBase phone) {
11122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        this.mPhone = phone;
112bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        IccRecords r = phone.mIccRecords.get();
113bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        if (r != null) {
11422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mAdnCache = r.getAdnCache();
115bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        }
116c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
117c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
118c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dispose() {
119c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
120c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
121bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka    public void updateIccRecords(IccRecords iccRecords) {
122bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        if (iccRecords != null) {
12322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mAdnCache = iccRecords.getAdnCache();
124bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        } else {
12522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mAdnCache = null;
126bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        }
127bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka    }
128bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka
129c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void publish() {
130c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        //NOTE service "simphonebook" added by IccSmsInterfaceManagerProxy
131c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        ServiceManager.addService("simphonebook", this);
132c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
134c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract void logd(String msg);
135c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
136c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected abstract void loge(String msg);
137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
138c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Replace oldAdn with newAdn in ADN-like record in EF
140c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * getAdnRecordsInEf must be called at least once before this function,
142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * otherwise an error will be returned. Currently the email field
143c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * if set in the ADN record is ignored.
144c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * throws SecurityException if no WRITE_CONTACTS permission
145c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
146c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param oldTag adn tag to be replaced
148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param oldPhoneNumber adn number to be replaced
149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        Set both oldTag and oldPhoneNubmer to "" means to replace an
150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        empty record, aka, insert new record
151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param newTag adn tag to be stored
152c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param newPhoneNumber adn number ot be stored
153c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        Set both newTag and newPhoneNubmer to "" means to replace the old
154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        record with empty one, aka, delete old record
155c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param pin2 required to update EF_FDN, otherwise must be null
156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return true for success
157c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
158cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
159c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean
160c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    updateAdnRecordsInEfBySearch (int efid,
161c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String oldTag, String oldPhoneNumber,
162c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String newTag, String newPhoneNumber, String pin2) {
163c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
16522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPhone.getContext().checkCallingOrSelfPermission(
166c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                android.Manifest.permission.WRITE_CONTACTS)
167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            != PackageManager.PERMISSION_GRANTED) {
168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            throw new SecurityException(
169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    "Requires android.permission.WRITE_CONTACTS permission");
170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
171c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
173c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) logd("updateAdnRecordsInEfBySearch: efid=" + efid +
174c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                " ("+ oldTag + "," + oldPhoneNumber + ")"+ "==>" +
175c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                " ("+ newTag + "," + newPhoneNumber + ")"+ " pin2=" + pin2);
176c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
177c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        efid = updateEfForIccType(efid);
178c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
179c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        synchronized(mLock) {
180c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            checkThread();
18122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mSuccess = false;
182c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AtomicBoolean status = new AtomicBoolean(false);
183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, status);
184c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AdnRecord oldAdn = new AdnRecord(oldTag, oldPhoneNumber);
185c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
18622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mAdnCache.updateAdnBySearch(efid, oldAdn, newAdn, pin2, response);
187c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            waitForResult(status);
188c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
18922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mSuccess;
190c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
191c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
192c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
193c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Update an ADN-like EF record by record index
194c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
195c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * This is useful for iteration the whole ADN file, such as write the whole
196c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * phone book or erase/format the whole phonebook. Currently the email field
197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * if set in the ADN record is ignored.
198c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * throws SecurityException if no WRITE_CONTACTS permission
199c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
200c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
201c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param newTag adn tag to be stored
202c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param newPhoneNumber adn number to be stored
203c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        Set both newTag and newPhoneNubmer to "" means to replace the old
204c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        record with empty one, aka, delete old record
205c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param index is 1-based adn record index to be updated
206c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param pin2 required to update EF_FDN, otherwise must be null
207c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return true for success
208c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
209cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
210c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean
211c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    updateAdnRecordsInEfByIndex(int efid, String newTag,
212c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String newPhoneNumber, int index, String pin2) {
213c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
21422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPhone.getContext().checkCallingOrSelfPermission(
215c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                android.Manifest.permission.WRITE_CONTACTS)
216c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                != PackageManager.PERMISSION_GRANTED) {
217c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            throw new SecurityException(
218c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    "Requires android.permission.WRITE_CONTACTS permission");
219c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
220c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
221c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) logd("updateAdnRecordsInEfByIndex: efid=" + efid +
222c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                " Index=" + index + " ==> " +
223c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                "("+ newTag + "," + newPhoneNumber + ")"+ " pin2=" + pin2);
224c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        synchronized(mLock) {
225c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            checkThread();
22622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mSuccess = false;
227c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AtomicBoolean status = new AtomicBoolean(false);
228c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, status);
229c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
23022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mAdnCache.updateAdnByIndex(efid, newAdn, index, pin2, response);
231c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            waitForResult(status);
232c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
23322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mSuccess;
234c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
235c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
236c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
237c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Get the capacity of records in efid
238c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
239c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param efid the EF id of a ADN-like ICC
240c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return  int[3] array
241c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *            recordSizes[0]  is the single record length
242c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *            recordSizes[1]  is the total length of the EF file
243c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *            recordSizes[2]  is the number of records in the EF file
244c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
245cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
246c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public abstract int[] getAdnRecordsSize(int efid);
247c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
248c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
249c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Loads the AdnRecords in efid and returns them as a
250c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * List of AdnRecords
251c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
252c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * throws SecurityException if no READ_CONTACTS permission
253c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
254c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param efid the EF id of a ADN-like ICC
255c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return List of AdnRecord
256c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
257cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
258c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public List<AdnRecord> getAdnRecordsInEf(int efid) {
259c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
26022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPhone.getContext().checkCallingOrSelfPermission(
261c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                android.Manifest.permission.READ_CONTACTS)
262c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                != PackageManager.PERMISSION_GRANTED) {
263c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            throw new SecurityException(
264c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    "Requires android.permission.READ_CONTACTS permission");
265c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
266c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
267c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        efid = updateEfForIccType(efid);
268c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) logd("getAdnRecordsInEF: efid=" + efid);
269c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
270c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        synchronized(mLock) {
271c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            checkThread();
272c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AtomicBoolean status = new AtomicBoolean(false);
273c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Message response = mBaseHandler.obtainMessage(EVENT_LOAD_DONE, status);
27422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mAdnCache.requestLoadAllAdnLike(efid, mAdnCache.extensionEfForEf(efid), response);
275c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            waitForResult(status);
276c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
27722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mRecords;
278c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
279c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
280c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void checkThread() {
281c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (!ALLOW_SIM_OP_IN_UI_THREAD) {
282c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Make sure this isn't the UI thread, since it will block
283c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (mBaseHandler.getLooper().equals(Looper.myLooper())) {
284c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                loge("query() called on the main UI thread!");
285c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                throw new IllegalStateException(
286c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        "You cannot call query on this provder from the main UI thread.");
287c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
288c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
289c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
290c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
291c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void waitForResult(AtomicBoolean status) {
292c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        while (!status.get()) {
293c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            try {
294c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mLock.wait();
295c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } catch (InterruptedException e) {
296c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                logd("interrupted while trying to update by search");
297c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
298c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
299c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
300c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
301c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private int updateEfForIccType(int efid) {
302c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Check if we are trying to read ADN records
303c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (efid == IccConstants.EF_ADN) {
30422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (mPhone.getCurrentUiccAppType() == AppType.APPTYPE_USIM) {
305c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                return IccConstants.EF_PBR;
306c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
307c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
308c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return efid;
309c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
310c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
311c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
312