diff --git a/Android.bp b/Android.bp
index 6712461..69fb459 100644
--- a/Android.bp
+++ b/Android.bp
@@ -200,6 +200,11 @@
         "core/java/android/nfc/INfcUnlockHandler.aidl",
         "core/java/android/nfc/INfcDta.aidl",
         "core/java/android/nfc/ITagRemovedCallback.aidl",
+        "core/java/android/se/omapi/ISecureElementService.aidl",
+        "core/java/android/se/omapi/ISecureElementListener.aidl",
+        "core/java/android/se/omapi/ISecureElementChannel.aidl",
+        "core/java/android/se/omapi/ISecureElementReader.aidl",
+        "core/java/android/se/omapi/ISecureElementSession.aidl",
         "core/java/android/os/IBatteryPropertiesListener.aidl",
         "core/java/android/os/IBatteryPropertiesRegistrar.aidl",
         "core/java/android/os/ICancellationSignal.aidl",
diff --git a/api/current.txt b/api/current.txt
index bc79db9..05e19ca 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -37013,6 +37013,59 @@
 
 }
 
+package android.se.omapi {
+
+  public class Channel {
+    method public void close();
+    method public byte[] getSelectResponse();
+    method public android.se.omapi.Session getSession();
+    method public boolean isBasicChannel();
+    method public boolean isClosed();
+    method public boolean selectNext() throws java.io.IOException;
+    method public byte[] transmit(byte[]) throws java.io.IOException;
+  }
+
+  public abstract interface ISecureElementListener implements android.os.IInterface {
+    method public abstract void serviceConnected() throws android.os.RemoteException;
+  }
+
+  public static abstract class ISecureElementListener.Stub extends android.os.Binder implements android.se.omapi.ISecureElementListener {
+    ctor public ISecureElementListener.Stub();
+    method public android.os.IBinder asBinder();
+    method public static android.se.omapi.ISecureElementListener asInterface(android.os.IBinder);
+    method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
+  }
+
+  public class Reader {
+    method public void closeSessions();
+    method public java.lang.String getName();
+    method public android.se.omapi.SEService getSEService();
+    method public boolean isSecureElementPresent();
+    method public android.se.omapi.Session openSession() throws java.io.IOException;
+  }
+
+  public class SEService {
+    ctor public SEService(android.content.Context, android.se.omapi.ISecureElementListener);
+    method public android.se.omapi.Reader[] getReaders();
+    method public java.lang.String getVersion();
+    method public boolean isConnected();
+    method public void shutdown();
+  }
+
+  public class Session {
+    method public void close();
+    method public void closeChannels();
+    method public byte[] getATR();
+    method public android.se.omapi.Reader getReader();
+    method public boolean isClosed();
+    method public android.se.omapi.Channel openBasicChannel(byte[], byte) throws java.io.IOException;
+    method public android.se.omapi.Channel openBasicChannel(byte[]) throws java.io.IOException;
+    method public android.se.omapi.Channel openLogicalChannel(byte[], byte) throws java.io.IOException;
+    method public android.se.omapi.Channel openLogicalChannel(byte[]) throws java.io.IOException;
+  }
+
+}
+
 package android.security {
 
   public final class KeyChain {
diff --git a/core/java/android/se/omapi/Channel.java b/core/java/android/se/omapi/Channel.java
new file mode 100644
index 0000000..f0b9fa2d
--- /dev/null
+++ b/core/java/android/se/omapi/Channel.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Copyright (c) 2015-2017, The Linux Foundation.
+ */
+/*
+ * Contributed by: Giesecke & Devrient GmbH.
+ */
+
+package android.se.omapi;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.io.IOException;
+
+/**
+ * Instances of this class represent an ISO/IEC 7816-4 channel opened to a
+ * Secure Element. It can be either a logical channel or the basic channel. They
+ * can be used to send APDUs to the secure element. Channels are opened by
+ * calling the Session.openBasicChannel(byte[]) or
+ * Session.openLogicalChannel(byte[]) methods.
+ *
+ * @see <a href="http://globalplatform.org">GlobalPlatform Open Mobile API</a>
+ */
+public class Channel {
+
+    private static final String TAG = "OMAPI.Channel";
+    private Session mSession;
+    private final ISecureElementChannel mChannel;
+    private final SEService mService;
+    private final Object mLock = new Object();
+
+    Channel(SEService service, Session session, ISecureElementChannel channel) {
+        if (service == null || session == null || channel == null) {
+            throw new IllegalArgumentException("Parameters cannot be null");
+        }
+        mService = service;
+        mSession = session;
+        mChannel = channel;
+    }
+
+    /**
+     * Closes this channel to the Secure Element. If the method is called when
+     * the channel is already closed, this method will be ignored. The close()
+     * method shall wait for completion of any pending transmit(byte[] command)
+     * before closing the channel.
+     */
+    public void close() {
+        if (!isClosed()) {
+            synchronized (mLock) {
+                try {
+                    mChannel.close();
+                } catch (Exception e) {
+                    Log.e(TAG, "Error closing channel", e);
+                }
+            }
+        }
+    }
+
+    /**
+     * Tells if this channel is closed.
+     *
+     * @return <code>true</code> if the channel is closed or in case of an error.
+     *         <code>false</code> otherwise.
+     */
+    public boolean isClosed() {
+        if (!mService.isConnected()) {
+            Log.e(TAG, "service not connected to system");
+            return true;
+        }
+        try {
+            return mChannel.isClosed();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Exception in isClosed()");
+            return true;
+        }
+    }
+
+    /**
+     * Returns a boolean telling if this channel is the basic channel.
+     *
+     * @return <code>true</code> if this channel is a basic channel. <code>false</code> if
+     *         this channel is a logical channel.
+     */
+    public boolean isBasicChannel() {
+        if (!mService.isConnected()) {
+            throw new IllegalStateException("service not connected to system");
+        }
+        try {
+            return mChannel.isBasicChannel();
+        } catch (RemoteException e) {
+            throw new IllegalStateException(e.getMessage());
+        }
+    }
+
+    /**
+     * Transmit an APDU command (as per ISO/IEC 7816-4) to the Secure Element. The
+     * underlying layers generate as many TPDUs as necessary to transport this APDU. The
+     * API shall ensure that all available data returned from Secure Element, including
+     * concatenated responses, are retrieved and made available to the calling application. If a
+     * warning status code is received the API wont check for further response data but will
+     * return all data received so far and the warning status code.<br>
+     * The transport part is invisible from the application. The generated response is the
+     * response of the APDU which means that all protocols related responses are handled
+     * inside the API or the underlying implementation.<br>
+     * The transmit method shall support extended length APDU commands independently of
+     * the coding within the ATR.<br>
+     * For status word '61 XX' the API or underlying implementation shall issue a GET
+     * RESPONSE command as specified by ISO 7816-4 standard with LE=XX; for the status
+     * word '6C XX', the API or underlying implementation shall reissue the input command
+     * with LE=XX. For other status words, the API (or underlying implementation) shall return
+     * the complete response including data and status word to the device application. The API
+     * (or underlying implementation) shall not handle internally the received status words. The
+     * channel shall not be closed even if the Secure Element answered with an error code.
+     * The system ensures the synchronization between all the concurrent calls to this method,
+     * and that only one APDU will be sent at a time, irrespective of the number of TPDUs that
+     * might be required to transport it to the SE. The entire APDU communication to this SE is
+     * locked to the APDU.<br>
+     * The channel information in the class byte in the APDU will be ignored. The system will
+     * add any required information to ensure the APDU is transported on this channel.
+     * The only restrictions on the set of commands that can be sent is defined below, the API
+     * implementation shall be able to send all other commands: <br>
+     * <ul>
+     * <li>MANAGE_CHANNEL commands are not allowed.</li>
+     * <li>SELECT by DF Name (p1=04) are not allowed.</li>
+     * <li>CLA bytes with channel numbers are de-masked.</li>
+     * </ul>
+     *
+     * @param command the APDU command to be transmitted, as a byte array.
+     *
+     * @return the response received, as a byte array. The returned byte array contains the data
+     * bytes in the following order:
+     * [&lt;first data byte&gt;, ..., &lt;last data byte&gt;, &lt;sw1&gt;, &lt;sw2&gt;]
+     *
+     * @throws IOException if there is a communication problem to the reader or the Secure Element.
+     * @throws IllegalStateException if the channel is used after being closed.
+     * @throws IllegalArgumentException if the command byte array is less than 4 bytes long.
+     * @throws IllegalArgumentException if Lc byte is inconsistent with length of the byte array.
+     * @throws IllegalArgumentException if CLA byte is invalid according to [2] (0xff).
+     * @throws IllegalArgumentException if INS byte is invalid according to [2] (0x6x or 0x9x).
+     * @throws SecurityException if the command is filtered by the security policy.
+     * @throws NullPointerException if command is NULL.
+     */
+    public @NonNull byte[] transmit(byte[] command) throws IOException {
+        if (!mService.isConnected()) {
+            throw new IllegalStateException("service not connected to system");
+        }
+        synchronized (mLock) {
+            try {
+                byte[] response = mChannel.transmit(command);
+                if (response == null) {
+                    throw new IOException("Error in communicating with Secure Element");
+                }
+                return response;
+            } catch (RemoteException e) {
+                throw new IOException(e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * Get the session that has opened this channel.
+     *
+     * @return the session object this channel is bound to.
+     */
+    public @NonNull Session getSession() {
+        return mSession;
+    }
+
+    /**
+     * Returns the data as received from the application select command inclusively the status word
+     * received at applet selection.
+     * The returned byte array contains the data bytes in the following order:
+     * [&lt;first data byte&gt;, ..., &lt;last data byte&gt;, &lt;sw1&gt;, &lt;sw2&gt;]
+     * @return The data as returned by the application select command inclusively the status word.
+     * Only the status word if the application select command has no returned data.
+     * Returns null if an application select command has not been performed or the selection
+     * response can not be retrieved by the reader implementation.
+     */
+    public @Nullable byte[] getSelectResponse() {
+        if (!mService.isConnected()) {
+            throw new IllegalStateException("service not connected to system");
+        }
+
+        byte[] response;
+        try {
+            response = mChannel.getSelectResponse();
+        } catch (RemoteException e) {
+            throw new IllegalStateException(e.getMessage());
+        }
+
+        if (response != null && response.length == 0) {
+            response = null;
+        }
+        return response;
+    }
+
+    /**
+     * Performs a selection of the next Applet on this channel that matches to the partial AID
+     * specified in the openBasicChannel(byte[] aid) or openLogicalChannel(byte[] aid) method.
+     * This mechanism can be used by a device application to iterate through all Applets
+     * matching to the same partial AID.
+     * If selectNext() returns true a new Applet was successfully selected on this channel.
+     * If no further Applet exists with matches to the partial AID this method returns false
+     * and the already selected Applet stays selected. <br>
+     *
+     * Since the API cannot distinguish between a partial and full AID the API shall rely on the
+     * response of the Secure Element for the return value of this method. <br>
+     * The implementation of the underlying SELECT command within this method shall use
+     * the same values as the corresponding openBasicChannel(byte[] aid) or
+     * openLogicalChannel(byte[] aid) command with the option: <br>
+     * P2='02' (Next occurrence) <br>
+     * The select response stored in the Channel object shall be updated with the APDU
+     * response of the SELECT command.
+
+     * @return <code>true</code> if new Applet was selected on this channel.
+               <code>false</code> he already selected Applet stays selected on this channel.
+     *
+     * @throws IOException if there is a communication problem to the reader or the Secure Element.
+     * @throws IllegalStateException if the channel is used after being closed.
+     * @throws UnsupportedOperationException if this operation is not supported by the card.
+     */
+    public boolean selectNext() throws IOException {
+        if (!mService.isConnected()) {
+            throw new IllegalStateException("service not connected to system");
+        }
+        try {
+            synchronized (mLock) {
+                return mChannel.selectNext();
+            }
+        } catch (RemoteException e) {
+            throw new IOException(e.getMessage());
+        }
+    }
+}
diff --git a/core/java/android/se/omapi/ISecureElementChannel.aidl b/core/java/android/se/omapi/ISecureElementChannel.aidl
new file mode 100644
index 0000000..4ae57ab
--- /dev/null
+++ b/core/java/android/se/omapi/ISecureElementChannel.aidl
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Contributed by: Giesecke & Devrient GmbH.
+ */
+
+package android.se.omapi;
+
+import android.se.omapi.ISecureElementSession;
+
+/** @hide */
+interface ISecureElementChannel {
+
+    /**
+     * Closes the specified connection and frees internal resources.
+     * A logical channel will be closed.
+     */
+    void close();
+
+    /**
+     * Tells if this channel is closed.
+     *
+     * @return <code>true</code> if the channel is closed,
+     *         <code>false</code> otherwise.
+     */
+    boolean isClosed();
+
+    /**
+     * Returns a boolean telling if this channel is the basic channel.
+     *
+     * @return <code>true</code> if this channel is a basic channel.
+     *         <code>false</code> if this channel is a logical channel.
+     */
+    boolean isBasicChannel();
+
+     /**
+     * Returns the data as received from the application select command
+     * inclusively the status word. The returned byte array contains the data
+     * bytes in the following order:
+     * [<first data byte>, ..., <last data byte>, <sw1>, <sw2>]
+     */
+    byte[] getSelectResponse();
+
+    /**
+     * Transmits the specified command APDU and returns the response APDU.
+     * MANAGE channel commands are not supported.
+     * Selection of applets is not supported in logical channels.
+     */
+    byte[] transmit(in byte[] command);
+
+    /**
+     * Performs a selection of the next Applet on this channel that matches to
+     * the partial AID specified in the openBasicChannel(byte[] aid) or
+     * openLogicalChannel(byte[] aid) method. This mechanism can be used by a
+     * device application to iterate through all Applets matching to the same
+     * partial AID.
+     * If selectNext() returns true a new Applet was successfully selected on
+     * this channel.
+     * If no further Applet exists with matches to the partial AID this method
+     * returns false and the already selected Applet stays selected.
+     *
+     * @return <code>true</code> if new Applet was successfully selected.
+     *         <code>false</code> if no further Applet exists which matches the
+     *         partial AID.
+     */
+    boolean selectNext();
+}
diff --git a/core/java/android/se/omapi/ISecureElementListener.aidl b/core/java/android/se/omapi/ISecureElementListener.aidl
new file mode 100644
index 0000000..3a99d63
--- /dev/null
+++ b/core/java/android/se/omapi/ISecureElementListener.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Contributed by: Giesecke & Devrient GmbH.
+ */
+
+package android.se.omapi;
+
+/**
+ * Interface to receive call-backs when the service is connected.
+ */
+interface ISecureElementListener {
+  /**
+   * Called by the framework when the service is connected.
+   */
+  void serviceConnected();
+}
diff --git a/core/java/android/se/omapi/ISecureElementReader.aidl b/core/java/android/se/omapi/ISecureElementReader.aidl
new file mode 100644
index 0000000..a312c44
--- /dev/null
+++ b/core/java/android/se/omapi/ISecureElementReader.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Contributed by: Giesecke & Devrient GmbH.
+ */
+
+package android.se.omapi;
+
+import android.se.omapi.ISecureElementSession;
+
+/** @hide */
+interface ISecureElementReader {
+
+    /**
+     * Returns true if a card is present in the specified reader.
+     * Returns false if a card is not present in the specified reader.
+     */
+    boolean isSecureElementPresent();
+
+    /**
+     * Connects to a secure element in this reader. <br>
+     * This method prepares (initialises) the Secure Element for communication
+     * before the Session object is returned (e.g. powers the Secure Element by
+     * ICC ON if its not already on). There might be multiple sessions opened at
+     * the same time on the same reader. The system ensures the interleaving of
+     * APDUs between the respective sessions.
+     *
+     * @return a Session object to be used to create Channels.
+     */
+    ISecureElementSession openSession();
+
+    /**
+     * Close all the sessions opened on this reader. All the channels opened by
+     * all these sessions will be closed.
+     */
+    void closeSessions();
+
+}
diff --git a/core/java/android/se/omapi/ISecureElementService.aidl b/core/java/android/se/omapi/ISecureElementService.aidl
new file mode 100644
index 0000000..4fa799e
--- /dev/null
+++ b/core/java/android/se/omapi/ISecureElementService.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Copyright (c) 2015-2017, The Linux Foundation.
+ */
+/*
+ * Contributed by: Giesecke & Devrient GmbH.
+ */
+
+package android.se.omapi;
+
+import android.se.omapi.ISecureElementReader;
+
+/**
+ * SecureElement service interface.
+ * @hide
+ */
+interface ISecureElementService {
+
+    /**
+     * Returns the friendly names of available Secure Element readers.
+     */
+    String[] getReaders();
+
+    /**
+     * Returns SecureElement Service reader object to the given name.
+     */
+    ISecureElementReader getReader(String reader);
+
+    /**
+     * Checks if the application defined by the package name is allowed to
+     * receive NFC transaction events for the defined AID.
+     */
+    boolean[] isNFCEventAllowed(String reader, in byte[] aid,
+            in String[] packageNames);
+
+}
diff --git a/core/java/android/se/omapi/ISecureElementSession.aidl b/core/java/android/se/omapi/ISecureElementSession.aidl
new file mode 100644
index 0000000..8ea599f
--- /dev/null
+++ b/core/java/android/se/omapi/ISecureElementSession.aidl
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Copyright (c) 2015-2017, The Linux Foundation.
+ */
+/*
+ * Contributed by: Giesecke & Devrient GmbH.
+ */
+
+package android.se.omapi;
+
+import android.se.omapi.ISecureElementChannel;
+import android.se.omapi.ISecureElementReader;
+import android.se.omapi.ISecureElementListener;
+
+/** @hide */
+interface ISecureElementSession {
+
+    /**
+     * Returns the ATR of the connected card or null if the ATR is not available
+     */
+    byte[] getAtr();
+
+    /**
+     * Close the connection with the Secure Element. This will close any
+     * channels opened by this application with this Secure Element.
+     */
+    void close();
+
+    /**
+     * Close any channel opened on this session.
+     */
+    void closeChannels();
+
+
+    /**
+     * Tells if this session is closed.
+     *
+     * @return <code>true</code> if the session is closed, false otherwise.
+     */
+    boolean isClosed();
+
+    /**
+     * Opens a connection using the basic channel of the card in the
+     * specified reader and returns a channel handle. Selects the specified
+     * applet if aid != null.
+     * Logical channels cannot be opened with this connection.
+     * Use interface method openLogicalChannel() to open a logical channel.
+     */
+    ISecureElementChannel openBasicChannel(in byte[] aid, in byte p2,
+            ISecureElementListener listener);
+
+    /**
+     * Opens a connection using the next free logical channel of the card in the
+     * specified reader. Selects the specified applet.
+     * Selection of other applets with this connection is not supported.
+     */
+    ISecureElementChannel openLogicalChannel(in byte[] aid, in byte p2,
+            ISecureElementListener listener);
+}
diff --git a/core/java/android/se/omapi/Reader.java b/core/java/android/se/omapi/Reader.java
new file mode 100644
index 0000000..9f15739
--- /dev/null
+++ b/core/java/android/se/omapi/Reader.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Copyright (c) 2015-2017, The Linux Foundation.
+ */
+/*
+ * Contributed by: Giesecke & Devrient GmbH.
+ */
+
+package android.se.omapi;
+
+import android.annotation.NonNull;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.io.IOException;
+
+/**
+ * Instances of this class represent Secure Element Readers supported to this
+ * device. These Readers can be physical devices or virtual devices. They can be
+ * removable or not. They can contain Secure Element that can or cannot be
+ * removed.
+ *
+ * @see <a href="http://globalplatform.org">GlobalPlatform Open Mobile API</a>
+ */
+public class Reader {
+
+    private static final String TAG = "OMAPI.Reader";
+    private final String mName;
+    private final SEService mService;
+    private ISecureElementReader mReader;
+    private final Object mLock = new Object();
+
+
+    Reader(SEService service, String name, ISecureElementReader reader) throws
+            IOException {
+        if (reader == null || service == null || name == null) {
+            throw new IllegalArgumentException("Parameters cannot be null");
+        }
+        mName = name;
+        mService = service;
+        mReader = reader;
+    }
+
+    /**
+     * Return the name of this reader.
+     * <ul>
+     * <li>If this reader is a SIM reader, then its name must be "SIM[Slot]".</li>
+     * <li>If the reader is a SD or micro SD reader, then its name must be "SD[Slot]"</li>
+     * <li>If the reader is a embedded SE reader, then its name must be "eSE[Slot]"</li>
+     * </ul>
+     * Slot is a decimal number without leading zeros. The Numbering must start with 1
+     * (e.g. SIM1, SIM2, ... or SD1, SD2, ... or eSE1, eSE2, ...).
+     * The slot number “1” for a reader is optional
+     * (SIM and SIM1 are both valid for the first SIM-reader,
+     * but if there are two readers then the second reader must be named SIM2).
+     * This applies also for other SD or SE readers.
+     *
+     * @return the reader name, as a String.
+     */
+    public @NonNull String getName() {
+        return mName;
+    }
+
+    /**
+     * Connects to a Secure Element in this reader. <br>
+     * This method prepares (initialises) the Secure Element for communication
+     * before the Session object is returned (e.g. powers the Secure Element by
+     * ICC ON if its not already on). There might be multiple sessions opened at
+     * the same time on the same reader. The system ensures the interleaving of
+     * APDUs between the respective sessions.
+     *
+     * @throws IOException if something went wrong with the communicating to the
+     *             Secure Element or the reader.
+     * @return a Session object to be used to create Channels.
+     */
+    public @NonNull Session openSession() throws IOException {
+        if (!mService.isConnected()) {
+            throw new IllegalStateException("service is not connected");
+        }
+
+        synchronized (mLock) {
+            ISecureElementSession session;
+            try {
+                session = mReader.openSession();
+            } catch (RemoteException e) {
+                throw new IOException(e.getMessage());
+            }
+            if (session == null) {
+                throw new IOException("service session is null.");
+            }
+            return new Session(mService, session, this);
+        }
+    }
+
+    /**
+     * Check if a Secure Element is present in this reader.
+     *
+     * @throws IllegalStateException if the service is not connected
+     * @return <code>true</code> if the SE is present, <code>false</code> otherwise.
+     */
+    public boolean isSecureElementPresent() {
+        if (!mService.isConnected()) {
+            throw new IllegalStateException("service is not connected");
+        }
+
+        try {
+            return mReader.isSecureElementPresent();
+        } catch (RemoteException e) {
+            throw new IllegalStateException("Error in isSecureElementPresent()");
+        }
+    }
+
+    /**
+     * Return the Secure Element service this reader is bound to.
+     *
+     * @return the SEService object.
+     */
+    public @NonNull SEService getSEService() {
+        return mService;
+    }
+
+    /**
+     * Close all the sessions opened on this reader.
+     * All the channels opened by all these sessions will be closed.
+     */
+    public void closeSessions() {
+        if (!mService.isConnected()) {
+            Log.e(TAG, "service is not connected");
+            return;
+        }
+        synchronized (mLock) {
+            try {
+                mReader.closeSessions();
+            } catch (RemoteException ignore) { }
+        }
+    }
+}
diff --git a/core/java/android/se/omapi/SEService.java b/core/java/android/se/omapi/SEService.java
new file mode 100644
index 0000000..1e37277d
--- /dev/null
+++ b/core/java/android/se/omapi/SEService.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ */
+/*
+ * Contributed by: Giesecke & Devrient GmbH.
+ */
+
+package android.se.omapi;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.HashMap;
+
+/**
+ * The SEService realises the communication to available Secure Elements on the
+ * device. This is the entry point of this API. It is used to connect to the
+ * infrastructure and get access to a list of Secure Element Readers.
+ *
+ * @see <a href="http://simalliance.org">SIMalliance Open Mobile API  v3.0</a>
+ */
+public class SEService {
+
+    private static final String TAG = "OMAPI.SEService";
+
+    private final Object mLock = new Object();
+
+    /** The client context (e.g. activity). */
+    private final Context mContext;
+
+    /** The backend system. */
+    private volatile ISecureElementService mSecureElementService;
+
+    /**
+     * Class for interacting with the main interface of the backend.
+     */
+    private ServiceConnection mConnection;
+
+    /**
+     * Collection of available readers
+     */
+    private final HashMap<String, Reader> mReaders = new HashMap<String, Reader>();
+
+    /**
+     * Listener object that allows the notification of the caller if this
+     * SEService could be bound to the backend.
+     */
+    private ISecureElementListener mSEListener;
+
+    /**
+     * Establishes a new connection that can be used to connect to all the
+     * Secure Elements available in the system. The connection process can be
+     * quite long, so it happens in an asynchronous way. It is usable only if
+     * the specified listener is called or if isConnected() returns
+     * <code>true</code>. <br>
+     * The call-back object passed as a parameter will have its
+     * serviceConnected() method called when the connection actually happen.
+     *
+     * @param context
+     *            the context of the calling application. Cannot be
+     *            <code>null</code>.
+     * @param listener
+     *            a ISecureElementListener object. Can be <code>null</code>.
+     */
+    public SEService(Context context, ISecureElementListener listener) {
+
+        if (context == null) {
+            throw new NullPointerException("context must not be null");
+        }
+
+        mContext = context;
+        mSEListener = listener;
+
+        mConnection = new ServiceConnection() {
+
+            public synchronized void onServiceConnected(
+                    ComponentName className, IBinder service) {
+
+                mSecureElementService = ISecureElementService.Stub.asInterface(service);
+                if (mSEListener != null) {
+                    try {
+                        mSEListener.serviceConnected();
+                    } catch (RemoteException ignore) { }
+                }
+                Log.i(TAG, "Service onServiceConnected");
+            }
+
+            public void onServiceDisconnected(ComponentName className) {
+                mSecureElementService = null;
+                Log.i(TAG, "Service onServiceDisconnected");
+            }
+        };
+
+        Intent intent = new Intent(ISecureElementService.class.getName());
+        intent.setClassName("com.android.se",
+                            "com.android.se.SecureElementService");
+        boolean bindingSuccessful =
+                mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+        if (bindingSuccessful) {
+            Log.i(TAG, "bindService successful");
+        }
+    }
+
+    /**
+     * Tells whether or not the service is connected.
+     *
+     * @return <code>true</code> if the service is connected.
+     */
+    public boolean isConnected() {
+        return mSecureElementService != null;
+    }
+
+    /**
+     * Returns the list of available Secure Element readers.
+     * There must be no duplicated objects in the returned list.
+     * All available readers shall be listed even if no card is inserted.
+     *
+     * @return The readers list, as an array of Readers. If there are no
+     * readers the returned array is of length 0.
+     */
+    public @NonNull Reader[] getReaders() {
+        if (mSecureElementService == null) {
+            throw new IllegalStateException("service not connected to system");
+        }
+        String[] readerNames;
+        try {
+            readerNames = mSecureElementService.getReaders();
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+
+        Reader[] readers = new Reader[readerNames.length];
+        int i = 0;
+        for (String readerName : readerNames) {
+            if (mReaders.get(readerName) == null) {
+                try {
+                    mReaders.put(readerName, new Reader(this, readerName,
+                            getReader(readerName)));
+                    readers[i++] = mReaders.get(readerName);
+                } catch (Exception e) {
+                    Log.e(TAG, "Error adding Reader: " + readerName, e);
+                }
+            } else {
+                readers[i++] = mReaders.get(readerName);
+            }
+        }
+        return readers;
+    }
+
+    /**
+     * Releases all Secure Elements resources allocated by this SEService
+     * (including any binding to an underlying service).
+     * As a result isConnected() will return false after shutdown() was called.
+     * After this method call, the SEService object is not connected.
+     * It is recommended to call this method in the termination method of the calling application
+     * (or part of this application) which is bound to this SEService.
+     */
+    public void shutdown() {
+        synchronized (mLock) {
+            if (mSecureElementService != null) {
+                for (Reader reader : mReaders.values()) {
+                    try {
+                        reader.closeSessions();
+                    } catch (Exception ignore) { }
+                }
+            }
+            try {
+                mContext.unbindService(mConnection);
+            } catch (IllegalArgumentException e) {
+                // Do nothing and fail silently since an error here indicates
+                // that binding never succeeded in the first place.
+            }
+            mSecureElementService = null;
+        }
+    }
+
+    /**
+     * Returns the version of the OpenMobile API specification this
+     * implementation is based on.
+     *
+     * @return String containing the OpenMobile API version (e.g. "3.0").
+     */
+    public String getVersion() {
+        return "3.2";
+    }
+
+    @NonNull ISecureElementListener getListener() {
+        return mSEListener;
+    }
+
+    /**
+     * Obtain a Reader instance from the SecureElementService
+     */
+    private @NonNull ISecureElementReader getReader(String name) {
+        try {
+            return mSecureElementService.getReader(name);
+        } catch (RemoteException e) {
+            throw new IllegalStateException(e.getMessage());
+        }
+    }
+}
diff --git a/core/java/android/se/omapi/Session.java b/core/java/android/se/omapi/Session.java
new file mode 100644
index 0000000..bb2a032
--- /dev/null
+++ b/core/java/android/se/omapi/Session.java
@@ -0,0 +1,347 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Copyright (c) 2017, The Linux Foundation.
+ */
+/*
+ * Contributed by: Giesecke & Devrient GmbH.
+ */
+
+package android.se.omapi;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.NoSuchElementException;
+
+/**
+ * Instances of this class represent a connection session to one of the Secure
+ * Elements available on the device. These objects can be used to get a
+ * communication channel with an Applet in the Secure Element.
+ * This channel can be the basic channel or a logical channel.
+ *
+ * @see <a href="http://simalliance.org">SIMalliance Open Mobile API  v3.0</a>
+ */
+public class Session {
+
+    private final Object mLock = new Object();
+    private final SEService mService;
+    private final Reader mReader;
+    private final ISecureElementSession mSession;
+    private static final String TAG = "OMAPI.Session";
+
+    Session(SEService service, ISecureElementSession session, Reader reader) {
+        if (service == null || reader == null || session == null) {
+            throw new IllegalArgumentException("Parameters cannot be null");
+        }
+        mService = service;
+        mReader = reader;
+        mSession = session;
+    }
+
+    /**
+     * Get the reader that provides this session.
+     *
+     * @return The Reader object.
+     */
+    public @NonNull Reader getReader() {
+        return mReader;
+    }
+
+    /**
+     * Get the Answer to Reset of this Secure Element. <br>
+     * The returned byte array can be null if the ATR for this Secure Element is
+     * not available.
+     *
+     * @throws IllegalStateException if there was an error connecting to SE or
+     *                               if the service was not connected.
+     * @return the ATR as a byte array or null.
+     */
+    public @Nullable byte[] getATR() {
+        if (!mService.isConnected()) {
+            throw new IllegalStateException("service not connected to system");
+        }
+        try {
+            return mSession.getAtr();
+        } catch (RemoteException e) {
+            throw new IllegalStateException(e.getMessage());
+        }
+    }
+
+    /**
+     * Close the connection with the Secure Element. This will close any
+     * channels opened by this application with this Secure Element.
+     */
+    public void close() {
+        if (!mService.isConnected()) {
+            Log.e(TAG, "service not connected to system");
+            return;
+        }
+        synchronized (mLock) {
+            try {
+                mSession.close();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error closing session", e);
+            }
+        }
+    }
+
+    /**
+     * Tells if this session is closed.
+     *
+     * @return <code>true</code> if the session is closed, false otherwise.
+     */
+    public boolean isClosed() {
+        try {
+            return mSession.isClosed();
+        } catch (RemoteException e) {
+            // If there was an error here, then the session is considered close
+            return true;
+        }
+    }
+
+    /**
+     * Close any channel opened on this session.
+     */
+    public void closeChannels() {
+        if (!mService.isConnected()) {
+            Log.e(TAG, "service not connected to system");
+            return;
+        }
+
+        synchronized (mLock) {
+            try {
+                mSession.closeChannels();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error closing channels", e);
+            }
+        }
+    }
+
+    /**
+     * Get an access to the basic channel, as defined in the ISO/IEC 7816-4 specification (the
+     * one that has number 0). The obtained object is an instance of the Channel class.
+     * If the AID is null, it means no Applet is to be selected on this channel and the default
+     * Applet is used. If the AID is defined then the corresponding Applet is selected.
+     * Once this channel has been opened by a device application, it is considered as "locked"
+     * by this device application, and other calls to this method will return null, until the
+     * channel is closed. Some Secure Elements (like the UICC) might always keep the basic channel
+     * locked (i.e. return null to applications), to prevent access to the basic channel, while
+     * some other might return a channel object implementing some kind of filtering on the
+     * commands, restricting the set of accepted command to a smaller set.
+     * It is recommended for the UICC to reject the opening of the basic channel to a specific
+     * applet, by always answering null to such a request.
+     * For other Secure Elements, the recommendation is to accept opening the basic channel
+     * on the default applet until another applet is selected on the basic channel. As there is no
+     * other way than a reset to select again the default applet, the implementation of the
+     * transport API should guarantee that the openBasicChannel(null) command will return
+     * null until a reset occurs.
+     * With previous release (V2.05) it was not possible to set P2 value, this value was always
+     * set to '00'.Except for specific needs it is recommended to keep P2 to '00'. It is
+     * recommended that the device allows all values for P2, however only the following values
+     * are mandatory: '00', '04', '08', '0C'(as defined in [2])
+     * The implementation of the underlying SELECT command within this method shall be
+     * based on ISO 7816-4 with following options:
+     * <ul>
+     * <li>CLA = '00'</li>
+     * <li>INS = 'A4'</li>
+     * <li>P1 = '04' (Select by DF name/application identifier)</li>
+     * </ul>
+     *
+     * The select response data can be retrieved with byte[] getSelectResponse().
+     * The API shall handle received status word as follow. If the status word indicates that the
+     * Secure Element was able to open a channel (e.g. status word '90 00' or status words
+     * referencing a warning in ISO-7816-4: '62 XX' or '63 XX') the API shall keep the
+     * channel opened and the next getSelectResponse() shall return the received status
+     * word.
+     * Other received status codes indicating that the Secure Element was able not to open a
+     * channel shall be considered as an error and the corresponding channel shall not be
+     * opened.
+     * The function without P2 as parameter is provided for backwards compatibility and will
+     * fall back to a select command with P2='00'.
+     *
+     * @param aid the AID of the Applet to be selected on this channel, as a
+     *            byte array, or null if no Applet is to be selected.
+     * @param p2 the P2 parameter of the SELECT APDU executed on this channel.
+     * @throws IOException if there is a communication problem to the reader or
+     *             the Secure Element.
+     * @throws IllegalStateException if the Secure Element session is used after
+     *             being closed.
+     * @throws IllegalArgumentException if the aid's length is not within 5 to
+     *             16 (inclusive).
+     * @throws SecurityException if the calling application cannot be granted
+     *             access to this AID or the default Applet on this
+     *             session.
+     * @throws NoSuchElementException if the AID on the Secure Element is not available or cannot be
+     *             selected.
+     * @throws UnsupportedOperationException if the given P2 parameter is not
+     *             supported by the device
+     * @return an instance of Channel if available or null.
+     */
+    public @Nullable Channel openBasicChannel(byte[] aid, byte p2) throws IOException {
+        if (!mService.isConnected()) {
+            throw new IllegalStateException("service not connected to system");
+        }
+
+        synchronized (mLock) {
+            try {
+                ISecureElementChannel channel = mSession.openBasicChannel(aid, p2,
+                        mReader.getSEService().getListener());
+                if (channel == null) {
+                    return null;
+                }
+                return new Channel(mService, this, channel);
+            } catch (RemoteException e) {
+                throw new IOException(e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * This method is provided to ease the development of mobile application and for compliancy
+     * with existing applications.
+     * This method is equivalent to openBasicChannel(aid, P2=0x00)
+     *
+     * @param aid the AID of the Applet to be selected on this channel, as a
+     *            byte array, or null if no Applet is to be selected.
+     * @throws IOException if there is a communication problem to the reader or
+     *             the Secure Element.
+     * @throws IllegalStateException if the Secure Element session is used after
+     *             being closed.
+     * @throws IllegalArgumentException if the aid's length is not within 5 to
+     *             16 (inclusive).
+     * @throws SecurityException if the calling application cannot be granted
+     *             access to this AID or the default Applet on this
+     *             session.
+     * @throws NoSuchElementException if the AID on the Secure Element is not available or cannot be
+     *             selected.
+     * @throws UnsupportedOperationException if the given P2 parameter is not
+     *             supported by the device
+     * @return an instance of Channel if available or null.
+     */
+    public @Nullable Channel openBasicChannel(byte[] aid) throws IOException {
+        return openBasicChannel(aid, (byte) 0x00);
+    }
+
+    /**
+     * Open a logical channel with the Secure Element, selecting the Applet represented by
+     * the given AID. If the AID is null, which means no Applet is to be selected on this
+     * channel, the default Applet is used. It's up to the Secure Element to choose which
+     * logical channel will be used.
+     * With previous release (V2.05) it was not possible to set P2 value, this value was always
+     * set to '00'.Except for specific needs it is recommended to keep P2 to '00'. It is
+     * recommended that the device allows all values for P2, however only the following values
+     * are mandatory: '00', '04', '08', '0C'(as defined in [2])
+     * The implementation of the underlying SELECT command within this method shall be
+     * based on ISO 7816-4 with following options:
+     *
+     * <ul>
+     * <li>CLA = '01' to '03', '40 to 4F'</li>
+     * <li>INS = 'A4'</li>
+     * <li>P1 = '04' (Select by DF name/application identifier)</li>
+     * </ul>
+     *
+     * The select response data can be retrieved with byte[] getSelectResponse().
+     * The API shall handle received status word as follow. If the status word indicates that the
+     * Secure Element was able to open a channel (e.g. status word '90 00' or status words
+     * referencing a warning in ISO-7816-4: '62 XX' or '63 XX') the API shall keep the
+     * channel opened and the next getSelectResponse() shall return the received status
+     * word.
+     * Other received status codes indicating that the Secure Element was able not to open a
+     * channel shall be considered as an error and the corresponding channel shall not be
+     * opened.
+     * In case of UICC it is recommended for the API to reject the opening of the logical
+     * channel without a specific AID, by always answering null to such a request.
+     * The function without P2 as parameter is provided for backwards compatibility and will
+     * fall back to a select command with P2=00.
+     *
+     * @param aid the AID of the Applet to be selected on this channel, as a
+     *            byte array.
+     * @param p2 the P2 parameter of the SELECT APDU executed on this channel.
+     * @throws IOException if there is a communication problem to the reader or
+     *             the Secure Element.
+     * @throws IllegalStateException if the Secure Element is used after being
+     *             closed.
+     * @throws IllegalArgumentException if the aid's length is not within 5 to
+     *             16 (inclusive).
+     * @throws SecurityException if the calling application cannot be granted
+     *             access to this AID or the default Applet on this
+     *             session.
+     * @throws NoSuchElementException if the AID on the Secure Element is not
+     *             available or cannot be selected or a logical channel is already
+     *             open to a non-multiselectable Applet.
+     * @throws UnsupportedOperationException if the given P2 parameter is not
+     *             supported by the device.
+     * @return an instance of Channel. Null if the Secure Element is unable to
+     *         provide a new logical channel.
+     */
+    public @Nullable Channel openLogicalChannel(byte[] aid, byte p2) throws IOException {
+
+        if ((mReader.getName().startsWith("SIM")) && (aid == null)) {
+            Log.e(TAG, "NULL AID not supported on " + mReader.getName());
+            return null;
+        }
+
+        if (!mService.isConnected()) {
+            throw new IllegalStateException("service not connected to system");
+        }
+        synchronized (mLock) {
+            try {
+                ISecureElementChannel channel = mSession.openLogicalChannel(
+                        aid,
+                        p2,
+                        mReader.getSEService().getListener());
+                if (channel == null) {
+                    return null;
+                }
+                return new Channel(mService, this, channel);
+            } catch (RemoteException e) {
+                throw new IOException(e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * This method is provided to ease the development of mobile application and for compliancy
+     * with existing applications.
+     * This method is equivalent to openLogicalChannel(aid, P2=0x00)
+     *
+     * @param aid the AID of the Applet to be selected on this channel, as a
+     *            byte array.
+     * @throws IOException if there is a communication problem to the reader or
+     *             the Secure Element.
+     * @throws IllegalStateException if the Secure Element is used after being
+     *             closed.
+     * @throws IllegalArgumentException if the aid's length is not within 5 to
+     *             16 (inclusive).
+     * @throws SecurityException if the calling application cannot be granted
+     *             access to this AID or the default Applet on this
+     *             session.
+     * @throws NoSuchElementException if the AID on the Secure Element is not
+     *             available or cannot be selected or a logical channel is already
+     *             open to a non-multiselectable Applet.
+     * @throws UnsupportedOperationException if the given P2 parameter is not
+     *             supported by the device.
+     * @return an instance of Channel. Null if the Secure Element is unable to
+     *         provide a new logical channel.
+     */
+    public @Nullable Channel openLogicalChannel(byte[] aid) throws IOException {
+        return openLogicalChannel(aid, (byte) 0x00);
+    }
+}
