Delete UiccCardApplication on recieving REFRESH_RESET for them.

After a REFRESH_RESET, the applications are not valid any more.

Bug: 17655366
Change-Id: Id3c9fab6fd863cd0c44c45f4bc27d780009668d8
diff --git a/src/java/com/android/internal/telephony/uicc/IccRecords.java b/src/java/com/android/internal/telephony/uicc/IccRecords.java
index 9b659f9..febb43d 100644
--- a/src/java/com/android/internal/telephony/uicc/IccRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/IccRecords.java
@@ -618,11 +618,6 @@
         return android.util.Base64.encodeToString(auth_rsp.payload, android.util.Base64.NO_WRAP);
     }
 
-    protected boolean requirePowerOffOnSimRefreshReset() {
-        return mContext.getResources().getBoolean(
-            com.android.internal.R.bool.config_requireRadioPowerOffOnSimRefreshReset);
-    }
-
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("IccRecords: " + this);
         pw.println(" mDestroyed=" + mDestroyed);
diff --git a/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java b/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
index c7c1c8f..ff6edae 100644
--- a/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
@@ -366,18 +366,8 @@
                 break;
 
             case IccRefreshResponse.REFRESH_RESULT_RESET:
+                // Refresh reset is handled by the UiccCard object.
                 if (DBG) log("handleIsimRefresh with REFRESH_RESULT_RESET");
-                // need to reload all files (that we care about)
-                if (requirePowerOffOnSimRefreshReset()) {
-                    mCi.setRadioPower(false, null);
-                    /* Note: no need to call setRadioPower(true).  Assuming the desired
-                    * radio power state is still ON (as tracked by ServiceStateTracker),
-                    * ServiceStateTracker will call setRadioPower when it receives the
-                    * RADIO_STATE_CHANGED notification for the power off.  And if the
-                    * desired power state has changed in the interim, we don't want to
-                    * override it with an unconditional power on.
-                    */
-                }
                 break;
 
             default:
diff --git a/src/java/com/android/internal/telephony/uicc/RuimRecords.java b/src/java/com/android/internal/telephony/uicc/RuimRecords.java
index 2e04289..85792ba 100644
--- a/src/java/com/android/internal/telephony/uicc/RuimRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/RuimRecords.java
@@ -964,17 +964,8 @@
                 onIccRefreshInit();
                 break;
             case IccRefreshResponse.REFRESH_RESULT_RESET:
+                // Refresh reset is handled by the UiccCard object.
                 if (DBG) log("handleRuimRefresh with SIM_REFRESH_RESET");
-                if (requirePowerOffOnSimRefreshReset()) {
-                    mCi.setRadioPower(false, null);
-                    /* Note: no need to call setRadioPower(true).  Assuming the desired
-                    * radio power state is still ON (as tracked by ServiceStateTracker),
-                    * ServiceStateTracker will call setRadioPower when it receives the
-                    * RADIO_STATE_CHANGED notification for the power off.  And if the
-                    * desired power state has changed in the interim, we don't want to
-                    * override it with an unconditional power on.
-                    */
-                }
                 break;
             default:
                 // unknown refresh operation
diff --git a/src/java/com/android/internal/telephony/uicc/SIMRecords.java b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
index 5cff7f4..ef43183 100644
--- a/src/java/com/android/internal/telephony/uicc/SIMRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
@@ -1291,18 +1291,8 @@
                 onIccRefreshInit();
                 break;
             case IccRefreshResponse.REFRESH_RESULT_RESET:
+                // Refresh reset is handled by the UiccCard object.
                 if (DBG) log("handleSimRefresh with SIM_REFRESH_RESET");
-                if (requirePowerOffOnSimRefreshReset()) {
-                    mCi.setRadioPower(false, null);
-                    /* Note: no need to call setRadioPower(true).  Assuming the desired
-                    * radio power state is still ON (as tracked by ServiceStateTracker),
-                    * ServiceStateTracker will call setRadioPower when it receives the
-                    * RADIO_STATE_CHANGED notification for the power off.  And if the
-                    * desired power state has changed in the interim, we don't want to
-                    * override it with an unconditional power on.
-                    */
-                }
-                mAdnCache.reset();
                 break;
             default:
                 // unknown refresh operation
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCard.java b/src/java/com/android/internal/telephony/uicc/UiccCard.java
index d776cc0..5d08b0e 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCard.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCard.java
@@ -79,7 +79,6 @@
     private Context mContext;
     private CommandsInterface mCi;
     private CatService mCatService;
-    private boolean mDestroyed = false; //set to true once this card is commanded to be disposed of.
     private RadioState mLastRadioState =  RadioState.RADIO_UNAVAILABLE;
     private UiccCarrierPrivilegeRules mCarrierPrivilegeRules;
 
