summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoshiaki Naka <yoshiaki.naka@sony.com>2018-03-22 14:00:29 +0900
committerRuchi Kandoi <kandoiruchi@google.com>2018-04-10 15:24:48 -0700
commitcf7d2f1d5d06675593e770e267d318357b598fdc (patch)
tree54a1f180f83bf420eb03c96e6729565340e01a65
parent55376b4dad37f48c1deebab431d0dc2eec26fc91 (diff)
downloadSecureElement-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.java26
-rw-r--r--src/com/android/se/Terminal.java84
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;
}