10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*
20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2006 The Android Open Source Project
30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License.
60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at
70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software
110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and
140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License.
150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkapackage com.android.internal.telephony.uicc;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.SparseArray;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.gsm.UsimPhoneBookManager;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Iterator;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
32ce000ddfbb615f873e9fc0a4c68f992b12d3f82ffionaxupublic class AdnRecordCache extends Handler implements IccConstants {
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Instance Variables
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private IccFileHandler mFh;
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private UsimPhoneBookManager mUsimPhoneBookManager;
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Indexed by EF ID
3922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    SparseArray<ArrayList<AdnRecord>> mAdnLikeFiles
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        = new SparseArray<ArrayList<AdnRecord>>();
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // People waiting for ADN-like files to be loaded
4322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    SparseArray<ArrayList<Message>> mAdnLikeWaiters
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        = new SparseArray<ArrayList<Message>>();
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // People waiting for adn record to be updated
4722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    SparseArray<Message> mUserWriteResponse = new SparseArray<Message>();
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Event Constants
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int EVENT_LOAD_ALL_ADN_LIKE_DONE = 1;
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int EVENT_UPDATE_ADN_DONE = 2;
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Constructor
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
58d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenka    AdnRecordCache(IccFileHandler fh) {
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mFh = fh;
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mUsimPhoneBookManager = new UsimPhoneBookManager(mFh, this);
610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Called from SIMRecords
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Called from SIMRecords.onRadioNotAvailable and SIMRecords.handleSimRefresh.
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void reset() {
6922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mAdnLikeFiles.clear();
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mUsimPhoneBookManager.reset();
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        clearWaiters();
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        clearUserWriters();
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void clearWaiters() {
7822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        int size = mAdnLikeWaiters.size();
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < size; i++) {
8022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ArrayList<Message> waiters = mAdnLikeWaiters.valueAt(i);
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            AsyncResult ar = new AsyncResult(null, null, new RuntimeException("AdnCache reset"));
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notifyWaiters(waiters, ar);
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mAdnLikeWaiters.clear();
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void clearUserWriters() {
8822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        int size = mUserWriteResponse.size();
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < size; i++) {
9022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            sendErrorResponse(mUserWriteResponse.valueAt(i), "AdnCace reset");
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mUserWriteResponse.clear();
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return List of AdnRecords for efid if we've already loaded them this
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * radio session, or null if we haven't
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public ArrayList<AdnRecord>
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    getRecordsIfLoaded(int efid) {
10122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mAdnLikeFiles.get(efid);
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Returns extension ef associated with ADN-like EF or -1 if
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * we don't know.
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * See 3GPP TS 51.011 for this mapping
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
110d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenka    public int extensionEfForEf(int efid) {
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (efid) {
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EF_MBDN: return EF_EXT6;
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EF_ADN: return EF_EXT1;
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EF_SDN: return EF_EXT3;
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EF_FDN: return EF_EXT2;
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EF_MSISDN: return EF_EXT1;
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EF_PBR: return 0; // The EF PBR doesn't have an extension record
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default: return -1;
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void sendErrorResponse(Message response, String errString) {
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (response != null) {
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Exception e = new RuntimeException(errString);
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            AsyncResult.forMessage(response).exception = e;
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            response.sendToTarget();
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Update an ADN-like record in EF by record index
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param adn is the new adn to be stored
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param recordIndex is the 1-based adn record index
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param pin2 is required to update EF_FDN, otherwise must be null
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param response message to be posted when done
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *        response.exception hold the exception in error
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void updateAdnByIndex(int efid, AdnRecord adn, int recordIndex, String pin2,
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Message response) {
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int extensionEF = extensionEfForEf(efid);
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (extensionEF < 0) {
1455003d3ea151f2f9fb95ab249ea9e687e619d932dJack Yu            sendErrorResponse(response, "EF is not known ADN-like EF:0x" +
1465003d3ea151f2f9fb95ab249ea9e687e619d932dJack Yu                    Integer.toHexString(efid).toUpperCase());
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        Message pendingResponse = mUserWriteResponse.get(efid);
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (pendingResponse != null) {
1525003d3ea151f2f9fb95ab249ea9e687e619d932dJack Yu            sendErrorResponse(response, "Have pending update for EF:0x" +
1535003d3ea151f2f9fb95ab249ea9e687e619d932dJack Yu                    Integer.toHexString(efid).toUpperCase());
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mUserWriteResponse.put(efid, response);
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        new AdnRecordLoader(mFh).updateEF(adn, efid, extensionEF,
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                recordIndex, pin2,
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                obtainMessage(EVENT_UPDATE_ADN_DONE, efid, recordIndex, adn));
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Replace oldAdn with newAdn in ADN-like record in EF
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * The ADN-like records must be read through requestLoadAllAdnLike() before
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param efid must be one of EF_ADN, EF_FDN, and EF_SDN
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param oldAdn is the adn to be replaced
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *        If oldAdn.isEmpty() is ture, it insert the newAdn
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param newAdn is the adn to be stored
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *        If newAdn.isEmpty() is true, it delete the oldAdn
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param pin2 is required to update EF_FDN, otherwise must be null
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param response message to be posted when done
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *        response.exception hold the exception in error
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void updateAdnBySearch(int efid, AdnRecord oldAdn, AdnRecord newAdn,
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String pin2, Message response) {
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int extensionEF;
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        extensionEF = extensionEfForEf(efid);
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (extensionEF < 0) {
1855003d3ea151f2f9fb95ab249ea9e687e619d932dJack Yu            sendErrorResponse(response, "EF is not known ADN-like EF:0x" +
1865003d3ea151f2f9fb95ab249ea9e687e619d932dJack Yu                    Integer.toHexString(efid).toUpperCase());
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ArrayList<AdnRecord>  oldAdnList;
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (efid == EF_PBR) {
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            oldAdnList = mUsimPhoneBookManager.loadEfFilesFromUsim();
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            oldAdnList = getRecordsIfLoaded(efid);
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (oldAdnList == null) {
1995003d3ea151f2f9fb95ab249ea9e687e619d932dJack Yu            sendErrorResponse(response, "Adn list not exist for EF:0x" +
2005003d3ea151f2f9fb95ab249ea9e687e619d932dJack Yu                    Integer.toHexString(efid).toUpperCase());
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int index = -1;
2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int count = 1;
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (Iterator<AdnRecord> it = oldAdnList.iterator(); it.hasNext(); ) {
2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (oldAdn.isEqual(it.next())) {
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                index = count;
2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            count++;
2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (index == -1) {
2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            sendErrorResponse(response, "Adn record don't exist for " + oldAdn);
2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (efid == EF_PBR) {
2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            AdnRecord foundAdn = oldAdnList.get(index-1);
22122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            efid = foundAdn.mEfid;
22222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            extensionEF = foundAdn.mExtRecord;
22322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            index = foundAdn.mRecordNumber;
2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            newAdn.mEfid = efid;
22622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            newAdn.mExtRecord = extensionEF;
22722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            newAdn.mRecordNumber = index;
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        Message pendingResponse = mUserWriteResponse.get(efid);
2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (pendingResponse != null) {
2335003d3ea151f2f9fb95ab249ea9e687e619d932dJack Yu            sendErrorResponse(response, "Have pending update for EF:0x" +
2345003d3ea151f2f9fb95ab249ea9e687e619d932dJack Yu                    Integer.toHexString(efid).toUpperCase());
2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mUserWriteResponse.put(efid, response);
2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        new AdnRecordLoader(mFh).updateEF(newAdn, efid, extensionEF,
2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                index, pin2,
2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                obtainMessage(EVENT_UPDATE_ADN_DONE, efid, index, newAdn));
2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Responds with exception (in response) if efid is not a known ADN-like
2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * record
2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    requestLoadAllAdnLike (int efid, int extensionEf, Message response) {
2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ArrayList<Message> waiters;
2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ArrayList<AdnRecord> result;
2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (efid == EF_PBR) {
2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            result = mUsimPhoneBookManager.loadEfFilesFromUsim();
2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            result = getRecordsIfLoaded(efid);
2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Have we already loaded this efid?
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (result != null) {
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (response != null) {
2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                AsyncResult.forMessage(response).result = result;
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                response.sendToTarget();
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Have we already *started* loading this efid?
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
27322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        waiters = mAdnLikeWaiters.get(efid);
2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (waiters != null) {
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // There's a pending request for this EF already
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // just add ourselves to it
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            waiters.add(response);
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Start loading efid
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        waiters = new ArrayList<Message>();
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        waiters.add(response);
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
28822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mAdnLikeWaiters.put(efid, waiters);
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (extensionEf < 0) {
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // respond with error if not known ADN-like record
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (response != null) {
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                AsyncResult.forMessage(response).exception
2965003d3ea151f2f9fb95ab249ea9e687e619d932dJack Yu                    = new RuntimeException("EF is not known ADN-like EF:0x" +
2975003d3ea151f2f9fb95ab249ea9e687e619d932dJack Yu                        Integer.toHexString(efid).toUpperCase());
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                response.sendToTarget();
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        new AdnRecordLoader(mFh).loadAllFromEF(efid, extensionEf,
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            obtainMessage(EVENT_LOAD_ALL_ADN_LIKE_DONE, efid, 0));
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Private methods
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    notifyWaiters(ArrayList<Message> waiters, AsyncResult ar) {
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (waiters == null) {
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, s = waiters.size() ; i < s ; i++) {
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Message waiter = waiters.get(i);
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            AsyncResult.forMessage(waiter, ar.result, ar.exception);
3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            waiter.sendToTarget();
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Overridden from Handler
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
327cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    handleMessage(Message msg) {
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AsyncResult ar;
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int efid;
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch(msg.what) {
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_LOAD_ALL_ADN_LIKE_DONE:
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                /* arg1 is efid, obj.result is ArrayList<AdnRecord>*/
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                efid = msg.arg1;
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ArrayList<Message> waiters;
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
34022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                waiters = mAdnLikeWaiters.get(efid);
34122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mAdnLikeWaiters.delete(efid);
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception == null) {
34422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mAdnLikeFiles.put(efid, (ArrayList<AdnRecord>) ar.result);
3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                notifyWaiters(waiters, ar);
3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_UPDATE_ADN_DONE:
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult)msg.obj;
3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                efid = msg.arg1;
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                int index = msg.arg2;
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                AdnRecord adn = (AdnRecord) (ar.userObj);
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception == null) {
35522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mAdnLikeFiles.get(efid).set(index - 1, adn);
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mUsimPhoneBookManager.invalidateCache();
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
35922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                Message response = mUserWriteResponse.get(efid);
36022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mUserWriteResponse.delete(efid);
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                AsyncResult.forMessage(response, null, ar.exception);
3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                response.sendToTarget();
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
368