Snap for 10453563 from a4b5490ae8ef1274c09da8c19b6916aa53a3277b to mainline-os-statsd-release
Change-Id: Iac56e3001b19fc777da7877ff76ab61b012695b5
diff --git a/Android.bp b/Android.bp
index ee4f8e0..05820b1 100644
--- a/Android.bp
+++ b/Android.bp
@@ -36,7 +36,8 @@
certificate: "platform",
static_libs: ["android.hardware.secure_element-V1.0-java",
"android.hardware.secure_element-V1.1-java",
- "android.hardware.secure_element-V1.2-java"],
+ "android.hardware.secure_element-V1.2-java",
+ "android.hardware.secure_element-V1-java"],
optimize: {
enabled: false,
},
diff --git a/src/com/android/se/SecureElementService.java b/src/com/android/se/SecureElementService.java
index 92b3b51..47d3103 100644
--- a/src/com/android/se/SecureElementService.java
+++ b/src/com/android/se/SecureElementService.java
@@ -68,7 +68,7 @@
public static final String VSTABLE_SECURE_ELEMENT_SERVICE =
"android.se.omapi.ISecureElementService/default";
private final String mTag = "SecureElementService";
- private static final boolean DEBUG = Build.IS_DEBUGGABLE;
+ private static final boolean DEBUG = Build.isDebuggable();
// LinkedHashMap will maintain the order of insertion
private LinkedHashMap<String, Terminal> mTerminals = new LinkedHashMap<String, Terminal>();
private int mActiveSimCount = 0;
@@ -207,6 +207,7 @@
@Override
public void onCreate() {
+ super.onCreate();
Log.i(mTag, Thread.currentThread().getName() + " onCreate");
initialize();
createTerminals();
@@ -229,6 +230,7 @@
* close all the channels.
*/
public void onDestroy() {
+ super.onDestroy();
Log.i(mTag, "onDestroy");
for (Terminal terminal : mTerminals.values()) {
terminal.closeChannels();
diff --git a/src/com/android/se/Terminal.java b/src/com/android/se/Terminal.java
index d338cf8..aba77bb 100644
--- a/src/com/android/se/Terminal.java
+++ b/src/com/android/se/Terminal.java
@@ -36,8 +36,10 @@
import android.os.Build;
import android.os.Handler;
import android.os.HwBinder;
+import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.ServiceSpecificException;
import android.os.UserHandle;
import android.se.omapi.ISecureElementListener;
@@ -75,7 +77,7 @@
private Context mContext;
private boolean mDefaultApplicationSelectedOnBasicChannel = true;
- private static final boolean DEBUG = Build.IS_DEBUGGABLE;
+ private static final boolean DEBUG = Build.isDebuggable();
private static final int GET_SERVICE_DELAY_MILLIS = 4 * 1000;
private static final int EVENT_GET_HAL = 1;
@@ -84,6 +86,7 @@
private ISecureElement mSEHal;
private android.hardware.secure_element.V1_2.ISecureElement mSEHal12;
+ private android.hardware.secure_element.ISecureElement mAidlHal;
/** For each Terminal there will be one AccessController object. */
private AccessControlEnforcer mAccessControlEnforcer;
@@ -130,6 +133,24 @@
}
};
+ private android.hardware.secure_element.ISecureElementCallback.Stub mAidlCallback =
+ new android.hardware.secure_element.ISecureElementCallback.Stub() {
+ @Override
+ public void onStateChange(boolean state, String debugReason) {
+ stateChange(state, debugReason);
+ }
+
+ @Override
+ public int getInterfaceVersion() {
+ return super.VERSION;
+ }
+
+ @Override
+ public String getInterfaceHash() {
+ return super.HASH;
+ }
+ };
+
private void stateChange(boolean state, String reason) {
synchronized (mLock) {
Log.i(mTag, "OnStateChange:" + state + " reason:" + reason);
@@ -174,9 +195,20 @@
mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
};
- class SecureElementDeathRecipient implements HwBinder.DeathRecipient {
+ class SecureElementDeathRecipient implements HwBinder.DeathRecipient, Binder.DeathRecipient {
+ // for AIDL
+ @Override
+ public void binderDied() {
+ onDied();
+ }
+
+ // for HIDL
@Override
public void serviceDied(long cookie) {
+ onDied();
+ }
+
+ private void onDied() {
Log.e(mTag, mName + " died");
SecureElementStatsLog.write(
SecureElementStatsLog.SE_STATE_CHANGED,
@@ -194,7 +226,7 @@
}
}
- private HwBinder.DeathRecipient mDeathRecipient = new SecureElementDeathRecipient();
+ private SecureElementDeathRecipient mDeathRecipient = new SecureElementDeathRecipient();
private Handler mHandler = new Handler() {
@Override
@@ -240,17 +272,35 @@
android.hardware.secure_element.V1_1.ISecureElement mSEHal11 = null;
synchronized (mLock) {
try {
- mSEHal = mSEHal11 = mSEHal12 =
- android.hardware.secure_element.V1_2.ISecureElement.getService(mName,
- retryOnFail);
+ String name = "android.hardware.secure_element.ISecureElement/" + mName;
+ IBinder binder = null;
+ if (retryOnFail) {
+ binder = ServiceManager.waitForDeclaredService(name);
+ } else {
+ if (ServiceManager.isDeclared(name)) {
+ binder = ServiceManager.getService(name);
+ }
+ }
+ mAidlHal = android.hardware.secure_element.ISecureElement.Stub.asInterface(binder);
} catch (Exception e) {
- Log.d(mTag, "SE Hal V1.2 is not supported");
+ Log.d(mTag, "SE AIDL Hal is not supported");
}
- if (mSEHal12 == null) {
+
+ if (mAidlHal == null) {
+ try {
+ mSEHal = mSEHal11 = mSEHal12 =
+ android.hardware.secure_element.V1_2.ISecureElement.getService(
+ mName, retryOnFail);
+ } catch (Exception e) {
+ Log.d(mTag, "SE Hal V1.2 is not supported");
+ }
+ }
+
+ if (mSEHal12 == null && mAidlHal == null) {
try {
mSEHal = mSEHal11 =
- android.hardware.secure_element.V1_1.ISecureElement.getService(mName,
- retryOnFail);
+ android.hardware.secure_element.V1_1.ISecureElement.getService(
+ mName, retryOnFail);
} catch (Exception e) {
Log.d(mTag, "SE Hal V1.1 is not supported");
}
@@ -262,12 +312,16 @@
}
}
}
- if (mSEHal11 != null || mSEHal12 != null) {
+ if (mAidlHal != null) {
+ mAidlHal.init(mAidlCallback);
+ mAidlHal.asBinder().linkToDeath(mDeathRecipient, 0);
+ } else if (mSEHal11 != null || mSEHal12 != null) {
mSEHal11.init_1_1(mHalCallback11);
+ mSEHal.linkToDeath(mDeathRecipient, 0);
} else {
mSEHal.init(mHalCallback);
+ mSEHal.linkToDeath(mDeathRecipient, 0);
}
- mSEHal.linkToDeath(mDeathRecipient, 0);
}
Log.i(mTag, mName + " was initialized");
SecureElementStatsLog.write(
@@ -309,7 +363,16 @@
synchronized (mLock) {
if (mIsConnected) {
try {
- byte status = mSEHal.closeChannel((byte) channel.getChannelNumber());
+ int status = 0;
+ if (mAidlHal != null) {
+ try {
+ mAidlHal.closeChannel((byte) channel.getChannelNumber());
+ } catch (ServiceSpecificException e) {
+ status = e.errorCode;
+ }
+ } else {
+ status = mSEHal.closeChannel((byte) channel.getChannelNumber());
+ }
/* For Basic Channels, errors are expected.
* Underlying implementations use this call as an indication when there
* aren't any users actively using the channel, and the chip can go
@@ -347,6 +410,13 @@
*/
public void close() {
synchronized (mLock) {
+ if (mAidlHal != null) {
+ try {
+ mAidlHal.asBinder().unlinkToDeath(mDeathRecipient, 0);
+ } catch (Exception e) {
+ // ignore
+ }
+ }
if (mSEHal != null) {
try {
mSEHal.unlinkToDeath(mDeathRecipient);
@@ -370,11 +440,19 @@
}
try {
- ArrayList<Byte> responseList = mSEHal.getAtr();
- if (responseList.isEmpty()) {
- return null;
+ byte[] atr;
+ if (mAidlHal != null) {
+ atr = mAidlHal.getAtr();
+ if (atr.length == 0) {
+ return null;
+ }
+ } else {
+ ArrayList<Byte> responseList = mSEHal.getAtr();
+ if (responseList.isEmpty()) {
+ return null;
+ }
+ atr = arrayListToByteArray(responseList);
}
- byte[] atr = arrayListToByteArray(responseList);
if (DEBUG) {
Log.i(mTag, "ATR : " + ByteArrayConverter.byteArrayToHexString(atr));
}
@@ -382,6 +460,9 @@
} catch (RemoteException e) {
Log.e(mTag, "Exception in getAtr()" + e);
return null;
+ } catch (ServiceSpecificException e) {
+ Log.e(mTag, "Exception in getAtr()" + e);
+ return null;
}
}
@@ -487,23 +568,35 @@
}
ArrayList<byte[]> responseList = new ArrayList<byte[]>();
- byte[] status = new byte[1];
+ int[] status = new int[1];
+ status[0] = 0;
- try {
- mSEHal.openBasicChannel(byteArrayToArrayList(aid), p2,
- new ISecureElement.openBasicChannelCallback() {
- @Override
- public void onValues(ArrayList<Byte> responseObject, byte halStatus) {
- status[0] = halStatus;
- responseList.add(arrayListToByteArray(responseObject));
- return;
- }
- });
- } catch (RemoteException e) {
- throw new IOException(e.getMessage());
+ if (mAidlHal != null) {
+ try {
+ responseList.add(mAidlHal.openBasicChannel(
+ aid == null ? new byte[0] : aid, p2));
+ } catch (RemoteException e) {
+ throw new IOException(e.getMessage());
+ } catch (ServiceSpecificException e) {
+ status[0] = e.errorCode;
+ }
+ } else {
+ try {
+ mSEHal.openBasicChannel(byteArrayToArrayList(aid), p2,
+ new ISecureElement.openBasicChannelCallback() {
+ @Override
+ public void onValues(ArrayList<Byte> responseObject,
+ byte halStatus) {
+ status[0] = halStatus;
+ responseList.add(arrayListToByteArray(responseObject));
+ return;
+ }
+ });
+ } catch (RemoteException e) {
+ throw new IOException(e.getMessage());
+ }
}
- byte[] selectResponse = responseList.get(0);
if (status[0] == SecureElementStatus.CHANNEL_NOT_AVAILABLE) {
return null;
} else if (status[0] == SecureElementStatus.UNSUPPORTED_OPERATION) {
@@ -514,6 +607,7 @@
throw new NoSuchElementException("OpenBasicChannel() failed");
}
+ byte[] selectResponse = responseList.get(0);
Channel basicChannel = new Channel(session, this, 0, selectResponse, aid,
listener);
basicChannel.setChannelAccess(channelAccess);
@@ -577,20 +671,36 @@
synchronized (mLock) {
LogicalChannelResponse[] responseArray = new LogicalChannelResponse[1];
- byte[] status = new byte[1];
+ int[] status = new int[1];
+ status[0] = 0;
- try {
- mSEHal.openLogicalChannel(byteArrayToArrayList(aid), p2,
- new ISecureElement.openLogicalChannelCallback() {
- @Override
- public void onValues(LogicalChannelResponse response, byte halStatus) {
- status[0] = halStatus;
- responseArray[0] = response;
- return;
- }
- });
- } catch (RemoteException e) {
- throw new IOException(e.getMessage());
+ if (mAidlHal != null) {
+ try {
+ responseArray[0] = new LogicalChannelResponse();
+ android.hardware.secure_element.LogicalChannelResponse aidlRs =
+ mAidlHal.openLogicalChannel(aid == null ? new byte[0] : aid, p2);
+ responseArray[0].channelNumber = aidlRs.channelNumber;
+ responseArray[0].selectResponse = byteArrayToArrayList(aidlRs.selectResponse);
+ } catch (RemoteException e) {
+ throw new IOException(e.getMessage());
+ } catch (ServiceSpecificException e) {
+ status[0] = e.errorCode;
+ }
+ } else {
+ try {
+ mSEHal.openLogicalChannel(byteArrayToArrayList(aid), p2,
+ new ISecureElement.openLogicalChannelCallback() {
+ @Override
+ public void onValues(LogicalChannelResponse response,
+ byte halStatus) {
+ status[0] = halStatus;
+ responseArray[0] = response;
+ return;
+ }
+ });
+ } catch (RemoteException e) {
+ throw new IOException(e.getMessage());
+ }
}
if (status[0] == SecureElementStatus.CHANNEL_NOT_AVAILABLE) {
@@ -610,7 +720,6 @@
Channel logicalChannel = new Channel(session, this, channelNumber,
selectResponse, aid, listener);
logicalChannel.setChannelAccess(channelAccess);
-
mChannels.put(channelNumber, logicalChannel);
return logicalChannel;
}
@@ -628,6 +737,19 @@
}
synchronized (mLock) {
+ if (mAidlHal != null) {
+ try {
+ android.hardware.secure_element.LogicalChannelResponse aidlRs =
+ mAidlHal.openLogicalChannel(aid, (byte) 0x00);
+ mAidlHal.closeChannel(aidlRs.channelNumber);
+ } catch (RemoteException e) {
+ return false;
+ } catch (ServiceSpecificException e) {
+ return false;
+ }
+ return true;
+ }
+
LogicalChannelResponse[] responseArray = new LogicalChannelResponse[1];
byte[] status = new byte[1];
try {
@@ -689,16 +811,31 @@
}
private byte[] transmitInternal(byte[] cmd) throws IOException {
- ArrayList<Byte> response;
- try {
- response = mSEHal.transmit(byteArrayToArrayList(cmd));
- } catch (RemoteException e) {
- throw new IOException(e.getMessage());
+ byte[] rsp;
+ if (mAidlHal != null) {
+ try {
+ rsp = mAidlHal.transmit(cmd);
+ if (rsp.length == 0) {
+ throw new IOException("Error in transmit()");
+ }
+ } catch (RemoteException e) {
+ throw new IOException(e.getMessage());
+ } catch (ServiceSpecificException e) {
+ throw new IOException(e.getMessage());
+ }
+ } else {
+ ArrayList<Byte> response;
+ try {
+ response = mSEHal.transmit(byteArrayToArrayList(cmd));
+ } catch (RemoteException e) {
+ throw new IOException(e.getMessage());
+ }
+ if (response.isEmpty()) {
+ throw new IOException("Error in transmit()");
+ }
+ rsp = arrayListToByteArray(response);
}
- if (response.isEmpty()) {
- throw new IOException("Error in transmit()");
- }
- byte[] rsp = arrayListToByteArray(response);
+
if (DEBUG) {
Log.i(mTag, "Sent : " + ByteArrayConverter.byteArrayToHexString(cmd));
Log.i(mTag, "Received : " + ByteArrayConverter.byteArrayToHexString(rsp));
@@ -737,7 +874,14 @@
*/
public boolean isSecureElementPresent() {
try {
- return mSEHal.isCardPresent();
+ if (mAidlHal != null) {
+ return mAidlHal.isCardPresent();
+ } else {
+ return mSEHal.isCardPresent();
+ }
+ } catch (ServiceSpecificException e) {
+ Log.e(mTag, "Error in isSecureElementPresent() " + e);
+ return false;
} catch (RemoteException e) {
Log.e(mTag, "Error in isSecureElementPresent() " + e);
return false;
@@ -748,23 +892,32 @@
* Reset the Secure Element. Return true if success, false otherwise.
*/
public boolean reset() {
- if (mSEHal12 == null) {
- return false;
- }
- mContext.enforceCallingOrSelfPermission(
+ synchronized (mLock) {
+ if (mSEHal12 == null && mAidlHal == null) {
+ return false;
+ }
+ mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION,
"Need SECURE_ELEMENT_PRIVILEGED_OPERATION permission");
- try {
- byte status = mSEHal12.reset();
- // Successfully trigger reset. HAL service should send onStateChange
- // after secure element reset and initialization process complete
- if (status == SecureElementStatus.SUCCESS) {
- return true;
+ try {
+ if (mAidlHal != null) {
+ mAidlHal.reset();
+ return true;
+ } else {
+ byte status = mSEHal12.reset();
+ // Successfully trigger reset. HAL service should send onStateChange
+ // after secure element reset and initialization process complete
+ if (status == SecureElementStatus.SUCCESS) {
+ return true;
+ }
+ Log.e(mTag, "Error resetting terminal " + mName);
+ }
+ } catch (ServiceSpecificException e) {
+ Log.e(mTag, "Exception in reset()" + e);
+ } catch (RemoteException e) {
+ Log.e(mTag, "Exception in reset()" + e);
}
- Log.e(mTag, "Error reseting terminal " + mName);
- } catch (RemoteException e) {
- Log.e(mTag, "Exception in reset()" + e);
}
return false;
}
diff --git a/src/com/android/se/security/AccessControlEnforcer.java b/src/com/android/se/security/AccessControlEnforcer.java
index e6f08cf..707e37a 100644
--- a/src/com/android/se/security/AccessControlEnforcer.java
+++ b/src/com/android/se/security/AccessControlEnforcer.java
@@ -65,7 +65,7 @@
public class AccessControlEnforcer {
private final String mTag = "SecureElement-AccessControlEnforcer";
- private static final boolean DEBUG = Build.IS_DEBUGGABLE;
+ private static final boolean DEBUG = Build.isDebuggable();
private PackageManager mPackageManager = null;
private boolean mNoRuleFound = false;
private AraController mAraController = null;
@@ -277,7 +277,7 @@
// check result of channel access during initialization procedure
if (mInitialChannelAccess.getAccess() == ChannelAccess.ACCESS.DENIED) {
throw new AccessControlException(
- mTag + "access denied: " + mInitialChannelAccess.getReason());
+ mTag + " access denied: " + mInitialChannelAccess.getReason());
}
// this is the new GP Access Control Enforcer implementation
if (mUseAra || mUseArf) {
@@ -512,7 +512,7 @@
}
private void readSecurityProfile() {
- if (!Build.IS_DEBUGGABLE) {
+ if (!Build.isDebuggable()) {
mUseArf = true;
mUseAra = true;
mFullAccess = false; // Per default we don't grant full access.
diff --git a/src/com/android/se/security/AccessRuleCache.java b/src/com/android/se/security/AccessRuleCache.java
index 97c63bb..c1aa1ba 100644
--- a/src/com/android/se/security/AccessRuleCache.java
+++ b/src/com/android/se/security/AccessRuleCache.java
@@ -56,7 +56,7 @@
/** Stores all the access rules from the Secure Element */
public class AccessRuleCache {
- private static final boolean DEBUG = Build.IS_DEBUGGABLE;
+ private static final boolean DEBUG = Build.isDebuggable();
private final String mTag = "SecureElement-AccessRuleCache";
// Previous "RefreshTag"
// 2012-09-25
diff --git a/src/com/android/se/security/HalRefDoParser.java b/src/com/android/se/security/HalRefDoParser.java
index 40ea7de..bc1e31d 100644
--- a/src/com/android/se/security/HalRefDoParser.java
+++ b/src/com/android/se/security/HalRefDoParser.java
@@ -41,7 +41,7 @@
*/
public class HalRefDoParser {
- private static final boolean DEBUG = Build.IS_DEBUGGABLE;
+ private static final boolean DEBUG = Build.isDebuggable();
private final String mTag = "SecureElement-HalRefDoParser";
private static final String PROP_PRODUCT_HARDWARE_SKU = "ro.boot.product.hardware.sku";