@@ -129,10 +128,6 @@
 
     public void update(Context c, CommandsInterface ci, IccCardStatus ics) {
         synchronized (mLock) {
-            if (mDestroyed) {
-                loge("Updated after destroyed! Fix me!");
-                return;
-            }
             CardState oldState = mCardState;
             mCardState = ics.mCardState;
             mUniversalPinState = ics.mUniversalPinState;
@@ -141,6 +136,7 @@
             mImsSubscriptionAppIndex = ics.mImsSubscriptionAppIndex;
             mContext = c;
             mCi = ci;
+
             //update applications
             if (DBG) log(ics.mApplications.length + " applications");
             for ( int i = 0; i < mUiccApplications.length; i++) {
@@ -354,12 +350,6 @@
     protected Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg){
-            if (mDestroyed) {
-                loge("Received message " + msg + "[" + msg.what
-                        + "] while being destroyed. Ignoring.");
-                return;
-            }
-
             switch (msg.what) {
                 case EVENT_CARD_REMOVED:
                     onIccSwap(false);
@@ -467,6 +457,23 @@
     }
 
     /**
+     * Resets the application with the input AID. Returns true if any changes were made.
+     */
+    public boolean resetAppWithAid(String aid) {
+        synchronized (mLock) {
+            for (int i = 0; i < mUiccApplications.length; i++) {
+                if (mUiccApplications[i] != null && aid.equals(mUiccApplications[i].getAid())) {
+                    // Delete removed applications
+                    mUiccApplications[i].dispose();
+                    mUiccApplications[i] = null;
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    /**
      * Exposes {@link CommandsInterface.iccOpenLogicalChannel}
      */
     public void iccOpenLogicalChannel(String AID, Message response) {
@@ -629,7 +636,6 @@
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("UiccCard:");
         pw.println(" mCi=" + mCi);
-        pw.println(" mDestroyed=" + mDestroyed);
         pw.println(" mLastRadioState=" + mLastRadioState);
         pw.println(" mCatService=" + mCatService);
         pw.println(" mAbsentRegistrants: size=" + mAbsentRegistrants.size());
diff --git a/src/java/com/android/internal/telephony/uicc/UiccController.java b/src/java/com/android/internal/telephony/uicc/UiccController.java
index 3b00ac9..6d662b3 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccController.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccController.java
@@ -83,6 +83,7 @@
     private static final int EVENT_ICC_STATUS_CHANGED = 1;
     private static final int EVENT_GET_ICC_STATUS_DONE = 2;
     private static final int EVENT_RADIO_UNAVAILABLE = 3;
+    private static final int EVENT_SIM_REFRESH = 4;
 
     private CommandsInterface[] mCis;
     private UiccCard[] mUiccCards = new UiccCard[TelephonyManager.getDefault().getPhoneCount()];
@@ -114,6 +115,7 @@
             // TODO remove this once modem correctly notifies the unsols
             mCis[i].registerForAvailable(this, EVENT_ICC_STATUS_CHANGED, index);
             mCis[i].registerForNotAvailable(this, EVENT_RADIO_UNAVAILABLE, index);
+            mCis[i].registerForIccRefresh(this, EVENT_SIM_REFRESH, index);
         }
     }
 
@@ -203,6 +205,7 @@
                 return;
             }
 
+            AsyncResult ar = (AsyncResult)msg.obj;
             switch (msg.what) {
                 case EVENT_ICC_STATUS_CHANGED:
                     if (DBG) log("Received EVENT_ICC_STATUS_CHANGED, calling getIccCardStatus");
@@ -210,7 +213,6 @@
                     break;
                 case EVENT_GET_ICC_STATUS_DONE:
                     if (DBG) log("Received EVENT_GET_ICC_STATUS_DONE");
-                    AsyncResult ar = (AsyncResult)msg.obj;
                     onGetIccCardStatusDone(ar, index);
                     break;
                 case EVENT_RADIO_UNAVAILABLE:
@@ -221,6 +223,10 @@
                     mUiccCards[index] = null;
                     mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null));
                     break;
+                case EVENT_SIM_REFRESH:
+                    if (DBG) log("Received EVENT_SIM_REFRESH");
+                    onSimRefresh(ar, index);
+                    break;
                 default:
                     Rlog.e(LOG_TAG, " Unknown Event " + msg.what);
             }
@@ -289,6 +295,46 @@
 
     }
 
+    private void onSimRefresh(AsyncResult ar, Integer index) {
+        if (ar.exception != null) {
+            Rlog.e(LOG_TAG, "Sim REFRESH with exception: " + ar.exception);
+            return;
+        }
+
+        if (!isValidCardIndex(index)) {
+            Rlog.e(LOG_TAG,"onSimRefresh: invalid index : " + index);
+            return;
+        }
+
+        IccRefreshResponse resp = (IccRefreshResponse) ar.result;
+        Rlog.d(LOG_TAG, "onSimRefresh: " + resp);
+
+        if (mUiccCards[index] == null) {
+            Rlog.e(LOG_TAG,"onSimRefresh: refresh on null card : " + index);
+            return;
+        }
+
+        if (resp.refreshResult != IccRefreshResponse.REFRESH_RESULT_RESET ||
+            resp.aid == null) {
+            Rlog.d(LOG_TAG, "Ignoring reset: " + resp);
+            return;
+        }
+
+        boolean changed = mUiccCards[index].resetAppWithAid(resp.aid);
+        if (changed) {
+            boolean requirePowerOffOnSimRefreshReset = mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_requireRadioPowerOffOnSimRefreshReset);
+            if (requirePowerOffOnSimRefreshReset) {
+                mCis[index].setRadioPower(false, null);
+            } else {
+                mCis[index].getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
+            }
+            mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null));
+        }
+        // TODO: For a card level notification, we should delete the CarrierPrivilegeRules and the
+        // CAT service.
+    }
+
     private boolean isValidCardIndex(int index) {
         return (index >= 0 && index < mUiccCards.length);
     }