diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 2d8a82e93d..f751efc419 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -425,6 +425,13 @@
default
+
+ android.hardware.nfc
+
+ INfc
+ default
+
+
android.hardware.oemlock
1.0
diff --git a/nfc/OWNERS b/nfc/OWNERS
new file mode 100644
index 0000000000..78672046e4
--- /dev/null
+++ b/nfc/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 48448
+alisher@google.com
+georgekgchang@google.com
+jackcwyu@google.com
+
+
diff --git a/nfc/aidl/Android.bp b/nfc/aidl/Android.bp
new file mode 100644
index 0000000000..d390c7ea05
--- /dev/null
+++ b/nfc/aidl/Android.bp
@@ -0,0 +1,34 @@
+// Copyright (C) 2021 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.
+
+aidl_interface {
+ name: "android.hardware.nfc",
+ vendor_available: true,
+ srcs: ["android/hardware/nfc/*.aidl"],
+ stability: "vintf",
+ backend: {
+ cpp: {
+ enabled: false,
+ },
+ java: {
+ sdk_version: "module_current",
+ enabled: false,
+ },
+ ndk: {
+ vndk: {
+ enabled: true,
+ },
+ },
+ },
+}
diff --git a/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/INfc.aidl b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/INfc.aidl
new file mode 100644
index 0000000000..7a0ae54963
--- /dev/null
+++ b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/INfc.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m -update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.nfc;
+@VintfStability
+interface INfc {
+ void open(in android.hardware.nfc.INfcClientCallback clientCallback);
+ void close(in android.hardware.nfc.NfcCloseType type);
+ void coreInitialized();
+ void factoryReset();
+ android.hardware.nfc.NfcConfig getConfig();
+ void powerCycle();
+ void preDiscover();
+ int write(in byte[] data);
+ void setEnableVerboseLogging(in boolean enable);
+ boolean isVerboseLoggingEnabled();
+}
diff --git a/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/INfcClientCallback.aidl b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/INfcClientCallback.aidl
new file mode 100644
index 0000000000..8150e818d7
--- /dev/null
+++ b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/INfcClientCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m -update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.nfc;
+@VintfStability
+interface INfcClientCallback {
+ void sendData(in byte[] data);
+ void sendEvent(in android.hardware.nfc.NfcEvent event, in android.hardware.nfc.NfcStatus status);
+}
diff --git a/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/NfcCloseType.aidl b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/NfcCloseType.aidl
new file mode 100644
index 0000000000..7d44d48e3e
--- /dev/null
+++ b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/NfcCloseType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m -update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.nfc;
+@Backing(type="int") @VintfStability
+enum NfcCloseType {
+ DISABLE = 0,
+ HOST_SWITCHED_OFF = 1,
+}
diff --git a/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/NfcConfig.aidl b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/NfcConfig.aidl
new file mode 100644
index 0000000000..92e0a9a82c
--- /dev/null
+++ b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/NfcConfig.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m -update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.nfc;
+@VintfStability
+parcelable NfcConfig {
+ boolean nfaPollBailOutMode;
+ android.hardware.nfc.PresenceCheckAlgorithm presenceCheckAlgorithm;
+ android.hardware.nfc.ProtocolDiscoveryConfig nfaProprietaryCfg;
+ byte defaultOffHostRoute;
+ byte defaultOffHostRouteFelica;
+ byte defaultSystemCodeRoute;
+ byte defaultSystemCodePowerState;
+ byte defaultRoute;
+ byte offHostESEPipeId;
+ byte offHostSIMPipeId;
+ int maxIsoDepTransceiveLength;
+ byte[] hostAllowlist;
+ byte[] offHostRouteUicc;
+ byte[] offHostRouteEse;
+ byte defaultIsoDepRoute;
+}
diff --git a/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/NfcEvent.aidl b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/NfcEvent.aidl
new file mode 100644
index 0000000000..dda258eb08
--- /dev/null
+++ b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/NfcEvent.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m -update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.nfc;
+@Backing(type="int") @VintfStability
+enum NfcEvent {
+ OPEN_CPLT = 0,
+ CLOSE_CPLT = 1,
+ POST_INIT_CPLT = 2,
+ PRE_DISCOVER_CPLT = 3,
+ HCI_NETWORK_RESET = 4,
+ ERROR = 5,
+}
diff --git a/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/NfcStatus.aidl b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/NfcStatus.aidl
new file mode 100644
index 0000000000..2632480bdb
--- /dev/null
+++ b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/NfcStatus.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m -update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.nfc;
+@Backing(type="int") @VintfStability
+enum NfcStatus {
+ OK = 0,
+ FAILED = 1,
+ ERR_TRANSPORT = 2,
+ ERR_CMD_TIMEOUT = 3,
+ REFUSED = 4,
+}
diff --git a/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/PresenceCheckAlgorithm.aidl b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/PresenceCheckAlgorithm.aidl
new file mode 100644
index 0000000000..9a9be215a6
--- /dev/null
+++ b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/PresenceCheckAlgorithm.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m -update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.nfc;
+@Backing(type="byte") @VintfStability
+enum PresenceCheckAlgorithm {
+ DEFAULT = 0,
+ I_BLOCK = 1,
+ ISO_DEP_NAK = 2,
+}
diff --git a/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/ProtocolDiscoveryConfig.aidl b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/ProtocolDiscoveryConfig.aidl
new file mode 100644
index 0000000000..021dfe22d4
--- /dev/null
+++ b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/ProtocolDiscoveryConfig.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m -update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.nfc;
+@VintfStability
+parcelable ProtocolDiscoveryConfig {
+ byte protocol18092Active;
+ byte protocolBPrime;
+ byte protocolDual;
+ byte protocol15693;
+ byte protocolKovio;
+ byte protocolMifare;
+ byte discoveryPollKovio;
+ byte discoveryPollBPrime;
+ byte discoveryListenBPrime;
+}
diff --git a/nfc/aidl/android/hardware/nfc/INfc.aidl b/nfc/aidl/android/hardware/nfc/INfc.aidl
new file mode 100644
index 0000000000..662f8d4c8f
--- /dev/null
+++ b/nfc/aidl/android/hardware/nfc/INfc.aidl
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2021 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 android.hardware.nfc;
+
+import android.hardware.nfc.INfcClientCallback;
+import android.hardware.nfc.NfcCloseType;
+import android.hardware.nfc.NfcConfig;
+import android.hardware.nfc.NfcStatus;
+
+@VintfStability
+interface INfc {
+ /**
+ * Opens the NFC controller device and performs initialization.
+ * This may include patch download and other vendor-specific initialization.
+ *
+ * If open completes successfully, the controller must be ready to perform NCI
+ * initialization - ie accept CORE_RESET and subsequent commands through the write()
+ * call.
+ *
+ * Returns ok() if initialization starts successfully.
+ * If open() returns ok(), the NCI stack must wait for a NfcEvent.OPEN_CPLT
+ * callback before continuing.
+ * If a NfcEvent.OPEN_CPLT callback received with status NfcStatus::OK, the controller
+ * must be ready to perform NCI initialization - ie accept CORE_RESET and subsequent
+ * commands through the write() call.
+ */
+ void open(in INfcClientCallback clientCallback);
+
+ /**
+ * Close the NFC HAL and setup NFC controller close type.
+ * Associated resources such as clientCallback must be released.
+ * The clientCallback reference from open() must be invalid after close().
+ * If close() returns ok(), the NCI stack must wait for a NfcEvent.CLOSE_CPLT
+ * callback before continuing.
+ * Returns an error if close may be called more than once.
+ * Calls to any other method which expect a callback after this must return
+ * a service-specific error NfcStatus::FAILED.
+ * HAL close automatically if the client drops the reference to the HAL or
+ * crashes.
+ */
+ void close(in NfcCloseType type);
+
+ /**
+ * coreInitialized() is called after the CORE_INIT_RSP is received from the
+ * NFCC. At this time, the HAL can do any chip-specific configuration.
+ *
+ * If coreInitialized() returns ok(), the NCI stack must wait for a
+ * NfcEvent.POST_INIT_CPLT before continuing.
+ * If coreInitialized() returns an error, the NCI stack must continue immediately.
+ *
+ * coreInitialized() must be called after open() registers the clientCallback
+ * or return a service-specific error NfcStatus::FAILED directly.
+ *
+ */
+ void coreInitialized();
+
+ /**
+ * Clears the NFC chip.
+ *
+ * Must be called during factory reset and/or before the first time the HAL is
+ * initialized after a factory reset.
+ */
+ void factoryReset();
+
+ /**
+ * Fetches vendor specific configurations.
+ * @return NfcConfig indicates support for certain features and
+ * populates the vendor specific configs.
+ */
+ NfcConfig getConfig();
+
+ /**
+ * Restart controller by power cyle;
+ * It's similar to open but just reset the controller without initialize all the
+ * resources.
+ *
+ * If powerCycle() returns ok(), the NCI stack must wait for a NfcEvent.OPEN_CPLT
+ * before continuing.
+ *
+ * powerCycle() must be called after open() registers the clientCallback
+ * or return a service-specific error NfcStatus::FAILED directly.
+ */
+ void powerCycle();
+
+ /**
+ * preDiscover is called every time before starting RF discovery.
+ * It is a good place to do vendor-specific configuration that must be
+ * performed every time RF discovery is about to be started.
+ *
+ * If preDiscover() returns ok(), the NCI stack must wait for a
+ * NfcEvent.PREDISCOVER_CPLT before continuing.
+ *
+ * preDiscover() must be called after open() registers the clientCallback
+ * or return a service-specific error NfcStatus::FAILED directly.
+ *
+ * If preDiscover() reports an error, the NCI stack must start RF discovery immediately.
+ */
+ void preDiscover();
+
+ /**
+ * Performs an NCI write.
+ *
+ * This method may queue writes and return immediately. The only
+ * requirement is that the writes are executed in order.
+ *
+ * @param data
+ * Data packet to transmit NCI Commands and Data Messages over write.
+ * Detailed format is defined in NFC Controller Interface (NCI) Technical Specification.
+ * https://nfc-forum.org/our-work/specification-releases/
+ *
+ * @return number of bytes written to the NFCC.
+ */
+ int write(in byte[] data);
+
+ /**
+ * Set the logging flag for NFC HAL to enable it's verbose logging.
+ * If verbose logging is not supported, the call must not have any effect on logging verbosity.
+ * However, isVerboseLoggingEnabled() must still return the value set by the last call to
+ * setEnableVerboseLogging().
+ * @param enable for setting the verbose logging flag to HAL
+ */
+ void setEnableVerboseLogging(in boolean enable);
+
+ /**
+ * Get the verbose logging flag value from NFC HAL.
+ * @return true if verbose logging flag value is enabled, false if disabled.
+ */
+ boolean isVerboseLoggingEnabled();
+}
diff --git a/nfc/aidl/android/hardware/nfc/INfcClientCallback.aidl b/nfc/aidl/android/hardware/nfc/INfcClientCallback.aidl
new file mode 100644
index 0000000000..43d4f5cc8b
--- /dev/null
+++ b/nfc/aidl/android/hardware/nfc/INfcClientCallback.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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 android.hardware.nfc;
+
+import android.hardware.nfc.NfcEvent;
+import android.hardware.nfc.NfcStatus;
+
+@VintfStability
+interface INfcClientCallback {
+ /**
+ * The callback passed in from the NFC stack that the HAL
+ * can use to pass incomming response data to the stack.
+ *
+ * @param data
+ * Data packet to transmit NCI Responses, Notifications, and Data
+ * Messages over sendData.
+ * Detailed format is defined in NFC Controller Interface (NCI) Technical Specification.
+ * https://nfc-forum.org/our-work/specification-releases/
+ */
+ void sendData(in byte[] data);
+
+ /**
+ * The callback passed in from the NFC stack that the HAL
+ * can use to pass events back to the stack.
+ */
+ void sendEvent(in NfcEvent event, in NfcStatus status);
+}
diff --git a/nfc/aidl/android/hardware/nfc/NfcCloseType.aidl b/nfc/aidl/android/hardware/nfc/NfcCloseType.aidl
new file mode 100644
index 0000000000..5160532dc8
--- /dev/null
+++ b/nfc/aidl/android/hardware/nfc/NfcCloseType.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 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 android.hardware.nfc;
+
+/**
+ * Different closing types for NFC HAL.
+ */
+@VintfStability
+@Backing(type="int")
+enum NfcCloseType {
+ /**
+ * Close the NFC controller and free NFC HAL resources.
+ */
+ DISABLE = 0,
+
+ /**
+ * Switch the NFC controller operation mode and free NFC HAL resources.
+ * Enable NFC functionality for off host card emulation usecases in
+ * device(host) power off(switched off) state, if the device
+ * supports power off use cases. If the device doesn't support power
+ * off use cases, this call should be same as DISABLE.
+ */
+ HOST_SWITCHED_OFF = 1,
+}
diff --git a/nfc/aidl/android/hardware/nfc/NfcConfig.aidl b/nfc/aidl/android/hardware/nfc/NfcConfig.aidl
new file mode 100644
index 0000000000..1b4fcfb8e8
--- /dev/null
+++ b/nfc/aidl/android/hardware/nfc/NfcConfig.aidl
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2021 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 android.hardware.nfc;
+
+import android.hardware.nfc.PresenceCheckAlgorithm;
+import android.hardware.nfc.ProtocolDiscoveryConfig;
+
+/**
+ * Define Nfc related configurations based on:
+ * NFC Controller Interface (NCI) Technical Specification
+ * https://nfc-forum.org/our-work/specification-releases/
+ */
+@VintfStability
+parcelable NfcConfig {
+ /**
+ * If true, NFCC is using bail out mode for either Type A or Type B poll
+ * based on: Nfc-Forum Activity Technical Specification
+ * https://nfc-forum.org/our-work/specification-releases/
+ */
+ boolean nfaPollBailOutMode;
+ PresenceCheckAlgorithm presenceCheckAlgorithm;
+ ProtocolDiscoveryConfig nfaProprietaryCfg;
+ /**
+ * Default off-host route. 0x00 if there aren't any. Refer to NCI spec.
+ */
+ byte defaultOffHostRoute;
+ /**
+ * Default off-host route for Felica. 0x00 if there aren't any. Refer to
+ * NCI spec.
+ */
+ byte defaultOffHostRouteFelica;
+ /**
+ * Default system code route. 0x00 if there aren't any. Refer NCI spec.
+ */
+ byte defaultSystemCodeRoute;
+ /**
+ * Default power state for system code route. 0x00 if there aren't any.
+ * Refer to NCI spec.
+ */
+ byte defaultSystemCodePowerState;
+ /**
+ * Default route for all remaining protocols and technology which haven't
+ * been configured.
+ * Device Host(0x00) is the default. Refer to NCI spec.
+ *
+ */
+ byte defaultRoute;
+ /**
+ * Pipe ID for eSE. 0x00 if there aren't any.
+ */
+ byte offHostESEPipeId;
+ /**
+ * Pipe ID for UICC. 0x00 if there aren't any.
+ */
+ byte offHostSIMPipeId;
+ /**
+ * Extended APDU length for ISO_DEP. If not supported default length is 261
+ */
+ int maxIsoDepTransceiveLength;
+ /**
+ * list of allowed host ids, as per ETSI TS 102 622
+ * https://www.etsi.org/
+ */
+ byte[] hostAllowlist;
+ /**
+ * NFCEE ID for offhost UICC & eSE secure element.
+ * 0x00 if there aren't any. Refer to NCI spec.
+ */
+ byte[] offHostRouteUicc;
+ byte[] offHostRouteEse;
+ /**
+ * Default IsoDep route. 0x00 if there aren't any. Refer to NCI spec.
+ */
+ byte defaultIsoDepRoute;
+}
diff --git a/nfc/aidl/android/hardware/nfc/NfcEvent.aidl b/nfc/aidl/android/hardware/nfc/NfcEvent.aidl
new file mode 100644
index 0000000000..a78b1cdb44
--- /dev/null
+++ b/nfc/aidl/android/hardware/nfc/NfcEvent.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 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 android.hardware.nfc;
+
+/**
+ * Nfc event to notify nfc status change.
+ */
+@VintfStability
+@Backing(type="int")
+enum NfcEvent {
+ /**
+ * Open complete event to notify upper layer when NFC HAL and NFCC
+ * initialization complete.
+ */
+ OPEN_CPLT = 0,
+ /**
+ * Close complete event to notify upper layer when HAL close is done.
+ */
+ CLOSE_CPLT = 1,
+ /**
+ * Post init complete event to notify upper layer when post init operations
+ * are done.
+ */
+ POST_INIT_CPLT = 2,
+ /**
+ * Pre-discover complete event to notify upper layer when pre-discover
+ * operations are done.
+ */
+ PRE_DISCOVER_CPLT = 3,
+ /**
+ * HCI network reset event to notify upplayer when HCI network needs to
+ * be re-initialized in case of an error.
+ */
+ HCI_NETWORK_RESET = 4,
+ /**
+ * Error event to notify upper layer when there's an unknown error.
+ */
+ ERROR = 5,
+}
diff --git a/nfc/aidl/android/hardware/nfc/NfcStatus.aidl b/nfc/aidl/android/hardware/nfc/NfcStatus.aidl
new file mode 100644
index 0000000000..a38d370f85
--- /dev/null
+++ b/nfc/aidl/android/hardware/nfc/NfcStatus.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 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 android.hardware.nfc;
+
+/**
+ * Used to specify the status of the NfcEvent
+ */
+@VintfStability
+@Backing(type="int")
+enum NfcStatus {
+ /**
+ * Default status when NfcEvent with status OK.
+ */
+ OK = 0,
+ /**
+ * Generic error.
+ */
+ FAILED = 1,
+ /**
+ * Transport error.
+ */
+ ERR_TRANSPORT = 2,
+ /**
+ * Command timeout error.
+ */
+ ERR_CMD_TIMEOUT = 3,
+ /**
+ * Refused error when command is rejected.
+ */
+ REFUSED = 4,
+}
diff --git a/nfc/aidl/android/hardware/nfc/PresenceCheckAlgorithm.aidl b/nfc/aidl/android/hardware/nfc/PresenceCheckAlgorithm.aidl
new file mode 100644
index 0000000000..20e7bffbfe
--- /dev/null
+++ b/nfc/aidl/android/hardware/nfc/PresenceCheckAlgorithm.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 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 android.hardware.nfc;
+
+/*
+ * Presence Check Algorithm as defined in ISO/IEC 14443-4:
+ * https://www.iso.org/standard/73599.html
+ */
+@VintfStability
+@Backing(type="byte")
+enum PresenceCheckAlgorithm {
+ /**
+ * Let the stack select an algorithm
+ */
+ DEFAULT = 0,
+ /**
+ * ISO-DEP protocol's empty I-block
+ */
+ I_BLOCK = 1,
+ /**
+ * Type - 4 tag protocol iso-dep nak presence check command is sent waiting for
+ * response and notification.
+ */
+ ISO_DEP_NAK = 2,
+}
diff --git a/nfc/aidl/android/hardware/nfc/ProtocolDiscoveryConfig.aidl b/nfc/aidl/android/hardware/nfc/ProtocolDiscoveryConfig.aidl
new file mode 100644
index 0000000000..f8e32288e6
--- /dev/null
+++ b/nfc/aidl/android/hardware/nfc/ProtocolDiscoveryConfig.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 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 android.hardware.nfc;
+
+/**
+ * Vendor Specific Proprietary Protocol & Discovery Configuration.
+ * Set to 0xFF if not supported.
+ * discovery* fields map to "RF Technology and Mode" in NCI Spec
+ * protocol* fields map to "RF protocols" in NCI Spec
+ */
+@VintfStability
+parcelable ProtocolDiscoveryConfig {
+ byte protocol18092Active;
+ byte protocolBPrime;
+ byte protocolDual;
+ byte protocol15693;
+ byte protocolKovio;
+ byte protocolMifare;
+ byte discoveryPollKovio;
+ byte discoveryPollBPrime;
+ byte discoveryListenBPrime;
+}
diff --git a/nfc/aidl/default/Android.bp b/nfc/aidl/default/Android.bp
new file mode 100644
index 0000000000..907d23d222
--- /dev/null
+++ b/nfc/aidl/default/Android.bp
@@ -0,0 +1,23 @@
+cc_binary {
+ name: "android.hardware.nfc-service.example",
+ relative_install_path: "hw",
+ init_rc: ["nfc-service-example.rc"],
+ vintf_fragments: ["nfc-service-example.xml"],
+ vendor: true,
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ ],
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "libutils",
+ "libbinder_ndk",
+ "android.hardware.nfc-V1-ndk",
+ ],
+ srcs: [
+ "main.cpp",
+ "Nfc.cpp",
+ "Vendor_hal_api.cpp",
+ ],
+}
diff --git a/nfc/aidl/default/Nfc.cpp b/nfc/aidl/default/Nfc.cpp
new file mode 100644
index 0000000000..a31ac5ec8e
--- /dev/null
+++ b/nfc/aidl/default/Nfc.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "Nfc.h"
+
+#include
+
+#include "Vendor_hal_api.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace nfc {
+
+std::shared_ptr Nfc::mCallback = nullptr;
+AIBinder_DeathRecipient* clientDeathRecipient = nullptr;
+
+void OnDeath(void* cookie) {
+ if (Nfc::mCallback != nullptr && !AIBinder_isAlive(Nfc::mCallback->asBinder().get())) {
+ LOG(INFO) << __func__ << " Nfc service has died";
+ Nfc* nfc = static_cast(cookie);
+ nfc->close(NfcCloseType::DISABLE);
+ }
+}
+
+::ndk::ScopedAStatus Nfc::open(const std::shared_ptr& clientCallback) {
+ LOG(INFO) << "open";
+ if (clientCallback == nullptr) {
+ LOG(INFO) << "Nfc::open null callback";
+ return ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast(NfcStatus::FAILED));
+ } else {
+ Nfc::mCallback = clientCallback;
+
+ clientDeathRecipient = AIBinder_DeathRecipient_new(OnDeath);
+ auto linkRet = AIBinder_linkToDeath(clientCallback->asBinder().get(), clientDeathRecipient,
+ this /* cookie */);
+ if (linkRet != STATUS_OK) {
+ LOG(ERROR) << __func__ << ": linkToDeath failed: " << linkRet;
+ // Just ignore the error.
+ }
+
+ int ret = Vendor_hal_open(eventCallback, dataCallback);
+ return ret == 0 ? ndk::ScopedAStatus::ok()
+ : ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast(NfcStatus::FAILED));
+ return ndk::ScopedAStatus::ok();
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Nfc::close(NfcCloseType type) {
+ LOG(INFO) << "close";
+ if (Nfc::mCallback == nullptr) {
+ LOG(ERROR) << __func__ << "mCallback null";
+ return ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast(NfcStatus::FAILED));
+ }
+ int ret = 0;
+ if (type == NfcCloseType::HOST_SWITCHED_OFF) {
+ ret = Vendor_hal_close_off();
+ } else {
+ ret = Vendor_hal_close();
+ }
+ Nfc::mCallback = nullptr;
+ AIBinder_DeathRecipient_delete(clientDeathRecipient);
+ clientDeathRecipient = nullptr;
+ return ret == 0 ? ndk::ScopedAStatus::ok()
+ : ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast(NfcStatus::FAILED));
+}
+
+::ndk::ScopedAStatus Nfc::coreInitialized() {
+ LOG(INFO) << "coreInitialized";
+ if (Nfc::mCallback == nullptr) {
+ LOG(ERROR) << __func__ << "mCallback null";
+ return ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast(NfcStatus::FAILED));
+ }
+ int ret = Vendor_hal_core_initialized();
+
+ return ret == 0 ? ndk::ScopedAStatus::ok()
+ : ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast(NfcStatus::FAILED));
+}
+
+::ndk::ScopedAStatus Nfc::factoryReset() {
+ LOG(INFO) << "factoryReset";
+ Vendor_hal_factoryReset();
+ return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Nfc::getConfig(NfcConfig* _aidl_return) {
+ LOG(INFO) << "getConfig";
+ NfcConfig nfcVendorConfig;
+ Vendor_hal_getConfig(nfcVendorConfig);
+
+ *_aidl_return = nfcVendorConfig;
+ return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Nfc::powerCycle() {
+ LOG(INFO) << "powerCycle";
+ if (Nfc::mCallback == nullptr) {
+ LOG(ERROR) << __func__ << "mCallback null";
+ return ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast(NfcStatus::FAILED));
+ }
+ return Vendor_hal_power_cycle() ? ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast(NfcStatus::FAILED))
+ : ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Nfc::preDiscover() {
+ LOG(INFO) << "preDiscover";
+ if (Nfc::mCallback == nullptr) {
+ LOG(ERROR) << __func__ << "mCallback null";
+ return ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast(NfcStatus::FAILED));
+ }
+ return Vendor_hal_pre_discover() ? ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast(NfcStatus::FAILED))
+ : ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Nfc::write(const std::vector& data, int32_t* _aidl_return) {
+ LOG(INFO) << "write";
+ if (Nfc::mCallback == nullptr) {
+ LOG(ERROR) << __func__ << "mCallback null";
+ return ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast(NfcStatus::FAILED));
+ }
+ *_aidl_return = Vendor_hal_write(data.size(), &data[0]);
+ return ndk::ScopedAStatus::ok();
+}
+::ndk::ScopedAStatus Nfc::setEnableVerboseLogging(bool enable) {
+ LOG(INFO) << "setVerboseLogging";
+ Vendor_hal_setVerboseLogging(enable);
+ return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Nfc::isVerboseLoggingEnabled(bool* _aidl_return) {
+ *_aidl_return = Vendor_hal_getVerboseLogging();
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace nfc
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/nfc/aidl/default/Nfc.h b/nfc/aidl/default/Nfc.h
new file mode 100644
index 0000000000..1b14534e1a
--- /dev/null
+++ b/nfc/aidl/default/Nfc.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include
+#include
+#include
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace nfc {
+
+using ::aidl::android::hardware::nfc::NfcCloseType;
+using ::aidl::android::hardware::nfc::NfcConfig;
+using ::aidl::android::hardware::nfc::NfcStatus;
+
+// Default implementation that reports no support NFC.
+struct Nfc : public BnNfc {
+ public:
+ Nfc() = default;
+
+ ::ndk::ScopedAStatus open(const std::shared_ptr& clientCallback) override;
+ ::ndk::ScopedAStatus close(NfcCloseType type) override;
+ ::ndk::ScopedAStatus coreInitialized() override;
+ ::ndk::ScopedAStatus factoryReset() override;
+ ::ndk::ScopedAStatus getConfig(NfcConfig* _aidl_return) override;
+ ::ndk::ScopedAStatus powerCycle() override;
+ ::ndk::ScopedAStatus preDiscover() override;
+ ::ndk::ScopedAStatus write(const std::vector& data, int32_t* _aidl_return) override;
+ ::ndk::ScopedAStatus setEnableVerboseLogging(bool enable) override;
+ ::ndk::ScopedAStatus isVerboseLoggingEnabled(bool* _aidl_return) override;
+
+ static void eventCallback(uint8_t event, uint8_t status) {
+ if (mCallback != nullptr) {
+ auto ret = mCallback->sendEvent((NfcEvent)event, (NfcStatus)status);
+ if (!ret.isOk()) {
+ LOG(ERROR) << "Failed to send event!";
+ }
+ }
+ }
+
+ static void dataCallback(uint16_t data_len, uint8_t* p_data) {
+ std::vector data(p_data, p_data + data_len);
+ if (mCallback != nullptr) {
+ auto ret = mCallback->sendData(data);
+ if (!ret.isOk()) {
+ LOG(ERROR) << "Failed to send data!";
+ }
+ }
+ }
+
+ static std::shared_ptr mCallback;
+};
+
+} // namespace nfc
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/nfc/aidl/default/Vendor_hal_api.cpp b/nfc/aidl/default/Vendor_hal_api.cpp
new file mode 100644
index 0000000000..66a2ebc5de
--- /dev/null
+++ b/nfc/aidl/default/Vendor_hal_api.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include
+#include
+#include
+#include
+
+#include "Vendor_hal_api.h"
+
+bool logging = false;
+
+int Vendor_hal_open(nfc_stack_callback_t* p_cback, nfc_stack_data_callback_t* p_data_cback) {
+ (void)p_cback;
+ (void)p_data_cback;
+ // nothing to open in this example
+ return -1;
+}
+
+int Vendor_hal_write(uint16_t data_len, const uint8_t* p_data) {
+ (void)data_len;
+ (void)p_data;
+ return -1;
+}
+
+int Vendor_hal_core_initialized() {
+ return -1;
+}
+
+int Vendor_hal_pre_discover() {
+ return -1;
+}
+
+int Vendor_hal_close() {
+ return -1;
+}
+
+int Vendor_hal_close_off() {
+ return -1;
+}
+
+int Vendor_hal_power_cycle() {
+ return -1;
+}
+
+void Vendor_hal_factoryReset() {}
+
+void Vendor_hal_getConfig(NfcConfig& config) {
+ (void)config;
+}
+
+void Vendor_hal_setVerboseLogging(bool enable) {
+ logging = enable;
+}
+
+bool Vendor_hal_getVerboseLogging() {
+ return logging;
+}
diff --git a/nfc/aidl/default/Vendor_hal_api.h b/nfc/aidl/default/Vendor_hal_api.h
new file mode 100644
index 0000000000..595c2dd8aa
--- /dev/null
+++ b/nfc/aidl/default/Vendor_hal_api.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "hardware_nfc.h"
+
+using aidl::android::hardware::nfc::NfcConfig;
+using aidl::android::hardware::nfc::NfcEvent;
+using aidl::android::hardware::nfc::NfcStatus;
+using aidl::android::hardware::nfc::PresenceCheckAlgorithm;
+using aidl::android::hardware::nfc::ProtocolDiscoveryConfig;
+
+int Vendor_hal_open(nfc_stack_callback_t* p_cback, nfc_stack_data_callback_t* p_data_cback);
+int Vendor_hal_write(uint16_t data_len, const uint8_t* p_data);
+
+int Vendor_hal_core_initialized();
+
+int Vendor_hal_pre_discover();
+
+int Vendor_hal_close();
+
+int Vendor_hal_close_off();
+
+int Vendor_hal_power_cycle();
+
+void Vendor_hal_factoryReset();
+
+void Vendor_hal_getConfig(NfcConfig& config);
+
+void Vendor_hal_setVerboseLogging(bool enable);
+
+bool Vendor_hal_getVerboseLogging();
diff --git a/nfc/aidl/default/hardware_nfc.h b/nfc/aidl/default/hardware_nfc.h
new file mode 100644
index 0000000000..0f856c5ac7
--- /dev/null
+++ b/nfc/aidl/default/hardware_nfc.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+typedef uint8_t nfc_event_t;
+typedef uint8_t nfc_status_t;
+
+/*
+ * The callback passed in from the NFC stack that the HAL
+ * can use to pass events back to the stack.
+ */
+typedef void(nfc_stack_callback_t)(nfc_event_t event, nfc_status_t event_status);
+
+/*
+ * The callback passed in from the NFC stack that the HAL
+ * can use to pass incomming data to the stack.
+ */
+typedef void(nfc_stack_data_callback_t)(uint16_t data_len, uint8_t* p_data);
diff --git a/nfc/aidl/default/main.cpp b/nfc/aidl/default/main.cpp
new file mode 100644
index 0000000000..0cc51e7207
--- /dev/null
+++ b/nfc/aidl/default/main.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include
+#include
+#include
+
+#include "Nfc.h"
+using ::aidl::android::hardware::nfc::Nfc;
+
+int main() {
+ LOG(INFO) << "NFC HAL starting up";
+ if (!ABinderProcess_setThreadPoolMaxThreadCount(1)) {
+ LOG(INFO) << "failed to set thread pool max thread count";
+ return 1;
+ }
+ std::shared_ptr nfc_service = ndk::SharedRefBase::make();
+
+ const std::string instance = std::string() + Nfc::descriptor + "/default";
+ binder_status_t status =
+ AServiceManager_addService(nfc_service->asBinder().get(), instance.c_str());
+ CHECK(status == STATUS_OK);
+ ABinderProcess_joinThreadPool();
+ return 0;
+}
diff --git a/nfc/aidl/default/nfc-service-example.rc b/nfc/aidl/default/nfc-service-example.rc
new file mode 100644
index 0000000000..7d7052ef0a
--- /dev/null
+++ b/nfc/aidl/default/nfc-service-example.rc
@@ -0,0 +1,4 @@
+service nfc_hal_service /vendor/bin/hw/android.hardware.nfc-service.st
+ class hal
+ user nfc
+ group nfc
diff --git a/nfc/aidl/default/nfc-service-example.xml b/nfc/aidl/default/nfc-service-example.xml
new file mode 100644
index 0000000000..70fed205b5
--- /dev/null
+++ b/nfc/aidl/default/nfc-service-example.xml
@@ -0,0 +1,6 @@
+
+
+ android.hardware.nfc
+ INfc/default
+
+
diff --git a/nfc/aidl/vts/functional/Android.bp b/nfc/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000000..99eecd060d
--- /dev/null
+++ b/nfc/aidl/vts/functional/Android.bp
@@ -0,0 +1,46 @@
+//
+// Copyright (C) 2021 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 {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+ name: "VtsAidlHalNfcTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: [
+ "VtsAidlHalNfcTargetTest.cpp",
+ ],
+ shared_libs: [
+ "libbinder",
+ "libbinder_ndk",
+ ],
+ static_libs: [
+ "android.hardware.nfc-V1-ndk",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/nfc/aidl/vts/functional/VtsAidlHalNfcTargetTest.cpp b/nfc/aidl/vts/functional/VtsAidlHalNfcTargetTest.cpp
new file mode 100644
index 0000000000..977b25cf92
--- /dev/null
+++ b/nfc/aidl/vts/functional/VtsAidlHalNfcTargetTest.cpp
@@ -0,0 +1,458 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#define LOG_TAG "nfc_aidl_hal_test"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+using aidl::android::hardware::nfc::INfc;
+using aidl::android::hardware::nfc::INfcClientCallback;
+using aidl::android::hardware::nfc::NfcCloseType;
+using aidl::android::hardware::nfc::NfcConfig;
+using aidl::android::hardware::nfc::NfcEvent;
+using aidl::android::hardware::nfc::NfcStatus;
+using aidl::android::hardware::nfc::PresenceCheckAlgorithm;
+
+using android::getAidlHalInstanceNames;
+using android::PrintInstanceNameToString;
+using android::base::StringPrintf;
+using ndk::enum_range;
+using ndk::ScopedAStatus;
+using ndk::SharedRefBase;
+using ndk::SpAIBinder;
+
+constexpr static int kCallbackTimeoutMs = 10000;
+
+// 261 bytes is the default and minimum transceive length
+constexpr unsigned int MIN_ISO_DEP_TRANSCEIVE_LENGTH = 261;
+
+// Range of valid off host route ids
+constexpr uint8_t MIN_OFFHOST_ROUTE_ID = 0x01;
+constexpr uint8_t MAX_OFFHOST_ROUTE_ID = 0xFE;
+
+class NfcClientCallback : public aidl::android::hardware::nfc::BnNfcClientCallback {
+ public:
+ NfcClientCallback(const std::function& on_hal_event_cb,
+ const std::function&)>& on_nci_data_cb)
+ : on_nci_data_cb_(on_nci_data_cb), on_hal_event_cb_(on_hal_event_cb) {}
+ virtual ~NfcClientCallback() = default;
+
+ ::ndk::ScopedAStatus sendEvent(NfcEvent event, NfcStatus event_status) override {
+ on_hal_event_cb_(event, event_status);
+ return ::ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus sendData(const std::vector& data) override {
+ on_nci_data_cb_(data);
+ return ::ndk::ScopedAStatus::ok();
+ };
+
+ private:
+ std::function&)> on_nci_data_cb_;
+ std::function on_hal_event_cb_;
+};
+
+class NfcAidl : public testing::TestWithParam {
+ public:
+ void SetUp() override {
+ SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
+ infc_ = INfc::fromBinder(binder);
+ ASSERT_NE(infc_, nullptr);
+ }
+ std::shared_ptr infc_;
+};
+
+/*
+ * OpenAndCloseForDisable:
+ * Makes an open call, waits for NfcEvent::OPEN_CPLT
+ * Immediately calls close(NfcCloseType::DISABLE) and
+ * waits for NfcEvent::CLOSE_CPLT
+ *
+ */
+TEST_P(NfcAidl, OpenAndCloseForDisable) {
+ std::promise open_cb_promise;
+ std::promise close_cb_promise;
+ auto open_cb_future = open_cb_promise.get_future();
+ auto close_cb_future = close_cb_promise.get_future();
+ std::shared_ptr mCallback = ::ndk::SharedRefBase::make(
+ [&open_cb_promise, &close_cb_promise](auto event, auto status) {
+ EXPECT_EQ(status, NfcStatus::OK);
+ LOG(INFO) << StringPrintf("%s,%d ", __func__, event);
+ if (event == NfcEvent::OPEN_CPLT) open_cb_promise.set_value();
+ if (event == NfcEvent::CLOSE_CPLT) close_cb_promise.set_value();
+ },
+ [](auto) {});
+ std::chrono::milliseconds timeout{kCallbackTimeoutMs};
+ // Open and wait for OPEN_CPLT
+ LOG(INFO) << "open";
+ EXPECT_TRUE(infc_->open(mCallback).isOk());
+ EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
+ // Close and wait for CLOSE_CPLT
+ LOG(INFO) << "close DISABLE";
+ EXPECT_TRUE(infc_->close(NfcCloseType::DISABLE).isOk());
+ LOG(INFO) << "wait for close";
+ EXPECT_EQ(close_cb_future.wait_for(timeout), std::future_status::ready);
+}
+
+/*
+ * OpenAndCloseForHostSwitchedOff:
+ * Makes an open call, waits for NfcEvent::OPEN_CPLT
+ * Immediately calls close(NfcCloseType::HOST_SWITCHED_OFF) and
+ * waits for NfcEvent::CLOSE_CPLT
+ *
+ */
+TEST_P(NfcAidl, OpenAndCloseForHostSwitchedOff) {
+ std::promise open_cb_promise;
+ std::promise close_cb_promise;
+ auto open_cb_future = open_cb_promise.get_future();
+ auto close_cb_future = close_cb_promise.get_future();
+ std::shared_ptr mCallback = ::ndk::SharedRefBase::make(
+ [&open_cb_promise, &close_cb_promise](auto event, auto status) {
+ EXPECT_EQ(status, NfcStatus::OK);
+ if (event == NfcEvent::OPEN_CPLT) open_cb_promise.set_value();
+ if (event == NfcEvent::CLOSE_CPLT) close_cb_promise.set_value();
+ },
+ [](auto) {});
+ std::chrono::milliseconds timeout{kCallbackTimeoutMs};
+ // Open and wait for OPEN_CPLT
+ LOG(INFO) << "open";
+ EXPECT_TRUE(infc_->open(mCallback).isOk());
+ EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
+
+ // Close and wait for CLOSE_CPLT
+ LOG(INFO) << "close HOST_SWITCHED_OFF";
+ EXPECT_TRUE(infc_->close(NfcCloseType::HOST_SWITCHED_OFF).isOk());
+ EXPECT_EQ(close_cb_future.wait_for(timeout), std::future_status::ready);
+}
+
+/*
+ * OpenAfterOpen:
+ * Calls open() multiple times
+ * Checks status
+ */
+TEST_P(NfcAidl, OpenAfterOpen) {
+ int open_count = 0;
+ std::promise open_cb_promise;
+ std::promise open2_cb_promise;
+ auto open_cb_future = open_cb_promise.get_future();
+ auto open2_cb_future = open2_cb_promise.get_future();
+ std::shared_ptr mCallback = ::ndk::SharedRefBase::make(
+ [&open_cb_promise, &open2_cb_promise, &open_count](auto event, auto status) {
+ EXPECT_EQ(status, NfcStatus::OK);
+ if (event == NfcEvent::OPEN_CPLT) {
+ open_count == 0 ? open_cb_promise.set_value() : open2_cb_promise.set_value();
+ open_count++;
+ }
+ },
+ [](auto) {});
+
+ std::chrono::milliseconds timeout{kCallbackTimeoutMs};
+ // Open and wait for OPEN_CPLT
+ LOG(INFO) << "open";
+ EXPECT_TRUE(infc_->open(mCallback).isOk());
+ EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
+
+ // Open again and wait for OPEN_CPLT
+ LOG(INFO) << "open again";
+ EXPECT_TRUE(infc_->open(mCallback).isOk());
+ EXPECT_EQ(open2_cb_future.wait_for(timeout), std::future_status::ready);
+}
+
+/*
+ * CloseAfterClose:
+ * Calls close() multiple times
+ * Checks status
+ */
+TEST_P(NfcAidl, CloseAfterClose) {
+ std::promise open_cb_promise;
+ std::promise close_cb_promise;
+ auto open_cb_future = open_cb_promise.get_future();
+ auto close_cb_future = close_cb_promise.get_future();
+ std::shared_ptr mCallback = ::ndk::SharedRefBase::make(
+ [&open_cb_promise, &close_cb_promise](auto event, auto status) {
+ EXPECT_EQ(status, NfcStatus::OK);
+ if (event == NfcEvent::OPEN_CPLT) open_cb_promise.set_value();
+ if (event == NfcEvent::CLOSE_CPLT) close_cb_promise.set_value();
+ },
+ [](auto) {});
+ std::chrono::milliseconds timeout{kCallbackTimeoutMs};
+ // Open and wait for OPEN_CPLT
+ LOG(INFO) << "open";
+ EXPECT_TRUE(infc_->open(mCallback).isOk());
+ EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
+
+ // Close and wait for CLOSE_CPLT
+ LOG(INFO) << "close";
+ EXPECT_TRUE(infc_->close(NfcCloseType::DISABLE).isOk());
+ EXPECT_EQ(close_cb_future.wait_for(timeout), std::future_status::ready);
+ // Close again should fail.
+ LOG(INFO) << "close again";
+ EXPECT_TRUE(!(infc_->close(NfcCloseType::DISABLE).isOk()));
+}
+
+/*
+ * PowerCycleAfterOpen:
+ * Calls powerCycle() after open
+ * Waits for NfcEvent.OPEN_CPLT
+ * Checks status
+ */
+TEST_P(NfcAidl, PowerCycleAfterOpen) {
+ int open_cplt_count = 0;
+ std::promise open_cb_promise;
+ std::promise power_cycle_cb_promise;
+ std::promise close_cb_promise;
+ auto open_cb_future = open_cb_promise.get_future();
+ auto power_cycle_cb_future = power_cycle_cb_promise.get_future();
+ auto close_cb_future = close_cb_promise.get_future();
+ std::shared_ptr mCallback = ::ndk::SharedRefBase::make(
+ [&open_cb_promise, &close_cb_promise, &power_cycle_cb_promise, &open_cplt_count](
+ auto event, auto status) {
+ EXPECT_EQ(status, NfcStatus::OK);
+ if (event == NfcEvent::OPEN_CPLT) {
+ if (open_cplt_count == 0) {
+ open_cplt_count++;
+ open_cb_promise.set_value();
+ } else {
+ power_cycle_cb_promise.set_value();
+ }
+ }
+ if (event == NfcEvent::CLOSE_CPLT) close_cb_promise.set_value();
+ },
+ [](auto) {});
+ std::chrono::milliseconds timeout{kCallbackTimeoutMs};
+ // Open and wait for OPEN_CPLT
+ LOG(INFO) << "open";
+ EXPECT_TRUE(infc_->open(mCallback).isOk());
+ EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
+
+ // PowerCycle and wait for OPEN_CPLT
+ LOG(INFO) << "PowerCycle";
+ EXPECT_TRUE(infc_->powerCycle().isOk());
+ EXPECT_EQ(power_cycle_cb_future.wait_for(timeout), std::future_status::ready);
+
+ // Close and wait for CLOSE_CPLT
+ LOG(INFO) << "close";
+ EXPECT_TRUE(infc_->close(NfcCloseType::DISABLE).isOk());
+ EXPECT_EQ(close_cb_future.wait_for(timeout), std::future_status::ready);
+}
+
+/*
+ * PowerCycleAfterClose:
+ * Calls powerCycle() after close
+ * PowerCycle should fail immediately
+ */
+TEST_P(NfcAidl, PowerCycleAfterClose) {
+ std::promise open_cb_promise;
+ std::promise close_cb_promise;
+ auto open_cb_future = open_cb_promise.get_future();
+ auto close_cb_future = close_cb_promise.get_future();
+ std::shared_ptr mCallback = ::ndk::SharedRefBase::make(
+ [&open_cb_promise, &close_cb_promise](auto event, auto status) {
+ EXPECT_EQ(status, NfcStatus::OK);
+ if (event == NfcEvent::OPEN_CPLT) open_cb_promise.set_value();
+ if (event == NfcEvent::CLOSE_CPLT) close_cb_promise.set_value();
+ },
+ [](auto) {});
+ std::chrono::milliseconds timeout{kCallbackTimeoutMs};
+ // Open and wait for OPEN_CPLT
+ LOG(INFO) << "open";
+ EXPECT_TRUE(infc_->open(mCallback).isOk());
+ EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
+
+ // Close and wait for CLOSE_CPLT
+ LOG(INFO) << "close";
+ EXPECT_TRUE(infc_->close(NfcCloseType::DISABLE).isOk());
+ EXPECT_EQ(close_cb_future.wait_for(timeout), std::future_status::ready);
+
+ // PowerCycle should fail
+ LOG(INFO) << "PowerCycle";
+ EXPECT_TRUE(!(infc_->powerCycle().isOk()));
+}
+
+/*
+ * CoreInitializedAfterOpen:
+ * Calls coreInitialized() after open
+ * Waits for NfcEvent.POST_INIT_CPLT
+ */
+TEST_P(NfcAidl, CoreInitializedAfterOpen) {
+ std::promise open_cb_promise;
+ std::promise core_init_cb_promise;
+ std::promise close_cb_promise;
+ auto open_cb_future = open_cb_promise.get_future();
+ auto core_init_cb_future = core_init_cb_promise.get_future();
+ auto close_cb_future = close_cb_promise.get_future();
+ std::shared_ptr mCallback = ::ndk::SharedRefBase::make(
+ [&open_cb_promise, &close_cb_promise, &core_init_cb_promise](auto event, auto status) {
+ EXPECT_EQ(status, NfcStatus::OK);
+ if (event == NfcEvent::OPEN_CPLT) open_cb_promise.set_value();
+ if (event == NfcEvent::POST_INIT_CPLT) core_init_cb_promise.set_value();
+ if (event == NfcEvent::CLOSE_CPLT) close_cb_promise.set_value();
+ },
+ [](auto) {});
+ std::chrono::milliseconds timeout{kCallbackTimeoutMs};
+ // Open and wait for OPEN_CPLT
+ LOG(INFO) << "open";
+ EXPECT_TRUE(infc_->open(mCallback).isOk());
+ EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
+
+ // CoreInitialized and wait for POST_INIT_CPLT
+ LOG(INFO) << "coreInitialized";
+ EXPECT_TRUE(infc_->coreInitialized().isOk());
+ EXPECT_EQ(core_init_cb_future.wait_for(timeout), std::future_status::ready);
+
+ // Close and wait for CLOSE_CPLT
+ LOG(INFO) << "close";
+ EXPECT_TRUE(infc_->close(NfcCloseType::DISABLE).isOk());
+ EXPECT_EQ(close_cb_future.wait_for(timeout), std::future_status::ready);
+}
+
+/*
+ * CoreInitializedAfterClose:
+ * Calls coreInitialized() after close
+ * coreInitialized() should fail immediately
+ */
+TEST_P(NfcAidl, CoreInitializedAfterClose) {
+ std::promise open_cb_promise;
+ std::promise close_cb_promise;
+ auto open_cb_future = open_cb_promise.get_future();
+ auto close_cb_future = close_cb_promise.get_future();
+ std::shared_ptr mCallback = ::ndk::SharedRefBase::make(
+ [&open_cb_promise, &close_cb_promise](auto event, auto status) {
+ EXPECT_EQ(status, NfcStatus::OK);
+ if (event == NfcEvent::OPEN_CPLT) open_cb_promise.set_value();
+ if (event == NfcEvent::CLOSE_CPLT) close_cb_promise.set_value();
+ },
+ [](auto) {});
+ std::chrono::milliseconds timeout{kCallbackTimeoutMs};
+ // Open and wait for OPEN_CPLT
+ LOG(INFO) << "open";
+ EXPECT_TRUE(infc_->open(mCallback).isOk());
+ EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
+
+ // Close and wait for CLOSE_CPLT
+ LOG(INFO) << "close";
+ EXPECT_TRUE(infc_->close(NfcCloseType::DISABLE).isOk());
+ EXPECT_EQ(close_cb_future.wait_for(timeout), std::future_status::ready);
+
+ // coreInitialized should fail
+ LOG(INFO) << "CoreInitialized";
+ EXPECT_TRUE(!(infc_->coreInitialized().isOk()));
+}
+
+/*
+ * PreDiscoverAfterClose:
+ * Call preDiscover() after close
+ * preDiscover() should fail immediately
+ */
+TEST_P(NfcAidl, PreDiscoverAfterClose) {
+ std::promise open_cb_promise;
+ std::promise close_cb_promise;
+ auto open_cb_future = open_cb_promise.get_future();
+ auto close_cb_future = close_cb_promise.get_future();
+ std::shared_ptr mCallback = ::ndk::SharedRefBase::make(
+ [&open_cb_promise, &close_cb_promise](auto event, auto status) {
+ EXPECT_EQ(status, NfcStatus::OK);
+ if (event == NfcEvent::OPEN_CPLT) open_cb_promise.set_value();
+ if (event == NfcEvent::CLOSE_CPLT) close_cb_promise.set_value();
+ },
+ [](auto) {});
+ std::chrono::milliseconds timeout{kCallbackTimeoutMs};
+ // Open and wait for OPEN_CPLT
+ LOG(INFO) << "open";
+ EXPECT_TRUE(infc_->open(mCallback).isOk());
+ EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
+
+ // Close and wait for CLOSE_CPLT
+ LOG(INFO) << "close";
+ EXPECT_TRUE(infc_->close(NfcCloseType::DISABLE).isOk());
+ EXPECT_EQ(close_cb_future.wait_for(timeout), std::future_status::ready);
+
+ // preDiscover should fail
+ LOG(INFO) << "preDiscover";
+ EXPECT_TRUE(!(infc_->preDiscover().isOk()));
+}
+
+/*
+ * checkGetConfigValues:
+ * Calls getConfig()
+ * checks if fields in NfcConfig are populated correctly
+ */
+TEST_P(NfcAidl, CheckGetConfigValues) {
+ NfcConfig configValue;
+ EXPECT_TRUE(infc_->getConfig(&configValue).isOk());
+ EXPECT_GE(configValue.maxIsoDepTransceiveLength, MIN_ISO_DEP_TRANSCEIVE_LENGTH);
+ LOG(INFO) << StringPrintf("configValue.maxIsoDepTransceiveLength = %x",
+ configValue.maxIsoDepTransceiveLength);
+ for (auto uicc : configValue.offHostRouteUicc) {
+ LOG(INFO) << StringPrintf("offHostRouteUicc = %x", uicc);
+ EXPECT_GE(uicc, MIN_OFFHOST_ROUTE_ID);
+ EXPECT_LE(uicc, MAX_OFFHOST_ROUTE_ID);
+ }
+ for (auto ese : configValue.offHostRouteEse) {
+ LOG(INFO) << StringPrintf("offHostRouteEse = %x", ese);
+ EXPECT_GE(ese, MIN_OFFHOST_ROUTE_ID);
+ EXPECT_LE(ese, MAX_OFFHOST_ROUTE_ID);
+ }
+ if (configValue.defaultIsoDepRoute != 0) {
+ EXPECT_GE((uint8_t)configValue.defaultIsoDepRoute, MIN_OFFHOST_ROUTE_ID);
+ EXPECT_LE((uint8_t)configValue.defaultIsoDepRoute, MAX_OFFHOST_ROUTE_ID);
+ }
+}
+
+/*
+ * CheckisVerboseLoggingEnabledAfterSetEnableVerboseLogging:
+ * Calls setEnableVerboseLogging()
+ * checks the return value of isVerboseLoggingEnabled
+ */
+TEST_P(NfcAidl, CheckisVerboseLoggingEnabledAfterSetEnableVerboseLogging) {
+ bool enabled = false;
+ EXPECT_TRUE(infc_->setEnableVerboseLogging(true).isOk());
+ EXPECT_TRUE(infc_->isVerboseLoggingEnabled(&enabled).isOk());
+ EXPECT_TRUE(enabled);
+ EXPECT_TRUE(infc_->setEnableVerboseLogging(false).isOk());
+ EXPECT_TRUE(infc_->isVerboseLoggingEnabled(&enabled).isOk());
+ EXPECT_TRUE(!enabled);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(NfcAidl);
+INSTANTIATE_TEST_SUITE_P(Nfc, NfcAidl,
+ testing::ValuesIn(::android::getAidlHalInstanceNames(INfc::descriptor)),
+ ::android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_startThreadPool();
+ std::system("/system/bin/svc nfc disable"); /* Turn off NFC */
+ sleep(5);
+ int status = RUN_ALL_TESTS();
+ LOG(INFO) << "Test result = " << status;
+ std::system("/system/bin/svc nfc enable"); /* Turn on NFC */
+ sleep(5);
+ return status;
+}