1 /* 2 * Copyright (c) 2020 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "ability_test_helper.h" 17 18 #include <ability_kit_command.h> 19 #include <ability_manager.h> 20 #include <ability_service_interface.h> 21 #include <appexecfwk_errors.h> 22 #include <bundle_manager.h> 23 #include <cstring> 24 #include <ctime> 25 #include <ohos_errno.h> 26 #include <samgr_lite.h> 27 #include <semaphore.h> 28 #include <want_utils.h> 29 30 namespace OHOS { 31 constexpr uint32_t WAIT_TIMEOUT = 30; 32 constexpr char ABILITY_STATE[] = "Ability State: ["; 33 constexpr char NO_ABILITY[] = "Ability not found"; 34 constexpr char SLICE_STACK[] = "\n ["; 35 constexpr char SLICE_STATE[] = "] State: ["; 36 37 static sem_t g_sem; 38 static bool g_result = false; 39 static std::string g_resultString; 40 41 SvcIdentity AbilityTestHelper::identity_ = {}; 42 IClientProxy *AbilityTestHelper::proxy_ = nullptr; 43 IpcObjectStub AbilityTestHelper::objectStub_ = {}; 44 Initialize()45 void AbilityTestHelper::Initialize() 46 { 47 objectStub_.func = AbilityCallback; 48 objectStub_.args = nullptr; 49 objectStub_.isRemote = false; 50 identity_.handle = IPC_INVALID_HANDLE; 51 identity_.token = SERVICE_TYPE_ANONYMOUS; 52 identity_.cookie = reinterpret_cast<uintptr_t>(&objectStub_); 53 54 proxy_ = GetAbilityInnerFeature(); 55 if (proxy_ == nullptr) { 56 exit(-1); 57 } 58 sleep(1); 59 } 60 UnInitialize()61 void AbilityTestHelper::UnInitialize() 62 { 63 sleep(1); 64 } 65 InstallCallback(const uint8_t resultCode,const void * resultMessage)66 void AbilityTestHelper::InstallCallback(const uint8_t resultCode, const void *resultMessage) 67 { 68 std::string strMessage = reinterpret_cast<const char *>(resultMessage); 69 if (!strMessage.empty()) { 70 printf("install resultMessage is %s\n", strMessage.c_str()); 71 } 72 73 g_result = (resultCode == ERR_OK); 74 SemPost(); 75 } 76 UninstallCallback(const uint8_t resultCode,const void * resultMessage)77 void AbilityTestHelper::UninstallCallback(const uint8_t resultCode, const void *resultMessage) 78 { 79 std::string strMessage = reinterpret_cast<const char *>(resultMessage); 80 if (!strMessage.empty()) { 81 printf("[INFO] [AbilityTestHelper] uninstall resultMessage is %s\n", strMessage.c_str()); 82 } 83 84 g_result = (resultCode == ERR_OK); 85 SemPost(); 86 } 87 AbilityCallback(uint32_t code,IpcIo * data,IpcIo * reply,MessageOption option)88 int32_t AbilityTestHelper::AbilityCallback(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option) 89 { 90 switch (code) 91 { 92 case SCHEDULER_APP_INIT: { 93 ElementName element = {}; 94 DeserializeElement(&element, data); 95 int32_t ret = 0; 96 ReadInt32(data, &ret); 97 printf("ams call back, start %s.%s ret = %d\n", element.bundleName, element.abilityName, ret); 98 ClearElement(&element); 99 g_result = (ret == EC_SUCCESS); 100 break; 101 } 102 case SCHEDULER_DUMP_ABILITY: { 103 size_t len = 0; 104 g_resultString = reinterpret_cast<char *>(ReadString(data, &len)); 105 break; 106 } 107 default: { 108 printf("ams call back error, funcId: %u\n", code); 109 break; 110 } 111 } 112 113 SemPost(); 114 return 0; 115 } 116 TestInstall(const std::string & hap)117 bool AbilityTestHelper::TestInstall(const std::string &hap) 118 { 119 InstallParam installParam = { 120 .installLocation = 1, 121 .keepData = false 122 }; 123 if (!Install(hap.c_str(), &installParam, InstallCallback)) { 124 printf("[ERROR] [AbilityTestHelper] Install hap failed!\n"); 125 exit(-1); 126 } 127 g_result = true; 128 SemWait(); 129 return g_result; 130 } 131 TestUnInstall(const std::string & bundleName)132 bool AbilityTestHelper::TestUnInstall(const std::string &bundleName) 133 { 134 InstallParam installParam = { 135 .installLocation = 1, 136 .keepData = false 137 }; 138 bool ret = Uninstall(bundleName.c_str(), &installParam, UninstallCallback); 139 SemWait(); 140 return ret; 141 } 142 TestStartAbility(const Want & want)143 bool AbilityTestHelper::TestStartAbility(const Want &want) 144 { 145 SetWantSvcIdentity(const_cast<Want *>(&want), identity_); 146 int32_t ret = StartAbility(&want); 147 g_result = (ERR_OK == ret); 148 SemWait(); 149 sleep(1); 150 return g_result; 151 } 152 TestTerminateApp(const std::string & bundleName)153 bool AbilityTestHelper::TestTerminateApp(const std::string &bundleName) 154 { 155 IpcIo req; 156 char data[MAX_IO_SIZE]; 157 IpcIoInit(&req, data, MAX_IO_SIZE, 0); 158 WriteString(&req, bundleName.c_str()); 159 int32_t ret = proxy_->Invoke(proxy_, TERMINATE_APP, &req, nullptr, nullptr); 160 sleep(2); 161 return ret == EC_SUCCESS; 162 } 163 GetAbilityState(const ElementName & elementName)164 State AbilityTestHelper::GetAbilityState(const ElementName &elementName) 165 { 166 TestDumpAbility(elementName); 167 168 auto position = g_resultString.find(ABILITY_STATE); 169 if (position != std::string::npos) { 170 return static_cast<State>(g_resultString[position + strlen(ABILITY_STATE)] - '0'); 171 } 172 173 if (g_resultString.find(NO_ABILITY) != std::string::npos) { 174 return STATE_INITIAL; 175 } 176 printf("[ERROR] [AbilityTestHelper] Failed to GetAbilityState\n"); 177 return STATE_UNINITIALIZED; 178 } 179 GetSliceStack(const ElementName & elementName)180 std::list<std::shared_ptr<SliceRecord>> AbilityTestHelper::GetSliceStack(const ElementName &elementName) 181 { 182 TestDumpAbility(elementName); 183 std::list<std::shared_ptr<SliceRecord>> sliceList; 184 std::string::size_type begin; 185 std::string::size_type end = 0; 186 187 while (((begin = g_resultString.find(SLICE_STACK, end)) != std::string::npos) && 188 ((end = g_resultString.find(SLICE_STATE, begin)) != std::string::npos)) { 189 auto record = std::make_shared<SliceRecord>(); 190 record->name = g_resultString.substr(begin + strlen(SLICE_STACK), end); 191 record->state = static_cast<State>(g_resultString[end + strlen(SLICE_STATE)] - '0'); 192 sliceList.push_back(record); 193 } 194 195 return sliceList; 196 } 197 GetAbilityInnerFeature()198 IClientProxy *AbilityTestHelper::GetAbilityInnerFeature() 199 { 200 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(AMS_SERVICE, AMS_INNER_FEATURE); 201 if (iUnknown == nullptr) { 202 printf("ams inner unknown is null\n"); 203 return nullptr; 204 } 205 IClientProxy *innerProxy = nullptr; 206 (void)iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&innerProxy); 207 if (innerProxy == nullptr) { 208 printf("ams inner feature is null\n"); 209 return nullptr; 210 } 211 return innerProxy; 212 } 213 TestDumpAbility(const ElementName & elementName)214 void AbilityTestHelper::TestDumpAbility(const ElementName &elementName) 215 { 216 IpcIo req; 217 char data[MAX_IO_SIZE]; 218 IpcIoInit(&req, data, MAX_IO_SIZE, 2); 219 Want want = {}; 220 SetWantElement(&want, elementName); 221 SetWantSvcIdentity(&want, identity_); 222 if (!SerializeWant(&req, &want)) { 223 printf("SerializeWant failed\n"); 224 ClearWant(&want); 225 exit(-1); 226 } 227 ClearWant(&want); 228 proxy_->Invoke(proxy_, DUMP_ABILITY, &req, nullptr, nullptr); 229 SemWait(); 230 231 printf("[Dump]\n%s\n", g_resultString.c_str()); 232 } 233 SemWait()234 void AbilityTestHelper::SemWait() 235 { 236 printf("waiting callback\n"); 237 sem_init(&g_sem, 0, 0); 238 struct timespec ts = {}; 239 clock_gettime(CLOCK_REALTIME, &ts); 240 ts.tv_sec += WAIT_TIMEOUT; 241 sem_timedwait(&g_sem, &ts); 242 } 243 SemPost()244 void AbilityTestHelper::SemPost() 245 { 246 printf("receive callback\n"); 247 sem_post(&g_sem); 248 } 249 } 250 251