From a0f9f4b73bababd5c56e6a2b22b21bb14ac4514c Mon Sep 17 00:00:00 2001 From: George Chang Date: Tue, 12 Jan 2021 10:27:49 +0800 Subject: [PATCH] Added setAlwaysOn feature Add setAlwaysOn() system api. This API is used to request that the NFC service shall kept controller state on. Add isAlwaysOnEnabled() system api. This API is used to check setAlwaysOn is enabled or not. Add isAlwaysOnSupported() system api. This API is used to check setAlwaysOn is supported or not. Bug: 176212892 Test: manual Change-Id: If7ece9730c57838d870bb70cb2725919e75ef6c2 --- core/api/system-current.txt | 3 + core/java/android/nfc/INfcAdapter.aidl | 3 + core/java/android/nfc/NfcAdapter.java | 118 +++++++++++++++++++++++++ 3 files changed, 124 insertions(+) diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 08644489c2dbb..0d1e8575f7cf1 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -6925,7 +6925,10 @@ package android.nfc { method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enable(); method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableNdefPush(); method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableSecureNfc(boolean); + method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isAlwaysOnEnabled(); + method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isAlwaysOnSupported(); method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean removeNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler); + method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean setAlwaysOn(boolean); method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, int); field public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 1; // 0x1 } diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl index 0b2cfdd9ece31..bc3d5c4ab1aca 100644 --- a/core/java/android/nfc/INfcAdapter.aidl +++ b/core/java/android/nfc/INfcAdapter.aidl @@ -72,4 +72,7 @@ interface INfcAdapter boolean deviceSupportsNfcSecure(); boolean setNfcSecure(boolean enable); + boolean setAlwaysOn(boolean value); + boolean isAlwaysOnEnabled(); + boolean isAlwaysOnSupported(); } diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java index f05706b0e7106..e85eb935a8e7e 100644 --- a/core/java/android/nfc/NfcAdapter.java +++ b/core/java/android/nfc/NfcAdapter.java @@ -349,6 +349,22 @@ public final class NfcAdapter { public static final String EXTRA_HANDOVER_TRANSFER_STATUS = "android.nfc.extra.HANDOVER_TRANSFER_STATUS"; + /** @hide */ + public static final String ACTION_ALWAYS_ON_STATE_CHANGED = + "android.nfc.action.ALWAYS_ON_STATE_CHANGED"; + + /** + * Used as an int extra field in {@link #ACTION_ALWAYS_ON_STATE_CHANGED} + * intents to request the current power state. Possible values are: + * {@link #STATE_OFF}, + * {@link #STATE_TURNING_ON}, + * {@link #STATE_ON}, + * {@link #STATE_TURNING_OFF}, + * @hide + */ + public static final String EXTRA_ALWAYS_ON_STATE = + "android.nfc.extra.ALWAYS_ON_STATE"; + /** @hide */ public static final int HANDOVER_TRANSFER_STATUS_SUCCESS = 0; /** @hide */ @@ -2219,4 +2235,106 @@ public final class NfcAdapter { return mContext.getApplicationInfo().targetSdkVersion; } } + + /** + * Sets NFC controller always on feature. + *

This API is for the NFCC internal state management. It allows to discriminate + * the controller function from the NFC function by keeping the NFC Controller on without + * any NFC RF enabled if necessary. + *

This call is asynchronous. Listen for {@link #ACTION_ALWAYS_ON_STATE_CHANGED} + * broadcasts to find out when the operation is complete. + *

If this returns true, then either NFCC is already on, or + * a {@link #ACTION_ALWAYS_ON_STATE_CHANGED} broadcast will be sent to indicate + * a state transition. + * If this returns false, then there is some problem that prevents an attempt to turn NFCC on. + * @param value if true the NFCC will be kept on (with no RF enabled if NFC adapter is + * disabled), if false the NFCC will follow completely the Nfc adapter state. + * @throws UnsupportedOperationException if FEATURE_NFC is unavailable. + * @return void + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) + public boolean setAlwaysOn(boolean value) { + if (!sHasNfcFeature) { + throw new UnsupportedOperationException(); + } + try { + return sService.setAlwaysOn(value); + } catch (RemoteException e) { + attemptDeadServiceRecovery(e); + // Try one more time + if (sService == null) { + Log.e(TAG, "Failed to recover NFC Service."); + return false; + } + try { + return sService.setAlwaysOn(value); + } catch (RemoteException ee) { + Log.e(TAG, "Failed to recover NFC Service."); + } + return false; + } + } + + /** + * Checks NFC controller always on feature is enabled. + * + * @return True if NFC controller always on is enabled, false otherwise + * @throws UnsupportedOperationException if FEATURE_NFC is unavailable. + * @hide + */ + + @SystemApi + @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) + public boolean isAlwaysOnEnabled() { + try { + return sService.isAlwaysOnEnabled(); + } catch (RemoteException e) { + attemptDeadServiceRecovery(e); + // Try one more time + if (sService == null) { + Log.e(TAG, "Failed to recover NFC Service."); + return false; + } + try { + return sService.isAlwaysOnEnabled(); + } catch (RemoteException ee) { + Log.e(TAG, "Failed to recover NFC Service."); + } + return false; + } + } + + /** + * Checks if the device supports NFC controller always on functionality. + * + * @return True if device supports NFC controller always on, false otherwise + * @throws UnsupportedOperationException if FEATURE_NFC is unavailable. + * @hide + */ + + @SystemApi + @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) + public boolean isAlwaysOnSupported() { + if (!sHasNfcFeature) { + throw new UnsupportedOperationException(); + } + try { + return sService.isAlwaysOnSupported(); + } catch (RemoteException e) { + attemptDeadServiceRecovery(e); + // Try one more time + if (sService == null) { + Log.e(TAG, "Failed to recover NFC Service."); + return false; + } + try { + return sService.isAlwaysOnSupported(); + } catch (RemoteException ee) { + Log.e(TAG, "Failed to recover NFC Service."); + } + return false; + } + } }