NfcAdapterExtras.java revision ab8f48c2ee524f67e5c3cab5846119e6c8a645b5
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.nfc_extras; 18 19import android.annotation.SdkConstant; 20import android.annotation.SdkConstant.SdkConstantType; 21import android.nfc.ApduList; 22import android.nfc.INfcAdapterExtras; 23import android.nfc.NfcAdapter; 24import android.os.RemoteException; 25import android.util.Log; 26 27/** 28 * Provides additional methods on an {@link NfcAdapter} for Card Emulation 29 * and management of {@link NfcExecutionEnvironment}'s. 30 * 31 * There is a 1-1 relationship between an {@link NfcAdapterExtras} object and 32 * a {@link NfcAdapter} object. 33 */ 34public final class NfcAdapterExtras { 35 private static final String TAG = "NfcAdapterExtras"; 36 37 /** 38 * Broadcast Action: an RF field ON has been detected. 39 * 40 * <p class="note">This is an unreliable signal, and will be removed. 41 * <p class="note"> 42 * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission 43 * to receive. 44 */ 45 public static final String ACTION_RF_FIELD_ON_DETECTED = 46 "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED"; 47 48 /** 49 * Broadcast Action: an RF field OFF has been detected. 50 * 51 * <p class="note">This is an unreliable signal, and will be removed. 52 * <p class="note"> 53 * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission 54 * to receive. 55 */ 56 public static final String ACTION_RF_FIELD_OFF_DETECTED = 57 "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED"; 58 59 // protected by NfcAdapterExtras.class, and final after first construction 60 private static INfcAdapterExtras sService; 61 private static NfcAdapterExtras sSingleton; 62 private static NfcExecutionEnvironment sEmbeddedEe; 63 private static CardEmulationRoute sRouteOff; 64 private static CardEmulationRoute sRouteOnWhenScreenOn; 65 66 /** 67 * Get the {@link NfcAdapterExtras} for the given {@link NfcAdapter}. 68 * 69 * <p class="note"> 70 * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission. 71 * 72 * @param adapter a {@link NfcAdapter}, must not be null 73 * @return the {@link NfcAdapterExtras} object for the given {@link NfcAdapter} 74 */ 75 public static NfcAdapterExtras get(NfcAdapter adapter) { 76 synchronized(NfcAdapterExtras.class) { 77 if (sSingleton == null) { 78 try { 79 sService = adapter.getNfcAdapterExtrasInterface(); 80 sEmbeddedEe = new NfcExecutionEnvironment(sService); 81 sRouteOff = new CardEmulationRoute(CardEmulationRoute.ROUTE_OFF, null); 82 sRouteOnWhenScreenOn = new CardEmulationRoute( 83 CardEmulationRoute.ROUTE_ON_WHEN_SCREEN_ON, sEmbeddedEe); 84 sSingleton = new NfcAdapterExtras(); 85 } finally { 86 if (sSingleton == null) { 87 sService = null; 88 sEmbeddedEe = null; 89 sRouteOff = null; 90 sRouteOnWhenScreenOn = null; 91 } 92 } 93 } 94 return sSingleton; 95 } 96 } 97 98 private NfcAdapterExtras() {} 99 100 /** 101 * Immutable data class that describes a card emulation route. 102 */ 103 public final static class CardEmulationRoute { 104 /** 105 * Card Emulation is turned off on this NfcAdapter. 106 * <p>This is the default routing state after boot. 107 */ 108 public static final int ROUTE_OFF = 1; 109 110 /** 111 * Card Emulation is routed to {@link #nfcEe} only when the screen is on, 112 * otherwise it is turned off. 113 */ 114 public static final int ROUTE_ON_WHEN_SCREEN_ON = 2; 115 116 /** 117 * A route such as {@link #ROUTE_OFF} or {@link #ROUTE_ON_WHEN_SCREEN_ON}. 118 */ 119 public final int route; 120 121 /** 122 * The {@link NFcExecutionEnvironment} that is Card Emulation is routed to. 123 * <p>null if {@link #route} is {@link #ROUTE_OFF}, otherwise not null. 124 */ 125 public final NfcExecutionEnvironment nfcEe; 126 127 public CardEmulationRoute(int route, NfcExecutionEnvironment nfcEe) { 128 if (route == ROUTE_OFF && nfcEe != null) { 129 throw new IllegalArgumentException("must not specifiy a NFC-EE with ROUTE_OFF"); 130 } else if (route != ROUTE_OFF && nfcEe == null) { 131 throw new IllegalArgumentException("must specifiy a NFC-EE for this route"); 132 } 133 this.route = route; 134 this.nfcEe = nfcEe; 135 } 136 } 137 138 /** 139 * Get the routing state of this NFC EE. 140 * 141 * <p class="note"> 142 * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission. 143 * 144 * @return 145 */ 146 public CardEmulationRoute getCardEmulationRoute() { 147 try { 148 int route = sService.getCardEmulationRoute(); 149 return route == CardEmulationRoute.ROUTE_OFF ? 150 sRouteOff : 151 sRouteOnWhenScreenOn; 152 } catch (RemoteException e) { 153 Log.e(TAG, "", e); 154 return sRouteOff; 155 } 156 } 157 158 /** 159 * Set the routing state of this NFC EE. 160 * 161 * <p>This routing state is not persisted across reboot. 162 * 163 * <p class="note"> 164 * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission. 165 * 166 * @param route a {@link #CardEmulationRoute} 167 */ 168 public void setCardEmulationRoute(CardEmulationRoute route) { 169 try { 170 sService.setCardEmulationRoute(route.route); 171 } catch (RemoteException e) { 172 Log.e(TAG, "", e); 173 } 174 } 175 176 /** 177 * Get the {@link NfcExecutionEnvironment} that is embedded with the 178 * {@link NFcAdapter}. 179 * 180 * <p class="note"> 181 * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission. 182 * 183 * @return a {@link NfcExecutionEnvironment}, or null if there is no embedded NFC-EE 184 */ 185 public NfcExecutionEnvironment getEmbeddedExecutionEnvironment() { 186 return sEmbeddedEe; 187 } 188 189 public void registerTearDownApdus(String packageName, ApduList apdus) { 190 try { 191 sService.registerTearDownApdus(packageName, apdus); 192 } catch (RemoteException e) { 193 Log.e(TAG, "", e); 194 } 195 } 196 197 public void unregisterTearDownApdus(String packageName) { 198 try { 199 sService.unregisterTearDownApdus(packageName); 200 } catch (RemoteException e) { 201 Log.e(TAG, "", e); 202 } 203 } 204} 205