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