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";