From a0108ddb86db8ae5e1bf58462e2f14c8fb1750cc Mon Sep 17 00:00:00 2001 From: Jack Yu Date: Wed, 8 Apr 2020 21:50:43 +0800 Subject: Refresh terminal instances when switching between SS and DS Listen to CARRIER_CONFIG_CHANGED and reinitialize UICC terminals. Bug: 152008670 Test: adb shell dumpsys secure_element Merged-In: I8bb13b43de6f17f0b5b82440708d90bf684ca7ec Change-Id: I8bb13b43de6f17f0b5b82440708d90bf684ca7ec --- src/com/android/se/SecureElementService.java | 62 ++++++++++++++++++++++++++++ src/com/android/se/Terminal.java | 18 ++++++-- 2 files changed, 77 insertions(+), 3 deletions(-) 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.ISecureElementReader; 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 @@ public final class SecureElementService extends Service { private static final boolean DEBUG = Build.IS_DEBUGGABLE; // LinkedHashMap will maintain the order of insertion private LinkedHashMap mTerminals = new LinkedHashMap(); + private int mActiveSimCount = 0; private final ISecureElementService.Stub mSecureElementServiceBinder = new ISecureElementService.Stub() { @@ -108,6 +112,13 @@ public final class SecureElementService extends Service { 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 @@ public final class SecureElementService extends Service { @Override public void onCreate() { Log.i(mTag, Thread.currentThread().getName() + " onCreate"); + initialize(); createTerminals(); ServiceManager.addService(Context.SECURE_ELEMENT_SERVICE, mSecureElementServiceBinder); } @@ -149,19 +161,29 @@ public final class SecureElementService extends Service { 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 @@ public final class SecureElementService extends Service { 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 @@ public final class SecureElementService extends Service { 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 @@ public class Terminal { 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 @@ public class Terminal { 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: -- cgit v1.2.3