diff options
author | Yoshiaki Naka <yoshiaki.naka@sony.com> | 2018-03-22 14:00:29 +0900 |
---|---|---|
committer | Ruchi Kandoi <kandoiruchi@google.com> | 2018-04-10 15:24:48 -0700 |
commit | cf7d2f1d5d06675593e770e267d318357b598fdc (patch) | |
tree | 54a1f180f83bf420eb03c96e6729565340e01a65 | |
parent | 55376b4dad37f48c1deebab431d0dc2eec26fc91 (diff) | |
download | SecureElement-cf7d2f1d5d06675593e770e267d318357b598fdc.tar.gz |
Receive callback when SE HAL died and obtain it again
SecureElement application shall receive a callback when SE HAL died and
attempt to obtain it again. To achieve it, the code to initialize SE HAL
should be moved from SecureElementService to Terminal.
Bug: 77606969
Test: Confirmed that Terminal can get SE HAL again after the accident.
Change-Id: I76a02464874d82f75daec4b4b70be4211e2d19ad
(cherry picked from commit 9cb94514739de4cb2edf48756af1cfb7db59eb5d)
-rw-r--r-- | src/com/android/se/SecureElementService.java | 26 | ||||
-rw-r--r-- | src/com/android/se/Terminal.java | 84 |
2 files changed, 84 insertions, 26 deletions
diff --git a/src/com/android/se/SecureElementService.java b/src/com/android/se/SecureElementService.java index 20f0524..b38cb22 100644 --- a/src/com/android/se/SecureElementService.java +++ b/src/com/android/se/SecureElementService.java @@ -26,7 +26,6 @@ import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; -import android.hardware.secure_element.V1_0.ISecureElement; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; @@ -101,7 +100,6 @@ public final class SecureElementService extends Service { } } }; - private Context mContext; public SecureElementService() { super(); @@ -134,8 +132,6 @@ public final class SecureElementService extends Service { @Override public void onCreate() { Log.i(mTag, Thread.currentThread().getName() + " onCreate"); - - mContext = getApplicationContext(); createTerminals(); ServiceManager.addService(Context.SECURE_ELEMENT_SERVICE, mSecureElementServiceBinder); } @@ -148,33 +144,31 @@ public final class SecureElementService extends Service { Log.i(mTag, "onDestroy"); for (Terminal terminal : mTerminals.values()) { terminal.closeChannels(); + terminal.close(); } } private void addTerminals(String terminalName) { int index = 1; - String name = terminalName + Integer.toString(index); + String name = null; try { - ISecureElement seHal = ISecureElement.getService(name); - while (seHal != null) { - Terminal terminal = new Terminal(name, mContext, seHal); - mTerminals.put(name, terminal); - index++; + do { name = terminalName + Integer.toString(index); - seHal = ISecureElement.getService(name); - } + Terminal terminal = new Terminal(name, this); + terminal.initialize(); + mTerminals.put(name, terminal); + } while (++index > 0); } catch (NoSuchElementException e) { - //Thrown if the HAL implementation doesn't exist. - } catch (RemoteException e) { + Log.i(mTag, "No HAL implementation for " + name); + } catch (RemoteException | RuntimeException e) { Log.e(mTag, "Error in getService() for " + name); } } private void createTerminals() { - // Check for all eSE HAL implementations + // Check for all SE HAL implementations addTerminals(ESE_TERMINAL); addTerminals(UICC_TERMINAL); - return; } private String getPackageNameFromCallingUid(int uid) { diff --git a/src/com/android/se/Terminal.java b/src/com/android/se/Terminal.java index ee42502..f92ff88 100644 --- a/src/com/android/se/Terminal.java +++ b/src/com/android/se/Terminal.java @@ -30,6 +30,9 @@ import android.hardware.secure_element.V1_0.ISecureElementHalCallback; import android.hardware.secure_element.V1_0.LogicalChannelResponse; import android.hardware.secure_element.V1_0.SecureElementStatus; import android.os.Build; +import android.os.Handler; +import android.os.HwBinder; +import android.os.Message; import android.os.RemoteException; import android.os.ServiceSpecificException; import android.se.omapi.ISecureElementListener; @@ -67,6 +70,8 @@ public class Terminal { private boolean mDefaultApplicationSelectedOnBasicChannel = true; private static final boolean DEBUG = Build.IS_DEBUGGABLE; + private static final int GET_SERVICE_DELAY_MILLIS = 4 * 1000; + private static final int EVENT_GET_HAL = 1; private ISecureElement mSEHal; @@ -89,26 +94,70 @@ public class Terminal { } catch (Exception e) { // ignore } - synchronized (mLock) { - mDefaultApplicationSelectedOnBasicChannel = true; - } + mDefaultApplicationSelectedOnBasicChannel = true; } } } }; - public Terminal(String name, Context context, ISecureElement seHal) { - if (seHal == null) { - throw new IllegalArgumentException("ISecureElement cannot be null "); + class SecureElementDeathRecipient implements HwBinder.DeathRecipient { + @Override + public void serviceDied(long cookie) { + Log.e(mTag, mName + " died"); + synchronized (mLock) { + mIsConnected = false; + if (mAccessControlEnforcer != null) { + mAccessControlEnforcer.reset(); + } + } + mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_GET_HAL, 0), + GET_SERVICE_DELAY_MILLIS); + } + } + + private HwBinder.DeathRecipient mDeathRecipient = new SecureElementDeathRecipient(); + + private Handler mHandler = new Handler() { + @Override + public void handleMessage(Message message) { + switch (message.what) { + case EVENT_GET_HAL: + try { + initialize(); + } catch (Exception e) { + Log.e(mTag, mName + " could not be initialized again"); + sendMessageDelayed(obtainMessage(EVENT_GET_HAL, 0), + GET_SERVICE_DELAY_MILLIS); + } + break; + default: + break; + } } + }; + + public Terminal(String name, Context context) { mContext = context; mName = name; mTag = "SecureElement-Terminal-" + getName(); - mSEHal = seHal; - try { - seHal.init(mHalCallback); - } catch (RemoteException e) { + } + + /** + * Initializes the terminal + * + * @throws NoSuchElementException if there is no HAL implementation for the specified SE name + * @throws RemoteException if there is a failure communicating with the remote + */ + public void initialize() throws NoSuchElementException, RemoteException { + synchronized (mLock) { + mSEHal = ISecureElement.getService(mName); + if (mSEHal == null) { + throw new NoSuchElementException("No HAL is provided for " + mName); + } + mSEHal.init(mHalCallback); + mSEHal.linkToDeath(mDeathRecipient, 0); } + Log.i(mTag, mName + " was initialized"); } private ArrayList<Byte> byteArrayToArrayList(byte[] array) { @@ -175,6 +224,21 @@ public class Terminal { } } + /** + * Closes the terminal. + */ + public void close() { + synchronized (mLock) { + if (mSEHal != null) { + try { + mSEHal.unlinkToDeath(mDeathRecipient); + } catch (RemoteException e) { + // ignore + } + } + } + } + public String getName() { return mName; } |