Merge "decouple HCE from FEATURE_NFC" into nyc-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
b8eb2c5608
@@ -290,6 +290,7 @@ public final class NfcAdapter {
|
|||||||
|
|
||||||
// Guarded by NfcAdapter.class
|
// Guarded by NfcAdapter.class
|
||||||
static boolean sIsInitialized = false;
|
static boolean sIsInitialized = false;
|
||||||
|
static boolean sHasNfcFeature;
|
||||||
|
|
||||||
// Final after first constructor, except for
|
// Final after first constructor, except for
|
||||||
// attemptDeadServiceRecovery() when NFC crashes - we accept a best effort
|
// attemptDeadServiceRecovery() when NFC crashes - we accept a best effort
|
||||||
@@ -433,6 +434,26 @@ public final class NfcAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to check if this device is NFC HCE capable, by checking for
|
||||||
|
* FEATURE_NFC_HOST_CARD_EMULATION and/or FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
|
||||||
|
* but without using a context.
|
||||||
|
*/
|
||||||
|
private static boolean hasNfcHceFeature() {
|
||||||
|
IPackageManager pm = ActivityThread.getPackageManager();
|
||||||
|
if (pm == null) {
|
||||||
|
Log.e(TAG, "Cannot get package manager, assuming no NFC feature");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION, 0)
|
||||||
|
|| pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF, 0);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(TAG, "Package manager query failed, assuming no NFC feature", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the NfcAdapter for application context,
|
* Returns the NfcAdapter for application context,
|
||||||
* or throws if NFC is not available.
|
* or throws if NFC is not available.
|
||||||
@@ -440,36 +461,39 @@ public final class NfcAdapter {
|
|||||||
*/
|
*/
|
||||||
public static synchronized NfcAdapter getNfcAdapter(Context context) {
|
public static synchronized NfcAdapter getNfcAdapter(Context context) {
|
||||||
if (!sIsInitialized) {
|
if (!sIsInitialized) {
|
||||||
|
sHasNfcFeature = hasNfcFeature();
|
||||||
|
boolean hasHceFeature = hasNfcHceFeature();
|
||||||
/* is this device meant to have NFC */
|
/* is this device meant to have NFC */
|
||||||
if (!hasNfcFeature()) {
|
if (!sHasNfcFeature && !hasHceFeature) {
|
||||||
Log.v(TAG, "this device does not have NFC support");
|
Log.v(TAG, "this device does not have NFC support");
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
sService = getServiceInterface();
|
sService = getServiceInterface();
|
||||||
if (sService == null) {
|
if (sService == null) {
|
||||||
Log.e(TAG, "could not retrieve NFC service");
|
Log.e(TAG, "could not retrieve NFC service");
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
try {
|
if (sHasNfcFeature) {
|
||||||
sTagService = sService.getNfcTagInterface();
|
try {
|
||||||
} catch (RemoteException e) {
|
sTagService = sService.getNfcTagInterface();
|
||||||
Log.e(TAG, "could not retrieve NFC Tag service");
|
} catch (RemoteException e) {
|
||||||
throw new UnsupportedOperationException();
|
Log.e(TAG, "could not retrieve NFC Tag service");
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (hasHceFeature) {
|
||||||
try {
|
try {
|
||||||
sCardEmulationService = sService.getNfcCardEmulationInterface();
|
sNfcFCardEmulationService = sService.getNfcFCardEmulationInterface();
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "could not retrieve card emulation service");
|
Log.e(TAG, "could not retrieve NFC-F card emulation service");
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
try {
|
sCardEmulationService = sService.getNfcCardEmulationInterface();
|
||||||
sNfcFCardEmulationService = sService.getNfcFCardEmulationInterface();
|
} catch (RemoteException e) {
|
||||||
} catch (RemoteException e) {
|
Log.e(TAG, "could not retrieve card emulation service");
|
||||||
Log.e(TAG, "could not retrieve NFC-F card emulation service");
|
throw new UnsupportedOperationException();
|
||||||
throw new UnsupportedOperationException();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sIsInitialized = true;
|
sIsInitialized = true;
|
||||||
@@ -837,8 +861,14 @@ public final class NfcAdapter {
|
|||||||
*
|
*
|
||||||
* @param uris an array of Uri(s) to push over Android Beam
|
* @param uris an array of Uri(s) to push over Android Beam
|
||||||
* @param activity activity for which the Uri(s) will be pushed
|
* @param activity activity for which the Uri(s) will be pushed
|
||||||
|
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||||
*/
|
*/
|
||||||
public void setBeamPushUris(Uri[] uris, Activity activity) {
|
public void setBeamPushUris(Uri[] uris, Activity activity) {
|
||||||
|
synchronized (NfcAdapter.class) {
|
||||||
|
if (!sHasNfcFeature) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (activity == null) {
|
if (activity == null) {
|
||||||
throw new NullPointerException("activity cannot be null");
|
throw new NullPointerException("activity cannot be null");
|
||||||
}
|
}
|
||||||
@@ -913,8 +943,14 @@ public final class NfcAdapter {
|
|||||||
*
|
*
|
||||||
* @param callback callback, or null to disable
|
* @param callback callback, or null to disable
|
||||||
* @param activity activity for which the Uri(s) will be pushed
|
* @param activity activity for which the Uri(s) will be pushed
|
||||||
|
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||||
*/
|
*/
|
||||||
public void setBeamPushUrisCallback(CreateBeamUrisCallback callback, Activity activity) {
|
public void setBeamPushUrisCallback(CreateBeamUrisCallback callback, Activity activity) {
|
||||||
|
synchronized (NfcAdapter.class) {
|
||||||
|
if (!sHasNfcFeature) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (activity == null) {
|
if (activity == null) {
|
||||||
throw new NullPointerException("activity cannot be null");
|
throw new NullPointerException("activity cannot be null");
|
||||||
}
|
}
|
||||||
@@ -991,9 +1027,15 @@ public final class NfcAdapter {
|
|||||||
* @param activities optional additional activities, however we strongly recommend
|
* @param activities optional additional activities, however we strongly recommend
|
||||||
* to only register one at a time, and to do so in that activity's
|
* to only register one at a time, and to do so in that activity's
|
||||||
* {@link Activity#onCreate}
|
* {@link Activity#onCreate}
|
||||||
|
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||||
*/
|
*/
|
||||||
public void setNdefPushMessage(NdefMessage message, Activity activity,
|
public void setNdefPushMessage(NdefMessage message, Activity activity,
|
||||||
Activity ... activities) {
|
Activity ... activities) {
|
||||||
|
synchronized (NfcAdapter.class) {
|
||||||
|
if (!sHasNfcFeature) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
int targetSdkVersion = getSdkVersion();
|
int targetSdkVersion = getSdkVersion();
|
||||||
try {
|
try {
|
||||||
if (activity == null) {
|
if (activity == null) {
|
||||||
@@ -1023,6 +1065,11 @@ public final class NfcAdapter {
|
|||||||
*/
|
*/
|
||||||
@SystemApi
|
@SystemApi
|
||||||
public void setNdefPushMessage(NdefMessage message, Activity activity, int flags) {
|
public void setNdefPushMessage(NdefMessage message, Activity activity, int flags) {
|
||||||
|
synchronized (NfcAdapter.class) {
|
||||||
|
if (!sHasNfcFeature) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (activity == null) {
|
if (activity == null) {
|
||||||
throw new NullPointerException("activity cannot be null");
|
throw new NullPointerException("activity cannot be null");
|
||||||
}
|
}
|
||||||
@@ -1093,9 +1140,15 @@ public final class NfcAdapter {
|
|||||||
* @param activities optional additional activities, however we strongly recommend
|
* @param activities optional additional activities, however we strongly recommend
|
||||||
* to only register one at a time, and to do so in that activity's
|
* to only register one at a time, and to do so in that activity's
|
||||||
* {@link Activity#onCreate}
|
* {@link Activity#onCreate}
|
||||||
|
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||||
*/
|
*/
|
||||||
public void setNdefPushMessageCallback(CreateNdefMessageCallback callback, Activity activity,
|
public void setNdefPushMessageCallback(CreateNdefMessageCallback callback, Activity activity,
|
||||||
Activity ... activities) {
|
Activity ... activities) {
|
||||||
|
synchronized (NfcAdapter.class) {
|
||||||
|
if (!sHasNfcFeature) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
int targetSdkVersion = getSdkVersion();
|
int targetSdkVersion = getSdkVersion();
|
||||||
try {
|
try {
|
||||||
if (activity == null) {
|
if (activity == null) {
|
||||||
@@ -1167,9 +1220,15 @@ public final class NfcAdapter {
|
|||||||
* @param activities optional additional activities, however we strongly recommend
|
* @param activities optional additional activities, however we strongly recommend
|
||||||
* to only register one at a time, and to do so in that activity's
|
* to only register one at a time, and to do so in that activity's
|
||||||
* {@link Activity#onCreate}
|
* {@link Activity#onCreate}
|
||||||
|
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||||
*/
|
*/
|
||||||
public void setOnNdefPushCompleteCallback(OnNdefPushCompleteCallback callback,
|
public void setOnNdefPushCompleteCallback(OnNdefPushCompleteCallback callback,
|
||||||
Activity activity, Activity ... activities) {
|
Activity activity, Activity ... activities) {
|
||||||
|
synchronized (NfcAdapter.class) {
|
||||||
|
if (!sHasNfcFeature) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
int targetSdkVersion = getSdkVersion();
|
int targetSdkVersion = getSdkVersion();
|
||||||
try {
|
try {
|
||||||
if (activity == null) {
|
if (activity == null) {
|
||||||
@@ -1226,9 +1285,15 @@ public final class NfcAdapter {
|
|||||||
* @param techLists the tech lists used to perform matching for dispatching of the
|
* @param techLists the tech lists used to perform matching for dispatching of the
|
||||||
* {@link NfcAdapter#ACTION_TECH_DISCOVERED} intent
|
* {@link NfcAdapter#ACTION_TECH_DISCOVERED} intent
|
||||||
* @throws IllegalStateException if the Activity is not currently in the foreground
|
* @throws IllegalStateException if the Activity is not currently in the foreground
|
||||||
|
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||||
*/
|
*/
|
||||||
public void enableForegroundDispatch(Activity activity, PendingIntent intent,
|
public void enableForegroundDispatch(Activity activity, PendingIntent intent,
|
||||||
IntentFilter[] filters, String[][] techLists) {
|
IntentFilter[] filters, String[][] techLists) {
|
||||||
|
synchronized (NfcAdapter.class) {
|
||||||
|
if (!sHasNfcFeature) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (activity == null || intent == null) {
|
if (activity == null || intent == null) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
}
|
}
|
||||||
@@ -1262,8 +1327,14 @@ public final class NfcAdapter {
|
|||||||
*
|
*
|
||||||
* @param activity the Activity to disable dispatch to
|
* @param activity the Activity to disable dispatch to
|
||||||
* @throws IllegalStateException if the Activity has already been paused
|
* @throws IllegalStateException if the Activity has already been paused
|
||||||
|
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||||
*/
|
*/
|
||||||
public void disableForegroundDispatch(Activity activity) {
|
public void disableForegroundDispatch(Activity activity) {
|
||||||
|
synchronized (NfcAdapter.class) {
|
||||||
|
if (!sHasNfcFeature) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
ActivityThread.currentActivityThread().unregisterOnActivityPausedListener(activity,
|
ActivityThread.currentActivityThread().unregisterOnActivityPausedListener(activity,
|
||||||
mForegroundDispatchListener);
|
mForegroundDispatchListener);
|
||||||
disableForegroundDispatchInternal(activity, false);
|
disableForegroundDispatchInternal(activity, false);
|
||||||
@@ -1308,9 +1379,15 @@ public final class NfcAdapter {
|
|||||||
* @param callback the callback to be called when a tag is discovered
|
* @param callback the callback to be called when a tag is discovered
|
||||||
* @param flags Flags indicating poll technologies and other optional parameters
|
* @param flags Flags indicating poll technologies and other optional parameters
|
||||||
* @param extras Additional extras for configuring reader mode.
|
* @param extras Additional extras for configuring reader mode.
|
||||||
|
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||||
*/
|
*/
|
||||||
public void enableReaderMode(Activity activity, ReaderCallback callback, int flags,
|
public void enableReaderMode(Activity activity, ReaderCallback callback, int flags,
|
||||||
Bundle extras) {
|
Bundle extras) {
|
||||||
|
synchronized (NfcAdapter.class) {
|
||||||
|
if (!sHasNfcFeature) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
mNfcActivityManager.enableReaderMode(activity, callback, flags, extras);
|
mNfcActivityManager.enableReaderMode(activity, callback, flags, extras);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1320,8 +1397,14 @@ public final class NfcAdapter {
|
|||||||
* all supported tag technologies.
|
* all supported tag technologies.
|
||||||
*
|
*
|
||||||
* @param activity the Activity that currently has reader mode enabled
|
* @param activity the Activity that currently has reader mode enabled
|
||||||
|
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||||
*/
|
*/
|
||||||
public void disableReaderMode(Activity activity) {
|
public void disableReaderMode(Activity activity) {
|
||||||
|
synchronized (NfcAdapter.class) {
|
||||||
|
if (!sHasNfcFeature) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
mNfcActivityManager.disableReaderMode(activity);
|
mNfcActivityManager.disableReaderMode(activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1348,8 +1431,14 @@ public final class NfcAdapter {
|
|||||||
*
|
*
|
||||||
* @param activity the current foreground Activity that has registered data to share
|
* @param activity the current foreground Activity that has registered data to share
|
||||||
* @return whether the Beam animation was successfully invoked
|
* @return whether the Beam animation was successfully invoked
|
||||||
|
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||||
*/
|
*/
|
||||||
public boolean invokeBeam(Activity activity) {
|
public boolean invokeBeam(Activity activity) {
|
||||||
|
synchronized (NfcAdapter.class) {
|
||||||
|
if (!sHasNfcFeature) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (activity == null) {
|
if (activity == null) {
|
||||||
throw new NullPointerException("activity may not be null.");
|
throw new NullPointerException("activity may not be null.");
|
||||||
}
|
}
|
||||||
@@ -1403,10 +1492,16 @@ public final class NfcAdapter {
|
|||||||
* @param activity foreground activity
|
* @param activity foreground activity
|
||||||
* @param message a NDEF Message to push over NFC
|
* @param message a NDEF Message to push over NFC
|
||||||
* @throws IllegalStateException if the activity is not currently in the foreground
|
* @throws IllegalStateException if the activity is not currently in the foreground
|
||||||
|
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||||
* @deprecated use {@link #setNdefPushMessage} instead
|
* @deprecated use {@link #setNdefPushMessage} instead
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void enableForegroundNdefPush(Activity activity, NdefMessage message) {
|
public void enableForegroundNdefPush(Activity activity, NdefMessage message) {
|
||||||
|
synchronized (NfcAdapter.class) {
|
||||||
|
if (!sHasNfcFeature) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (activity == null || message == null) {
|
if (activity == null || message == null) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
}
|
}
|
||||||
@@ -1431,10 +1526,16 @@ public final class NfcAdapter {
|
|||||||
*
|
*
|
||||||
* @param activity the Foreground activity
|
* @param activity the Foreground activity
|
||||||
* @throws IllegalStateException if the Activity has already been paused
|
* @throws IllegalStateException if the Activity has already been paused
|
||||||
|
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||||
* @deprecated use {@link #setNdefPushMessage} instead
|
* @deprecated use {@link #setNdefPushMessage} instead
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void disableForegroundNdefPush(Activity activity) {
|
public void disableForegroundNdefPush(Activity activity) {
|
||||||
|
synchronized (NfcAdapter.class) {
|
||||||
|
if (!sHasNfcFeature) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (activity == null) {
|
if (activity == null) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
}
|
}
|
||||||
@@ -1451,6 +1552,9 @@ public final class NfcAdapter {
|
|||||||
*/
|
*/
|
||||||
@SystemApi
|
@SystemApi
|
||||||
public boolean enableNdefPush() {
|
public boolean enableNdefPush() {
|
||||||
|
if (!sHasNfcFeature) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return sService.enableNdefPush();
|
return sService.enableNdefPush();
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -1466,6 +1570,11 @@ public final class NfcAdapter {
|
|||||||
*/
|
*/
|
||||||
@SystemApi
|
@SystemApi
|
||||||
public boolean disableNdefPush() {
|
public boolean disableNdefPush() {
|
||||||
|
synchronized (NfcAdapter.class) {
|
||||||
|
if (!sHasNfcFeature) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return sService.disableNdefPush();
|
return sService.disableNdefPush();
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -1496,8 +1605,14 @@ public final class NfcAdapter {
|
|||||||
*
|
*
|
||||||
* @see android.provider.Settings#ACTION_NFCSHARING_SETTINGS
|
* @see android.provider.Settings#ACTION_NFCSHARING_SETTINGS
|
||||||
* @return true if NDEF Push feature is enabled
|
* @return true if NDEF Push feature is enabled
|
||||||
|
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
|
||||||
*/
|
*/
|
||||||
public boolean isNdefPushEnabled() {
|
public boolean isNdefPushEnabled() {
|
||||||
|
synchronized (NfcAdapter.class) {
|
||||||
|
if (!sHasNfcFeature) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return sService.isNdefPushEnabled();
|
return sService.isNdefPushEnabled();
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -1622,6 +1737,11 @@ public final class NfcAdapter {
|
|||||||
@SystemApi
|
@SystemApi
|
||||||
public boolean addNfcUnlockHandler(final NfcUnlockHandler unlockHandler,
|
public boolean addNfcUnlockHandler(final NfcUnlockHandler unlockHandler,
|
||||||
String[] tagTechnologies) {
|
String[] tagTechnologies) {
|
||||||
|
synchronized (NfcAdapter.class) {
|
||||||
|
if (!sHasNfcFeature) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
// If there are no tag technologies, don't bother adding unlock handler
|
// If there are no tag technologies, don't bother adding unlock handler
|
||||||
if (tagTechnologies.length == 0) {
|
if (tagTechnologies.length == 0) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1665,6 +1785,11 @@ public final class NfcAdapter {
|
|||||||
*/
|
*/
|
||||||
@SystemApi
|
@SystemApi
|
||||||
public boolean removeNfcUnlockHandler(NfcUnlockHandler unlockHandler) {
|
public boolean removeNfcUnlockHandler(NfcUnlockHandler unlockHandler) {
|
||||||
|
synchronized (NfcAdapter.class) {
|
||||||
|
if (!sHasNfcFeature) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
if (mNfcUnlockHandlers.containsKey(unlockHandler)) {
|
if (mNfcUnlockHandlers.containsKey(unlockHandler)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user