mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Test: atest VtsNfcBehaviorChangesTest Bug: 345575225 (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:f113bc3a9ea32c6eb53df761f745079fa0e2bb2e) Merged-In: I22393acc260d200d2e472d276c64af005a75ab6b Change-Id: I22393acc260d200d2e472d276c64af005a75ab6b
236 lines
8.2 KiB
C++
236 lines
8.2 KiB
C++
/*
|
|
* Copyright (C) 2024 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_behavior_changes_test"
|
|
|
|
#include <aidl/Gtest.h>
|
|
#include <aidl/Vintf.h>
|
|
#include <aidl/android/hardware/nfc/BnNfc.h>
|
|
#include <aidl/android/hardware/nfc/INfc.h>
|
|
#include <android-base/logging.h>
|
|
#include <android-base/stringprintf.h>
|
|
#include <android/binder_process.h>
|
|
#include <gtest/gtest.h>
|
|
|
|
#include <chrono>
|
|
#include <future>
|
|
|
|
#include "NfcAdaptation.h"
|
|
#include "SyncEvent.h"
|
|
#include "nci_defs.h"
|
|
#include "nfa_api.h"
|
|
#include "nfa_ee_api.h"
|
|
|
|
using aidl::android::hardware::nfc::INfc;
|
|
using android::getAidlHalInstanceNames;
|
|
using android::PrintInstanceNameToString;
|
|
using android::base::StringPrintf;
|
|
|
|
static SyncEvent sNfaEnableEvent; // event for NFA_Enable()
|
|
static SyncEvent sNfaVsCommand; // event for VS commands
|
|
static SyncEvent sNfaEnableDisablePollingEvent;
|
|
static SyncEvent sNfaPowerChangeEvent;
|
|
static bool sIsNfaEnabled;
|
|
static tNFA_STATUS sVSCmdStatus;
|
|
|
|
static void nfaDeviceManagementCallback(uint8_t dmEvent, tNFA_DM_CBACK_DATA* eventData) {
|
|
LOG(DEBUG) << StringPrintf("%s: enter; event=0x%X", __func__, dmEvent);
|
|
|
|
switch (dmEvent) {
|
|
case NFA_DM_ENABLE_EVT: /* Result of NFA_Enable */
|
|
{
|
|
SyncEventGuard guard(sNfaEnableEvent);
|
|
LOG(DEBUG) << StringPrintf("%s: NFA_DM_ENABLE_EVT; status=0x%X", __func__,
|
|
eventData->status);
|
|
sIsNfaEnabled = eventData->status == NFA_STATUS_OK;
|
|
sNfaEnableEvent.notifyOne();
|
|
} break;
|
|
|
|
case NFA_DM_DISABLE_EVT: /* Result of NFA_Disable */
|
|
{
|
|
SyncEventGuard guard(sNfaEnableEvent);
|
|
LOG(DEBUG) << StringPrintf("%s: NFA_DM_DISABLE_EVT; status=0x%X", __func__,
|
|
eventData->status);
|
|
sIsNfaEnabled = eventData->status == NFA_STATUS_OK;
|
|
sNfaEnableEvent.notifyOne();
|
|
} break;
|
|
|
|
case NFA_DM_PWR_MODE_CHANGE_EVT: {
|
|
SyncEventGuard guard(sNfaPowerChangeEvent);
|
|
LOG(DEBUG) << StringPrintf(
|
|
"%s: NFA_DM_PWR_MODE_CHANGE_EVT: status=0x%X, power_mode=0x%X", __func__,
|
|
eventData->status, eventData->power_mode.power_mode);
|
|
|
|
sNfaPowerChangeEvent.notifyOne();
|
|
|
|
} break;
|
|
}
|
|
}
|
|
|
|
static void nfaConnectionCallback(uint8_t connEvent, tNFA_CONN_EVT_DATA* eventData) {
|
|
LOG(DEBUG) << StringPrintf("%s: event= %u", __func__, connEvent);
|
|
|
|
switch (connEvent) {
|
|
case NFA_LISTEN_DISABLED_EVT: {
|
|
SyncEventGuard guard(sNfaEnableDisablePollingEvent);
|
|
sNfaEnableDisablePollingEvent.notifyOne();
|
|
} break;
|
|
|
|
case NFA_LISTEN_ENABLED_EVT: {
|
|
SyncEventGuard guard(sNfaEnableDisablePollingEvent);
|
|
sNfaEnableDisablePollingEvent.notifyOne();
|
|
} break;
|
|
|
|
case NFA_RF_DISCOVERY_STARTED_EVT: // RF Discovery started
|
|
{
|
|
LOG(DEBUG) << StringPrintf("%s: NFA_RF_DISCOVERY_STARTED_EVT: status = %u", __func__,
|
|
eventData->status);
|
|
|
|
SyncEventGuard guard(sNfaEnableDisablePollingEvent);
|
|
sNfaEnableDisablePollingEvent.notifyOne();
|
|
} break;
|
|
|
|
case NFA_RF_DISCOVERY_STOPPED_EVT: // RF Discovery stopped event
|
|
{
|
|
LOG(DEBUG) << StringPrintf("%s: NFA_RF_DISCOVERY_STOPPED_EVT: status = %u", __func__,
|
|
eventData->status);
|
|
|
|
SyncEventGuard guard(sNfaEnableDisablePollingEvent);
|
|
sNfaEnableDisablePollingEvent.notifyOne();
|
|
} break;
|
|
}
|
|
}
|
|
|
|
void static nfaVSCallback(uint8_t event, uint16_t /* param_len */, uint8_t* p_param) {
|
|
switch (event & NCI_OID_MASK) {
|
|
case NCI_MSG_PROP_ANDROID: {
|
|
uint8_t android_sub_opcode = p_param[3];
|
|
switch (android_sub_opcode) {
|
|
case NCI_ANDROID_PASSIVE_OBSERVE: {
|
|
sVSCmdStatus = p_param[4];
|
|
LOG(INFO) << StringPrintf("Observe mode RSP: status: %x", sVSCmdStatus);
|
|
SyncEventGuard guard(sNfaVsCommand);
|
|
sNfaVsCommand.notifyOne();
|
|
} break;
|
|
case NCI_ANDROID_POLLING_FRAME_NTF: {
|
|
// TODO
|
|
} break;
|
|
default:
|
|
LOG(WARNING) << StringPrintf("Unknown Android sub opcode %x",
|
|
android_sub_opcode);
|
|
}
|
|
} break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Enable passive observe mode.
|
|
*/
|
|
tNFA_STATUS static nfaObserveModeEnable(bool enable) {
|
|
tNFA_STATUS status = NFA_STATUS_FAILED;
|
|
|
|
status = NFA_StopRfDiscovery();
|
|
if (status == NFA_STATUS_OK) {
|
|
if (!sNfaEnableDisablePollingEvent.wait(1000)) {
|
|
LOG(WARNING) << "Timeout waiting to disable NFC RF discovery";
|
|
return NFA_STATUS_TIMEOUT;
|
|
}
|
|
}
|
|
|
|
uint8_t cmd[] = {(NCI_MT_CMD << NCI_MT_SHIFT) | NCI_GID_PROP, NCI_MSG_PROP_ANDROID,
|
|
NCI_ANDROID_PASSIVE_OBSERVE_PARAM_SIZE, NCI_ANDROID_PASSIVE_OBSERVE,
|
|
static_cast<uint8_t>(enable ? NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE
|
|
: NCI_ANDROID_PASSIVE_OBSERVE_PARAM_DISABLE)};
|
|
|
|
status = NFA_SendRawVsCommand(sizeof(cmd), cmd, nfaVSCallback);
|
|
|
|
if (status == NFA_STATUS_OK) {
|
|
if (!sNfaVsCommand.wait(1000)) {
|
|
LOG(WARNING) << "Timeout waiting for NFA VS command response";
|
|
return NFA_STATUS_TIMEOUT;
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
class NfcBehaviorChanges : public testing::TestWithParam<std::string> {
|
|
protected:
|
|
void SetUp() override {
|
|
tNFA_STATUS status = NFA_STATUS_OK;
|
|
|
|
sIsNfaEnabled = false;
|
|
sVSCmdStatus = NFA_STATUS_OK;
|
|
|
|
NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
|
|
theInstance.Initialize(); // start GKI, NCI task, NFC task
|
|
|
|
{
|
|
SyncEventGuard guard(sNfaEnableEvent);
|
|
tHAL_NFC_ENTRY* halFuncEntries = theInstance.GetHalEntryFuncs();
|
|
|
|
NFA_Init(halFuncEntries);
|
|
|
|
status = NFA_Enable(nfaDeviceManagementCallback, nfaConnectionCallback);
|
|
ASSERT_EQ(status, NFA_STATUS_OK);
|
|
|
|
// wait for NFA command to finish
|
|
ASSERT_TRUE(sNfaEnableEvent.wait(1000))
|
|
<< "Timeout waiting for NFA command on NFA_Enable";
|
|
}
|
|
|
|
ASSERT_TRUE(sIsNfaEnabled) << "Could not initialize NFC controller";
|
|
|
|
status = NFA_StartRfDiscovery();
|
|
ASSERT_EQ(status, NFA_STATUS_OK);
|
|
ASSERT_TRUE(sNfaEnableDisablePollingEvent.wait(1000)) << "Timeout starting RF discovery";
|
|
}
|
|
};
|
|
|
|
/*
|
|
* ObserveModeEnable:
|
|
* Attempts to enable observe mode. Does not test Observe Mode functionality,
|
|
* but simply verifies that the enable command responds successfully.
|
|
*
|
|
* @VsrTest = GMS-VSR-3.2.8-001
|
|
*/
|
|
TEST_P(NfcBehaviorChanges, ObserveModeEnableDisable) {
|
|
tNFA_STATUS status = nfaObserveModeEnable(true);
|
|
ASSERT_EQ(status, NFA_STATUS_OK);
|
|
|
|
status = nfaObserveModeEnable(false);
|
|
ASSERT_EQ(status, NFA_STATUS_OK);
|
|
}
|
|
|
|
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(NfcBehaviorChanges);
|
|
INSTANTIATE_TEST_SUITE_P(Nfc, NfcBehaviorChanges,
|
|
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 service */
|
|
sleep(5);
|
|
int status = RUN_ALL_TESTS();
|
|
LOG(INFO) << "Test result = " << status;
|
|
std::system("/system/bin/svc nfc enable"); /* Turn on NFC service */
|
|
sleep(5);
|
|
return status;
|
|
}
|