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

Commit c8598dd9 authored by Amit Mahajan's avatar Amit Mahajan Committed by android-build-merger
Browse files

Merge "Fix the synchronization pattern in IccPhoneBookInterfaceManager."

am: 198d1baf

Change-Id: Ie19df4bfee2fc2919676fbd6c686227f531f272b
parents 9eca6898 198d1baf
Loading
Loading
Loading
Loading
+76 −89
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@ import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
import com.android.internal.telephony.uicc.IccConstants;
import com.android.internal.telephony.uicc.IccFileHandler;
import com.android.internal.telephony.uicc.IccRecords;
import com.android.internal.telephony.uicc.UiccCardApplication;

import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -43,76 +42,67 @@ public class IccPhoneBookInterfaceManager {
    protected static final boolean DBG = true;

    protected Phone mPhone;
    private   UiccCardApplication mCurrentApp = null;
    protected AdnRecordCache mAdnCache;
    protected final Object mLock = new Object();
    protected int mRecordSize[];
    protected boolean mSuccess;
    private   boolean mIs3gCard = false;  // flag to determine if card is 3G or 2G
    protected List<AdnRecord> mRecords;


    protected static final boolean ALLOW_SIM_OP_IN_UI_THREAD = false;

    protected static final int EVENT_GET_SIZE_DONE = 1;
    protected static final int EVENT_LOAD_DONE = 2;
    protected static final int EVENT_UPDATE_DONE = 3;

    private static final class Request {
        AtomicBoolean mStatus = new AtomicBoolean(false);
        Object mResult = null;
    }

    protected Handler mBaseHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            AsyncResult ar;
            AsyncResult ar = (AsyncResult) msg.obj;
            Request request = (Request) ar.userObj;

            switch (msg.what) {
                case EVENT_GET_SIZE_DONE:
                    ar = (AsyncResult) msg.obj;
                    synchronized (mLock) {
                    int[] recordSize = null;
                    if (ar.exception == null) {
                            mRecordSize = (int[])ar.result;
                        recordSize = (int[]) ar.result;
                        // recordSize[0]  is the record length
                        // recordSize[1]  is the total length of the EF file
                        // recordSize[2]  is the number of records in the EF file
                            logd("GET_RECORD_SIZE Size " + mRecordSize[0] +
                                    " total " + mRecordSize[1] +
                                    " #record " + mRecordSize[2]);
                        logd("GET_RECORD_SIZE Size " + recordSize[0]
                                + " total " + recordSize[1]
                                + " #record " + recordSize[2]);
                    } else {
                        loge("EVENT_GET_SIZE_DONE: failed; ex=" + ar.exception);
                    }
                        notifyPending(ar);
                    }
                    notifyPending(request, recordSize);
                    break;
                case EVENT_UPDATE_DONE:
                    ar = (AsyncResult) msg.obj;
                    synchronized (mLock) {
                        mSuccess = (ar.exception == null);
                        if (!mSuccess) {
                    boolean success = (ar.exception == null);
                    if (!success) {
                        loge("EVENT_UPDATE_DONE - failed; ex=" + ar.exception);
                    }
                        notifyPending(ar);
                    }
                    notifyPending(request, success);
                    break;
                case EVENT_LOAD_DONE:
                    ar = (AsyncResult)msg.obj;
                    synchronized (mLock) {
                    List<AdnRecord> records = null;
                    if (ar.exception == null) {
                            mRecords = (List<AdnRecord>) ar.result;
                        records = (List<AdnRecord>) ar.result;
                    } else {
                        loge("EVENT_LOAD_DONE: Cannot load ADN records; ex="
                                + ar.exception);
                            mRecords = null;
                        }
                        notifyPending(ar);
                    }
                    notifyPending(request, records);
                    break;
            }
        }

        private void notifyPending(AsyncResult ar) {
            if (ar.userObj != null) {
                AtomicBoolean status = (AtomicBoolean) ar.userObj;
                status.set(true);
        private void notifyPending(Request request, Object result) {
            if (request != null) {
                synchronized (request) {
                    request.mResult = result;
                    request.mStatus.set(true);
                    request.notifyAll();
                }
            }
            mLock.notifyAll();
        }
    };

@@ -184,21 +174,20 @@ public class IccPhoneBookInterfaceManager {

        efid = updateEfForIccType(efid);

        synchronized(mLock) {
        checkThread();
            mSuccess = false;
            AtomicBoolean status = new AtomicBoolean(false);
            Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, status);
        Request updateRequest = new Request();
        synchronized (updateRequest) {
            Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, updateRequest);
            AdnRecord oldAdn = new AdnRecord(oldTag, oldPhoneNumber);
            AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
            if (mAdnCache != null) {
                mAdnCache.updateAdnBySearch(efid, oldAdn, newAdn, pin2, response);
                waitForResult(status);
                waitForResult(updateRequest);
            } else {
                loge("Failure while trying to update by search due to uninitialised adncache");
            }
        }
        return mSuccess;
        return (boolean) updateRequest.mResult;
    }

    /**
@@ -233,20 +222,21 @@ public class IccPhoneBookInterfaceManager {
                Integer.toHexString(efid).toUpperCase() + " Index=" + index + " ==> " + "(" +
                Rlog.pii(LOG_TAG, newTag) + "," + Rlog.pii(LOG_TAG, newPhoneNumber) + ")" +
                " pin2=" + Rlog.pii(LOG_TAG, pin2));
        synchronized(mLock) {


        checkThread();
            mSuccess = false;
            AtomicBoolean status = new AtomicBoolean(false);
            Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, status);
        Request updateRequest = new Request();
        synchronized (updateRequest) {
            Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, updateRequest);
            AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
            if (mAdnCache != null) {
                mAdnCache.updateAdnByIndex(efid, newAdn, index, pin2, response);
                waitForResult(status);
                waitForResult(updateRequest);
            } else {
                loge("Failure while trying to update by index due to uninitialised adncache");
            }
        }
        return mSuccess;
        return (boolean) updateRequest.mResult;
    }

    /**
@@ -260,22 +250,19 @@ public class IccPhoneBookInterfaceManager {
     */
    public int[] getAdnRecordsSize(int efid) {
        if (DBG) logd("getAdnRecordsSize: efid=" + efid);
        synchronized(mLock) {
        checkThread();
            mRecordSize = new int[3];

        Request getSizeRequest = new Request();
        synchronized (getSizeRequest) {
            //Using mBaseHandler, no difference in EVENT_GET_SIZE_DONE handling
            AtomicBoolean status = new AtomicBoolean(false);
            Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE, status);

            Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE, getSizeRequest);
            IccFileHandler fh = mPhone.getIccFileHandler();
            if (fh != null) {
                fh.getEFLinearRecordSize(efid, response);
                waitForResult(status);
                waitForResult(getSizeRequest);
            }
        }

        return mRecordSize;
        return getSizeRequest.mResult == null ? new int[3] : (int[]) getSizeRequest.mResult;
    }


