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 case SCHEDULER_APP_INIT: { 92 ElementName element = {}; 93 DeserializeElement(&element, data); 94 int32_t ret = 0; 95 ReadInt32(data, &ret); 96 printf("ams call back, start %s.%s ret = %d\n", element.bundleName, element.abilityName, ret); 97 ClearElement(&element); 98 g_result = (ret == EC_SUCCESS); 99 break; 100 } 101 case SCHEDULER_DUMP_ABILITY: { 102 size_t len = 0; 103 g_resultString = reinterpret_cast<char *>(ReadString(data, &len)); 104 break; 105 } 106 default: { 107 printf("ams call back error, funcId: %u\n", code); 108 break; 109 } 110 } 111 112 SemPost(); 113 return 0; 114 } 115 TestInstall(const std::string & hap)116 bool AbilityTestHelper::TestInstall(const std::string &hap) 117 { 118 InstallParam installParam = { 119 .installLocation = 1, 120 .keepData = false 121 }; 122 if (!Install(hap.c_str(), &installParam, InstallCallback)) { 123 printf("[ERROR] [AbilityTestHelper] Install hap failed!\n"); 124 exit(-1); 125 } 126 g_result = true; 127 SemWait(); 128 return g_result; 129 } 130 TestUnInstall(const std::string & bundleName)131 bool AbilityTestHelper::TestUnInstall(const std::string &bundleName) 132 { 133 InstallParam installParam = { 134 .installLocation = 1, 135 .keepData = false 136 }; 137 bool ret = Uninstall(bundleName.c_str(), &installParam, UninstallCallback); 138 SemWait(); 139 return ret; 140 } 141 TestStartAbility(const Want & want)142 bool AbilityTestHelper::TestStartAbility(const Want &want) 143 { 144 SetWantSvcIdentity(const_cast<Want *>(&want), identity_); 145 int32_t ret = StartAbility(&want); 146 g_result = (ERR_OK == ret); 147 SemWait(); 148 sleep(1); 149 return g_result; 150 } 151 TestTerminateApp(const std::string & bundleName)152 bool AbilityTestHelper::TestTerminateApp(const std::string &bundleName) 153 { 154 IpcIo req; 155 char data[MAX_IO_SIZE]; 156 IpcIoInit(&req, data, MAX_IO_SIZE, 0); 157 WriteString(&req, bundleName.c_str()); 158 int32_t ret = proxy_->Invoke(proxy_, TERMINATE_APP, &req, nullptr, nullptr); 159 sleep(2); // 2:出让CPU 160 return ret == EC_SUCCESS; 161 } 162 GetAbilityState(const ElementName & elementName)163 State AbilityTestHelper::GetAbilityState(const ElementName &elementName) 164 { 165 TestDumpAbility(elementName); 166 167 auto position = g_resultString.find(ABILITY_STATE); 168 if (position != std::string::npos) { 169 return static_cast<State>(g_resultString[position + strlen(ABILITY_STATE)] - '0'); 170 } 171 172 if (g_resultString.find(NO_ABILITY) != std::string::npos) { 173 return STATE_INITIAL; 174 } 175 printf("[ERROR] [AbilityTestHelper] Failed to GetAbilityState\n"); 176 return STATE_UNINITIALIZED; 177 } 178 GetSliceStack(const ElementName & elementName)179 std::list<std::shared_ptr<SliceRecord>> AbilityTestHelper::GetSliceStack(const ElementName &elementName) 180 { 181 TestDumpAbility(elementName); 182 std::list<std::shared_ptr<SliceRecord>> sliceList; 183 std::string::size_type begin; 184 std::string::size_type end = 0; 185 186 while (((begin = g_resultString.find(SLICE_STACK, end)) != std::string::npos) && 187 ((end = g_resultString.find(SLICE_STATE, begin)) != std::string::npos)) { 188 auto record = std::make_shared<SliceRecord>(); 189 record->name = g_resultString.substr(begin + strlen(SLICE_STACK), end); 190 record->state = static_cast<State>(g_resultString[end + strlen(SLICE_STATE)] - '0'); 191 sliceList.push_back(record); 192 } 193 194 return sliceList; 195 } 196 GetAbilityInnerFeature()197 IClientProxy *AbilityTestHelper::GetAbilityInnerFeature() 198 { 199 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(AMS_SERVICE, AMS_INNER_FEATURE); 200 if (iUnknown == nullptr) { 201 printf("ams inner unknown is null\n"); 202 return nullptr; 203 } 204 IClientProxy *innerProxy = nullptr; 205 (void)iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&innerProxy); 206 if (innerProxy == nullptr) { 207 printf("ams inner feature is null\n"); 208 return nullptr; 209 } 210 return innerProxy; 211 } 212 TestDumpAbility(const ElementName & elementName)213 void AbilityTestHelper::TestDumpAbility(const ElementName &elementName) 214 { 215 IpcIo req; 216 char data[MAX_IO_SIZE]; 217 IpcIoInit(&req, data, MAX_IO_SIZE, 2); // 2:IPC初始化 218 Want want = {}; 219 SetWantElement(&want, elementName); 220 SetWantSvcIdentity(&want, identity_); 221 if (!SerializeWant(&req, &want)) { 222 printf("SerializeWant failed\n"); 223 ClearWant(&want); 224 exit(-1); 225 } 226 ClearWant(&want); 227 proxy_->Invoke(proxy_, DUMP_ABILITY, &req, nullptr, nullptr); 228 SemWait(); 229 230 printf("[Dump]\n%s\n", g_resultString.c_str()); 231 } 232 SemWait()233 void AbilityTestHelper::SemWait() 234 { 235 printf("waiting callback\n"); 236 sem_init(&g_sem, 0, 0); 237 struct timespec ts = {}; 238 clock_gettime(CLOCK_REALTIME, &ts); 239 ts.tv_sec += WAIT_TIMEOUT; 240 sem_timedwait(&g_sem, &ts); 241 } 242 SemPost()243 void AbilityTestHelper::SemPost() 244 { 245 printf("receive callback\n"); 246 sem_post(&g_sem); 247 } 248 } 249 250