From 367f41f8f61126c2ab34a34cc676756a9fc23ac2 Mon Sep 17 00:00:00 2001 From: Nick Pelly Date: Tue, 8 Mar 2011 11:43:30 -0800 Subject: Implement new NFC-EE API's as shared library (frameworks/base). Change-Id: I45c4eaf59ec78167fc236fdd59676465a5e1bcb7 --- nfc-extras/Android.mk | 11 ++ nfc-extras/com.android.nfc_extras.xml | 20 +++ .../com/android/nfc_extras/NfcAdapterExtras.java | 180 +++++++++++++++++++++ .../nfc_extras/NfcExecutionEnvironment.java | 125 ++++++++++++++ 4 files changed, 336 insertions(+) create mode 100644 nfc-extras/Android.mk create mode 100644 nfc-extras/com.android.nfc_extras.xml create mode 100644 nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java create mode 100644 nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java (limited to 'nfc-extras') diff --git a/nfc-extras/Android.mk b/nfc-extras/Android.mk new file mode 100644 index 0000000..330e2d4 --- /dev/null +++ b/nfc-extras/Android.mk @@ -0,0 +1,11 @@ +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_MODULE:= com.android.nfc_extras + +include $(BUILD_JAVA_LIBRARY) diff --git a/nfc-extras/com.android.nfc_extras.xml b/nfc-extras/com.android.nfc_extras.xml new file mode 100644 index 0000000..370145d --- /dev/null +++ b/nfc-extras/com.android.nfc_extras.xml @@ -0,0 +1,20 @@ + + + + + + diff --git a/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java b/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java new file mode 100644 index 0000000..cf38bd1 --- /dev/null +++ b/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2011 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. + */ + +package com.android.nfc_extras; + +import android.annotation.SdkConstant; +import android.annotation.SdkConstant.SdkConstantType; +import android.nfc.INfcAdapterExtras; +import android.nfc.NfcAdapter; +import android.os.RemoteException; +import android.util.Log; + +/** + * Provides additional methods on an {@link NfcAdapter} for Card Emulation + * and management of {@link NfcExecutionEnvironment}'s. + * + * There is a 1-1 relationship between an {@link NfcAdapterExtras} object and + * a {@link NfcAdapter} object. + */ +public final class NfcAdapterExtras { + private static final String TAG = "NfcAdapterExtras"; + + /** + * Broadcast Action: an RF field ON has been detected. + * + *

This is an unreliable signal, and will be removed. + *

+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission + * to receive. + */ + public static final String ACTION_RF_FIELD_ON_DETECTED = + "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED"; + + /** + * Broadcast Action: an RF field OFF has been detected. + * + *

This is an unreliable signal, and will be removed. + *

+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission + * to receive. + */ + public static final String ACTION_RF_FIELD_OFF_DETECTED = + "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED"; + + // protected by NfcAdapterExtras.class, and final after first construction + private static INfcAdapterExtras sService; + private static boolean sIsInitialized = false; + private static NfcAdapterExtras sSingleton; + private static NfcExecutionEnvironment sEmbeddedEe; + private static CardEmulationRoute sRouteOff; + private static CardEmulationRoute sRouteOnWhenScreenOn; + + /** + * Get the {@link NfcAdapterExtras} for the given {@link NfcAdapter}. + * + *

+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission. + * + * @param adapter a {@link NfcAdapter}, must not be null + * @return the {@link NfcAdapterExtras} object for the given {@link NfcAdapter} + */ + public static NfcAdapterExtras get(NfcAdapter adapter) { + synchronized(NfcAdapterExtras.class) { + if (!sIsInitialized) { + sIsInitialized = true; + sService = adapter.getNfcAdapterExtrasInterface(); + sEmbeddedEe = new NfcExecutionEnvironment(sService); + sRouteOff = new CardEmulationRoute(CardEmulationRoute.ROUTE_OFF, null); + sRouteOnWhenScreenOn = new CardEmulationRoute( + CardEmulationRoute.ROUTE_ON_WHEN_SCREEN_ON, sEmbeddedEe); + sSingleton = new NfcAdapterExtras(); + } + return sSingleton; + } + } + + private NfcAdapterExtras() {} + + /** + * Immutable data class that describes a card emulation route. + */ + public final static class CardEmulationRoute { + /** + * Card Emulation is turned off on this NfcAdapter. + *

This is the default routing state after boot. + */ + public static final int ROUTE_OFF = 1; + + /** + * Card Emulation is routed to {@link #nfcEe} only when the screen is on, + * otherwise it is turned off. + */ + public static final int ROUTE_ON_WHEN_SCREEN_ON = 2; + + /** + * A route such as {@link #ROUTE_OFF} or {@link #ROUTE_ON_WHEN_SCREEN_ON}. + */ + public final int route; + + /** + * The {@link NFcExecutionEnvironment} that is Card Emulation is routed to. + *

null if {@link #route} is {@link #ROUTE_OFF}, otherwise not null. + */ + public final NfcExecutionEnvironment nfcEe; + + public CardEmulationRoute(int route, NfcExecutionEnvironment nfcEe) { + if (route == ROUTE_OFF && nfcEe != null) { + throw new IllegalArgumentException("must not specifiy a NFC-EE with ROUTE_OFF"); + } else if (route != ROUTE_OFF && nfcEe == null) { + throw new IllegalArgumentException("must specifiy a NFC-EE for this route"); + } + this.route = route; + this.nfcEe = nfcEe; + } + } + + /** + * Get the routing state of this NFC EE. + * + *

+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission. + * + * @return + */ + public CardEmulationRoute getCardEmulationRoute() { + try { + int route = sService.getCardEmulationRoute(); + return route == CardEmulationRoute.ROUTE_OFF ? + sRouteOff : + sRouteOnWhenScreenOn; + } catch (RemoteException e) { + Log.e(TAG, "", e); + return sRouteOff; + } + } + + /** + * Set the routing state of this NFC EE. + * + *

This routing state is not persisted across reboot. + * + *

+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission. + * + * @param route a {@link #CardEmulationRoute} + */ + public void setCardEmulationRoute(CardEmulationRoute route) { + try { + sService.setCardEmulationRoute(route.route); + } catch (RemoteException e) { + Log.e(TAG, "", e); + } + } + + /** + * Get the {@link NfcExecutionEnvironment} that is embedded with the + * {@link NFcAdapter}. + * + *

+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission. + * + * @return a {@link NfcExecutionEnvironment}, or null if there is no embedded NFC-EE + */ + public NfcExecutionEnvironment getEmbeddedExecutionEnvironment() { + return sEmbeddedEe; + } +} diff --git a/nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java b/nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java new file mode 100644 index 0000000..3efe492 --- /dev/null +++ b/nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2011 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. + */ + +package com.android.nfc_extras; + +import java.io.IOException; + +import android.annotation.SdkConstant; +import android.annotation.SdkConstant.SdkConstantType; +import android.content.Context; +import android.nfc.INfcAdapterExtras; +import android.nfc.NfcAdapter; +import android.os.Binder; +import android.os.Bundle; +import android.os.IBinder; +import android.os.RemoteException; + +public class NfcExecutionEnvironment { + private final INfcAdapterExtras mService; + + /** + * Broadcast Action: An ISO-DEP AID was selected. + * + *

This happens as the result of a 'SELECT AID' command from an + * external NFC reader/writer. + * + *

Always contains the extra field {@link #EXTRA_AID} + * + *

+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission + * to receive. + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_AID_SELECTED = + "com.android.nfc_extras.action.AID_SELECTED"; + + /** + * Mandatory byte array extra field in {@link #ACTION_AID_SELECTED}. + * + *

Contains the AID selected. + * @hide + */ + public static final String EXTRA_AID = "com.android.nfc_extras.extra.AID"; + + NfcExecutionEnvironment(INfcAdapterExtras service) { + mService = service; + } + + /** + * Open the NFC Execution Environment on its contact interface. + * + *

Only one process may open the secure element at a time. If it is + * already open, an {@link IOException} is thrown. + * + *

All other NFC functionality is disabled while the NFC-EE is open + * on its contact interface, so make sure to call {@link #close} once complete. + * + *

+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission. + * + * @throws IOException if the NFC-EE is already open, or some other error occurs + */ + public void open() throws IOException { + try { + Bundle b = mService.open(new Binder()); + throwBundle(b); + } catch (RemoteException e) { + return; + } + } + + /** + * Close the NFC Execution Environment on its contact interface. + * + *

+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission. + * + * @throws IOException if the NFC-EE is already open, or some other error occurs + */ + public void close() throws IOException { + try { + throwBundle(mService.close()); + } catch (RemoteException e) { + return; + } + } + + /** + * Send raw commands to the NFC-EE and receive the response. + * + *

+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission. + * + * @throws IOException if the NFC-EE is not open, or some other error occurs + */ + public byte[] transceive(byte[] in) throws IOException { + Bundle b; + try { + b = mService.transceive(in); + } catch (RemoteException e) { + throw new IOException(e.getMessage()); + } + throwBundle(b); + return b.getByteArray("out"); + } + + private static void throwBundle(Bundle b) throws IOException { + if (b.getInt("e") == -1) { + throw new IOException(b.getString("m")); + } + } +} -- cgit v1.1