• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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