/**
   * Replace oldAdn with newAdn in ADN-like record in EF
   *
   * <p>getAdnRecordsInEf must be called at least once before this function, otherwise an error will
   * be returned. Currently the email field if set in the ADN record is ignored. throws
   * SecurityException if no WRITE_CONTACTS permission
   *
   * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
   * @param oldTag adn tag to be replaced
   * @param oldPhoneNumber adn number to be replaced Set both oldTag and oldPhoneNubmer to "" means
   *     to replace an empty record, aka, insert new record
   * @param newTag adn tag to be stored
   * @param newPhoneNumber adn number ot be stored Set both newTag and newPhoneNubmer to "" means to
   *     replace the old record with empty one, aka, delete old record
   * @param pin2 required to update EF_FDN, otherwise must be null
   * @return true for success
   */
  public boolean updateAdnRecordsInEfBySearch(
      int efid,
      String oldTag,
      String oldPhoneNumber,
      String newTag,
      String newPhoneNumber,
      String pin2) {

    if (phone.getContext().checkCallingOrSelfPermission(android.Manifest.permission.WRITE_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {
      throw new SecurityException("Requires android.permission.WRITE_CONTACTS permission");
    }

    if (DBG)
      logd(
          "updateAdnRecordsInEfBySearch: efid="
              + efid
              + " ("
              + oldTag
              + ","
              + oldPhoneNumber
              + ")"
              + "==>"
              + " ("
              + newTag
              + ","
              + newPhoneNumber
              + ")"
              + " pin2="
              + pin2);

    efid = updateEfForIccType(efid);

    synchronized (mLock) {
      checkThread();
      success = false;
      Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE);
      AdnRecord oldAdn = new AdnRecord(oldTag, oldPhoneNumber);
      AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
      adnCache.updateAdnBySearch(efid, oldAdn, newAdn, pin2, response);
      try {
        mLock.wait();
      } catch (InterruptedException e) {
        logd("interrupted while trying to update by search");
      }
    }
    return success;
  }
        @Override
        public void handleMessage(Message msg) {
          AsyncResult ar;

          switch (msg.what) {
            case EVENT_GET_SIZE_DONE:
              ar = (AsyncResult) msg.obj;
              synchronized (mLock) {
                if (ar.exception == null) {
                  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 "
                          + recordSize[0]
                          + " total "
                          + recordSize[1]
                          + " #record "
                          + recordSize[2]);
                  mLock.notifyAll();
                }
              }
              break;
            case EVENT_UPDATE_DONE:
              ar = (AsyncResult) msg.obj;
              synchronized (mLock) {
                success = (ar.exception == null);
                mLock.notifyAll();
              }
              break;
            case EVENT_LOAD_DONE:
              ar = (AsyncResult) msg.obj;
              synchronized (mLock) {
                if (ar.exception == null) {
                  records = (List<AdnRecord>) ar.result;
                } else {
                  if (DBG) logd("Cannot load ADN records");
                  if (records != null) {
                    records.clear();
                  }
                }
                mLock.notifyAll();
              }
              break;
          }
        }
  /**
   * Loads the AdnRecords in efid and returns them as a List of AdnRecords
   *
   * <p>throws SecurityException if no READ_CONTACTS permission
   *
   * @param efid the EF id of a ADN-like ICC
   * @return List of AdnRecord
   */
  public List<AdnRecord> getAdnRecordsInEf(int efid) {

    if (phone.getContext().checkCallingOrSelfPermission(android.Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {
      throw new SecurityException("Requires android.permission.READ_CONTACTS permission");
    }

    efid = updateEfForIccType(efid);
    if (DBG) logd("getAdnRecordsInEF: efid=" + efid);

    synchronized (mLock) {
      checkThread();
      Message response = mBaseHandler.obtainMessage(EVENT_LOAD_DONE);
      adnCache.requestLoadAllAdnLike(efid, adnCache.extensionEfForEf(efid), response);
      try {
        mLock.wait();
      } catch (InterruptedException e) {
        logd("interrupted while trying to load from the SIM");
      }
    }
    return records;
  }