Snap for 6586311 from 66db1eb2836aa575c0642cbbed7ea787d5f1291c to rvc-d1-release

Change-Id: I22cd977591cb5408acac693860f56d01d06b2de2
diff --git a/src/com/android/se/SecureElementService.java b/src/com/android/se/SecureElementService.java
index e979fd9..758fc77 100644
--- a/src/com/android/se/SecureElementService.java
+++ b/src/com/android/se/SecureElementService.java
@@ -23,8 +23,10 @@
 package com.android.se;
 
 import android.app.Service;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.os.Binder;
 import android.os.Build;
@@ -38,6 +40,7 @@
 import android.se.omapi.ISecureElementService;
 import android.se.omapi.ISecureElementSession;
 import android.se.omapi.SEService;
+import android.telephony.TelephonyManager;
 import android.util.Log;
 
 import com.android.se.Terminal.SecureElementReader;
@@ -63,6 +66,7 @@
     private static final boolean DEBUG = Build.IS_DEBUGGABLE;
     // LinkedHashMap will maintain the order of insertion
     private LinkedHashMap<String, Terminal> mTerminals = new LinkedHashMap<String, Terminal>();
+    private int mActiveSimCount = 0;
     private final ISecureElementService.Stub mSecureElementServiceBinder =
             new ISecureElementService.Stub() {
 
@@ -108,6 +112,13 @@
         super();
     }
 
+    private void initialize() {
+        // listen for events
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED);
+        this.registerReceiver(mMultiSimConfigChangedReceiver, intentFilter);
+    }
+
     /** Returns the terminal from the Reader name. */
     private Terminal getTerminal(String reader) {
         if (reader == null) {
@@ -135,6 +146,7 @@
     @Override
     public void onCreate() {
         Log.i(mTag, Thread.currentThread().getName() + " onCreate");
+        initialize();
         createTerminals();
         ServiceManager.addService(Context.SECURE_ELEMENT_SERVICE, mSecureElementServiceBinder);
     }
@@ -149,19 +161,29 @@
             terminal.closeChannels();
             terminal.close();
         }
+        if (mMultiSimConfigChangedReceiver != null) {
+            this.unregisterReceiver(mMultiSimConfigChangedReceiver);
+        }
     }
 
     private void addTerminals(String terminalName) {
         int index = 1;
         String name = null;
+        if (terminalName.startsWith(SecureElementService.UICC_TERMINAL)) {
+            index = mActiveSimCount + 1;
+        }
         try {
             do {
                 name = terminalName + Integer.toString(index);
                 Terminal terminal = new Terminal(name, this);
 
+                Log.i(mTag, "Check if terminal " + name + " is available.");
                 // Only retry on fail for the first terminal of each type.
                 terminal.initialize(index == 1);
                 mTerminals.put(name, terminal);
+                if (terminalName.equals(UICC_TERMINAL)) {
+                    mActiveSimCount = index;
+                }
             } while (++index > 0);
         } catch (NoSuchElementException e) {
             Log.i(mTag, "No HAL implementation for " + name);
@@ -176,6 +198,29 @@
         addTerminals(UICC_TERMINAL);
     }
 
+    private void refreshUiccTerminals(int activeSimCount) {
+        String name = null;
+        synchronized (this) {
+            if (activeSimCount < mActiveSimCount) {
+                // Remove non-supported UICC terminals
+                for (int i = activeSimCount + 1; i <= mActiveSimCount; i++) {
+                    name = UICC_TERMINAL + Integer.toString(i);
+                    Terminal terminal = mTerminals.get(name);
+                    if (terminal != null) {
+                        terminal.closeChannels();
+                        terminal.close();
+                    }
+                    mTerminals.remove(name);
+                    Log.i(mTag, name + " is removed from available Terminals");
+                }
+                mActiveSimCount = activeSimCount;
+            } else if (activeSimCount > mActiveSimCount) {
+                // Try to initialize new UICC terminals
+                addTerminals(UICC_TERMINAL);
+            }
+        }
+    }
+
     private String getPackageNameFromCallingUid(int uid) {
         PackageManager packageManager = getPackageManager();
         if (packageManager != null) {
@@ -332,4 +377,21 @@
             return channel.new SecureElementChannel();
         }
     }
+
+    private final BroadcastReceiver mMultiSimConfigChangedReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED)) {
+                int activeSimCount =
+                        intent.getIntExtra(TelephonyManager.EXTRA_ACTIVE_SIM_SUPPORTED_COUNT, 1);
+                Log.i(mTag, "received action MultiSimConfigChanged. Refresh UICC terminals");
+                Log.i(mTag, "Current ActiveSimCount:" + activeSimCount
+                        + ". Previous ActiveSimCount:" + mActiveSimCount);
+
+                // Check for any change to UICC SE HAL implementations
+                refreshUiccTerminals(activeSimCount);
+            }
+        }
+    };
 }
diff --git a/src/com/android/se/Terminal.java b/src/com/android/se/Terminal.java
index 4638926..54dc256 100644
--- a/src/com/android/se/Terminal.java
+++ b/src/com/android/se/Terminal.java
@@ -76,6 +76,9 @@
     private static final int GET_SERVICE_DELAY_MILLIS = 4 * 1000;
     private static final int EVENT_GET_HAL = 1;
 
+    private final int mMaxGetHalRetryCount = 5;
+    private int mGetHalRetryCount = 0;
+
     private ISecureElement mSEHal;
     private android.hardware.secure_element.V1_2.ISecureElement mSEHal12;
 
@@ -186,11 +189,20 @@
             switch (message.what) {
                 case EVENT_GET_HAL:
                     try {
-                        initialize(true);
+                        if (mName.startsWith(SecureElementService.ESE_TERMINAL)) {
+                            initialize(true);
+                        } else {
+                            initialize(false);
+                        }
                     } catch (Exception e) {
                         Log.e(mTag, mName + " could not be initialized again");
-                        sendMessageDelayed(obtainMessage(EVENT_GET_HAL, 0),
-                                GET_SERVICE_DELAY_MILLIS);
+                        if (mGetHalRetryCount < mMaxGetHalRetryCount) {
+                            mGetHalRetryCount++;
+                            sendMessageDelayed(obtainMessage(EVENT_GET_HAL, 0),
+                                    GET_SERVICE_DELAY_MILLIS);
+                        } else {
+                            Log.e(mTag, mName + " reach maximum retry count");
+                        }
                     }
                     break;
                 default: