diff --git a/omapi/java/Android.bp b/omapi/java/Android.bp
new file mode 100644
index 0000000..8d38da0
--- /dev/null
+++ b/omapi/java/Android.bp
@@ -0,0 +1,17 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+filegroup {
+    name: "framework-omapi-sources",
+    srcs: [
+        "**/*.java",
+        "**/*.aidl",
+    ],
+    visibility: ["//frameworks/base"],
+}
diff --git a/omapi/java/android/se/OWNERS b/omapi/java/android/se/OWNERS
new file mode 100644
index 0000000..5682fd3
--- /dev/null
+++ b/omapi/java/android/se/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 456592
+
+zachoverflow@google.com
+alisher@google.com
+jackcwyu@google.com
diff --git a/omapi/java/android/se/omapi/Channel.java b/omapi/java/android/se/omapi/Channel.java
new file mode 100644
index 0000000..90ce11a
--- /dev/null
+++ b/omapi/java/android/se/omapi/Channel.java
@@ -0,0 +1,257 @@
+/*
+ * 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.os.ServiceSpecificException;
+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 final class Channel implements java.nio.channels.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(@NonNull SEService service, @NonNull Session session,
+            @NonNull 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 (isOpen()) {
+            synchronized (mLock) {
+                try {
+                    mChannel.close();
+                } catch (Exception e) {
+                    Log.e(TAG, "Error closing channel", e);
+                }
+            }
+        }
+    }
+
+    /**
+     * Tells if this channel is open.
+     *
+     * @return <code>false</code> if the channel is closed or in case of an error.
+     *         <code>true</code> otherwise.
+     */
+    public boolean isOpen() {
+        if (!mService.isConnected()) {
+            Log.e(TAG, "service not connected to system");
+            return false;
+        }
+        try {
+            return !mChannel.isClosed();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Exception in isClosed()");
+            return false;
+        }
+    }
+
+    /**
+     * 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(@NonNull 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 (ServiceSpecificException e) {
+                throw new IOException(e.getMessage());
+            } catch (RemoteException e) {
+                throw new IllegalStateException(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> the 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 (ServiceSpecificException e) {
+            throw new IOException(e.getMessage());
+        } catch (RemoteException e) {
+            throw new IllegalStateException(e.getMessage());
+        }
+    }
+}
diff --git a/omapi/java/android/se/omapi/OWNERS b/omapi/java/android/se/omapi/OWNERS
new file mode 100644
index 0000000..5682fd3
--- /dev/null
+++ b/omapi/java/android/se/omapi/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 456592
+
+zachoverflow@google.com
+alisher@google.com
+jackcwyu@google.com
diff --git a/omapi/java/android/se/omapi/Reader.java b/omapi/java/android/se/omapi/Reader.java
new file mode 100644
index 0000000..3c2135d9
--- /dev/null
+++ b/omapi/java/android/se/omapi/Reader.java
@@ -0,0 +1,178 @@
+/*
+ * 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.RequiresPermission;
+import android.annotation.SystemApi;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+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 final 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(@NonNull SEService service, @NonNull String name, @NonNull ISecureElementReader reader) {
+        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 (ServiceSpecificException e) {
+                throw new IOException(e.getMessage());
+            } catch (RemoteException e) {
+                throw new IllegalStateException(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) { }
+        }
+    }
+
+    /**
+     * Close all the sessions opened on this reader and reset the reader.
+     * All the channels opened by all these sessions will be closed.
+     * @return <code>true</code> if reset success, <code>false</code> otherwise.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION)
+    public boolean reset() {
+        if (!mService.isConnected()) {
+            Log.e(TAG, "service is not connected");
+            return false;
+        }
+        synchronized (mLock) {
+            try {
+                closeSessions();
+                return mReader.reset();
+            } catch (RemoteException ignore) {
+                return false;
+            }
+        }
+    }
+}
diff --git a/omapi/java/android/se/omapi/SEService.java b/omapi/java/android/se/omapi/SEService.java
new file mode 100644
index 0000000..f42ca36
--- /dev/null
+++ b/omapi/java/android/se/omapi/SEService.java
@@ -0,0 +1,327 @@
+/*
+ * 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.BroadcastBehavior;
+import android.annotation.NonNull;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+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;
+import java.util.concurrent.Executor;
+
+/**
+ * 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 final class SEService {
+
+    /**
+     * Error code used with ServiceSpecificException.
+     * Thrown if there was an error communicating with the Secure Element.
+     *
+     * @hide
+     */
+    public static final int IO_ERROR = 1;
+
+    /**
+     * Error code used with ServiceSpecificException.
+     * Thrown if AID cannot be selected or is not available when opening
+     * a logical channel.
+     *
+     * @hide
+     */
+    public static final int NO_SUCH_ELEMENT_ERROR = 2;
+
+    /**
+     * Interface to send call-backs to the application when the service is connected.
+     */
+    public interface OnConnectedListener {
+        /**
+         * Called by the framework when the service is connected.
+         */
+        void onConnected();
+    }
+
+    /**
+     * Broadcast Action: Intent to notify if the secure element state is changed.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(registeredOnly = true, protectedBroadcast = true)
+    public static final String ACTION_SECURE_ELEMENT_STATE_CHANGED =
+            "android.se.omapi.action.SECURE_ELEMENT_STATE_CHANGED";
+
+    /**
+     * Mandatory extra containing the reader name of the state changed secure element.
+     *
+     * @see Reader#getName()
+     */
+    public static final String EXTRA_READER_NAME = "android.se.omapi.extra.READER_NAME";
+
+    /**
+     * Mandatory extra containing the connected state of the state changed secure element.
+     *
+     * True if the secure element is connected correctly, false otherwise.
+     */
+    public static final String EXTRA_READER_STATE = "android.se.omapi.extra.READER_STATE";
+
+    /**
+     * Listener object that allows the notification of the caller if this
+     * SEService could be bound to the backend.
+     */
+    private class SEListener extends ISecureElementListener.Stub {
+        public OnConnectedListener mListener = null;
+        public Executor mExecutor = null;
+
+        @Override
+        public IBinder asBinder() {
+            return this;
+        }
+
+        public void onConnected() {
+            if (mListener != null && mExecutor != null) {
+                mExecutor.execute(new Runnable() {
+                    @Override
+                    public void run() {
+                        mListener.onConnected();
+                    }
+                });
+            }
+        }
+    }
+    private SEListener mSEListener = new SEListener();
+
+    private static final String TAG = "OMAPI.SEService";
+
+    private static final String UICC_TERMINAL = "SIM";
+
+    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>();
+
+    /**
+     * 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
+     * onConnected() method called when the connection actually happen.
+     *
+     * @param context
+     *            the context of the calling application. Cannot be
+     *            <code>null</code>.
+     * @param listener
+     *            a OnConnectedListener object.
+     * @param executor
+     *            an Executor which will be used when invoking the callback.
+     */
+    public SEService(@NonNull Context context, @NonNull Executor executor,
+            @NonNull OnConnectedListener listener) {
+
+        if (context == null || listener == null || executor == null) {
+            throw new NullPointerException("Arguments must not be null");
+        }
+
+        mContext = context;
+        mSEListener.mListener = listener;
+        mSEListener.mExecutor = executor;
+
+        mConnection = new ServiceConnection() {
+
+            public synchronized void onServiceConnected(
+                    ComponentName className, IBinder service) {
+
+                mSecureElementService = ISecureElementService.Stub.asInterface(service);
+                if (mSEListener != null) {
+                    mSEListener.onConnected();
+                }
+                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 an array 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 An array of Readers. If there are no readers the returned array
+     * is of length 0.
+     */
+    public @NonNull Reader[] getReaders() {
+        loadReaders();
+
+        return mReaders.values().toArray(new Reader[0]);
+    }
+
+    /**
+      * Obtain a UICC Reader instance with specific slot number from the SecureElementService
+      *
+      * @param slotNumber The index of the uicc slot. The index starts from 1.
+      * @throws IllegalArgumentException if the reader object corresponding to the uiccSlotNumber
+      *         is not exist.
+      * @return A Reader object for this uicc slot.
+      */
+    public @NonNull Reader getUiccReader(int slotNumber) {
+        if (slotNumber < 1) {
+            throw new IllegalArgumentException("slotNumber should be larger than 0");
+        }
+        loadReaders();
+
+        String readerName = UICC_TERMINAL + slotNumber;
+        Reader reader = mReaders.get(readerName);
+
+        if (reader == null) {
+            throw new IllegalArgumentException("Reader:" + readerName + " doesn't exist");
+        }
+
+        return reader;
+    }
+
+    /**
+     * 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.
+     * This method should be called when connection to the Secure Element is not needed
+     * or 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 @NonNull String getVersion() {
+        return "3.3";
+    }
+
+    @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());
+        }
+    }
+
+    /**
+     * Load available Secure Element Readers
+     */
+    private void loadReaders() {
+        if (mSecureElementService == null) {
+            throw new IllegalStateException("service not connected to system");
+        }
+        String[] readerNames;
+        try {
+            readerNames = mSecureElementService.getReaders();
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+
+        for (String readerName : readerNames) {
+            if (mReaders.get(readerName) == null) {
+                try {
+                    mReaders.put(readerName, new Reader(this, readerName,
+                            getReader(readerName)));
+                } catch (Exception e) {
+                    Log.e(TAG, "Error adding Reader: " + readerName, e);
+                }
+            }
+        }
+    }
+}
diff --git a/omapi/java/android/se/omapi/Session.java b/omapi/java/android/se/omapi/Session.java
new file mode 100644
index 0000000..d5f8c82
--- /dev/null
+++ b/omapi/java/android/se/omapi/Session.java
@@ -0,0 +1,361 @@
+/*
+ * 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.os.ServiceSpecificException;
+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 final 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(@NonNull SEService service, @NonNull ISecureElementSession session,
+            @NonNull 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(@Nullable byte[] aid, @Nullable 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 (ServiceSpecificException e) {
+                if (e.errorCode == SEService.IO_ERROR) {
+                    throw new IOException(e.getMessage());
+                } else if (e.errorCode == SEService.NO_SUCH_ELEMENT_ERROR) {
+                    throw new NoSuchElementException(e.getMessage());
+                } else {
+                    throw new IllegalStateException(e.getMessage());
+                }
+            } catch (RemoteException e) {
+                throw new IllegalStateException(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(@Nullable 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(@Nullable byte[] aid, @Nullable byte p2)
+            throws IOException {
+        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 (ServiceSpecificException e) {
+                if (e.errorCode == SEService.IO_ERROR) {
+                    throw new IOException(e.getMessage());
+                } else if (e.errorCode == SEService.NO_SUCH_ELEMENT_ERROR) {
+                    throw new NoSuchElementException(e.getMessage());
+                } else {
+                    throw new IllegalStateException(e.getMessage());
+                }
+            } catch (RemoteException e) {
+                throw new IllegalStateException(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(@Nullable byte[] aid) throws IOException {
+        return openLogicalChannel(aid, (byte) 0x00);
+    }
+}
