/* * Copyright (c) 2020 Huawei Device Co., Ltd. * 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 "ability_test_helper.h" #include #include #include #include #include #include #include #include #include #include #include namespace OHOS { constexpr uint32_t WAIT_TIMEOUT = 30; constexpr char ABILITY_STATE[] = "Ability State: ["; constexpr char NO_ABILITY[] = "Ability not found"; constexpr char SLICE_STACK[] = "\n ["; constexpr char SLICE_STATE[] = "] State: ["; static sem_t g_sem; static bool g_result = false; static std::string g_resultString; SvcIdentity AbilityTestHelper::identity_ = {}; IClientProxy *AbilityTestHelper::proxy_ = nullptr; IpcObjectStub AbilityTestHelper::objectStub_ = {}; void AbilityTestHelper::Initialize() { objectStub_.func = AbilityCallback; objectStub_.args = nullptr; objectStub_.isRemote = false; identity_.handle = IPC_INVALID_HANDLE; identity_.token = SERVICE_TYPE_ANONYMOUS; identity_.cookie = reinterpret_cast(&objectStub_); proxy_ = GetAbilityInnerFeature(); if (proxy_ == nullptr) { exit(-1); } sleep(1); } void AbilityTestHelper::UnInitialize() { sleep(1); } void AbilityTestHelper::InstallCallback(const uint8_t resultCode, const void *resultMessage) { std::string strMessage = reinterpret_cast(resultMessage); if (!strMessage.empty()) { printf("install resultMessage is %s\n", strMessage.c_str()); } g_result = (resultCode == ERR_OK); SemPost(); } void AbilityTestHelper::UninstallCallback(const uint8_t resultCode, const void *resultMessage) { std::string strMessage = reinterpret_cast(resultMessage); if (!strMessage.empty()) { printf("[INFO] [AbilityTestHelper] uninstall resultMessage is %s\n", strMessage.c_str()); } g_result = (resultCode == ERR_OK); SemPost(); } int32_t AbilityTestHelper::AbilityCallback(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option) { switch (code) { case SCHEDULER_APP_INIT: { ElementName element = {}; DeserializeElement(&element, data); int32_t ret = 0; ReadInt32(data, &ret); printf("ams call back, start %s.%s ret = %d\n", element.bundleName, element.abilityName, ret); ClearElement(&element); g_result = (ret == EC_SUCCESS); break; } case SCHEDULER_DUMP_ABILITY: { size_t len = 0; g_resultString = reinterpret_cast(ReadString(data, &len)); break; } default: { printf("ams call back error, funcId: %u\n", code); break; } } SemPost(); return 0; } bool AbilityTestHelper::TestInstall(const std::string &hap) { InstallParam installParam = { .installLocation = 1, .keepData = false }; if (!Install(hap.c_str(), &installParam, InstallCallback)) { printf("[ERROR] [AbilityTestHelper] Install hap failed!\n"); exit(-1); } g_result = true; SemWait(); return g_result; } bool AbilityTestHelper::TestUnInstall(const std::string &bundleName) { InstallParam installParam = { .installLocation = 1, .keepData = false }; bool ret = Uninstall(bundleName.c_str(), &installParam, UninstallCallback); SemWait(); return ret; } bool AbilityTestHelper::TestStartAbility(const Want &want) { SetWantSvcIdentity(const_cast(&want), identity_); int32_t ret = StartAbility(&want); g_result = (ERR_OK == ret); SemWait(); sleep(1); return g_result; } bool AbilityTestHelper::TestTerminateApp(const std::string &bundleName) { IpcIo req; char data[MAX_IO_SIZE]; IpcIoInit(&req, data, MAX_IO_SIZE, 0); WriteString(&req, bundleName.c_str()); int32_t ret = proxy_->Invoke(proxy_, TERMINATE_APP, &req, nullptr, nullptr); sleep(2); // 2:出让CPU return ret == EC_SUCCESS; } State AbilityTestHelper::GetAbilityState(const ElementName &elementName) { TestDumpAbility(elementName); auto position = g_resultString.find(ABILITY_STATE); if (position != std::string::npos) { return static_cast(g_resultString[position + strlen(ABILITY_STATE)] - '0'); } if (g_resultString.find(NO_ABILITY) != std::string::npos) { return STATE_INITIAL; } printf("[ERROR] [AbilityTestHelper] Failed to GetAbilityState\n"); return STATE_UNINITIALIZED; } std::list> AbilityTestHelper::GetSliceStack(const ElementName &elementName) { TestDumpAbility(elementName); std::list> sliceList; std::string::size_type begin; std::string::size_type end = 0; while (((begin = g_resultString.find(SLICE_STACK, end)) != std::string::npos) && ((end = g_resultString.find(SLICE_STATE, begin)) != std::string::npos)) { auto record = std::make_shared(); record->name = g_resultString.substr(begin + strlen(SLICE_STACK), end); record->state = static_cast(g_resultString[end + strlen(SLICE_STATE)] - '0'); sliceList.push_back(record); } return sliceList; } IClientProxy *AbilityTestHelper::GetAbilityInnerFeature() { IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(AMS_SERVICE, AMS_INNER_FEATURE); if (iUnknown == nullptr) { printf("ams inner unknown is null\n"); return nullptr; } IClientProxy *innerProxy = nullptr; (void)iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&innerProxy); if (innerProxy == nullptr) { printf("ams inner feature is null\n"); return nullptr; } return innerProxy; } void AbilityTestHelper::TestDumpAbility(const ElementName &elementName) { IpcIo req; char data[MAX_IO_SIZE]; IpcIoInit(&req, data, MAX_IO_SIZE, 2); // 2:IPC初始化 Want want = {}; SetWantElement(&want, elementName); SetWantSvcIdentity(&want, identity_); if (!SerializeWant(&req, &want)) { printf("SerializeWant failed\n"); ClearWant(&want); exit(-1); } ClearWant(&want); proxy_->Invoke(proxy_, DUMP_ABILITY, &req, nullptr, nullptr); SemWait(); printf("[Dump]\n%s\n", g_resultString.c_str()); } void AbilityTestHelper::SemWait() { printf("waiting callback\n"); sem_init(&g_sem, 0, 0); struct timespec ts = {}; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += WAIT_TIMEOUT; sem_timedwait(&g_sem, &ts); } void AbilityTestHelper::SemPost() { printf("receive callback\n"); sem_post(&g_sem); } }