@@ -300,22 +287,21 @@ public class IccPhoneBookInterfaceManager {
        efid = updateEfForIccType(efid);
        if (DBG) logd("getAdnRecordsInEF: efid=0x" + Integer.toHexString(efid).toUpperCase());

        synchronized(mLock) {
        checkThread();
            AtomicBoolean status = new AtomicBoolean(false);
            Message response = mBaseHandler.obtainMessage(EVENT_LOAD_DONE, status);
        Request loadRequest = new Request();
        synchronized (loadRequest) {
            Message response = mBaseHandler.obtainMessage(EVENT_LOAD_DONE, loadRequest);
            if (mAdnCache != null) {
                mAdnCache.requestLoadAllAdnLike(efid, mAdnCache.extensionEfForEf(efid), response);
                waitForResult(status);
                waitForResult(loadRequest);
            } else {
                loge("Failure while trying to load from SIM due to uninitialised adncache");
            }
        }
        return mRecords;
        return (List<AdnRecord>) loadRequest.mResult;
    }

    protected void checkThread() {
        if (!ALLOW_SIM_OP_IN_UI_THREAD) {
        // Make sure this isn't the UI thread, since it will block
        if (mBaseHandler.getLooper().equals(Looper.myLooper())) {
            loge("query() called on the main UI thread!");
@@ -323,17 +309,18 @@ public class IccPhoneBookInterfaceManager {
                    "You cannot call query on this provder from the main UI thread.");
        }
    }
    }

    protected void waitForResult(AtomicBoolean status) {
        while (!status.get()) {
    protected void waitForResult(Request request) {
        synchronized (request) {
            while (!request.mStatus.get()) {
                try {
                mLock.wait();
                    request.wait();
                } catch (InterruptedException e) {
                    logd("interrupted while trying to update by search");
                }
            }
        }
    }

    private int updateEfForIccType(int efid) {
        // Check if we are trying to read ADN records