Test the overall function of the framework

Signed-off-by: njupthan <hanhaibin@huawei.com>
This commit is contained in:
njupthan 2022-01-28 15:06:40 +08:00
parent 723daf0edd
commit 54fcdb6a94
90 changed files with 5016 additions and 4 deletions

View File

@ -282,6 +282,32 @@ public:
return 0;
}
virtual int StartUserTest(const Want &want, const sptr<IRemoteObject> &observer) override
{
return 0;
}
virtual int FinishUserTest(const std::string &msg, const int &resultCode,
const std::string &bundleName, const sptr<IRemoteObject> &observer) override
{
return 0;
}
virtual int GetCurrentTopAbility(sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int DelegatorDoAbilityForeground(const sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int DelegatorDoAbilityBackground(const sptr<IRemoteObject> &token) override
{
return 0;
}
sptr<IAbilityScheduler> abilityScheduler_ = nullptr; // kit interface used to schedule ability life
Want want_;
bool startAbility = false;

View File

@ -275,6 +275,32 @@ public:
return true;
}
virtual int StartUserTest(const Want &want, const sptr<IRemoteObject> &observer) override
{
return 0;
}
virtual int FinishUserTest(const std::string &msg, const int &resultCode,
const std::string &bundleName, const sptr<IRemoteObject> &observer) override
{
return 0;
}
virtual int GetCurrentTopAbility(sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int DelegatorDoAbilityForeground(const sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int DelegatorDoAbilityBackground(const sptr<IRemoteObject> &token) override
{
return 0;
}
enum RequestCode {
E_STATE_INITIAL = 0,
E_STATE_INACTIVE,

View File

@ -38,6 +38,7 @@ config("appkit_public_config") {
"//base/global/resmgr_standard/interfaces/innerkits/include",
"//base/global/i18n_standard/frameworks/intl/include",
"//third_party/icu/icu4c/source/common",
"${aafwk_path}/frameworks/kits/appkit/native/ability_delegator/include",
]
}
@ -93,6 +94,7 @@ ohos_shared_library("appkit_native") {
"${aafwk_path}/frameworks/kits/appkit/native/ability_runtime/context",
"${aafwk_path}/frameworks/kits/appkit/native",
"${aafwk_path}/frameworks/kits/ability/native/include",
"${aafwk_path}/frameworks/kits/appkit/native/ability_delegator/include",
"${aafwk_path}/interfaces/innerkits/ability_manager/include",
"${aafwk_path}/services/abilitymgr/include",
"//utils/native/base/include",
@ -123,6 +125,14 @@ ohos_shared_library("appkit_native") {
"${aafwk_path}/frameworks/kits/appkit/native/app/src/context_container.cpp",
#"${aafwk_path}/frameworks/kits/appkit/native/app/main.cpp",
"${aafwk_path}/frameworks/kits/appkit/native/ability_delegator/src/ability_delegator.cpp",
"${aafwk_path}/frameworks/kits/appkit/native/ability_delegator/src/ability_delegator_args.cpp",
"${aafwk_path}/frameworks/kits/appkit/native/ability_delegator/src/ability_delegator_registry.cpp",
"${aafwk_path}/frameworks/kits/appkit/native/ability_delegator/src/delegator_thread.cpp",
"${aafwk_path}/frameworks/kits/appkit/native/ability_delegator/src/iability_monitor.cpp",
"${aafwk_path}/frameworks/kits/appkit/native/ability_delegator/src/runner_runtime/js_test_runner.cpp",
"${aafwk_path}/frameworks/kits/appkit/native/ability_delegator/src/shell_cmd_result.cpp",
"${aafwk_path}/frameworks/kits/appkit/native/ability_delegator/src/test_runner.cpp",
"${aafwk_path}/frameworks/kits/appkit/native/ability_runtime/app/ability_stage.cpp",
"${aafwk_path}/frameworks/kits/appkit/native/ability_runtime/app/js_ability_stage.cpp",
"${aafwk_path}/frameworks/kits/appkit/native/app/src/context_deal.cpp",
@ -130,6 +140,7 @@ ohos_shared_library("appkit_native") {
"${aafwk_path}/frameworks/kits/appkit/native/app/src/ohos_application.cpp",
"${aafwk_path}/frameworks/kits/appkit/native/app/src/sys_mgr_client.cpp",
"${aafwk_path}/frameworks/kits/appkit/native/app/src/watchdog.cpp",
"//foundation/aafwk/standard/tools/aa/src/shell_command_result.cpp",
]
cflags = []
if (target_cpu == "arm") {

View File

@ -0,0 +1,127 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef FOUNDATION_APPEXECFWK_OHOS_ABILITY_DELEGATOR_H
#define FOUNDATION_APPEXECFWK_OHOS_ABILITY_DELEGATOR_H
#include <list>
#include <memory>
#include <mutex>
#include <optional>
#include <string>
#include <tuple>
#include <vector>
#include "iability_monitor.h"
#include "delegator_thread.h"
#include "shell_cmd_result.h"
#include "test_runner.h"
#include "ability_lifecycle_callbacks.h"
#include "ability_lifecycle_executor.h"
#include "ability_runtime/context/context.h"
#include "main_thread.h"
namespace OHOS {
namespace AppExecFwk {
class AbilityDelegator : public AbilityLifecycleCallbacks, public std::enable_shared_from_this<AbilityDelegator> {
public:
enum class AbilityState : uint8_t {
UNINITIALIZED = 0,
STARTED,
FOREGROUND,
BACKGROUND,
STOPED
};
using ability_property = std::tuple<sptr<IRemoteObject>, std::shared_ptr<Ability>, AbilityDelegator::AbilityState>;
using list_ability_property = std::list<ability_property>;
public:
AbilityDelegator(const sptr<MainThread> &mainThread, std::unique_ptr<TestRunner> runner,
const sptr<IRemoteObject> &observer);
~AbilityDelegator();
void Init();
void OnAbilityStart(const std::shared_ptr<Ability> &ability) override;
void OnAbilityInactive(const std::shared_ptr<Ability> &ability) override;
void OnAbilityBackground(const std::shared_ptr<Ability> &ability) override;
void OnAbilityForeground(const std::shared_ptr<Ability> &ability) override;
void OnAbilityActive(const std::shared_ptr<Ability> &ability) override;
void OnAbilityStop(const std::shared_ptr<Ability> &ability) override;
void OnAbilitySaveState(const PacMap &outState) override;
void AddAbilityMonitor(const std::shared_ptr<IAbilityMonitor> &monitor);
void RemoveAbilityMonitor(const std::shared_ptr<IAbilityMonitor> &monitor);
void ClearAllMonitors();
size_t GetMonitorsNum();
sptr<IRemoteObject> WaitAbilityMonitor(const std::shared_ptr<IAbilityMonitor> &monitor);
sptr<IRemoteObject> WaitAbilityMonitor(
const std::shared_ptr<IAbilityMonitor> &monitor, const int64_t timeoutMs);
std::shared_ptr<AbilityRuntime::Context> GetAppContext() const;
AbilityDelegator::AbilityState GetAbilityState(const sptr<IRemoteObject> &token);
sptr<IRemoteObject> GetCurrentTopAbility();
std::string GetThreadName() const;
void Prepare();
void OnRun();
bool DoAbilityForeground(const sptr<IRemoteObject> &token);
bool DoAbilityBackground(const sptr<IRemoteObject> &token);
std::unique_ptr<ShellCmdResult> ExecuteShellCommand(const std::string &cmd, const int64_t timeoutMs);
void Print(const std::string &msg);
void PrePerformStart(const std::shared_ptr<Ability> &ability);
void PostPerformStart(const std::shared_ptr<Ability> &ability);
void PrePerformScenceCreated(const std::shared_ptr<Ability> &ability);
void PrePerformScenceRestored(const std::shared_ptr<Ability> &ability);
void PrePerformScenceDestroyed(const std::shared_ptr<Ability> &ability);
void PrePerformForeground(const std::shared_ptr<Ability> &ability);
void PrePerformBackground(const std::shared_ptr<Ability> &ability);
void PrePerformStop(const std::shared_ptr<Ability> &ability);
private:
AbilityDelegator::AbilityState ConvertAbilityState(const AbilityLifecycleExecutor::LifecycleState lifecycleState);
void ProcessAbilityProperties(const std::shared_ptr<Ability> &ability);
sptr<IRemoteObject> GetAbilityToken(const std::shared_ptr<Ability> &ability);
std::optional<ability_property> DoesPropertyExist(const sptr<IRemoteObject> &token);
void FinishUserTest(const int32_t resultCode);
private:
static constexpr size_t FIRST_PROPERTY {0};
static constexpr size_t SECOND_PROPERTY {1};
static constexpr size_t THIRD_PROPERTY {2};
private:
sptr<MainThread> mainThread_;
std::unique_ptr<TestRunner> testRunner_;
std::unique_ptr<DelegatorThread> delegatorThread_;
list_ability_property abilityProperties_;
std::vector<std::shared_ptr<IAbilityMonitor>> abilityMonitors_;
std::shared_ptr<AbilityRuntime::Context> appContext_;
sptr<IRemoteObject> observer_;
std::mutex mutexMonitor_;
std::mutex mutexAbilityProperties_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_OHOS_ABILITY_DELEGATOR_H

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef FOUNDATION_APPEXECFWK_OHOS_ABILITY_DELEGATOR_ARGS_H
#define FOUNDATION_APPEXECFWK_OHOS_ABILITY_DELEGATOR_ARGS_H
#include <map>
#include <string>
#include "want.h"
namespace OHOS {
namespace AppExecFwk {
class AbilityDelegatorArgs {
public:
static const std::string KEY_TEST_RUNNER_CLASS;
static const std::string KEY_TEST_CASE;
public:
AbilityDelegatorArgs();
explicit AbilityDelegatorArgs(const AAFwk::Want &want);
~AbilityDelegatorArgs();
void SetTestBundleName(const std::string &bundleName);
std::string GetTestBundleName() const;
std::string GetTestRunnerClassName() const;
std::string GetTestCaseName() const;
void SetTestParam(const std::map<std::string, std::string> &params);
std::map<std::string, std::string> GetTestParam() const;
private:
std::string bundleName_;
std::map<std::string, std::string> params_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_OHOS_ABILITY_DELEGATOR_ARGS_H

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef FOUNDATION_APPEXECFWK_OHOS_ABILITY_DELEGATOR_REGISTRY_H
#define FOUNDATION_APPEXECFWK_OHOS_ABILITY_DELEGATOR_REGISTRY_H
#include <memory>
#include "ability_delegator.h"
#include "ability_delegator_args.h"
namespace OHOS {
namespace AppExecFwk {
class AbilityDelegatorRegistry {
public:
static std::shared_ptr<AbilityDelegator> GetAbilityDelegator();
static std::shared_ptr<AbilityDelegatorArgs> GetArguments();
static void RegisterInstance(
const std::shared_ptr<AbilityDelegator> &delegator, const std::shared_ptr<AbilityDelegatorArgs> &args);
private:
static std::shared_ptr<AbilityDelegator> abilityDelegator_;
static std::shared_ptr<AbilityDelegatorArgs> abilityDelegatorArgs_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_OHOS_ABILITY_DELEGATOR_REGISTRY_H

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef FOUNDATION_APPEXECFWK_OHOS_DELEGATOR_THREAD_H
#define FOUNDATION_APPEXECFWK_OHOS_DELEGATOR_THREAD_H
#include <functional>
#include <memory>
#include <string>
#include "event_handler.h"
#include "event_runner.h"
namespace OHOS {
namespace AppExecFwk {
class DelegatorThread {
public:
using DTask = std::function<void()>;
public:
explicit DelegatorThread(bool isMain = false);
~DelegatorThread() = default;
bool Run(const DTask &task);
std::string GetThreadName() const;
private:
std::string threadName_;
std::shared_ptr<EventRunner> runner_;
std::shared_ptr<EventHandler> handler_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_OHOS_DELEGATOR_THREAD_H

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef FOUNDATION_APPEXECFWK_OHOS_IABILITY_MONITORE_H
#define FOUNDATION_APPEXECFWK_OHOS_IABILITY_MONITORE_H
#include <condition_variable>
#include <chrono>
#include <memory>
#include <mutex>
#include <string>
#include <thread>
#include "ability.h"
#include "want.h"
namespace OHOS {
namespace AppExecFwk {
class IAbilityMonitor {
public:
static constexpr int64_t MAX_TIME_OUT {5000};
public:
explicit IAbilityMonitor(const std::string &abilityName);
virtual ~IAbilityMonitor() = default;
virtual bool Match(const std::shared_ptr<Ability> &ability, const Want &want);
virtual std::shared_ptr<Ability> waitForAbility();
virtual std::shared_ptr<Ability> waitForAbility(const int64_t timeoutMs);
virtual void OnAbilityStart();
virtual void OnAbilityForeground();
virtual void OnAbilityBackground();
virtual void OnAbilityStop();
virtual void OnWindowStageCreate();
virtual void OnWindowStageRestore();
virtual void OnWindowStageDestroy();
private:
std::string abilityName_;
std::shared_ptr<Ability> matchedAbility_;
std::condition_variable cvMatch_;
std::mutex mMatch_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_OHOS_IABILITY_MONITORE_H

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef RUNNER_RUNTIME_JS_TEST_RUNNER_H
#define RUNNER_RUNTIME_JS_TEST_RUNNER_H
#include "js_runtime.h"
#include "test_runner.h"
class NativeReference;
class NativeValue;
namespace OHOS {
namespace RunnerRuntime {
using namespace AppExecFwk;
using namespace AbilityRuntime;
class JsTestRunner : public TestRunner {
public:
static std::unique_ptr<TestRunner> Create(
const std::unique_ptr<Runtime> &runtime, const std::shared_ptr<AbilityDelegatorArgs> &args);
JsTestRunner(JsRuntime &jsRuntime, const std::shared_ptr<AbilityDelegatorArgs> &args);
~JsTestRunner() override;
void Prepare() override;
void Run() override;
private:
void CallObjectMethod(const char *name, NativeValue *const *argv = nullptr, size_t argc = 0);
JsRuntime &jsRuntime_;
std::unique_ptr<NativeReference> jsTestRunnerObj_;
};
} // namespace RunnerRuntime
} // namespace OHOS
#endif // RUNNER_RUNTIME_JS_TEST_RUNNER_H

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef FOUNDATION_APPEXECFWK_OHOS_SHELL_CMD_RESULT_H
#define FOUNDATION_APPEXECFWK_OHOS_SHELL_CMD_RESULT_H
#include <string>
#include "shell_command_result.h"
namespace OHOS {
namespace AppExecFwk {
class ShellCmdResult {
public:
ShellCmdResult() = default;
ShellCmdResult(const int32_t exitCode, const std::string &stdResult);
ShellCmdResult(const AAFwk::ShellCommandResult &result);
~ShellCmdResult() = default;
void SetExitCode(const int32_t exitCode);
int32_t GetExitCode() const;
void SetStdResult(const std::string &stdResult);
std::string GetStdResult() const;
std::string Dump();
private:
int32_t exitCode_ {-1};
std::string stdResult_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_OHOS_SHELL_CMD_RESULT_H

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef FOUNDATION_APPEXECFWK_OHOS_TEST_RUNNER_H
#define FOUNDATION_APPEXECFWK_OHOS_TEST_RUNNER_H
#include <memory>
#include "ability_delegator_args.h"
namespace OHOS {
namespace AbilityRuntime {
class Runtime;
}
namespace AppExecFwk {
class TestRunner {
public:
static std::unique_ptr<TestRunner> Create(const std::unique_ptr<AbilityRuntime::Runtime>& runtime,
const std::shared_ptr<AbilityDelegatorArgs> &args);
TestRunner() = default;
virtual ~TestRunner() = default;
virtual void Prepare();
virtual void Run();
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_OHOS_TEST_RUNNER_H

View File

@ -0,0 +1,600 @@
/*
* Copyright (c) 2021 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_delegator.h"
#include "app_log_wrapper.h"
#include "ohos_application.h"
#include "ability_manager_client.h"
#include "ability_delegator_registry.h"
#include "itest_observer.h"
namespace OHOS {
namespace AppExecFwk {
AbilityDelegator::AbilityDelegator(const sptr<MainThread> &mainThread, std::unique_ptr<TestRunner> runner,
const sptr<IRemoteObject> &observer)
: mainThread_(mainThread), testRunner_(std::move(runner)), observer_(observer)
{}
AbilityDelegator::~AbilityDelegator()
{
if (mainThread_) {
auto app = mainThread_->GetApplication();
if (app) {
app->UnregisterAbilityLifecycleCallbacks(shared_from_this());
}
}
}
void AbilityDelegator::Init()
{
APP_LOGI("Enter");
if (!mainThread_) {
APP_LOGE("Invalid mainThread");
return;
}
auto app = mainThread_->GetApplication();
if (!app) {
APP_LOGE("Invalid application");
return;
}
appContext_ = app->GetAppContext();
app->RegisterAbilityLifecycleCallbacks(shared_from_this());
}
void AbilityDelegator::OnAbilityStart(const std::shared_ptr<Ability> &ability)
{
ProcessAbilityProperties(ability);
}
void AbilityDelegator::OnAbilityInactive(const std::shared_ptr<Ability> &ability)
{}
void AbilityDelegator::OnAbilityBackground(const std::shared_ptr<Ability> &ability)
{
ProcessAbilityProperties(ability);
}
void AbilityDelegator::OnAbilityForeground(const std::shared_ptr<Ability> &ability)
{
ProcessAbilityProperties(ability);
}
void AbilityDelegator::OnAbilityActive(const std::shared_ptr<Ability> &ability)
{}
void AbilityDelegator::OnAbilityStop(const std::shared_ptr<Ability> &ability)
{
ProcessAbilityProperties(ability);
}
void AbilityDelegator::OnAbilitySaveState(const PacMap &outState)
{}
void AbilityDelegator::AddAbilityMonitor(const std::shared_ptr<IAbilityMonitor> &monitor)
{
if (!monitor) {
APP_LOGW("Invalid input parameter");
return;
}
std::unique_lock<std::mutex> lck(mutexMonitor_);
auto pos = std::find(abilityMonitors_.begin(), abilityMonitors_.end(), monitor);
if (pos != abilityMonitors_.end()) {
APP_LOGW("Monitor has been added");
return;
}
abilityMonitors_.emplace_back(monitor);
}
void AbilityDelegator::RemoveAbilityMonitor(const std::shared_ptr<IAbilityMonitor> &monitor)
{
if (!monitor) {
APP_LOGW("Invalid input parameter");
return;
}
std::unique_lock<std::mutex> lck(mutexMonitor_);
auto pos = std::find(abilityMonitors_.begin(), abilityMonitors_.end(), monitor);
if (pos != abilityMonitors_.end()) {
abilityMonitors_.erase(pos);
}
}
void AbilityDelegator::ClearAllMonitors()
{
std::unique_lock<std::mutex> lck(mutexMonitor_);
abilityMonitors_.clear();
}
size_t AbilityDelegator::GetMonitorsNum()
{
std::unique_lock<std::mutex> lck(mutexMonitor_);
return abilityMonitors_.size();
}
sptr<IRemoteObject> AbilityDelegator::WaitAbilityMonitor(const std::shared_ptr<IAbilityMonitor> &monitor)
{
if (!monitor) {
APP_LOGW("Invalid input parameter");
return {};
}
AddAbilityMonitor(monitor);
auto obtainedAbility = monitor->waitForAbility();
if (!obtainedAbility) {
APP_LOGW("Invalid obtained ability");
return {};
}
return GetAbilityToken(obtainedAbility);
}
sptr<IRemoteObject> AbilityDelegator::WaitAbilityMonitor(
const std::shared_ptr<IAbilityMonitor> &monitor, const int64_t timeoutMs)
{
if (!monitor) {
APP_LOGW("Invalid input parameter");
return {};
}
AddAbilityMonitor(monitor);
auto obtainedAbility = monitor->waitForAbility(timeoutMs);
if (!obtainedAbility) {
APP_LOGW("Invalid obtained ability");
return {};
}
return GetAbilityToken(obtainedAbility);
}
std::shared_ptr<AbilityRuntime::Context> AbilityDelegator::GetAppContext() const
{
return appContext_;
}
AbilityDelegator::AbilityState AbilityDelegator::GetAbilityState(const sptr<IRemoteObject> &token)
{
if (!token) {
APP_LOGW("Invalid input parameter");
return AbilityDelegator::AbilityState::UNINITIALIZED;
}
std::unique_lock<std::mutex> lck(mutexAbilityProperties_);
auto existedProperty = DoesPropertyExist(token);
if (!existedProperty) {
APP_LOGW("Unknown ability token");
return AbilityDelegator::AbilityState::UNINITIALIZED;
}
return std::get<THIRD_PROPERTY>(existedProperty.value());
}
sptr<IRemoteObject> AbilityDelegator::GetCurrentTopAbility()
{
sptr<IRemoteObject> topAbilityToken;
if (AAFwk::AbilityManagerClient::GetInstance()->GetCurrentTopAbility(topAbilityToken)) {
APP_LOGE("Failed to get top ability");
return {};
}
return topAbilityToken;
}
std::string AbilityDelegator::GetThreadName() const
{
return {};
}
void AbilityDelegator::Prepare()
{
APP_LOGI("Enter");
if (!testRunner_) {
APP_LOGW("Invalid TestRunner");
return;
}
APP_LOGI("Call TestRunner::Prepare()");
testRunner_->Prepare();
if (!delegatorThread_) {
delegatorThread_ = std::make_unique<DelegatorThread>(true);
if (!delegatorThread_) {
APP_LOGE("Create delegatorThread failed");
return;
}
}
auto runTask = [this]() { this->OnRun(); };
if (!delegatorThread_->Run(runTask)) {
APP_LOGE("Run task on delegatorThread failed");
}
}
void AbilityDelegator::OnRun()
{
APP_LOGI("Enter");
if (!testRunner_) {
APP_LOGW("Invalid TestRunner");
return;
}
APP_LOGI("Call TestRunner::Run(), Start run");
testRunner_->Run();
APP_LOGI("Run finished");
FinishUserTest(0);
}
bool AbilityDelegator::DoAbilityForeground(const sptr<IRemoteObject> &token)
{
if (!token) {
APP_LOGW("Invalid input parameter");
return false;
}
if (AAFwk::AbilityManagerClient::GetInstance()->DelegatorDoAbilityForeground(token)) {
APP_LOGE("Failed to call DelegatorDoAbilityForeground");
return false;
}
return true;
}
bool AbilityDelegator::DoAbilityBackground(const sptr<IRemoteObject> &token)
{
if (!token) {
APP_LOGW("Invalid input parameter");
return false;
}
if (AAFwk::AbilityManagerClient::GetInstance()->DelegatorDoAbilityBackground(token)) {
APP_LOGE("Failed to call DelegatorDoAbilityBackground");
return false;
}
return true;
}
std::unique_ptr<ShellCmdResult> AbilityDelegator::ExecuteShellCommand(const std::string &cmd, const int64_t timeoutMs)
{
APP_LOGI("command : %{public}s, timeout : %{public}" PRId64, cmd.data(), timeoutMs);
if (cmd.empty()) {
APP_LOGE("Invalid cmd");
return {};
}
auto testObserver = iface_cast<ITestObserver>(observer_);
if (!testObserver) {
APP_LOGW("Invalid testObserver");
return {};
}
auto result = testObserver->ExecuteShellCommand(cmd, timeoutMs);
return std::make_unique<ShellCmdResult>(result);
}
void AbilityDelegator::Print(const std::string &msg)
{
auto testObserver = iface_cast<ITestObserver>(observer_);
if (!testObserver) {
APP_LOGW("Invalid testObserver");
return;
}
testObserver->TestStatus(msg, 0);
}
void AbilityDelegator::PrePerformStart(const std::shared_ptr<Ability> &ability)
{
if (!ability) {
APP_LOGW("Invalid input parameter");
return;
}
std::unique_lock<std::mutex> lck(mutexMonitor_);
if (abilityMonitors_.empty()) {
APP_LOGW("Empty abilityMonitors");
return;
}
for (auto &monitor : abilityMonitors_) {
if (!monitor) {
continue;
}
monitor->Match(ability, {});
monitor->OnAbilityStart();
}
}
void AbilityDelegator::PostPerformStart(const std::shared_ptr<Ability> &ability)
{
if (!ability) {
APP_LOGW("Invalid input parameter");
return;
}
std::unique_lock<std::mutex> lck(mutexMonitor_);
if (abilityMonitors_.empty()) {
APP_LOGW("Empty abilityMonitors");
return;
}
for (auto &monitor : abilityMonitors_) {
if (!monitor) {
continue;
}
monitor->Match(ability, {});
}
}
void AbilityDelegator::PrePerformScenceCreated(const std::shared_ptr<Ability> &ability)
{
if (!ability) {
APP_LOGW("Invalid input parameter");
return;
}
std::unique_lock<std::mutex> lck(mutexMonitor_);
if (abilityMonitors_.empty()) {
APP_LOGW("Empty abilityMonitors");
return;
}
for (auto &monitor : abilityMonitors_) {
if (!monitor) {
continue;
}
monitor->Match(ability, {});
monitor->OnWindowStageCreate();
}
}
void AbilityDelegator::PrePerformScenceRestored(const std::shared_ptr<Ability> &ability)
{
if (!ability) {
APP_LOGW("Invalid input parameter");
return;
}
std::unique_lock<std::mutex> lck(mutexMonitor_);
if (abilityMonitors_.empty()) {
APP_LOGW("Empty abilityMonitors");
return;
}
for (auto &monitor : abilityMonitors_) {
if (!monitor) {
continue;
}
monitor->Match(ability, {});
monitor->OnWindowStageRestore();
}
}
void AbilityDelegator::PrePerformScenceDestroyed(const std::shared_ptr<Ability> &ability)
{
if (!ability) {
APP_LOGW("Invalid input parameter");
return;
}
std::unique_lock<std::mutex> lck(mutexMonitor_);
if (abilityMonitors_.empty()) {
APP_LOGW("Empty abilityMonitors");
return;
}
for (auto &monitor : abilityMonitors_) {
if (!monitor) {
continue;
}
monitor->Match(ability, {});
monitor->OnWindowStageDestroy();
}
}
void AbilityDelegator::PrePerformForeground(const std::shared_ptr<Ability> &ability)
{
if (!ability) {
APP_LOGW("Invalid input parameter");
return;
}
std::unique_lock<std::mutex> lck(mutexMonitor_);
if (abilityMonitors_.empty()) {
APP_LOGW("Empty abilityMonitors");
return;
}
for (auto &monitor : abilityMonitors_) {
if (!monitor) {
continue;
}
monitor->Match(ability, {});
monitor->OnAbilityForeground();
}
}
void AbilityDelegator::PrePerformBackground(const std::shared_ptr<Ability> &ability)
{
if (!ability) {
APP_LOGW("Invalid input parameter");
return;
}
std::unique_lock<std::mutex> lck(mutexMonitor_);
if (abilityMonitors_.empty()) {
APP_LOGW("Empty abilityMonitors");
return;
}
for (auto &monitor : abilityMonitors_) {
if (!monitor) {
continue;
}
monitor->Match(ability, {});
monitor->OnAbilityBackground();
}
}
void AbilityDelegator::PrePerformStop(const std::shared_ptr<Ability> &ability)
{
if (!ability) {
APP_LOGW("Invalid input parameter");
return;
}
std::unique_lock<std::mutex> lck(mutexMonitor_);
if (abilityMonitors_.empty()) {
APP_LOGW("Empty abilityMonitors");
return;
}
for (auto &monitor : abilityMonitors_) {
if (!monitor) {
continue;
}
monitor->Match(ability, {});
monitor->OnAbilityStop();
}
}
AbilityDelegator::AbilityState AbilityDelegator::ConvertAbilityState(
const AbilityLifecycleExecutor::LifecycleState lifecycleState)
{
AbilityDelegator::AbilityState abilityState {AbilityDelegator::AbilityState::UNINITIALIZED};
switch (lifecycleState) {
case AbilityLifecycleExecutor::LifecycleState::STARTED_NEW:
abilityState = AbilityDelegator::AbilityState::STARTED;
break;
case AbilityLifecycleExecutor::LifecycleState::FOREGROUND_NEW:
abilityState = AbilityDelegator::AbilityState::FOREGROUND;
break;
case AbilityLifecycleExecutor::LifecycleState::BACKGROUND_NEW:
abilityState = AbilityDelegator::AbilityState::BACKGROUND;
break;
case AbilityLifecycleExecutor::LifecycleState::STOPED_NEW:
abilityState = AbilityDelegator::AbilityState::STOPED;
break;
default:
APP_LOGE("Unknown lifecycleState");
break;
}
return abilityState;
}
void AbilityDelegator::ProcessAbilityProperties(const std::shared_ptr<Ability> &ability)
{
if (!ability) {
APP_LOGW("Invalid ability");
return;
}
auto abilityToken = GetAbilityToken(ability);
if (!abilityToken) {
APP_LOGE("Invalid ability token");
return;
}
std::unique_lock<std::mutex> lck(mutexAbilityProperties_);
auto existedProperty = DoesPropertyExist(abilityToken);
if (existedProperty) {
abilityProperties_.remove(existedProperty.value());
}
auto abilityState = ConvertAbilityState(ability->GetState());
if (abilityState == AbilityDelegator::AbilityState::FOREGROUND) {
abilityProperties_.emplace_front(abilityToken, ability, abilityState);
} else {
abilityProperties_.emplace_back(abilityToken, ability, abilityState);
}
}
sptr<IRemoteObject> AbilityDelegator::GetAbilityToken(const std::shared_ptr<Ability> &ability)
{
if (!ability) {
APP_LOGW("Invalid ability");
return {};
}
auto abilityContext = ability->GetAbilityContext();
if (!abilityContext) {
APP_LOGE("Invalid ability context");
return {};
}
return abilityContext->GetAbilityToken();
}
std::optional<AbilityDelegator::ability_property> AbilityDelegator::DoesPropertyExist(const sptr<IRemoteObject> &token)
{
if (!token) {
APP_LOGW("Invalid input parameter");
return std::nullopt;
}
for (auto &it : abilityProperties_) {
auto tmpToken = std::get<FIRST_PROPERTY>(it);
if (token == tmpToken) {
return it;
}
}
return std::nullopt;
}
void AbilityDelegator::FinishUserTest(const int32_t resultCode)
{
APP_LOGI("Enter");
if (!mainThread_) {
APP_LOGE("Invalid mainThread");
return;
}
if (!observer_) {
APP_LOGE("Invalid observer");
return;
}
auto delegatorArgs = AbilityDelegatorRegistry::GetArguments();
if (!delegatorArgs) {
APP_LOGE("Invalid delegator args");
return;
}
const auto &bundleName = delegatorArgs->GetTestBundleName();
mainThread_->FinishUserTest("UserTest finished", resultCode, bundleName, observer_);
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 2021 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_delegator_args.h"
namespace OHOS {
namespace AppExecFwk {
const std::string AbilityDelegatorArgs::KEY_TEST_RUNNER_CLASS {"-s unittest"};
const std::string AbilityDelegatorArgs::KEY_TEST_CASE {"-s class"};
AbilityDelegatorArgs::AbilityDelegatorArgs()
{}
AbilityDelegatorArgs::AbilityDelegatorArgs(const AAFwk::Want &want)
{
bundleName_ = want.GetStringParam("-p");
params_["-p"] = want.GetStringParam("-p");
params_["-s unittest"] = want.GetStringParam("-s unittest");
params_["-s class"] = want.GetStringParam("-s class");
if (!want.GetStringParam("-w").empty()) {
params_["-w"] = want.GetStringParam("-w");
}
}
AbilityDelegatorArgs::~AbilityDelegatorArgs()
{}
void AbilityDelegatorArgs::SetTestBundleName(const std::string &bundleName)
{
bundleName_ = bundleName;
}
std::string AbilityDelegatorArgs::GetTestBundleName() const
{
return bundleName_;
}
std::string AbilityDelegatorArgs::GetTestRunnerClassName() const
{
auto target = params_.find(AbilityDelegatorArgs::KEY_TEST_RUNNER_CLASS);
if (target != params_.end()) {
return target->second;
}
return {};
}
std::string AbilityDelegatorArgs::GetTestCaseName() const
{
auto target = params_.find(AbilityDelegatorArgs::KEY_TEST_CASE);
if (target != params_.end()) {
return target->second;
}
return {};
}
void AbilityDelegatorArgs::SetTestParam(const std::map<std::string, std::string> &params)
{
params_ = params;
}
std::map<std::string, std::string> AbilityDelegatorArgs::GetTestParam() const
{
return params_;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2021 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_delegator_registry.h"
namespace OHOS {
namespace AppExecFwk {
std::shared_ptr<AbilityDelegator> AbilityDelegatorRegistry::abilityDelegator_ {};
std::shared_ptr<AbilityDelegatorArgs> AbilityDelegatorRegistry::abilityDelegatorArgs_ {};
std::shared_ptr<AbilityDelegator> AbilityDelegatorRegistry::GetAbilityDelegator()
{
return abilityDelegator_;
}
std::shared_ptr<AbilityDelegatorArgs> AbilityDelegatorRegistry::GetArguments()
{
return abilityDelegatorArgs_;
}
void AbilityDelegatorRegistry::RegisterInstance(
const std::shared_ptr<AbilityDelegator> &delegator, const std::shared_ptr<AbilityDelegatorArgs> &args)
{
abilityDelegator_ = delegator;
abilityDelegatorArgs_ = args;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2021 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 "delegator_thread.h"
#include "app_log_wrapper.h"
namespace OHOS {
namespace AppExecFwk {
DelegatorThread::DelegatorThread(bool isMain)
{
if (isMain) {
runner_ = EventRunner::GetMainEventRunner();
} else {
runner_ = EventRunner::Create();
}
handler_ = std::make_shared<EventHandler>(runner_);
}
bool DelegatorThread::Run(const DTask &task)
{
if (!task) {
APP_LOGW("Invalid input parameter");
return false;
}
if (!handler_) {
APP_LOGW("Invalid EventHandler");
return false;
}
return handler_->PostTask(task);
}
std::string DelegatorThread::GetThreadName() const
{
return threadName_;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 2021 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 "iability_monitor.h"
#include "app_log_wrapper.h"
using namespace std::chrono_literals;
namespace OHOS {
namespace AppExecFwk {
IAbilityMonitor::IAbilityMonitor(const std::string &abilityName) : abilityName_(abilityName)
{}
bool IAbilityMonitor::Match(const std::shared_ptr<Ability> &ability, const Want &want)
{
std::string aName;
if (ability) {
aName = ability->GetAbilityName();
} else {
aName = want.GetElement().GetAbilityName();
}
if (abilityName_.empty() || aName.empty()) {
APP_LOGW("Invalid name");
return false;
}
if (abilityName_.compare(aName)) {
APP_LOGW("Different name");
return false;
}
if (ability) {
{
std::lock_guard<std::mutex> matchLock(mMatch_);
matchedAbility_ = ability;
}
cvMatch_.notify_one();
return true;
}
return false;
}
std::shared_ptr<Ability> IAbilityMonitor::waitForAbility()
{
return waitForAbility(MAX_TIME_OUT);
}
std::shared_ptr<Ability> IAbilityMonitor::waitForAbility(const int64_t timeoutMs)
{
auto realTime = timeoutMs;
if (timeoutMs <= 0) {
APP_LOGW("Timeout should be a positive number");
realTime = MAX_TIME_OUT;
}
std::unique_lock<std::mutex> matchLock(mMatch_);
auto condition = [this] { return this->matchedAbility_ != nullptr; };
if (!cvMatch_.wait_for(matchLock, realTime * 1ms, condition)) {
APP_LOGW("Wait ability timeout");
}
return matchedAbility_;
}
void IAbilityMonitor::OnAbilityStart()
{}
void IAbilityMonitor::OnAbilityForeground()
{}
void IAbilityMonitor::OnAbilityBackground()
{}
void IAbilityMonitor::OnAbilityStop()
{}
void IAbilityMonitor::OnWindowStageCreate()
{}
void IAbilityMonitor::OnWindowStageRestore()
{}
void IAbilityMonitor::OnWindowStageDestroy()
{}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2021 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 "app_log_wrapper.h"
#include "js_runtime_utils.h"
#include "runner_runtime/js_test_runner.h"
namespace OHOS {
namespace RunnerRuntime {
std::unique_ptr<TestRunner> JsTestRunner::Create(
const std::unique_ptr<Runtime> &runtime, const std::shared_ptr<AbilityDelegatorArgs> &args)
{
return std::make_unique<JsTestRunner>(static_cast<JsRuntime &>(*runtime), args);
}
JsTestRunner::JsTestRunner(JsRuntime &jsRuntime, const std::shared_ptr<AbilityDelegatorArgs> &args)
: jsRuntime_(jsRuntime)
{
std::string srcPath;
srcPath.append(args->GetTestBundleName());
srcPath.append("/assets/js/");
srcPath.append(args->GetTestRunnerClassName());
srcPath.append(".abc");
APP_LOGI("JsTestRunner srcPath is %{public}s", srcPath.c_str());
std::string moduleName;
jsTestRunnerObj_ = jsRuntime_.LoadModule(moduleName, srcPath);
}
JsTestRunner::~JsTestRunner() = default;
void JsTestRunner::Prepare()
{
APP_LOGI("Enter");
TestRunner::Prepare();
CallObjectMethod("onPrepare");
APP_LOGI("End");
}
void JsTestRunner::Run()
{
APP_LOGI("Enter");
TestRunner::Run();
CallObjectMethod("onRun");
APP_LOGI("End");
}
void JsTestRunner::CallObjectMethod(const char *name, NativeValue *const *argv, size_t argc)
{
APP_LOGI("JsTestRunner::CallObjectMethod(%{public}s)", name);
if (!jsTestRunnerObj_) {
APP_LOGE("Not found test_runner.js");
return;
}
HandleScope handleScope(jsRuntime_);
auto &nativeEngine = jsRuntime_.GetNativeEngine();
NativeValue *value = jsTestRunnerObj_->Get();
NativeObject *obj = ConvertNativeValueTo<NativeObject>(value);
if (obj == nullptr) {
APP_LOGE("Failed to get Test Runner object");
return;
}
NativeValue *methodOnCreate = obj->GetProperty(name);
if (methodOnCreate == nullptr) {
APP_LOGE("Failed to get '%{public}s' from Test Runner object", name);
return;
}
nativeEngine.CallFunction(value, methodOnCreate, argv, argc);
}
} // namespace AbilityRuntime
} // namespace OHOS

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2021 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 "shell_cmd_result.h"
namespace OHOS {
namespace AppExecFwk {
ShellCmdResult::ShellCmdResult(const int32_t exitCode, const std::string &stdResult)
: exitCode_(exitCode), stdResult_(stdResult)
{}
ShellCmdResult::ShellCmdResult(const AAFwk::ShellCommandResult &result)
{
exitCode_ = result.exitCode;
stdResult_ = result.stdResult;
}
void ShellCmdResult::SetExitCode(const int32_t exitCode)
{
exitCode_ = exitCode;
}
int32_t ShellCmdResult::GetExitCode() const
{
return exitCode_;
}
void ShellCmdResult::SetStdResult(const std::string &stdResult)
{
stdResult_ = stdResult;
}
std::string ShellCmdResult::GetStdResult() const
{
return stdResult_;
}
std::string ShellCmdResult::Dump()
{
return "ShellCmdResult { exitCode = " + std::to_string(exitCode_) + ", stdResult = " + stdResult_ + "}";
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2021 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 "test_runner.h"
#include "runtime.h"
#include "runner_runtime/js_test_runner.h"
namespace OHOS {
namespace AppExecFwk {
std::unique_ptr<TestRunner> TestRunner::Create(const std::unique_ptr<AbilityRuntime::Runtime>& runtime,
const std::shared_ptr<AbilityDelegatorArgs> &args)
{
if (!runtime) {
return std::make_unique<TestRunner>();
}
switch (runtime->GetLanguage()) {
case AbilityRuntime::Runtime::Language::JS:
return RunnerRuntime::JsTestRunner::Create(runtime, args);
default:
return std::make_unique<TestRunner>();
}
}
void TestRunner::Prepare()
{}
void TestRunner::Run()
{}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -217,6 +217,18 @@ public:
void ScheduleAcceptWant(const AAFwk::Want &want, const std::string &moduleName) override;
/**
* @brief Finish user test.
* @param msg user test message.
* @param resultCode user test result Code.
* @param bundleName user test bundleName.
* @param observer test observer callback.
*
* @return Returns ERR_OK on success, others on failure.
*/
int FinishUserTest(const std::string &msg, const int &resultCode,
const std::string &bundleName, const sptr<IRemoteObject> &observer);
private:
/**
*
@ -404,6 +416,15 @@ private:
void LoadAndRegisterExtension(const std::string &libName, const std::string &extensionName,
const std::unique_ptr<Runtime>& runtime);
/**
*
* @brief Ability Delegator Prepare.
*
* @param UserTestRecord User Test info.
*
*/
bool AbilityDelegatorPrepare(const UserTestRecord &record);
class MainHandler : public EventHandler {
public:
MainHandler(const std::shared_ptr<EventRunner> &runner, const sptr<MainThread> &thread);

View File

@ -17,6 +17,8 @@
#include <new>
#include "ability_delegator.h"
#include "ability_delegator_registry.h"
#include "ability_loader.h"
#include "ability_thread.h"
#include "app_loader.h"
@ -849,6 +851,12 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con
}
application_->SetRuntime(std::move(runtime));
auto usertestInfo = appLaunchData.GetUserTestInfo();
if (usertestInfo.observer) {
if (!AbilityDelegatorPrepare(usertestInfo)) {
return;
}
}
AbilityLoader::GetInstance().RegisterAbility("Ability", [application = application_]() {
return Ability::Create(application->GetRuntime());
});
@ -933,6 +941,44 @@ void MainThread::LoadAndRegisterExtension(const std::string &libName,
});
}
bool MainThread::AbilityDelegatorPrepare(const UserTestRecord &record)
{
APP_LOGI("MainThread::AbilityDelegatorPrepare");
auto args = std::make_shared<AbilityDelegatorArgs>(record.want);
if (!args) {
APP_LOGE("args is null");
return false;
}
auto testRunner = TestRunner::Create(application_->GetRuntime(), args);
if (!testRunner) {
APP_LOGE("testRunner is null");
return false;
}
auto delegator = std::make_shared<AbilityDelegator>(this, std::move(testRunner), record.observer);
if (!delegator) {
APP_LOGE("delegator is null");
return false;
}
delegator->Init();
AbilityDelegatorRegistry::RegisterInstance(delegator, args);
delegator->Prepare();
return true;
}
int MainThread::FinishUserTest(const std::string &msg, const int &resultCode,
const std::string &bundleName, const sptr<IRemoteObject> &observer)
{
APP_LOGI("MainThread::FinishUserTest");
ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->FinishUserTest(
msg, resultCode, bundleName, observer);
if (err != ERR_OK) {
APP_LOGE("MainThread::FinishUserTest is failed %{public}d", err);
}
return ERR_OK;
}
/**
*
* @brief launch the ability.

View File

@ -238,6 +238,32 @@ public:
return true;
}
virtual int StartUserTest(const Want &want, const sptr<IRemoteObject> &observer) override
{
return 0;
}
virtual int FinishUserTest(const std::string &msg, const int &resultCode,
const std::string &bundleName, const sptr<IRemoteObject> &observer) override
{
return 0;
}
virtual int GetCurrentTopAbility(sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int DelegatorDoAbilityForeground(const sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int DelegatorDoAbilityBackground(const sptr<IRemoteObject> &token) override
{
return 0;
}
AbilityLifeCycleState curstate_ = AbilityLifeCycleState::ABILITY_STATE_INITIAL;
sptr<IAbilityScheduler> abilityScheduler_; // kit interface used to schedule ability life
Want want_;

View File

@ -259,6 +259,32 @@ public:
return true;
}
virtual int StartUserTest(const Want &want, const sptr<IRemoteObject> &observer) override
{
return 0;
}
virtual int FinishUserTest(const std::string &msg, const int &resultCode,
const std::string &bundleName, const sptr<IRemoteObject> &observer) override
{
return 0;
}
virtual int GetCurrentTopAbility(sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int DelegatorDoAbilityForeground(const sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int DelegatorDoAbilityBackground(const sptr<IRemoteObject> &token) override
{
return 0;
}
sptr<IAbilityScheduler> abilityScheduler_ = nullptr; // kit interface used to schedule ability life
Want want_;
bool startAbility = false;

View File

@ -685,6 +685,52 @@ public:
* @return Returns ERR_OK on success, others on failure.
*/
ErrCode SetMissionLabel(const sptr<IRemoteObject> &abilityToken, const std::string &label);
/**
* @brief start user test.
* @param want the want of the ability user test to start.
* @param observer test observer callback.
*
* @return Returns ERR_OK on success, others on failure.
*/
ErrCode StartUserTest(const Want &want, const sptr<IRemoteObject> &observer);
/**
* @brief Finish user test.
* @param msg user test message.
* @param resultCode user test result Code.
* @param bundleName user test bundleName.
* @param observer test observer callback.
*
* @return Returns ERR_OK on success, others on failure.
*/
ErrCode FinishUserTest(const std::string &msg, const int &resultCode,
const std::string &bundleName, const sptr<IRemoteObject> &observer);
/**
* GetCurrentTopAbility, get the token of current top ability.
*
* @param token, the token of current top ability.
* @return Returns ERR_OK on success, others on failure.
*/
ErrCode GetCurrentTopAbility(sptr<IRemoteObject> &token);
/**
* DelegatorDoAbilityForeground, the delegator calls this interface to move the ability to the foreground.
*
* @param token, ability's token.
* @return Returns ERR_OK on success, others on failure.
*/
ErrCode DelegatorDoAbilityForeground(const sptr<IRemoteObject> &token);
/**
* DelegatorDoAbilityBackground, the delegator calls this interface to move the ability to the background.
*
* @param token, ability's token.
* @return Returns ERR_OK on success, others on failure.
*/
ErrCode DelegatorDoAbilityBackground(const sptr<IRemoteObject> &token);
private:
static std::mutex mutex_;
static std::shared_ptr<AbilityManagerClient> instance_;

View File

@ -370,6 +370,11 @@ enum {
* Result() for invalid userid.
*/
INVALID_USERID_VALUE,
/**
* Result() for start user test fail.
*/
START_USER_TEST_FAIL,
};
enum {

View File

@ -640,6 +640,35 @@ public:
*/
virtual int RegisterSnapshotHandler(const sptr<ISnapshotHandler>& handler) = 0;
virtual int StartUserTest(const Want &want, const sptr<IRemoteObject> &observer) = 0;
virtual int FinishUserTest(const std::string &msg, const int &resultCode,
const std::string &bundleName, const sptr<IRemoteObject> &observer) = 0;
/**
* GetCurrentTopAbility, get the token of current top ability.
*
* @param token, the token of current top ability.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int GetCurrentTopAbility(sptr<IRemoteObject> &token) = 0;
/**
* The delegator calls this interface to move the ability to the foreground.
*
* @param token, ability's token.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int DelegatorDoAbilityForeground(const sptr<IRemoteObject> &token) = 0;
/**
* The delegator calls this interface to move the ability to the background.
*
* @param token, ability's token.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int DelegatorDoAbilityBackground(const sptr<IRemoteObject> &token) = 0;
/**
* Send not response process ID to ability manager service.
* @param pid The not response process ID.
@ -891,6 +920,13 @@ public:
REGISTER_SNAPSHOT_HANDLER = 1114,
GET_MISSION_SNAPSHOT_INFO = 1115,
// ipc id for user test(1120)
START_USER_TEST = 1120,
FINISH_USER_TEST = 1121,
DELEGATOR_DO_ABILITY_FOREGROUND = 1122,
DELEGATOR_DO_ABILITY_BACKGROUND = 1123,
GET_CURRENT_TOP_ABILITY = 1124,
// ipc id 2001-3000 for tools
// ipc id for dumping state (2001)
DUMP_STATE = 2001,

View File

@ -18,14 +18,27 @@
#include <string>
#include "iremote_object.h"
#include "parcel.h"
#include "application_info.h"
#include "process_info.h"
#include "profile.h"
#include "want.h"
namespace OHOS {
namespace AppExecFwk {
struct UserTestRecord : public Parcelable {
AAFwk::Want want;
sptr<IRemoteObject> observer;
UserTestRecord() : observer(nullptr)
{}
bool ReadFromParcel(Parcel &parcel);
virtual bool Marshalling(Parcel &parcel) const override;
static UserTestRecord *Unmarshalling(Parcel &parcel);
};
class AppLaunchData : public Parcelable {
public:
/**
@ -63,6 +76,13 @@ public:
*/
void SetUId(const int32_t);
/**
* @brief set user test info.
*
* @param UserTestRecord, user test info.
*/
void SetUserTestInfo(const UserTestRecord &record);
/**
* @brief Obtains the info of the application.
*
@ -113,6 +133,16 @@ public:
return uId_;
}
/**
* @brief get user test info.
*
* @return Returns user test info.
*/
inline const UserTestRecord &GetUserTestInfo() const
{
return userTestRecord_;
}
/**
* @brief read this Sequenceable object from a Parcel.
*
@ -141,6 +171,7 @@ private:
ProcessInfo processInfo_;
int32_t recordId_ = 0;
int32_t uId_ = 0;
UserTestRecord userTestRecord_;
};
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -18,10 +18,12 @@
#include "iremote_object.h"
#include "refbase.h"
#include "want.h"
#include "ability_info.h"
#include "application_info.h"
#include "app_mgr_constants.h"
#include "bundle_info.h"
#include "iapp_state_callback.h"
#include "running_process_info.h"
#include "system_memory_attr.h"
@ -241,6 +243,12 @@ public:
*/
virtual AppMgrResultCode UpdateConfiguration(const Configuration &config);
/**
* Start a user test
*/
virtual int StartUserTestProcess(const AAFwk::Want &want, const sptr<IRemoteObject> &observer,
const BundleInfo &bundleInfo);
virtual void StartSpecifiedAbility(const AAFwk::Want &want, const AppExecFwk::AbilityInfo &abilityInfo);
virtual void RegisterStartSpecifiedAbilityResponse(const sptr<IStartSpecifiedAbilityResponse> &response);

View File

@ -18,10 +18,12 @@
#include "iremote_broker.h"
#include "iremote_object.h"
#include "want.h"
#include "ability_info.h"
#include "application_info.h"
#include "app_record_id.h"
#include "bundle_info.h"
#include "iapp_state_callback.h"
#include "ams_mgr_interface.h"
#include "running_process_info.h"
@ -187,6 +189,16 @@ public:
*/
virtual int32_t GetForegroundApplications(std::vector<AppStateData> &list) = 0;
/**
* Start user test process.
* @param want, want object.
* @param observer, test observer remote object.
* @param bundleInfo, bundle info.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int StartUserTestProcess(const AAFwk::Want &want, const sptr<IRemoteObject> &observer,
const BundleInfo &bundleInfo) = 0;
virtual void ScheduleAcceptWantDone(const int32_t recordId, const AAFwk::Want &want, const std::string &flag) = 0;
enum class Message {
@ -209,6 +221,7 @@ public:
REGISTER_APPLICATION_STATE_OBSERVER,
UNREGISTER_APPLICATION_STATE_OBSERVER,
GET_FOREGROUND_APPLICATIONS,
START_USER_TEST_PROCESS,
SCHEDULE_ACCEPT_WANT_DONE,
};
};

View File

@ -17,8 +17,10 @@
#define FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_CORE_INCLUDE_APPMGR_APP_MGR_CLIENT_H
#include "iremote_proxy.h"
#include "want.h"
#include "app_mgr_interface.h"
#include "bundle_info.h"
namespace OHOS {
namespace AppExecFwk {
@ -179,6 +181,16 @@ public:
*/
virtual int32_t GetForegroundApplications(std::vector<AppStateData> &list) override;
/**
* Start user test process.
* @param want, want object.
* @param observer, test observer remote object.
* @param bundleInfo, bundle info.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int StartUserTestProcess(const AAFwk::Want &want, const sptr<IRemoteObject> &observer,
const BundleInfo &bundleInfo) override;
virtual void ScheduleAcceptWantDone(
const int32_t recordId, const AAFwk::Want &want, const std::string &flag) override;

View File

@ -74,6 +74,7 @@ private:
int32_t HandleRegisterApplicationStateObserver(MessageParcel &data, MessageParcel &reply);
int32_t HandleUnregisterApplicationStateObserver(MessageParcel &data, MessageParcel &reply);
int32_t HandleGetForegroundApplications(MessageParcel &data, MessageParcel &reply);
int32_t HandleStartUserTestProcess(MessageParcel &data, MessageParcel &reply);
int32_t HandleScheduleAcceptWantDone(MessageParcel &data, MessageParcel &reply);
using AppMgrFunc = int32_t (AppMgrStub::*)(MessageParcel &data, MessageParcel &reply);

View File

@ -44,10 +44,16 @@ void AppLaunchData::SetUId(const int32_t uId)
uId_ = uId;
}
void AppLaunchData::SetUserTestInfo(const UserTestRecord &record)
{
userTestRecord_ = record;
}
bool AppLaunchData::Marshalling(Parcel &parcel) const
{
return (parcel.WriteParcelable(&applicationInfo_) && parcel.WriteParcelable(&profile_) &&
parcel.WriteParcelable(&processInfo_) && parcel.WriteInt32(recordId_) && parcel.WriteInt32(uId_));
parcel.WriteParcelable(&processInfo_) && parcel.WriteInt32(recordId_) &&
parcel.WriteInt32(uId_) && parcel.WriteParcelable(&userTestRecord_));
}
bool AppLaunchData::ReadFromParcel(Parcel &parcel)
@ -75,6 +81,13 @@ bool AppLaunchData::ReadFromParcel(Parcel &parcel)
recordId_ = parcel.ReadInt32();
uId_ = parcel.ReadInt32();
std::unique_ptr<UserTestRecord> userTestRecord(parcel.ReadParcelable<UserTestRecord>());
if (!userTestRecord) {
APP_LOGE("failed, userTestRecord is nullptr");
return false;
}
userTestRecord_ = *userTestRecord;
return true;
}
@ -88,5 +101,59 @@ AppLaunchData *AppLaunchData::Unmarshalling(Parcel &parcel)
}
return appLaunchData;
}
bool UserTestRecord::Marshalling(Parcel &parcel) const
{
if (!parcel.WriteParcelable(&want)) {
APP_LOGE("Failed to write want");
return false;
}
auto valid = observer ? true : false;
if (!parcel.WriteBool(valid)) {
APP_LOGE("Failed to write the flag which indicate whether observer is null");
return false;
}
if (valid) {
if (!parcel.WriteParcelable(observer)) {
APP_LOGE("Failed to write observer");
return false;
}
}
return true;
}
UserTestRecord *UserTestRecord::Unmarshalling(Parcel &parcel)
{
UserTestRecord *userTestRecord = new (std::nothrow) UserTestRecord();
if (userTestRecord && !userTestRecord->ReadFromParcel(parcel)) {
APP_LOGW("failed, because ReadFromParcel failed");
delete userTestRecord;
userTestRecord = nullptr;
}
return userTestRecord;
}
bool UserTestRecord::ReadFromParcel(Parcel &parcel)
{
AAFwk::Want *wantPtr = parcel.ReadParcelable<AAFwk::Want>();
if (wantPtr == nullptr) {
APP_LOGE("wantPtr is nullptr");
return ERR_INVALID_VALUE;
}
want = *wantPtr;
delete wantPtr;
auto valid = parcel.ReadBool();
if (valid) {
observer = parcel.ReadParcelable<IRemoteObject>();
if (!observer) {
APP_LOGE("observer is nullptr");
return false;
}
}
return true;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -374,6 +374,17 @@ void AppMgrClient::StartupResidentProcess()
service->StartupResidentProcess();
}
int AppMgrClient::StartUserTestProcess(const AAFwk::Want &want, const sptr<IRemoteObject> &observer,
const BundleInfo &bundleInfo)
{
sptr<IAppMgr> service = iface_cast<IAppMgr>(remote_);
if (service == nullptr) {
APP_LOGE("service is nullptr");
return AppMgrResultCode::ERROR_SERVICE_NOT_READY;
}
return service->StartUserTestProcess(want, observer, bundleInfo);
}
void AppMgrClient::StartSpecifiedAbility(const AAFwk::Want &want, const AppExecFwk::AbilityInfo &abilityInfo)
{
sptr<IAppMgr> service = iface_cast<IAppMgr>(remote_);

View File

@ -534,6 +534,37 @@ int AppMgrProxy::GetForegroundApplications(std::vector<AppStateData> &list)
return reply.ReadInt32();
}
int AppMgrProxy::StartUserTestProcess(const AAFwk::Want &want, const sptr<IRemoteObject> &observer,
const BundleInfo &bundleInfo)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!WriteInterfaceToken(data)) {
return ERR_FLATTEN_OBJECT;
}
if (!data.WriteParcelable(&want)) {
APP_LOGE("want write failed.");
return ERR_FLATTEN_OBJECT;
}
if (!data.WriteParcelable(observer)) {
APP_LOGE("observer write failed.");
return ERR_FLATTEN_OBJECT;
}
if (!data.WriteParcelable(&bundleInfo)) {
APP_LOGE("bundleInfo write failed.");
return ERR_FLATTEN_OBJECT;
}
int32_t ret =
Remote()->SendRequest(static_cast<uint32_t>(IAppMgr::Message::START_USER_TEST_PROCESS), data, reply, option);
if (ret != NO_ERROR) {
APP_LOGW("SendRequest is failed, error code: %{public}d", ret);
return ret;
}
return reply.ReadInt32();
}
void AppMgrProxy::ScheduleAcceptWantDone(const int32_t recordId, const AAFwk::Want &want, const std::string &flag)
{
MessageParcel data;

View File

@ -26,6 +26,8 @@
#include "appexecfwk_errors.h"
#include "bytrace.h"
#include "iapp_state_callback.h"
#include "want.h"
#include "bundle_info.h"
namespace OHOS {
namespace AppExecFwk {
@ -68,6 +70,8 @@ AppMgrStub::AppMgrStub()
&AppMgrStub::HandleUnregisterApplicationStateObserver;
memberFuncMap_[static_cast<uint32_t>(IAppMgr::Message::GET_FOREGROUND_APPLICATIONS)] =
&AppMgrStub::HandleGetForegroundApplications;
memberFuncMap_[static_cast<uint32_t>(IAppMgr::Message::START_USER_TEST_PROCESS)] =
&AppMgrStub::HandleStartUserTestProcess;
memberFuncMap_[static_cast<uint32_t>(IAppMgr::Message::SCHEDULE_ACCEPT_WANT_DONE)] =
&AppMgrStub::HandleScheduleAcceptWantDone;
}
@ -291,6 +295,25 @@ int32_t AppMgrStub::HandleGetForegroundApplications(MessageParcel &data, Message
return result;
}
int32_t AppMgrStub::HandleStartUserTestProcess(MessageParcel &data, MessageParcel &reply)
{
AAFwk::Want *want = data.ReadParcelable<AAFwk::Want>();
if (want == nullptr) {
APP_LOGE("want is nullptr");
return ERR_INVALID_VALUE;
}
BundleInfo *bundleInfo = data.ReadParcelable<BundleInfo>();
if (want == nullptr) {
APP_LOGE("want is nullptr");
return ERR_INVALID_VALUE;
}
auto observer = data.ReadParcelable<IRemoteObject>();
int32_t result = StartUserTestProcess(*want, observer, *bundleInfo);
reply.WriteInt32(result);
delete want;
return result;
}
int32_t AppMgrStub::RegisterApplicationStateObserver(const sptr<IApplicationStateObserver> &observer)
{
return NO_ERROR;

View File

@ -19,11 +19,13 @@ group("napi_packages") {
"//foundation/aafwk/standard/interfaces/kits/napi/aafwk/abilityManager:abilitymanager",
"//foundation/aafwk/standard/interfaces/kits/napi/aafwk/ability_context:abilitycontext_napi",
"//foundation/aafwk/standard/interfaces/kits/napi/aafwk/ability_manager:abilitymanager_napi",
"//foundation/aafwk/standard/interfaces/kits/napi/aafwk/app/ability_delegator:abilityDelegatorRegistry",
"//foundation/aafwk/standard/interfaces/kits/napi/aafwk/app/ability_stage:abilitystage_napi",
"//foundation/aafwk/standard/interfaces/kits/napi/aafwk/app/ability_stage_context:abilitystagecontext_napi",
"//foundation/aafwk/standard/interfaces/kits/napi/aafwk/app/appMgr:napi_app_mgr",
"//foundation/aafwk/standard/interfaces/kits/napi/aafwk/app/app_manager:appmanager_napi",
"//foundation/aafwk/standard/interfaces/kits/napi/aafwk/app/context:context_napi",
"//foundation/aafwk/standard/interfaces/kits/napi/aafwk/app/test_runner:testrunner_napi",
"//foundation/aafwk/standard/interfaces/kits/napi/aafwk/callee:callee_napi",
"//foundation/aafwk/standard/interfaces/kits/napi/aafwk/caller:caller_napi",
"//foundation/aafwk/standard/interfaces/kits/napi/aafwk/dataUriUtils:datauriutils",

View File

@ -0,0 +1,57 @@
# Copyright (c) 2021 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.
import("//build/ohos.gni")
ohos_shared_library("abilityDelegatorRegistry") {
include_dirs = [
"//foundation/aafwk/standard/interfaces/kits/napi/aafwk/inner/napi_common/",
"//foundation/communication/ipc/ipc/native/src/napi/include/",
"//foundation/ace/napi/native_engine/",
"//foundation/aafwk/standard/interfaces/kits/napi/aafwk/app/ability_delegator/",
"//foundation/aafwk/standard/frameworks/kits/appkit/native/ability_delegator/include/",
]
sources = [
"ability_monitor.cpp",
"js_ability_delegator.cpp",
"js_ability_delegator_utils.cpp",
"js_ability_delegator_registry.cpp",
"js_ability_monitor.cpp",
"native_module.cpp",
]
configs = [ "//foundation/aafwk/standard/services/common:common_config" ]
deps = [
"//foundation/aafwk/standard/frameworks/kits/ability/native:abilitykit_native",
"//foundation/aafwk/standard/frameworks/kits/appkit:app_context",
"//foundation/aafwk/standard/frameworks/kits/appkit:appkit_native",
"//foundation/aafwk/standard/interfaces/innerkits/ability_manager:ability_manager",
"//foundation/aafwk/standard/interfaces/innerkits/base:base",
]
external_deps = [
"ability_runtime:runtime",
"bundle_framework:appexecfwk_base",
"bundle_framework:appexecfwk_core",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"ipc_js:rpc",
]
relative_install_dir = "module/application"
subsystem_name = "aafwk"
part_name = "ability_runtime"
}

View File

@ -0,0 +1,120 @@
/*
* Copyright (c) 2021 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_monitor.h"
#include "hilog_wrapper.h"
#include "js_ability_delegator_utils.h"
#include "napi/native_common.h"
namespace OHOS {
namespace AbilityDelegatorJs {
using namespace OHOS::AbilityRuntime;
AbilityMonitor::AbilityMonitor(const std::string &name, JSAbilityMonitor *jsAbilityMonitor)
: IAbilityMonitor(name), jsMonitor_(jsAbilityMonitor)
{}
void AbilityMonitor::onAbilityStart()
{
HILOG_INFO("onAbilityCreate is called");
if (jsMonitor_ == nullptr) {
return;
}
jsMonitor_->onAbilityCreate();
HILOG_INFO("onAbilityCreate is called end");
}
void AbilityMonitor::onAbilityForeground()
{
HILOG_INFO("onAbilityForeground is called");
if (jsMonitor_ == nullptr) {
return;
}
jsMonitor_->onAbilityForeground();
HILOG_INFO("onAbilityForeground is called end");
}
void AbilityMonitor::onAbilityBackground()
{
HILOG_INFO("onAbilityBackground is called");
if (jsMonitor_ == nullptr) {
return;
}
jsMonitor_->onAbilityBackground();
HILOG_INFO("onAbilityBackground is called end");
}
void AbilityMonitor::onAbilityStop()
{
HILOG_INFO("onAbilityDestroy is called");
if (jsMonitor_ == nullptr) {
return;
}
jsMonitor_->onAbilityDestroy();
HILOG_INFO("onAbilityDestroy is called end");
}
void AbilityMonitor::onWindowStageCreate()
{
HILOG_INFO("onWindowStageCreate is called");
if (jsMonitor_ == nullptr) {
return;
}
jsMonitor_->onWindowStageCreate();
HILOG_INFO("onWindowStageCreate is called end");
}
void AbilityMonitor::onWindowStageRestore()
{
HILOG_INFO("onWindowStageRestore is called");
if (jsMonitor_ == nullptr) {
return;
}
jsMonitor_->onWindowStageRestore();
HILOG_INFO("onWindowStageRestore is called end");
}
void AbilityMonitor::onWindowStageDestroy()
{
HILOG_INFO("onWindowStageDestroy is called");
if (jsMonitor_ == nullptr) {
return;
}
jsMonitor_->onWindowStageDestroy();
HILOG_INFO("onWindowStageDestroy is called end");
}
} // namespace AbilityDelegatorJs
} // namespace OHOS

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef OHOS_ABILITY_DELEGATOR_ABILITY_MONITOR_H
#define OHOS_ABILITY_DELEGATOR_ABILITY_MONITOR_H
#include <memory>
#include "iability_monitor.h"
#include "js_ability_monitor.h"
#include "native_engine/native_reference.h"
class NativeReference;
class NativeValue;
namespace OHOS {
namespace AbilityDelegatorJs {
using namespace OHOS::AppExecFwk;
using Function = void(*)();
class AbilityMonitor : public IAbilityMonitor {
public:
AbilityMonitor(const std::string &name, JSAbilityMonitor *jsAbilityMonitor);
~AbilityMonitor() = default;
void onAbilityStart();
void onAbilityForeground();
void onAbilityBackground();
void onAbilityStop();
void onWindowStageCreate();
void onWindowStageRestore();
void onWindowStageDestroy();
private:
std::shared_ptr<JSAbilityMonitor> jsMonitor_;
};
} // namespace AbilityDelegatorJs
} // namespace OHOS
#endif // OHOS_ABILITY_DELEGATOR_JS_ABILITY_MONITOR_H

View File

@ -0,0 +1,515 @@
/*
* Copyright (c) 2021 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 "js_ability_delegator.h"
#include "ability_delegator_registry.h"
#include "ability_runtime/js_ability.h"
#include "hilog_wrapper.h"
#include "js_ability_delegator_utils.h"
#include "js_context_utils.h"
#include "js_runtime_utils.h"
#include "napi_remote_object.h"
#include "shell_cmd_result.h"
namespace OHOS {
namespace AbilityDelegatorJs {
constexpr size_t ARGC_ONE = 1;
constexpr size_t ARGC_TWO = 2;
constexpr size_t ARGC_THREE = 3;
constexpr size_t ARGC_FOUR = 4;
constexpr size_t INDEX_ZERO = 0;
constexpr size_t INDEX_ONE = 1;
constexpr size_t INDEX_TWO = 2;
using namespace OHOS::AppExecFwk;
using namespace OHOS::AbilityRuntime;
std::map<std::shared_ptr<NativeReference>, std::shared_ptr<AbilityMonitor>> monitorRecord;
std::map<std::shared_ptr<NativeReference>, sptr<IRemoteObject>> ablityRecord;
void JSAbilityDelegator::Finalizer(NativeEngine *engine, void *data, void *hint)
{
HILOG_INFO("JSAbilityDelegator::Finalizer is called");
std::unique_ptr<JSAbilityDelegator>(static_cast<JSAbilityDelegator *>(data));
}
NativeValue *JSAbilityDelegator::AddAbilityMonitor(NativeEngine *engine, NativeCallbackInfo *info)
{
JSAbilityDelegator *me = CheckParamsAndGetThis<JSAbilityDelegator>(engine, info);
return (me != nullptr) ? me->OnAddAbilityMonitor(*engine, *info) : nullptr;
}
NativeValue *JSAbilityDelegator::RemoveAbilityMonitor(NativeEngine *engine, NativeCallbackInfo *info)
{
JSAbilityDelegator *me = CheckParamsAndGetThis<JSAbilityDelegator>(engine, info);
return (me != nullptr) ? me->OnRemoveAbilityMonitor(*engine, *info) : nullptr;
}
NativeValue *JSAbilityDelegator::WaitAbilityMonitor(NativeEngine *engine, NativeCallbackInfo *info)
{
JSAbilityDelegator *me = CheckParamsAndGetThis<JSAbilityDelegator>(engine, info);
return (me != nullptr) ? me->OnWaitAbilityMonitor(*engine, *info) : nullptr;
}
NativeValue *JSAbilityDelegator::GetAppContext(NativeEngine *engine, NativeCallbackInfo *info)
{
JSAbilityDelegator *me = CheckParamsAndGetThis<JSAbilityDelegator>(engine, info);
return (me != nullptr) ? me->OnGetAppContext(*engine, *info) : nullptr;
}
NativeValue *JSAbilityDelegator::GetAbilityState(NativeEngine *engine, NativeCallbackInfo *info)
{
JSAbilityDelegator *me = CheckParamsAndGetThis<JSAbilityDelegator>(engine, info);
return (me != nullptr) ? me->OnGetAbilityState(*engine, *info) : nullptr;
}
NativeValue *JSAbilityDelegator::GetCurrentTopAbility(NativeEngine *engine, NativeCallbackInfo *info)
{
JSAbilityDelegator *me = CheckParamsAndGetThis<JSAbilityDelegator>(engine, info);
return (me != nullptr) ? me->OnGetCurrentTopAbility(*engine, *info) : nullptr;
}
NativeValue *JSAbilityDelegator::DoAbilityForeground(NativeEngine *engine, NativeCallbackInfo *info)
{
JSAbilityDelegator *me = CheckParamsAndGetThis<JSAbilityDelegator>(engine, info);
return (me != nullptr) ? me->OnDoAbilityForeground(*engine, *info) : nullptr;
}
NativeValue *JSAbilityDelegator::DoAbilityBackground(NativeEngine *engine, NativeCallbackInfo *info)
{
JSAbilityDelegator *me = CheckParamsAndGetThis<JSAbilityDelegator>(engine, info);
return (me != nullptr) ? me->OnDoAbilityBackground(*engine, *info) : nullptr;
}
NativeValue *JSAbilityDelegator::Print(NativeEngine *engine, NativeCallbackInfo *info)
{
JSAbilityDelegator *me = CheckParamsAndGetThis<JSAbilityDelegator>(engine, info);
return (me != nullptr) ? me->OnPrint(*engine, *info) : nullptr;
}
NativeValue *JSAbilityDelegator::ExecuteShellCommand(NativeEngine *engine, NativeCallbackInfo *info)
{
JSAbilityDelegator *me = CheckParamsAndGetThis<JSAbilityDelegator>(engine, info);
return (me != nullptr) ? me->OnExecuteShellCommand(*engine, *info) : nullptr;
}
NativeValue *JSAbilityDelegator::OnAddAbilityMonitor(NativeEngine &engine, NativeCallbackInfo &info)
{
HILOG_INFO("OnAddAbilityMonitor is called, argc = %{public}d", static_cast<int>(info.argc));
if (info.argc < ARGC_ONE || info.argc > ARGC_TWO) {
HILOG_ERROR("Incorrect number of parameters");
return engine.CreateUndefined();
}
std::shared_ptr<AbilityMonitor> monitor = nullptr;
if (!ParseJSMonitorPara(engine, info.argv[INDEX_ZERO], monitor)) {
return engine.CreateUndefined();
}
AsyncTask::CompleteCallback complete = [monitor](NativeEngine &engine, AsyncTask &task, int32_t status) {
HILOG_INFO("OnAddAbilityMonitor AsyncTask is called");
AbilityDelegatorRegistry::GetAbilityDelegator()->AddAbilityMonitor(monitor);
task.Resolve(engine, engine.CreateUndefined());
};
NativeValue *lastParam = (info.argc == ARGC_TWO) ? info.argv[INDEX_ONE] : nullptr;
NativeValue *result = nullptr;
AsyncTask::Schedule(engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
return result;
}
NativeValue *JSAbilityDelegator::OnRemoveAbilityMonitor(NativeEngine &engine, NativeCallbackInfo &info)
{
HILOG_INFO("OnRemoveAbilityMonitor is called, argc = %{public}d", static_cast<int>(info.argc));
if (info.argc < ARGC_ONE || info.argc > ARGC_TWO) {
HILOG_ERROR("Incorrect number of parameters");
return engine.CreateUndefined();
}
std::shared_ptr<AbilityMonitor> monitor = nullptr;
if (!ParseJSMonitorPara(engine, info.argv[INDEX_ZERO], monitor)) {
return engine.CreateUndefined();
}
AsyncTask::CompleteCallback complete =
[monitor](NativeEngine &engine, AsyncTask &task, int32_t status) mutable {
HILOG_INFO("OnRemoveAbilityMonitor AsyncTask is called");
AbilityDelegatorRegistry::GetAbilityDelegator()->RemoveAbilityMonitor(monitor);
task.Resolve(engine, engine.CreateUndefined());
};
NativeValue *lastParam = (info.argc == ARGC_TWO) ? info.argv[INDEX_ONE] : nullptr;
NativeValue *result = nullptr;
AsyncTask::Schedule(engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
for (auto iter = monitorRecord.begin(); iter != monitorRecord.end(); ++iter) {
std::shared_ptr<NativeReference> jsMonitor = iter->first;
if ((info.argv[INDEX_ZERO])->StrictEquals(jsMonitor->Get())) {
monitorRecord.erase(iter);
break;
}
}
return result;
}
NativeValue *JSAbilityDelegator::OnWaitAbilityMonitor(NativeEngine &engine, NativeCallbackInfo &info)
{
HILOG_INFO("OnWaitAbilityMonitor is called, argc = %{public}d", static_cast<int>(info.argc));
if (info.argc < ARGC_ONE || info.argc > ARGC_THREE) {
HILOG_ERROR("Incorrect number of parameters");
return engine.CreateUndefined();
}
std::shared_ptr<AbilityMonitor> monitor = nullptr;
if (!ParseJSMonitorPara(engine, info.argv[INDEX_ZERO], monitor)) {
return engine.CreateUndefined();
}
bool hasTimeoutPara = false;
int64_t timeout = 0;
if (info.argc >= ARGC_TWO) {
if (!ConvertFromJsValue(engine, info.argv[INDEX_ONE], timeout)) {
HILOG_ERROR("Parse timeout failed");
} else {
hasTimeoutPara = true;
}
}
int argcnum = info.argc;
AsyncTask::CompleteCallback complete =
[argcnum, monitor, timeout, hasTimeoutPara, this](NativeEngine &engine, AsyncTask &task, int32_t status) {
HILOG_INFO("OnWaitAbilityMonitor AsyncTask is called");
sptr<IRemoteObject> remoteObject = nullptr;
if (((argcnum == ARGC_TWO) && !hasTimeoutPara) || (argcnum == ARGC_ONE)) {
remoteObject = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator()->WaitAbilityMonitor(monitor);
} else if (((argcnum == ARGC_TWO) && hasTimeoutPara) || (argcnum == ARGC_THREE)) {
remoteObject =
AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator()->WaitAbilityMonitor(monitor, timeout);
}
task.Resolve(engine, CreateJsAbilityObject(engine, remoteObject));
};
NativeValue *lastParam = nullptr;
if ((argcnum == ARGC_ONE) || ((argcnum == ARGC_TWO) && hasTimeoutPara)) {
lastParam = nullptr;
} else if ((argcnum == ARGC_TWO) && !hasTimeoutPara) {
lastParam = info.argv[INDEX_ONE];
} else if (argcnum == ARGC_THREE) {
lastParam = info.argv[INDEX_TWO];
}
NativeValue *result = nullptr;
AsyncTask::Schedule(engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
return result;
}
NativeValue *JSAbilityDelegator::OnPrint(NativeEngine &engine, NativeCallbackInfo &info)
{
HILOG_INFO("OnPrint is called, argc = %{public}d", static_cast<int>(info.argc));
if (info.argc < ARGC_ONE || info.argc > ARGC_TWO) {
HILOG_ERROR("Incorrect number of parameters");
return engine.CreateUndefined();
}
std::string msg;
if (!ConvertFromJsValue(engine, info.argv[INDEX_ZERO], msg)) {
HILOG_ERROR("Parse para failed");
return engine.CreateUndefined();
}
AsyncTask::CompleteCallback complete = [msg](NativeEngine &engine, AsyncTask &task, int32_t status) {
HILOG_INFO("OnPrint AsyncTask is called");
AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator()->Print(msg);
task.Resolve(engine, engine.CreateUndefined());
};
NativeValue *lastParam = (info.argc == ARGC_TWO) ? info.argv[INDEX_ONE] : nullptr;
NativeValue *result = nullptr;
AsyncTask::Schedule(engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
return result;
}
NativeValue *JSAbilityDelegator::OnExecuteShellCommand(NativeEngine &engine, NativeCallbackInfo &info)
{
HILOG_INFO("OnExecuteShellCommand is called, argc = %{public}d", static_cast<int>(info.argc));
if (info.argc < ARGC_ONE || info.argc > ARGC_FOUR) {
HILOG_ERROR("Incorrect number of parameters");
return engine.CreateUndefined();
}
std::string cmd;
bool hasTimeoutPara = false;
int64_t timeoutSecs = 0;
if (!ParseJSExecuteShellCommandPara(engine, info, cmd, timeoutSecs, hasTimeoutPara)) {
return engine.CreateUndefined();
}
AsyncTask::CompleteCallback complete = [cmd, timeoutSecs](NativeEngine &engine, AsyncTask &task, int32_t status) {
HILOG_INFO("OnExecuteShellCommand AsyncTask is called");
std::unique_ptr<ShellCmdResult> shellResult =
AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator()->ExecuteShellCommand(cmd, timeoutSecs);
task.Resolve(engine, CreateJsShellCmdResult(engine, shellResult));
};
int argcnum = info.argc;
NativeValue *lastParam = nullptr;
if ((argcnum == ARGC_ONE) || ((argcnum == ARGC_TWO) && hasTimeoutPara)) {
lastParam = nullptr;
} else if ((argcnum == ARGC_TWO) && !hasTimeoutPara) {
lastParam = info.argv[INDEX_ONE];
} else if (argcnum == ARGC_THREE) {
lastParam = info.argv[INDEX_TWO];
}
NativeValue *result = nullptr;
AsyncTask::Schedule(engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
return result;
}
NativeValue *JSAbilityDelegator::OnGetAppContext(NativeEngine &engine, NativeCallbackInfo &info)
{
HILOG_INFO("OnGetAppContext is called, argc = %{public}d", static_cast<int>(info.argc));
if (info.argc > ARGC_ONE) {
HILOG_ERROR("Incorrect number of parameters");
return engine.CreateUndefined();
}
AsyncTask::CompleteCallback complete = [](NativeEngine &engine, AsyncTask &task, int32_t status) {
HILOG_INFO("OnGetAppContext AsyncTask is called");
std::shared_ptr<AbilityRuntime::Context> context =
AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator()->GetAppContext();
task.Resolve(engine, CreateJsBaseContext(engine, context, false));
};
NativeValue *lastParam = (info.argc == ARGC_ONE) ? info.argv[INDEX_ZERO] : nullptr;
NativeValue *result = nullptr;
AsyncTask::Schedule(engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
return result;
}
NativeValue *JSAbilityDelegator::OnGetAbilityState(NativeEngine &engine, NativeCallbackInfo &info)
{
HILOG_INFO("OnGetAbilityState is called, argc = %{public}d", static_cast<int>(info.argc));
if (info.argc < ARGC_ONE || info.argc > ARGC_TWO) {
HILOG_ERROR("Incorrect number of parameters");
return engine.CreateUndefined();
}
sptr<OHOS::IRemoteObject> remoteObject = nullptr;
if (!ParseJSAbilityPara(engine, info.argv[INDEX_ZERO], remoteObject)) {
return engine.CreateUndefined();
}
AsyncTask::CompleteCallback complete = [remoteObject](NativeEngine &engine, AsyncTask &task, int32_t status) {
HILOG_INFO("OnGetAbilityState AsyncTask is called");
AbilityDelegator::AbilityState lifeState =
AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator()->GetAbilityState(remoteObject);
task.Resolve(engine, CreateJsAbilityState(engine, lifeState));
};
NativeValue *lastParam = (info.argc == ARGC_TWO) ? info.argv[INDEX_ONE] : nullptr;
NativeValue *result = nullptr;
AsyncTask::Schedule(engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
return result;
}
NativeValue *JSAbilityDelegator::OnGetCurrentTopAbility(NativeEngine &engine, NativeCallbackInfo &info)
{
HILOG_INFO("OnGetCurrentTopAbility is called, argc = %{public}d", static_cast<int>(info.argc));
if (info.argc > ARGC_ONE) {
HILOG_ERROR("Incorrect number of parameters");
return engine.CreateUndefined();
}
AsyncTask::CompleteCallback complete = [this](NativeEngine &engine, AsyncTask &task, int32_t status) {
HILOG_INFO("OnGetCurrentTopAbility AsyncTask is called");
sptr<IRemoteObject> remoteObject =
AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator()->GetCurrentTopAbility();
task.Resolve(engine, CreateJsAbilityObject(engine, remoteObject));
};
NativeValue *lastParam = (info.argc == ARGC_ONE) ? info.argv[INDEX_ZERO] : nullptr;
NativeValue *result = nullptr;
AsyncTask::Schedule(engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
return result;
}
NativeValue *JSAbilityDelegator::OnDoAbilityForeground(NativeEngine &engine, NativeCallbackInfo &info)
{
HILOG_INFO("OnDoAbilityForeground is called, argc = %{public}d", static_cast<int>(info.argc));
if (info.argc < ARGC_ONE || info.argc > ARGC_TWO) {
HILOG_ERROR("Incorrect number of parameters");
return engine.CreateUndefined();
}
sptr<OHOS::IRemoteObject> remoteObject = nullptr;
if (!ParseJSAbilityPara(engine, info.argv[INDEX_ZERO], remoteObject)) {
return engine.CreateUndefined();
}
AsyncTask::CompleteCallback complete = [remoteObject](NativeEngine &engine, AsyncTask &task, int32_t status) {
HILOG_INFO("OnDoAbilityForeground AsyncTask is called");
bool ret = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator()->DoAbilityForeground(remoteObject);
task.Resolve(engine, CreateJsBool(engine, ret));
};
NativeValue *lastParam = (info.argc == ARGC_TWO) ? info.argv[INDEX_ONE] : nullptr;
NativeValue *result = nullptr;
AsyncTask::Schedule(engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
return result;
}
NativeValue *JSAbilityDelegator::OnDoAbilityBackground(NativeEngine &engine, NativeCallbackInfo &info)
{
HILOG_INFO("OnDoAbilityBackground is called, argc = %{public}d", static_cast<int>(info.argc));
if (info.argc < ARGC_ONE || info.argc > ARGC_TWO) {
HILOG_ERROR("Incorrect number of parameters");
return engine.CreateUndefined();
}
sptr<OHOS::IRemoteObject> remoteObject = nullptr;
if (!ParseJSAbilityPara(engine, info.argv[INDEX_ZERO], remoteObject)) {
return engine.CreateUndefined();
}
AsyncTask::CompleteCallback complete = [remoteObject](NativeEngine &engine, AsyncTask &task, int32_t status) {
HILOG_INFO("OnDoAbilityBackground AsyncTask is called");
bool ret = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator()->DoAbilityBackground(remoteObject);
task.Resolve(engine, CreateJsBool(engine, ret));
};
NativeValue *lastParam = (info.argc == ARGC_TWO) ? info.argv[INDEX_ONE] : nullptr;
NativeValue *result = nullptr;
AsyncTask::Schedule(engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
return result;
}
NativeValue *JSAbilityDelegator::ParseJSMonitorPara(
NativeEngine &engine, NativeValue *value, std::shared_ptr<AbilityMonitor> &monitor)
{
HILOG_INFO("ParseJSMonitorPara is called, monitorRecord size = %{public}zu", monitorRecord.size());
for (auto iter = monitorRecord.begin(); iter != monitorRecord.end(); ++iter) {
std::shared_ptr<NativeReference> jsMonitor = iter->first;
if (value->StrictEquals(jsMonitor->Get())) {
HILOG_ERROR("monitor existed");
monitor = iter->second;
return monitor ? engine.CreateNull() : nullptr;
}
}
NativeObject *object = ConvertNativeValueTo<NativeObject>(value);
if (object == nullptr) {
HILOG_ERROR("Failed to get object");
return nullptr;
}
auto abilityNameValue = object->GetProperty("abilityName");
if (abilityNameValue == nullptr) {
return nullptr;
}
std::string abilityName;
if (!ConvertFromJsValue(engine, abilityNameValue, abilityName)) {
return nullptr;
}
std::shared_ptr<JSAbilityMonitor> abilityMonitor = std::make_shared<JSAbilityMonitor>(abilityName);
abilityMonitor->SetJsAbilityMonitorEnv(&engine);
abilityMonitor->SetJsAbilityMonitor(value);
monitor = std::make_shared<AbilityMonitor>(abilityName, abilityMonitor.get());
if (!monitor) {
HILOG_INFO("Failed to create monitor");
return nullptr;
}
std::shared_ptr<NativeReference> refence = nullptr;
refence.reset(engine.CreateReference(value, 1));
monitorRecord[refence] = monitor;
return engine.CreateNull();
}
NativeValue *JSAbilityDelegator::ParseJSAbilityPara(
NativeEngine &engine, NativeValue *value, sptr<OHOS::IRemoteObject> &remoteObject)
{
HILOG_INFO("ParseJSAbilityPara is called");
for (auto iter = ablityRecord.begin(); iter != ablityRecord.end(); ++iter) {
if (value->StrictEquals(iter->first->Get())) {
remoteObject = iter->second;
return remoteObject ? engine.CreateNull() : nullptr;
}
}
HILOG_ERROR("Ablity doesn't exist");
remoteObject = nullptr;
return nullptr;
}
NativeValue *JSAbilityDelegator::ParseJSExecuteShellCommandPara(
NativeEngine &engine, NativeCallbackInfo &info, std::string &cmd, int64_t &timeoutSecs, bool &hasTimeoutPara)
{
HILOG_INFO("ParseJSExecuteShellCommandPara is called");
if (!ConvertFromJsValue(engine, info.argv[INDEX_ZERO], cmd)) {
HILOG_ERROR("Parse para argv[0] failed");
return nullptr;
}
if ((info.argc >= ARGC_TWO) && ((info.argv[INDEX_ONE])->TypeOf() == NativeValueType::NATIVE_NUMBER)) {
if (!ConvertFromJsValue(engine, info.argv[INDEX_ONE], timeoutSecs)) {
HILOG_ERROR("Parse para argv[1] failed");
return nullptr;
}
hasTimeoutPara = true;
} else {
hasTimeoutPara = false;
}
return engine.CreateNull();
}
NativeValue *JSAbilityDelegator::CreateJsAbilityObject(NativeEngine &engine, const sptr<IRemoteObject> &remoteObject)
{
HILOG_INFO("CreateJsAbilityObject is called");
if (!remoteObject) {
return engine.CreateUndefined();
}
NativeValue *objValue = engine.CreateObject();
NativeObject *object = ConvertNativeValueTo<NativeObject>(objValue);
if (object == nullptr) {
HILOG_ERROR("Failed to get object");
return nullptr;
}
std::shared_ptr<NativeReference> refence = nullptr;
refence.reset(engine.CreateReference(objValue, 1));
ablityRecord[refence] = remoteObject;
return objValue;
}
} // namespace AbilityDelegatorJs
} // namespace OHOS

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef OHOS_ABILITY_DELEGATOR_JS_ABILITY_DELEGATOR_H
#define OHOS_ABILITY_DELEGATOR_JS_ABILITY_DELEGATOR_H
#include <string>
#include "ability_monitor.h"
#include "js_ability_monitor.h"
namespace OHOS {
namespace AbilityDelegatorJs {
class JSAbilityDelegator {
public:
JSAbilityDelegator() = default;
~JSAbilityDelegator() = default;
static void Finalizer(NativeEngine *engine, void *data, void *hint);
static NativeValue *AddAbilityMonitor(NativeEngine *engine, NativeCallbackInfo *info);
static NativeValue *RemoveAbilityMonitor(NativeEngine *engine, NativeCallbackInfo *info);
static NativeValue *WaitAbilityMonitor(NativeEngine *engine, NativeCallbackInfo *info);
static NativeValue *Print(NativeEngine *engine, NativeCallbackInfo *info);
static NativeValue *ExecuteShellCommand(NativeEngine *engine, NativeCallbackInfo *info);
static NativeValue *GetAppContext(NativeEngine *engine, NativeCallbackInfo *info);
static NativeValue *GetAbilityState(NativeEngine *engine, NativeCallbackInfo *info);
static NativeValue *GetCurrentTopAbility(NativeEngine *engine, NativeCallbackInfo *info);
static NativeValue *DoAbilityForeground(NativeEngine *engine, NativeCallbackInfo *info);
static NativeValue *DoAbilityBackground(NativeEngine *engine, NativeCallbackInfo *info);
private:
NativeValue *OnAddAbilityMonitor(NativeEngine &engine, NativeCallbackInfo &info);
NativeValue *OnRemoveAbilityMonitor(NativeEngine &engine, NativeCallbackInfo &info);
NativeValue *OnWaitAbilityMonitor(NativeEngine &engine, NativeCallbackInfo &info);
NativeValue *OnPrint(NativeEngine &engine, NativeCallbackInfo &info);
NativeValue *OnExecuteShellCommand(NativeEngine &engine, NativeCallbackInfo &info);
NativeValue *OnGetAppContext(NativeEngine &engine, NativeCallbackInfo &info);
NativeValue *OnGetAbilityState(NativeEngine &engine, NativeCallbackInfo &info);
NativeValue *OnGetCurrentTopAbility(NativeEngine &engine, NativeCallbackInfo &info);
NativeValue *OnDoAbilityForeground(NativeEngine &engine, NativeCallbackInfo &info);
NativeValue *OnDoAbilityBackground(NativeEngine &engine, NativeCallbackInfo &info);
private:
NativeValue *CreateJsAbilityObject(NativeEngine &engine, const sptr<IRemoteObject> &remoteObject);
NativeValue *ParseJSMonitorPara(NativeEngine &engine, NativeValue *value, std::shared_ptr<AbilityMonitor> &monitor);
NativeValue *ParseJSAbilityPara(NativeEngine &engine, NativeValue *value, sptr<OHOS::IRemoteObject> &remoteObject);
NativeValue *ParseJSExecuteShellCommandPara(
NativeEngine& engine, NativeCallbackInfo &info, std::string &cmd, int64_t &timeoutSecs, bool &hasTimeoutPara);
void SetJsAbilityMonitor(std::string jstring);
};
} // namespace AbilityDelegatorJs
} // namespace OHOS
#endif // ABILITY_RUNTIME_JS_ABILITY_DELEGATOR_H

View File

@ -0,0 +1,122 @@
/*
* Copyright (c) 2021 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 "js_ability_delegator_registry.h"
#include "ability_delegator.h"
#include "ability_delegator_registry.h"
#include "hilog_wrapper.h"
#include "js_ability_delegator.h"
#include "js_ability_delegator_utils.h"
#include "js_runtime_utils.h"
namespace OHOS {
namespace AbilityDelegatorJs {
using namespace OHOS::AppExecFwk;
using namespace OHOS::AbilityRuntime;
namespace {
constexpr int32_t ARGC_ONE = 1;
class JsAbilityDelegatorRegistry {
public:
JsAbilityDelegatorRegistry() = default;
~JsAbilityDelegatorRegistry() = default;
static void Finalizer(NativeEngine *engine, void *data, void *hint)
{
HILOG_INFO("JsAbilityDelegatorRegistry::Finalizer is called");
std::unique_ptr<JsAbilityDelegatorRegistry>(static_cast<JsAbilityDelegatorRegistry *>(data));
}
static NativeValue *GetAbilityDelegator(NativeEngine *engine, NativeCallbackInfo *info)
{
JsAbilityDelegatorRegistry *me = CheckParamsAndGetThis<JsAbilityDelegatorRegistry>(engine, info);
return (me != nullptr) ? me->OnGetAbilityDelegator(*engine, *info) : nullptr;
}
static NativeValue *GetArguments(NativeEngine *engine, NativeCallbackInfo *info)
{
JsAbilityDelegatorRegistry *me = CheckParamsAndGetThis<JsAbilityDelegatorRegistry>(engine, info);
return (me != nullptr) ? me->OnGetArguments(*engine, *info) : nullptr;
}
private:
NativeValue *OnGetAbilityDelegator(NativeEngine &engine, NativeCallbackInfo &info)
{
HILOG_INFO("%{public}s is called", __FUNCTION__);
if (info.argc > ARGC_ONE) {
HILOG_ERROR("Params not match");
return engine.CreateUndefined();
}
AsyncTask::CompleteCallback complete = [](NativeEngine &engine, AsyncTask &task, int32_t status) {
task.Resolve(engine, CreateJsAbilityDelegator(engine));
};
NativeValue *lastParam = (info.argc == ARGC_ONE) ? info.argv[0] : nullptr;
NativeValue *result = nullptr;
AsyncTask::Schedule(
engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
return result;
}
NativeValue *OnGetArguments(NativeEngine &engine, NativeCallbackInfo &info)
{
HILOG_INFO("%{public}s is called", __FUNCTION__);
if (info.argc > ARGC_ONE) {
HILOG_ERROR("Params not match");
return engine.CreateUndefined();
}
AsyncTask::CompleteCallback complete = [](NativeEngine &engine, AsyncTask &task, int32_t status) {
std::shared_ptr<AppExecFwk::AbilityDelegatorArgs> abilityDelegatorArgs =
AppExecFwk::AbilityDelegatorRegistry::GetArguments();
task.Resolve(engine, CreateJsAbilityDelegatorArguments(engine, abilityDelegatorArgs));
};
NativeValue *lastParam = (info.argc == ARGC_ONE) ? info.argv[0] : nullptr;
NativeValue *result = nullptr;
AsyncTask::Schedule(
engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
return result;
}
};
} // namespace
NativeValue *JsAbilityDelegatorRegistryInit(NativeEngine *engine, NativeValue *exportObj)
{
HILOG_INFO("JsAbilityDelegatorManagerInit is called");
if (engine == nullptr || exportObj == nullptr) {
HILOG_ERROR("Invalid input parameters");
return nullptr;
}
NativeObject *object = ConvertNativeValueTo<NativeObject>(exportObj);
if (object == nullptr) {
HILOG_ERROR("Failed to get object");
return nullptr;
}
std::unique_ptr<JsAbilityDelegatorRegistry> jsDelegatorManager =
std::make_unique<JsAbilityDelegatorRegistry>();
object->SetNativePointer(jsDelegatorManager.release(), JsAbilityDelegatorRegistry::Finalizer, nullptr);
BindNativeFunction(*engine, *object, "getAbilityDelegator", JsAbilityDelegatorRegistry::GetAbilityDelegator);
BindNativeFunction(*engine, *object, "getArguments", JsAbilityDelegatorRegistry::GetArguments);
return engine->CreateUndefined();
}
} // namespace AbilityDelegatorJs
} // namespace OHOS

View File

@ -0,0 +1,26 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef OHOS_ABILITY_DELEGATOR_ABILITY_DELEGATOR_REGISTRY_H
#define OHOS_ABILITY_DELEGATOR_ABILITY_DELEGATOR_REGISTRY_H
#include "native_engine/native_engine.h"
namespace OHOS {
namespace AbilityDelegatorJs {
NativeValue *JsAbilityDelegatorRegistryInit(NativeEngine *engine, NativeValue *exportObj);
} // namespace AbilityDelegatorJs
} // namespace OHOS
#endif // OHOS_ABILITY_DELEGATOR_ABILITY_DELEGATOR_REGISTRY_H

View File

@ -0,0 +1,135 @@
/*
* Copyright (c) 2021 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 "js_ability_delegator_utils.h"
#include <map>
#include "ability_runtime/js_ability.h"
#include "hilog_wrapper.h"
#include "js_ability_monitor.h"
#include "napi/native_common.h"
namespace OHOS {
namespace AbilityDelegatorJs {
using namespace OHOS::AbilityRuntime;
NativeValue *CreateJsAbilityDelegator(NativeEngine &engine)
{
HILOG_INFO("CreateJsAbilityDelegator is called");
NativeValue *objValue = engine.CreateObject();
NativeObject *object = ConvertNativeValueTo<NativeObject>(objValue);
if (object == nullptr) {
HILOG_ERROR("Failed to get object");
return nullptr;
}
std::unique_ptr<JSAbilityDelegator> jsAbilityDelegator = std::make_unique<JSAbilityDelegator>();
object->SetNativePointer(jsAbilityDelegator.release(), JSAbilityDelegator::Finalizer, nullptr);
BindNativeFunction(engine, *object, "addAbilityMonitor", JSAbilityDelegator::AddAbilityMonitor);
BindNativeFunction(engine, *object, "removeAbilityMonitor", JSAbilityDelegator::RemoveAbilityMonitor);
BindNativeFunction(engine, *object, "waitAbilityMonitor", JSAbilityDelegator::WaitAbilityMonitor);
BindNativeFunction(engine, *object, "getAppContext", JSAbilityDelegator::GetAppContext);
BindNativeFunction(engine, *object, "getAbilityState", JSAbilityDelegator::GetAbilityState);
BindNativeFunction(engine, *object, "getCurrentTopAbility", JSAbilityDelegator::GetCurrentTopAbility);
BindNativeFunction(engine, *object, "doAbilityForeground", JSAbilityDelegator::DoAbilityForeground);
BindNativeFunction(engine, *object, "doAbilityBackground", JSAbilityDelegator::DoAbilityBackground);
BindNativeFunction(engine, *object, "print", JSAbilityDelegator::Print);
BindNativeFunction(engine, *object, "executeShellCommand", JSAbilityDelegator::ExecuteShellCommand);
return objValue;
}
napi_value WrapStringToJS(napi_env env, const std::string &value)
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result));
return result;
}
void SetAbilityDelegatorArgumentsPara(napi_env env, const std::map<std::string, std::string> &paras)
{
HILOG_INFO("SetAbilityDelegatorArgumentsPara is called");
napi_value parameter = nullptr;
napi_value result = nullptr;
auto iter = paras.begin();
for (; iter != paras.end(); ++iter) {
NAPI_CALL_RETURN_VOID(
env, napi_set_named_property(env, parameter, iter->first.c_str(), WrapStringToJS(env, iter->second)));
}
napi_set_named_property(env, result, "parameters", parameter);
return;
}
NativeValue *CreateJsAbilityDelegatorArguments(
NativeEngine &engine, const std::shared_ptr<AbilityDelegatorArgs> &abilityDelegatorArgs)
{
HILOG_INFO("CreateJsAbilityDelegatorArguments is called");
NativeValue *objValue = engine.CreateObject();
NativeObject *object = ConvertNativeValueTo<NativeObject>(objValue);
if (object == nullptr) {
HILOG_ERROR("Failed to get object");
return nullptr;
}
object->SetProperty("bundleName", CreateJsValue(engine, abilityDelegatorArgs->GetTestBundleName()));
SetAbilityDelegatorArgumentsPara(reinterpret_cast<napi_env>(&engine), abilityDelegatorArgs->GetTestParam());
object->SetProperty("testCaseNames", CreateJsValue(engine, abilityDelegatorArgs->GetTestCaseName()));
object->SetProperty("testRunnerClassName", CreateJsValue(engine, abilityDelegatorArgs->GetTestRunnerClassName()));
return objValue;
}
NativeValue *CreateJsAbilityState(NativeEngine &engine, AbilityDelegator::AbilityState &lifeState)
{
HILOG_INFO("CreateJsAbilityState is called");
NativeValue *objValue = CreateJsValue(engine, static_cast<int>(lifeState));
if (!objValue) {
HILOG_ERROR("CreateJsAbilityState objValue is nullptr");
return nullptr;
}
return objValue;
}
NativeValue *CreateJsBool(NativeEngine &engine, bool &flag)
{
HILOG_INFO("CreateJsBool is called");
NativeValue *objValue = CreateJsValue(engine, static_cast<bool>(flag));
if (!objValue) {
HILOG_ERROR("CreateJsBool objValue is nullptr");
return nullptr;
}
return objValue;
}
NativeValue *CreateJsShellCmdResult(NativeEngine &engine, std::unique_ptr<ShellCmdResult> &shellResult)
{
HILOG_INFO("CreateJsShellCmdResult is called");
NativeValue *objValue = engine.CreateObject();
NativeObject *object = ConvertNativeValueTo<NativeObject>(objValue);
if (object == nullptr) {
HILOG_ERROR("Failed to get object");
return nullptr;
}
object->SetProperty("stdResult", CreateJsValue(engine, shellResult->GetStdResult()));
object->SetProperty("exitCode", CreateJsValue(engine, shellResult->GetExitCode()));
return objValue;
}
} // namespace AbilityDelegatorJs
} // namespace OHOS

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef OHOS_ABILITY_DELEGATOR_JS_ABILITY_DELEGATOR_UTILS_H
#define OHOS_ABILITY_DELEGATOR_JS_ABILITY_DELEGATOR_UTILS_H
#include "js_runtime_utils.h"
#include "ability_delegator.h"
#include "ability_delegator_args.h"
#include "js_ability_delegator.h"
#include "native_engine/native_engine.h"
#include "shell_cmd_result.h"
namespace OHOS {
namespace AbilityDelegatorJs {
using namespace OHOS::AppExecFwk;
NativeValue *CreateJsAbilityDelegator(NativeEngine &engine);
NativeValue *CreateJsAbilityDelegatorArguments(
NativeEngine &engine, const std::shared_ptr<AbilityDelegatorArgs> &abilityDelegatorArgs);
NativeValue *CreateJsAbilityState(NativeEngine &engine, AbilityDelegator::AbilityState &lifeState);
NativeValue *CreateJsBool(NativeEngine &engine, bool &flag);
NativeValue *CreateJsShellCmdResult(NativeEngine &engine, std::unique_ptr<ShellCmdResult> &shellResult);
} // namespace AbilityDelegatorJs
} // namespace OHOS
#endif // OHOS_ABILITY_DELEGATOR_JS_ABILITY_DELEGATOR_UTILS_H

View File

@ -0,0 +1,218 @@
/*
* Copyright (c) 2021 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 "js_ability_monitor.h"
#include "js_ability_delegator_utils.h"
#include "napi/native_common.h"
namespace OHOS {
namespace AbilityDelegatorJs {
using namespace OHOS::AbilityRuntime;
JSAbilityMonitor::JSAbilityMonitor(const std::string &abilityName) : abilityName_(abilityName)
{}
void JSAbilityMonitor::onAbilityCreate()
{
HILOG_INFO("onAbilityCreate is called");
if (jsAbilityMonitor_ == nullptr) {
HILOG_ERROR("jsAbilityMonitor_ nullptr");
return;
}
NativeValue* value = jsAbilityMonitor_->Get();
NativeObject* obj = ConvertNativeValueTo<NativeObject>(value);
if (obj == nullptr) {
HILOG_ERROR("Failed to get object");
return;
}
NativeValue* method = obj->GetProperty("onAbilityCreate");
if (method == nullptr) {
HILOG_ERROR("Failed to get onAbilityCreate from object");
return;
}
NativeValue* argv[] = {};
engine_->CallFunction(value, method, argv, 0);
HILOG_INFO("onAbilityCreate is called end");
}
void JSAbilityMonitor::onAbilityForeground()
{
HILOG_INFO("onAbilityForeground is called");
if (jsAbilityMonitor_ == nullptr) {
HILOG_ERROR("jsAbilityMonitor_ nullptr");
return;
}
NativeValue *value = jsAbilityMonitor_->Get();
NativeObject *obj = ConvertNativeValueTo<NativeObject>(value);
if (obj == nullptr) {
HILOG_ERROR("Failed to get object");
return;
}
NativeValue *method = obj->GetProperty("onAbilityForeground");
if (method == nullptr) {
HILOG_ERROR("Failed to get onAbilityForeground from object");
return;
}
NativeValue *argv[] = {};
engine_->CallFunction(value, method, argv, 0);
HILOG_INFO("onAbilityForeground is called end");
}
void JSAbilityMonitor::onAbilityBackground()
{
HILOG_INFO("onAbilityBackground is called");
if (jsAbilityMonitor_ == nullptr) {
HILOG_ERROR("jsAbilityMonitor_ nullptr");
return;
}
NativeValue *value = jsAbilityMonitor_->Get();
NativeObject *obj = ConvertNativeValueTo<NativeObject>(value);
if (obj == nullptr) {
HILOG_ERROR("Failed to get object");
return;
}
NativeValue *method = obj->GetProperty("onAbilityBackground");
if (method == nullptr) {
HILOG_ERROR("Failed to get onAbilityBackground from object");
return;
}
NativeValue *argv[] = {};
engine_->CallFunction(value, method, argv, 0);
HILOG_INFO("onAbilityBackground is called end");
}
void JSAbilityMonitor::onAbilityDestroy()
{
HILOG_INFO("onAbilityDestroy is called");
if (jsAbilityMonitor_ == nullptr) {
HILOG_ERROR("jsAbilityMonitor_ nullptr");
return;
}
NativeValue *value = jsAbilityMonitor_->Get();
NativeObject *obj = ConvertNativeValueTo<NativeObject>(value);
if (obj == nullptr) {
HILOG_ERROR("Failed to get object");
return;
}
NativeValue *method = obj->GetProperty("onAbilityDestroy");
if (method == nullptr) {
HILOG_ERROR("Failed to get onAbilityDestroy from object");
return;
}
NativeValue *argv[] = {};
engine_->CallFunction(value, method, argv, 0);
HILOG_INFO("onAbilityDestroy is called end");
}
void JSAbilityMonitor::onWindowStageCreate()
{
HILOG_INFO("onWindowStageCreate is called");
if (jsAbilityMonitor_ == nullptr) {
HILOG_ERROR("jsAbilityMonitor_ nullptr");
return;
}
NativeValue *value = jsAbilityMonitor_->Get();
NativeObject *obj = ConvertNativeValueTo<NativeObject>(value);
if (obj == nullptr) {
HILOG_ERROR("Failed to get object");
return;
}
NativeValue *method = obj->GetProperty("onWindowStageCreate");
if (method == nullptr) {
HILOG_ERROR("Failed to get onWindowStageCreate from object");
return;
}
NativeValue *argv[] = {};
engine_->CallFunction(value, method, argv, 0);
HILOG_INFO("onWindowStageCreate is called end");
}
void JSAbilityMonitor::onWindowStageRestore()
{
HILOG_INFO("onWindowStageRestore is called");
if (jsAbilityMonitor_ == nullptr) {
HILOG_ERROR("jsAbilityMonitor_ nullptr");
return;
}
NativeValue *value = jsAbilityMonitor_->Get();
NativeObject *obj = ConvertNativeValueTo<NativeObject>(value);
if (obj == nullptr) {
HILOG_ERROR("Failed to get object");
return;
}
NativeValue *method = obj->GetProperty("onWindowStageRestore");
if (method == nullptr) {
HILOG_ERROR("Failed to get onWindowStageRestore from object");
return;
}
NativeValue *argv[] = {};
engine_->CallFunction(value, method, argv, 0);
HILOG_INFO("onWindowStageRestore is called end");
}
void JSAbilityMonitor::onWindowStageDestroy()
{
HILOG_INFO("onWindowStageDestroy is called");
NativeValue *value = jsAbilityMonitor_->Get();
NativeObject *obj = ConvertNativeValueTo<NativeObject>(value);
if (obj == nullptr) {
HILOG_ERROR("Failed to get object");
return;
}
NativeValue *method = obj->GetProperty("onWindowStageDestroy");
if (method == nullptr) {
HILOG_ERROR("Failed to get onWindowStageDestroy from object");
return;
}
NativeValue *argv[] = {};
engine_->CallFunction(value, method, argv, 0);
HILOG_INFO("onWindowStageDestroy is called end");
}
void JSAbilityMonitor::SetJsAbilityMonitor(NativeValue *jsAbilityMonitor)
{
HILOG_INFO("SetJsAbilityMonitor is called");
jsAbilityMonitor_ = std::unique_ptr<NativeReference>(engine_->CreateReference(jsAbilityMonitor, 1));
}
} // namespace AbilityDelegatorJs
} // namespace OHOS

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef OHOS_ABILITY_DELEGATOR_JS_ABILITY_MONITOR_H
#define OHOS_ABILITY_DELEGATOR_JS_ABILITY_MONITOR_H
#include <memory>
#include "iability_monitor.h"
#include "hilog_wrapper.h"
#include "native_engine/native_reference.h"
class NativeReference;
class NativeValue;
namespace OHOS {
namespace AbilityDelegatorJs {
using namespace OHOS::AppExecFwk;
class JSAbilityMonitor {
public:
explicit JSAbilityMonitor(const std::string &abilityName);
~JSAbilityMonitor() = default;
static void Finalizer(NativeEngine *engine, void *data, void *hint)
{
HILOG_INFO("JsAbilityContext::Finalizer is called");
std::unique_ptr<JSAbilityMonitor>(static_cast<JSAbilityMonitor *>(data));
}
void onAbilityCreate();
void onAbilityForeground();
void onAbilityBackground();
void onAbilityDestroy();
void onWindowStageCreate();
void onWindowStageRestore();
void onWindowStageDestroy();
void SetJsAbilityMonitor(NativeValue *jsAbilityMonitor);
void SetJsAbilityMonitorEnv(NativeEngine *engine)
{
engine_ = engine;
}
std::unique_ptr<NativeReference> &GetJsAbilityMonitor()
{
return jsAbilityMonitor_;
}
private:
std::string abilityName_;
NativeEngine* engine_ = nullptr;
std::unique_ptr<NativeReference> jsAbilityMonitor_ = nullptr;
};
} // namespace AbilityDelegatorJs
} // namespace OHOS
#endif // OHOS_ABILITY_DELEGATOR_JS_ABILITY_MONITOR_H

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 2021 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 "native_engine/native_engine.h"
#include "js_ability_delegator_registry.h"
extern "C" __attribute__((constructor)) void NAPI_application_AbilityDelegatorRegistry_AutoRegister()
{
auto moduleManager = NativeModuleManager::GetInstance();
NativeModule newModuleInfo = {
.name = "application.AbilityDelegatorRegistry",
.fileName = "application/libabilitydelegator_napi.so/ability_delegator_registry.js",
.registerCallback = OHOS::AbilityDelegatorJs::JsAbilityDelegatorRegistryInit,
};
moduleManager->Register(&newModuleInfo);
}

View File

@ -0,0 +1,50 @@
# Copyright (c) 2021 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.
import("//ark/ts2abc/ts2panda/ts2abc_config.gni")
import("//build/ohos.gni")
ts2abc_gen_abc("gen_test_runner_abc") {
src_js = rebase_path("test_runner.js")
dst_file = rebase_path(target_out_dir + "/test_runner.abc")
in_puts = [ "test_runner.js" ]
out_puts = [ target_out_dir + "/test_runner.abc" ]
extra_args = [ "--module" ]
}
gen_js_obj("test_runner_js") {
input = "test_runner.js"
output = target_out_dir + "/test_runner.o"
}
gen_js_obj("test_runner_abc") {
input = get_label_info(":gen_test_runner_abc", "target_out_dir") +
"/test_runner.abc"
output = target_out_dir + "/test_runner_abc.o"
dep = ":gen_test_runner_abc"
}
ohos_shared_library("testrunner_napi") {
sources = [ "test_runner_module.cpp" ]
deps = [
":test_runner_abc",
":test_runner_js",
]
external_deps = [ "napi:ace_napi" ]
relative_install_dir = "module/application"
subsystem_name = "aafwk"
part_name = "ability_runtime"
}

View File

@ -0,0 +1,22 @@
/*
* Copyright (c) 2021 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.
*/
class TestRunner {
constructor() {}
onPrepare() {}
onRun() {}
}
export default TestRunner

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2021 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 "native_engine/native_engine.h"
extern const char _binary_test_runner_js_start[];
extern const char _binary_test_runner_js_end[];
extern const char _binary_test_runner_abc_start[];
extern const char _binary_test_runner_abc_end[];
extern "C" __attribute__((constructor)) void NAPI_application_testRunner_AutoRegister()
{
auto moduleManager = NativeModuleManager::GetInstance();
NativeModule newModuleInfo = {
.name = "application.testRunner",
.fileName = "application/libtestrunner_napi.so/test_runner.js",
};
moduleManager->Register(&newModuleInfo);
}
extern "C" __attribute__((visibility("default"))) void NAPI_application_testRunner_GetJSCode(
const char **buf, int *bufLen)
{
if (buf != nullptr) {
*buf = _binary_test_runner_js_start;
}
if (bufLen != nullptr) {
*bufLen = _binary_test_runner_js_end - _binary_test_runner_js_start;
}
}
// testRunner JS register
extern "C" __attribute__((visibility("default"))) void NAPI_application_testRunner_GetABCCode(
const char **buf, int *buflen)
{
if (buf != nullptr) {
*buf = _binary_test_runner_abc_start;
}
if (buflen != nullptr) {
*buflen = _binary_test_runner_abc_end - _binary_test_runner_abc_start;
}
}

View File

@ -54,6 +54,7 @@ config("abilityms_config") {
"//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_appdatafwk/include",
"//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_dataability/include",
"//foundation/aafwk/standard/interfaces/innerkits/dataobs_manager/include",
"//foundation/aafwk/standard/tools/aa/include",
"//foundation/graphic/standard/interfaces/innerkits/wmservice",
"//base/global/i18n_standard/frameworks/intl/include",
"//foundation/distributedschedule/dmsfwk/services/dtbschedmgr/include",

View File

@ -602,6 +602,35 @@ public:
virtual int GetMissionSnapshot(const std::string& deviceId, int32_t missionId, MissionSnapshot& snapshot) override;
virtual int StartUserTest(const Want &want, const sptr<IRemoteObject> &observer) override;
virtual int FinishUserTest(const std::string &msg, const int &resultCode,
const std::string &bundleName, const sptr<IRemoteObject> &observer) override;
/**
* GetCurrentTopAbility, get the token of current top ability.
*
* @param token, the token of current top ability.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int GetCurrentTopAbility(sptr<IRemoteObject> &token) override;
/**
* The delegator calls this interface to move the ability to the foreground.
*
* @param token, ability's token.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int DelegatorDoAbilityForeground(const sptr<IRemoteObject> &token) override;
/**
* The delegator calls this interface to move the ability to the background.
*
* @param token, ability's token.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int DelegatorDoAbilityBackground(const sptr<IRemoteObject> &token) override;
/**
* Send not response process ID to ability manager service.
* @param pid The not response process ID.

View File

@ -792,6 +792,35 @@ public:
*/
virtual bool IsRunningInStabilityTest() override;
virtual int StartUserTest(const Want &want, const sptr<IRemoteObject> &observer) override;
virtual int FinishUserTest(const std::string &msg, const int &resultCode,
const std::string &bundleName, const sptr<IRemoteObject> &observer) override;
/**
* GetCurrentTopAbility, get the token of current top ability.
*
* @param token, the token of current top ability.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int GetCurrentTopAbility(sptr<IRemoteObject> &token) override;
/**
* The delegator calls this interface to move the ability to the foreground.
*
* @param token, ability's token.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int DelegatorDoAbilityForeground(const sptr<IRemoteObject> &token) override;
/**
* The delegator calls this interface to move the ability to the background.
*
* @param token, ability's token.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int DelegatorDoAbilityBackground(const sptr<IRemoteObject> &token) override;
bool IsAbilityControllerStart(const Want &want, const std::string &bundleName);
bool IsAbilityControllerForeground(const std::string &bundleName);
@ -1039,6 +1068,8 @@ private:
int32_t GetValidUserId(const Want &want, const int32_t userId);
int DelegatorMoveMissionToFront(int32_t missionId);
using DumpFuncType = void (AbilityManagerService::*)(const std::string &args, std::vector<std::string> &info);
std::map<uint32_t, DumpFuncType> dumpFuncMap_;

View File

@ -39,6 +39,7 @@ public:
private:
void FirstStepInit();
void SecondStepInit();
void ThirdStepInit();
int TerminateAbilityInner(MessageParcel &data, MessageParcel &reply);
int TerminateAbilityByCallerInner(MessageParcel &data, MessageParcel &reply);
int MinimizeAbilityInner(MessageParcel &data, MessageParcel &reply);
@ -142,6 +143,13 @@ private:
int SendANRProcessIDInner(MessageParcel &data, MessageParcel &reply);
int SetAbilityControllerInner(MessageParcel &data, MessageParcel &reply);
int StartUserTestInner(MessageParcel &data, MessageParcel &reply);
int FinishUserTestInner(MessageParcel &data, MessageParcel &reply);
int GetCurrentTopAbilityInner(MessageParcel &data, MessageParcel &reply);
int DelegatorDoAbilityForegroundInner(MessageParcel &data, MessageParcel &reply);
int DelegatorDoAbilityBackgroundInner(MessageParcel &data, MessageParcel &reply);
int IsRunningInStabilityTestInner(MessageParcel &data, MessageParcel &reply);
using RequestFuncType = int (AbilityManagerStub::*)(MessageParcel &data, MessageParcel &reply);

View File

@ -25,6 +25,7 @@
#include "appmgr/app_state_callback_host.h"
#include "appmgr/start_specified_ability_response_stub.h"
#include "application_info.h"
#include "bundle_info.h"
#include "iremote_object.h"
#include "refbase.h"
#include "singleton.h"
@ -245,6 +246,12 @@ public:
void StartSpecifiedAbility(const AAFwk::Want &want, const AppExecFwk::AbilityInfo &abilityInfo);
int GetProcessRunningInfos(std::vector<AppExecFwk::RunningProcessInfo> &info);
/**
* Start a user test
*/
int StartUserTest(const Want &want, const sptr<IRemoteObject> &observer, const AppExecFwk::BundleInfo &bundleInfo);
int GetProcessRunningInfosByUserId(std::vector<AppExecFwk::RunningProcessInfo> &info, int32_t userId);
std::string ConvertAppState(const AppState &state);

View File

@ -309,6 +309,13 @@ public:
MissionSnapshot& missionSnapshot);
void GetAbilityRunningInfos(std::vector<AbilityRunningInfo> &info);
/**
* @brief get current top ability by bundle name
* @param bundleName the bundle name
* @return the current top ability.
*/
std::shared_ptr<AbilityRecord> GetCurrentTopAbility(const std::string &bundleName);
bool IsStarted();
void PauseManager();
void ResumeManager();

View File

@ -861,6 +861,46 @@ ErrCode AbilityManagerClient::GetMissionSnapshot(const std::string& deviceId, in
return abms->GetMissionSnapshot(deviceId, missionId, snapshot);
}
ErrCode AbilityManagerClient::StartUserTest(const Want &want, const sptr<IRemoteObject> &observer)
{
CHECK_REMOTE_OBJECT_AND_RETURN(remoteObject_, ABILITY_SERVICE_NOT_CONNECTED);
sptr<IAbilityManager> abms = iface_cast<IAbilityManager>(remoteObject_);
return abms->StartUserTest(want, observer);
}
ErrCode AbilityManagerClient::FinishUserTest(const std::string &msg, const int &resultCode,
const std::string &bundleName, const sptr<IRemoteObject> &observer)
{
CHECK_REMOTE_OBJECT_AND_RETURN(remoteObject_, ABILITY_SERVICE_NOT_CONNECTED);
sptr<IAbilityManager> abms = iface_cast<IAbilityManager>(remoteObject_);
return abms->FinishUserTest(msg, resultCode, bundleName, observer);
}
ErrCode AbilityManagerClient::GetCurrentTopAbility(sptr<IRemoteObject> &token)
{
CHECK_REMOTE_OBJECT_AND_RETURN(remoteObject_, ABILITY_SERVICE_NOT_CONNECTED);
sptr<IAbilityManager> abms = iface_cast<IAbilityManager>(remoteObject_);
return abms->GetCurrentTopAbility(token);
}
ErrCode AbilityManagerClient::DelegatorDoAbilityForeground(const sptr<IRemoteObject> &token)
{
CHECK_REMOTE_OBJECT_AND_RETURN(remoteObject_, ABILITY_SERVICE_NOT_CONNECTED);
sptr<IAbilityManager> abms = iface_cast<IAbilityManager>(remoteObject_);
return abms->DelegatorDoAbilityForeground(token);
}
ErrCode AbilityManagerClient::DelegatorDoAbilityBackground(const sptr<IRemoteObject> &token)
{
CHECK_REMOTE_OBJECT_AND_RETURN(remoteObject_, ABILITY_SERVICE_NOT_CONNECTED);
sptr<IAbilityManager> abms = iface_cast<IAbilityManager>(remoteObject_);
return abms->DelegatorDoAbilityBackground(token);
}
ErrCode AbilityManagerClient::SetMissionLabel(const sptr<IRemoteObject> &token, const std::string& label)
{
CHECK_REMOTE_OBJECT_AND_RETURN(remoteObject_, ABILITY_SERVICE_NOT_CONNECTED);

View File

@ -2361,6 +2361,138 @@ bool AbilityManagerProxy::IsRunningInStabilityTest()
return reply.ReadBool();
}
int AbilityManagerProxy::StartUserTest(const Want &want, const sptr<IRemoteObject> &observer)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!WriteInterfaceToken(data)) {
return INNER_ERR;
}
if (!data.WriteParcelable(&want)) {
HILOG_ERROR("want write failed.");
return INNER_ERR;
}
if (!data.WriteParcelable(observer)) {
HILOG_ERROR("observer write failed.");
return INNER_ERR;
}
auto error = Remote()->SendRequest(IAbilityManager::START_USER_TEST, data, reply, option);
if (error != NO_ERROR) {
HILOG_ERROR("Send request error: %{public}d", error);
return error;
}
return reply.ReadInt32();
}
int AbilityManagerProxy::FinishUserTest(const std::string &msg, const int &resultCode,
const std::string &bundleName, const sptr<IRemoteObject> &observer)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!WriteInterfaceToken(data)) {
return INNER_ERR;
}
if (!data.WriteString(msg)) {
HILOG_ERROR("msg write failed.");
return ERR_INVALID_VALUE;
}
if (!data.WriteInt32(resultCode)) {
HILOG_ERROR("resultCode:WriteInt32 fail.");
return ERR_INVALID_VALUE;
}
if (!data.WriteString(bundleName)) {
HILOG_ERROR("bundleName write failed.");
return ERR_INVALID_VALUE;
}
if (!data.WriteParcelable(observer)) {
HILOG_ERROR("observer write failed.");
return ERR_INVALID_VALUE;
}
auto error = Remote()->SendRequest(IAbilityManager::FINISH_USER_TEST, data, reply, option);
if (error != NO_ERROR) {
HILOG_ERROR("Send request error: %{public}d", error);
return error;
}
return reply.ReadInt32();
}
int AbilityManagerProxy::GetCurrentTopAbility(sptr<IRemoteObject> &token)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!WriteInterfaceToken(data)) {
return INNER_ERR;
}
auto error = Remote()->SendRequest(IAbilityManager::GET_CURRENT_TOP_ABILITY, data, reply, option);
if (error != NO_ERROR) {
HILOG_ERROR("Send request error: %{public}d", error);
return error;
}
token = sptr<IRemoteObject>(reply.ReadParcelable<IRemoteObject>());
if (!token) {
HILOG_ERROR("read IRemoteObject failed.");
return ERR_UNKNOWN_OBJECT;
}
return reply.ReadInt32();
}
int AbilityManagerProxy::DelegatorDoAbilityForeground(const sptr<IRemoteObject> &token)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!WriteInterfaceToken(data)) {
return INNER_ERR;
}
if (!data.WriteParcelable(token)) {
HILOG_ERROR("data write failed.");
return ERR_INVALID_VALUE;
}
auto error = Remote()->SendRequest(IAbilityManager::DELEGATOR_DO_ABILITY_FOREGROUND, data, reply, option);
if (error != NO_ERROR) {
HILOG_ERROR("Send request error: %{public}d", error);
return error;
}
return reply.ReadInt32();
}
int AbilityManagerProxy::DelegatorDoAbilityBackground(const sptr<IRemoteObject> &token)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!WriteInterfaceToken(data)) {
return INNER_ERR;
}
if (!data.WriteParcelable(token)) {
HILOG_ERROR("data write failed.");
return ERR_INVALID_VALUE;
}
auto error = Remote()->SendRequest(IAbilityManager::DELEGATOR_DO_ABILITY_BACKGROUND, data, reply, option);
if (error != NO_ERROR) {
HILOG_ERROR("Send request error: %{public}d", error);
return error;
}
return reply.ReadInt32();
}
bool AbilityManagerProxy::SendANRProcessID(int pid)
{
int error;

View File

@ -35,6 +35,7 @@
#include "if_system_ability_manager.h"
#include "ipc_skeleton.h"
#include "iservice_registry.h"
#include "itest_observer.h"
#include "locale_config.h"
#include "lock_screen_white_list.h"
#include "mission/mission_info_converter.h"
@ -3950,6 +3951,104 @@ int32_t AbilityManagerService::GetAbilityInfoFromExtension(const Want &want, App
return found;
}
int AbilityManagerService::StartUserTest(const Want &want, const sptr<IRemoteObject> &observer)
{
HILOG_DEBUG("enter");
if (observer == nullptr) {
HILOG_ERROR("observer is nullptr");
return ERR_INVALID_VALUE;
}
std::string bundleName = want.GetStringParam("-p");
if (bundleName.empty()) {
HILOG_ERROR("Invalid bundle name");
return ERR_INVALID_VALUE;
}
auto bms = GetBundleManager();
CHECK_POINTER_AND_RETURN(bms, START_USER_TEST_FAIL);
AppExecFwk::BundleInfo bundleInfo;
if (!bms->GetBundleInfo(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo)) {
HILOG_ERROR("Failed to get bundle info.");
return GET_BUNDLE_INFO_FAILED;
}
int ret = KillProcess(bundleName);
if (ret) {
HILOG_ERROR("Failed to kill process.");
return ret;
}
return DelayedSingleton<AppScheduler>::GetInstance()->StartUserTest(want, observer, bundleInfo);
}
int AbilityManagerService::FinishUserTest(const std::string &msg, const int &resultCode,
const std::string &bundleName, const sptr<IRemoteObject> &observer)
{
HILOG_DEBUG("enter");
int ret = KillProcess(bundleName);
if (ret) {
HILOG_ERROR("Failed to kill process.");
return ret;
}
sptr<ITestObserver> observerProxy = iface_cast<ITestObserver>(observer);
if (!observerProxy) {
HILOG_ERROR("Failed to get ITestObserver proxy");
return ERR_INVALID_VALUE;
}
observerProxy->TestFinished(msg, resultCode);
return ERR_OK;
}
int AbilityManagerService::GetCurrentTopAbility(sptr<IRemoteObject> &token)
{
HILOG_DEBUG("enter");
auto bms = GetBundleManager();
CHECK_POINTER_AND_RETURN(bms, GET_ABILITY_SERVICE_FAILED);
auto callerUid = IPCSkeleton::GetCallingUid();
std::string bundleName;
auto result = bms->GetBundleNameForUid(callerUid, bundleName);
if (!result) {
HILOG_ERROR("GetBundleNameForUid fail");
return GET_BUNDLENAME_BY_UID_FAIL;
}
auto abilityRecord = currentMissionListManager_->GetCurrentTopAbility(bundleName);
if (!abilityRecord) {
HILOG_ERROR("Failed to get top ability");
return ERR_INVALID_VALUE;
}
token = abilityRecord->GetToken();
return ERR_OK;
}
int AbilityManagerService::DelegatorDoAbilityForeground(const sptr<IRemoteObject> &token)
{
HILOG_DEBUG("enter");
CHECK_POINTER_AND_RETURN(token, ERR_INVALID_VALUE);
auto missionId = GetMissionIdByAbilityToken(token);
return DelegatorMoveMissionToFront(missionId);
}
int AbilityManagerService::DelegatorDoAbilityBackground(const sptr<IRemoteObject> &token)
{
HILOG_DEBUG("enter");
return MinimizeAbility(token);
}
int AbilityManagerService::DelegatorMoveMissionToFront(int32_t missionId)
{
HILOG_INFO("enter missionId : %{public}d", missionId);
CHECK_POINTER_AND_RETURN(currentMissionListManager_, ERR_NO_INIT);
return currentMissionListManager_->MoveMissionToFront(missionId);
}
int32_t AbilityManagerService::ShowPickerDialog(const Want& want, int32_t userId)
{
auto bms = GetBundleManager();

View File

@ -138,6 +138,15 @@ void AbilityManagerStub::SecondStepInit()
requestFuncMap_[SEND_APP_NOT_RESPONSE_PROCESS_ID] = &AbilityManagerStub::SendANRProcessIDInner;
}
void AbilityManagerStub::ThirdStepInit()
{
requestFuncMap_[START_USER_TEST] = &AbilityManagerStub::StartUserTestInner;
requestFuncMap_[FINISH_USER_TEST] = &AbilityManagerStub::FinishUserTestInner;
requestFuncMap_[GET_CURRENT_TOP_ABILITY] = &AbilityManagerStub::GetCurrentTopAbilityInner;
requestFuncMap_[DELEGATOR_DO_ABILITY_FOREGROUND] = &AbilityManagerStub::DelegatorDoAbilityForegroundInner;
requestFuncMap_[DELEGATOR_DO_ABILITY_BACKGROUND] = &AbilityManagerStub::DelegatorDoAbilityBackgroundInner;
}
int AbilityManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
{
HILOG_DEBUG("cmd = %{public}d, flags= %{public}d", code, option.GetFlags());
@ -1382,6 +1391,61 @@ int AbilityManagerStub::IsRunningInStabilityTestInner(MessageParcel &data, Messa
return NO_ERROR;
}
int AbilityManagerStub::StartUserTestInner(MessageParcel &data, MessageParcel &reply)
{
Want *want = data.ReadParcelable<Want>();
if (want == nullptr) {
HILOG_ERROR("want is nullptr");
return ERR_INVALID_VALUE;
}
auto observer = data.ReadParcelable<IRemoteObject>();
int32_t result = StartUserTest(*want, observer);
reply.WriteInt32(result);
delete want;
return result;
}
int AbilityManagerStub::FinishUserTestInner(MessageParcel &data, MessageParcel &reply)
{
std::string msg = data.ReadString();
int resultCode = data.ReadInt32();
std::string bundleName = data.ReadString();
auto observer = data.ReadParcelable<IRemoteObject>();
int32_t result = FinishUserTest(msg, resultCode, bundleName, observer);
reply.WriteInt32(result);
return result;
}
int AbilityManagerStub::GetCurrentTopAbilityInner(MessageParcel &data, MessageParcel &reply)
{
sptr<IRemoteObject> token;
auto result = GetCurrentTopAbility(token);
if (!reply.WriteParcelable(token)) {
HILOG_ERROR("data write failed.");
return ERR_INVALID_VALUE;
}
reply.WriteInt32(result);
return NO_ERROR;
}
int AbilityManagerStub::DelegatorDoAbilityForegroundInner(MessageParcel &data, MessageParcel &reply)
{
sptr<IRemoteObject> token = data.ReadParcelable<IRemoteObject>();
auto result = DelegatorDoAbilityForeground(token);
reply.WriteInt32(result);
return NO_ERROR;
}
int AbilityManagerStub::DelegatorDoAbilityBackgroundInner(MessageParcel &data, MessageParcel &reply)
{
sptr<IRemoteObject> token = data.ReadParcelable<IRemoteObject>();
auto result = DelegatorDoAbilityBackground(token);
reply.WriteInt32(result);
return NO_ERROR;
}
int AbilityManagerStub::SendANRProcessIDInner(MessageParcel &data, MessageParcel &reply)
{
int32_t pid = data.ReadInt32();

View File

@ -305,6 +305,18 @@ std::string AppScheduler::ConvertAppState(const AppState &state)
return "INVALIDSTATE";
}
int AppScheduler::StartUserTest(const Want &want, const sptr<IRemoteObject> &observer,
const AppExecFwk::BundleInfo &bundleInfo)
{
CHECK_POINTER_AND_RETURN(appMgrClient_, INNER_ERR);
int ret = appMgrClient_->StartUserTestProcess(want, observer, bundleInfo);
if (ret != ERR_OK) {
HILOG_ERROR("Fail to start user test.");
return INNER_ERR;
}
return ERR_OK;
}
int AppScheduler::UpdateConfiguration(const AppExecFwk::Configuration &config)
{
CHECK_POINTER_AND_RETURN(appMgrClient_, INNER_ERR);

View File

@ -1946,6 +1946,29 @@ void MissionListManager::GetAbilityRunningInfos(std::vector<AbilityRunningInfo>
}
}
std::shared_ptr<AbilityRecord> MissionListManager::GetCurrentTopAbility(const std::string &bundleName)
{
for (auto &missionList : currentMissionLists_) {
if (!missionList) {
HILOG_WARN("Invalid missionList.");
continue;
}
auto abilityRecord = missionList->GetLauncherRoot();
if (!abilityRecord) {
HILOG_ERROR("Invalid ability record.");
return {};
}
auto appInfo = abilityRecord->GetApplicationInfo();
if (bundleName.compare(appInfo.bundleName)) {
return abilityRecord;
}
}
return {};
}
bool MissionListManager::IsStarted()
{
std::lock_guard<std::recursive_mutex> guard(managerLock_);

View File

@ -179,6 +179,12 @@ void AppScheduler::GetRunningProcessInfoByToken(const sptr<IRemoteObject> &token
void AppScheduler::StartSpecifiedAbility(const AAFwk::Want &want, const AppExecFwk::AbilityInfo &abilityInfo)
{}
int AppScheduler::StartUserTest(const Want &want, const sptr<IRemoteObject> &observer,
const AppExecFwk::BundleInfo &bundleInfo)
{
return 0;
}
int AppScheduler::UpdateConfiguration(const AppExecFwk::Configuration &)
{
return 0;

View File

@ -415,6 +415,32 @@ public:
MOCK_METHOD2(GetExtensionRunningInfos, int(int upperLimit, std::vector<ExtensionRunningInfo> &info));
MOCK_METHOD1(GetProcessRunningInfos, int(std::vector<AppExecFwk::RunningProcessInfo> &info));
MOCK_METHOD3(StartAbilityByCall, int(const Want &, const sptr<IAbilityConnection> &, const sptr<IRemoteObject> &));
virtual int StartUserTest(const Want &want, const sptr<IRemoteObject> &observer) override
{
return 0;
}
virtual int FinishUserTest(const std::string &msg, const int &resultCode,
const std::string &bundleName, const sptr<IRemoteObject> &observer) override
{
return 0;
}
virtual int GetCurrentTopAbility(sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int DelegatorDoAbilityForeground(const sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int DelegatorDoAbilityBackground(const sptr<IRemoteObject> &token) override
{
return 0;
}
};
} // namespace AAFwk
} // namespace OHOS

View File

@ -422,6 +422,32 @@ public:
{
return true;
}
virtual int StartUserTest(const Want &want, const sptr<IRemoteObject> &observer) override
{
return 0;
}
virtual int FinishUserTest(const std::string &msg, const int &resultCode,
const std::string &bundleName, const sptr<IRemoteObject> &observer) override
{
return 0;
}
virtual int GetCurrentTopAbility(sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int DelegatorDoAbilityForeground(const sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int DelegatorDoAbilityBackground(const sptr<IRemoteObject> &token) override
{
return 0;
}
};
} // namespace AAFwk
} // namespace OHOS

View File

@ -202,6 +202,16 @@ public:
*/
virtual void StartupResidentProcess() override;
/**
* Start user test process.
* @param want, want object.
* @param observer, test observer remote object.
* @param bundleInfo, bundle info.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int StartUserTestProcess(const AAFwk::Want &want, const sptr<IRemoteObject> &observer,
const AppExecFwk::BundleInfo &bundleInfo) override;
virtual void ScheduleAcceptWantDone(
const int32_t recordId, const AAFwk::Want &want, const std::string &flag) override;

View File

@ -550,6 +550,16 @@ public:
*/
int32_t GetForegroundApplications(std::vector<AppStateData> &list);
/**
* Start user test process.
* @param want, want object.
* @param observer, test observer remote object.
* @param bundleInfo, bundle info.
* @return Returns ERR_OK on success, others on failure.
*/
int StartUserTestProcess(const AAFwk::Want &want, const sptr<IRemoteObject> &observer,
const AppExecFwk::BundleInfo &bundleInfo);
void StartSpecifiedAbility(const AAFwk::Want &want, const AppExecFwk::AbilityInfo &abilityInfo);
void RegisterStartSpecifiedAbilityResponse(const sptr<IStartSpecifiedAbilityResponse> &response);
@ -773,6 +783,9 @@ private:
void OnProcessDied(const std::shared_ptr<AppRunningRecord> &appRecord);
int StartEmptyProcess(const AAFwk::Want &want, const sptr<IRemoteObject> &observer,
const BundleInfo &info, const std::string &processName);
void HandleStartSpecifiedAbilityTimeOut(const int64_t eventId);
void GetGlobalConfiguration();

View File

@ -442,6 +442,8 @@ public:
void GetBundleNames(std::vector<std::string> &bundleNames);
void SetUserTestInfo(const UserTestRecord &record);
void SetSpecifiedAbilityFlagAndWant(const bool flag, const AAFwk::Want &want, const std::string &moduleName);
bool IsStartSpecifiedAbility() const;
void ScheduleAcceptWant(const std::string &moduleName);
@ -524,6 +526,8 @@ private:
bool isSpecifiedAbility_ = false;
AAFwk::Want SpecifiedWant_;
std::string moduleName_;
UserTestRecord userTestRecord_;
};
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -43,6 +43,7 @@ const std::string TASK_ADD_APP_DEATH_RECIPIENT = "AddAppRecipientTask";
const std::string TASK_CLEAR_UP_APPLICATION_DATA = "ClearUpApplicationDataTask";
const std::string TASK_STARTUP_RESIDENT_PROCESS = "StartupResidentProcess";
const std::string TASK_ADD_ABILITY_STAGE_DONE = "AddAbilityStageDone";
const std::string TASK_START_USER_TEST_PROCESS = "StartUserTestProcess";
} // namespace
REGISTER_SYSTEM_ABILITY_BY_ID(AppMgrService, APP_MGR_SERVICE_ID, true);
@ -378,6 +379,18 @@ int32_t AppMgrService::GetForegroundApplications(std::vector<AppStateData> &list
return appMgrServiceInner_->GetForegroundApplications(list);
}
int AppMgrService::StartUserTestProcess(const AAFwk::Want &want, const sptr<IRemoteObject> &observer,
const AppExecFwk::BundleInfo &bundleInfo)
{
if (!IsReady()) {
return ERR_INVALID_OPERATION;
}
std::function<void()> startUserTestProcessFunc =
std::bind(&AppMgrServiceInner::StartUserTestProcess, appMgrServiceInner_, want, observer, bundleInfo);
handler_->PostTask(startUserTestProcessFunc, TASK_START_USER_TEST_PROCESS);
return ERR_OK;
}
void AppMgrService::ScheduleAcceptWantDone(const int32_t recordId, const AAFwk::Want &want, const std::string &flag)
{
if (!IsReady()) {

View File

@ -1948,6 +1948,65 @@ int32_t AppMgrServiceInner::GetForegroundApplications(std::vector<AppStateData>
return ERR_OK;
}
int AppMgrServiceInner::StartUserTestProcess(const AAFwk::Want &want, const sptr<IRemoteObject> &observer,
const BundleInfo &bundleInfo)
{
if (!appRunningManager_) {
APP_LOGE("appRunningManager_ is nullptr");
return ERR_INVALID_VALUE;
}
auto processName = bundleInfo.applicationInfo.process.empty() ?
bundleInfo.applicationInfo.bundleName : bundleInfo.applicationInfo.process;
APP_LOGI("processName = [%{public}s]", processName.c_str());
// Inspection records
auto appRecord = appRunningManager_->CheckAppRunningRecordIsExist(
bundleInfo.applicationInfo.name, processName, bundleInfo.applicationInfo.uid, bundleInfo);
if (appRecord) {
APP_LOGI("processName [%{public}s] Already exists ", processName.c_str());
return ERR_INVALID_VALUE;
}
return StartEmptyProcess(want, observer, bundleInfo, processName);
}
int AppMgrServiceInner::StartEmptyProcess(const AAFwk::Want &want, const sptr<IRemoteObject> &observer,
const BundleInfo &info, const std::string &processName)
{
APP_LOGI("enter bundle [%{public}s | processName [%{public}s]]", info.name.c_str(), processName.c_str());
if (!CheckRemoteClient() || !appRunningManager_) {
APP_LOGE("Failed to start the process being tested!");
return ERR_INVALID_VALUE;
}
auto appInfo = std::make_shared<ApplicationInfo>(info.applicationInfo);
auto appRecord = appRunningManager_->CreateAppRunningRecord(appInfo, processName, info);
if (!appRecord) {
APP_LOGE("start process [%{public}s] failed!", processName.c_str());
return ERR_INVALID_VALUE;
}
UserTestRecord testRecord;
testRecord.want = want;
testRecord.observer = observer;
appRecord->SetUserTestInfo(testRecord);
StartProcess(appInfo->name, processName, appRecord, appInfo->uid, appInfo->bundleName);
// If it is empty, the startup failed
if (!appRecord) {
APP_LOGE("start process [%{public}s] failed!", processName.c_str());
return ERR_INVALID_VALUE;
}
appRecord->SetEventHandler(eventHandler_);
appRecord->AddModules(appInfo, info.hapModuleInfos);
APP_LOGI("StartEmptyProcess OK pid : [%{public}d]", appRecord->GetPriorityObject()->GetPid());
return ERR_OK;
}
void AppMgrServiceInner::StartSpecifiedAbility(const AAFwk::Want &want, const AppExecFwk::AbilityInfo &abilityInfo)
{
APP_LOGD("Start specified ability.");

View File

@ -247,7 +247,7 @@ void AppRunningRecord::LaunchApplication(const Configuration &config)
launchData.SetProcessInfo(processInfo);
launchData.SetRecordId(appRecordId_);
launchData.SetUId(mainUid_);
launchData.SetUserTestInfo(userTestRecord_);
APP_LOGI("ScheduleLaunchApplication app:%{public}s", GetName().c_str());
appLifeCycleDeal_->LaunchApplication(launchData, config);
}
@ -863,6 +863,11 @@ void AppRunningRecord::GetBundleNames(std::vector<std::string> &bundleNames)
}
}
void AppRunningRecord::SetUserTestInfo(const UserTestRecord &record)
{
userTestRecord_ = record;
}
void AppRunningRecord::SetSpecifiedAbilityFlagAndWant(
const bool flag, const AAFwk::Want &want, const std::string &moduleName)
{

View File

@ -52,6 +52,12 @@ public:
MOCK_METHOD3(ScheduleAcceptWantDone,
void(const int32_t recordId, const AAFwk::Want &want, const std::string &flag));
virtual int StartUserTestProcess(const AAFwk::Want &want, const sptr<IRemoteObject> &observer,
const BundleInfo &bundleInfo)
{
return 0;
}
virtual void RegisterAppStateCallback(const sptr<IAppStateCallback> &callback)
{
callback_ = callback;

View File

@ -335,6 +335,32 @@ public:
{
return 0;
}
virtual int StartUserTest(const Want &want, const sptr<IRemoteObject> &observer) override
{
return 0;
}
virtual int FinishUserTest(const std::string &msg, const int &resultCode,
const std::string &bundleName, const sptr<IRemoteObject> &observer) override
{
return 0;
}
virtual int GetCurrentTopAbility(sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int DelegatorDoAbilityForeground(const sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int DelegatorDoAbilityBackground(const sptr<IRemoteObject> &token) override
{
return 0;
}
};
class MockAbilityMgrStub : public IRemoteStub<AAFwk::IAbilityManager> {
@ -732,6 +758,32 @@ public:
return 0;
}
virtual int StartUserTest(const Want &want, const sptr<IRemoteObject> &observer) override
{
return 0;
}
virtual int FinishUserTest(const std::string &msg, const int &resultCode,
const std::string &bundleName, const sptr<IRemoteObject> &observer) override
{
return 0;
}
virtual int GetCurrentTopAbility(sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int DelegatorDoAbilityForeground(const sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int DelegatorDoAbilityBackground(const sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int MoveMissionToFront(int32_t missionId) override
{
return 0;

View File

@ -187,6 +187,32 @@ public:
return true;
}
virtual int StartUserTest(const Want &want, const sptr<IRemoteObject> &observer) override
{
return 0;
}
virtual int FinishUserTest(const std::string &msg, const int &resultCode,
const std::string &bundleName, const sptr<IRemoteObject> &observer) override
{
return 0;
}
virtual int GetCurrentTopAbility(sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int DelegatorDoAbilityForeground(const sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int DelegatorDoAbilityBackground(const sptr<IRemoteObject> &token) override
{
return 0;
}
void Wait()
{
sem_.Wait();

View File

@ -28,6 +28,11 @@ ohos_source_set("tools_aa_source_set") {
sources = [
"src/ability_command.cpp",
"src/shell_command.cpp",
"src/shell_command_result.cpp",
"src/system_time.cpp",
"src/test_observer.cpp",
"src/test_observer_proxy.cpp",
"src/test_observer_stub.cpp",
]
public_configs = [

View File

@ -31,7 +31,8 @@ const std::string HELP_MSG = "usage: aa <command> <options>\n"
" stop-service stop service with options\n"
" dump dump the ability stack info\n"
" dumpsys dump the ability info\n"
" force-stop <bundle-name> force stop the process with bundle name\n";
" force-stop <bundle-name> force stop the process with bundle name\n"
" test start the test framework with options\n";
const std::string HELP_MSG_SCREEN =
"usage: aa screen <options>\n"
@ -74,6 +75,14 @@ const std::string HELP_MSG_DUMPSYS = "usage: aa dumpsys <options>\n"
" -u, --userId userId\n"
" -c, --client client\n";
const std::string HELP_MSG_TEST =
"usage: aa test <options>\n"
"options list:\n"
" -h, --help \
list available commands\n"
" -p <bundle-name> -s unittest <test-runner> -s class <test-class> [-w <wait-time>] \
start the test framework with options\n";
const std::string HELP_MSG_FORCE_STOP = "usage: aa force-stop <bundle-name>\n";
const std::string HELP_MSG_NO_ABILITY_NAME_OPTION = "error: -a <ability-name> is expected";
@ -94,6 +103,13 @@ const std::string STRING_SCREEN_POWER_OFF_NG = "error: failed to power off scree
const std::string STRING_FORCE_STOP_OK = "force stop process successfully.";
const std::string STRING_FORCE_STOP_NG = "error: failed to force stop process.";
const std::string STRING_START_USER_TEST_OK = "start user test successfully.";
const std::string STRING_START_USER_TEST_NG = "error: failed to start user test.";
const int USER_TEST_COMMAND_START_INDEX = 2;
const int USER_TEST_COMMAND_PARAMS_NUM = 2;
const int TIME_RATE_MS = 1000;
} // namespace
class AbilityManagerShellCommand : public ShellCommand {
@ -118,8 +134,12 @@ private:
ErrCode RunAsDumpCommandOptopt();
ErrCode MakeWantFromCmd(Want &want, std::string &windowMode);
ErrCode RunAsDumpSysCommandOptopt();
};
ErrCode RunAsTestCommand();
bool IsTestCommandIntegrity(const std::map<std::string, std::string> &params);
ErrCode TestCommandError(const std::string &info);
ErrCode StartUserTest(const std::map<std::string, std::string> &params);
};
} // namespace AAFwk
} // namespace OHOS

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef FOUNDATION_AAFWK_STANDARD_TOOLS_AA_INCLUDE_ITEST_OBSERVER_H
#define FOUNDATION_AAFWK_STANDARD_TOOLS_AA_INCLUDE_ITEST_OBSERVER_H
#include "iremote_broker.h"
#include "shell_command_result.h"
namespace OHOS {
namespace AAFwk {
class ITestObserver : public IRemoteBroker {
public:
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.aafwk.ITestObserver");
virtual void TestStatus(const std::string &msg, const int &resultCode) = 0;
virtual void TestFinished(const std::string &msg, const int &resultCode) = 0;
virtual ShellCommandResult ExecuteShellCommand(
const std::string &cmd, const int64_t timeoutMs) = 0;
enum class Message {
AA_TEST_STATUS = 1,
AA_TEST_FINISHED = 2,
AA_EXECUTE_SHELL_COMMAND = 3,
};
};
} // namespace AAFwk
} // namespace OHOS
#endif // FOUNDATION_AAFWK_STANDARD_TOOLS_AA_INCLUDE_ITEST_OBSERVER_H

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef FOUNDATION_AAFWK_STANDARD_TOOLS_AA_INCLUDE_SHELL_COMMAND_RESULT_H
#define FOUNDATION_AAFWK_STANDARD_TOOLS_AA_INCLUDE_SHELL_COMMAND_RESULT_H
#include <string>
#include "parcel.h"
namespace OHOS {
namespace AAFwk {
struct ShellCommandResult : public Parcelable {
int32_t exitCode {-1};
std::string stdResult {};
bool ReadFromParcel(Parcel &parcel);
virtual bool Marshalling(Parcel &parcel) const override;
static ShellCommandResult *Unmarshalling(Parcel &parcel);
};
} // namespace AAFwk
} // namespace OHOS
#endif // FOUNDATION_AAFWK_STANDARD_TOOLS_AA_INCLUDE_SHELL_COMMAND_RESULT_H

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef FOUNDATION_AAFWK_STANDARD_TOOLS_AA_INCLUDE_SYSTEM_TIME_H
#define FOUNDATION_AAFWK_STANDARD_TOOLS_AA_INCLUDE_SYSTEM_TIME_H
#include "singleton.h"
namespace OHOS {
namespace AAFwk {
class SystemTime {
public:
static int64_t GetNowSysTime();
};
} // namespace AAFwk
} // namespace OHOS
#endif // FOUNDATION_AAFWK_STANDARD_TOOLS_AA_INCLUDE_SYSTEM_TIME_H

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef FOUNDATION_AAFWK_STANDARD_TOOLS_AA_INCLUDE_TEST_OBSERVER_H
#define FOUNDATION_AAFWK_STANDARD_TOOLS_AA_INCLUDE_TEST_OBSERVER_H
#include "test_observer_stub.h"
namespace OHOS {
namespace AAFwk {
class TestObserver : public TestObserverStub {
public:
TestObserver();
virtual ~TestObserver() override;
virtual void TestStatus(const std::string &msg, const int &resultCode) override;
virtual void TestFinished(const std::string &msg, const int &resultCode) override;
virtual ShellCommandResult ExecuteShellCommand(
const std::string &cmd, const int64_t timeoutMs) override;
bool waitForFinish(const int64_t &timeoutMs);
private:
bool isFinished_;
static constexpr int64_t SHELL_COMMAND_TIMEOUT_MAX = 5000;
};
} // namespace AAFwk
} // namespace OHOS
#endif // FOUNDATION_AAFWK_STANDARD_TOOLS_AA_INCLUDE_TEST_OBSERVER_H

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef FOUNDATION_AAFWK_STANDARD_TOOLS_AA_INCLUDE_TEST_OBSERVER_PROXY_H
#define FOUNDATION_AAFWK_STANDARD_TOOLS_AA_INCLUDE_TEST_OBSERVER_PROXY_H
#include "itest_observer.h"
#include "iremote_proxy.h"
namespace OHOS {
namespace AAFwk {
class TestObserverProxy : public IRemoteProxy<ITestObserver> {
public:
explicit TestObserverProxy(const sptr<IRemoteObject> &object);
virtual ~TestObserverProxy() override;
virtual void TestStatus(const std::string &msg, const int &resultCode) override;
virtual void TestFinished(const std::string &msg, const int &resultCode) override;
virtual ShellCommandResult ExecuteShellCommand(
const std::string &cmd, const int64_t timeoutMs) override;
private:
static inline BrokerDelegator<TestObserverProxy> delegator_;
};
} // namespace AAFwk
} // namespace OHOS
#endif // FOUNDATION_AAFWK_STANDARD_TOOLS_AA_INCLUDE_TEST_OBSERVER_PROXY_H

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef FOUNDATION_AAFWK_STANDARD_TOOLS_AA_INCLUDE_TEST_OBSERVER_STUB_H
#define FOUNDATION_AAFWK_STANDARD_TOOLS_AA_INCLUDE_TEST_OBSERVER_STUB_H
#include "itest_observer.h"
#include "iremote_stub.h"
namespace OHOS {
namespace AAFwk {
class TestObserverStub : public IRemoteStub<ITestObserver> {
public:
TestObserverStub();
virtual ~TestObserverStub() override;
virtual int OnRemoteRequest(
uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
};
} // namespace AAFwk
} // namespace OHOS
#endif // FOUNDATION_AAFWK_STANDARD_TOOLS_AA_INCLUDE_TEST_OBSERVER_STUB_H

View File

@ -20,6 +20,7 @@
#include "mission_snapshot.h"
#include "hilog_wrapper.h"
#include "ohos/aafwk/base/bool_wrapper.h"
#include "test_observer.h"
using namespace OHOS::AppExecFwk;
@ -84,6 +85,7 @@ ErrCode AbilityManagerShellCommand::CreateCommandMap()
{"dump", std::bind(&AbilityManagerShellCommand::RunAsDumpCommand, this)},
{"dumpsys", std::bind(&AbilityManagerShellCommand::RunAsDumpsysCommand, this)},
{"force-stop", std::bind(&AbilityManagerShellCommand::RunAsForceStop, this)},
{"test", std::bind(&AbilityManagerShellCommand::RunAsTestCommand, this)},
};
return OHOS::ERR_OK;
@ -1140,6 +1142,104 @@ ErrCode AbilityManagerShellCommand::MakeWantFromCmd(Want &want, std::string &win
return result;
}
ErrCode AbilityManagerShellCommand::RunAsTestCommand()
{
HILOG_INFO("enter");
std::map<std::string, std::string> params;
for (int i = USER_TEST_COMMAND_START_INDEX; i < argc_; i++) {
HILOG_INFO("argv_[%{public}d]: %{public}s", i, argv_[i]);
std::string opt = argv_[i];
if (opt == "-h" || opt == "--help") {
resultReceiver_.append(HELP_MSG_TEST);
return OHOS::ERR_OK;
} else if (opt == "-p" || opt == "-w") {
if (i >= argc_ - 1) {
return TestCommandError("error: option [" + opt + "] requires a value.\n");
}
std::string argv = argv_[++i];
params[opt] = argv;
} else if (opt == "-s") {
if (i >= argc_ - USER_TEST_COMMAND_PARAMS_NUM) {
return TestCommandError(
"error: option Should be [-s unittest <test-runner>] or [-s class <test-class>].\n");
}
std::string argKey = argv_[++i];
std::string argValue = argv_[++i];
if (!(argKey == "unittest" || argKey == "class")) {
return TestCommandError("error: option Should be [-s unittest] or [-s class].\n");
}
params[opt + " " + argKey] = argValue;
} else if (opt.at(0) == '-') {
return TestCommandError("error: unknown option: " + opt + "\n");
}
}
if (!IsTestCommandIntegrity(params)) {
return OHOS::ERR_INVALID_VALUE;
}
return StartUserTest(params);
}
bool AbilityManagerShellCommand::IsTestCommandIntegrity(const std::map<std::string, std::string> &params)
{
HILOG_INFO("enter");
std::vector<std::string> opts = {"-p", "-s unittest", "-s class"};
for (auto opt : opts) {
auto it = params.find(opt);
if (it == params.end()) {
TestCommandError("error: the option [" + opt + "] is expected.\n");
return false;
}
}
return true;
}
ErrCode AbilityManagerShellCommand::TestCommandError(const std::string &info)
{
resultReceiver_.append(info);
resultReceiver_.append(HELP_MSG_TEST);
return OHOS::ERR_INVALID_VALUE;
}
ErrCode AbilityManagerShellCommand::StartUserTest(const std::map<std::string, std::string> &params)
{
HILOG_INFO("enter");
Want want;
for (auto param : params) {
want.SetParam(param.first, param.second);
}
sptr<TestObserver> observer = new (std::nothrow) TestObserver();
if (!observer) {
HILOG_ERROR("Failed: the TestObserver is null");
return OHOS::ERR_INVALID_VALUE;
}
int result = AbilityManagerClient::GetInstance()->StartUserTest(want, observer->AsObject());
if (result != OHOS::ERR_OK) {
HILOG_INFO("%{public}s result = %{public}d", STRING_START_USER_TEST_NG.c_str(), result);
resultReceiver_ = STRING_START_USER_TEST_NG + "\n";
resultReceiver_.append(GetMessageFromCode(result));
return result;
}
HILOG_INFO("%{public}s", STRING_START_USER_TEST_OK.c_str());
int64_t timeMs = 0;
if (!want.GetStringParam("-w").empty()) {
int time = std::stoi(want.GetStringParam("-w"));
timeMs = time * TIME_RATE_MS;
}
if (!observer->waitForFinish(timeMs)) {
resultReceiver_ = "Timeout: user test is not completed within the specified time.\n";
return OHOS::ERR_INVALID_VALUE;
}
resultReceiver_ = STRING_START_USER_TEST_OK + "\n";
return result;
}
} // namespace AAFwk
} // namespace OHOS

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2021 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 "shell_command_result.h"
#include "hilog_wrapper.h"
namespace OHOS {
namespace AAFwk {
bool ShellCommandResult::Marshalling(Parcel &parcel) const
{
if (!parcel.WriteInt32(exitCode)) {
HILOG_ERROR("Failed to write exitCode");
return false;
}
if (!parcel.WriteString(stdResult)) {
HILOG_ERROR("Failed to write stdResult");
return false;
}
return true;
}
bool ShellCommandResult::ReadFromParcel(Parcel &parcel)
{
exitCode = parcel.ReadInt32();
stdResult = parcel.ReadString();
return true;
}
ShellCommandResult *ShellCommandResult::Unmarshalling(Parcel &parcel)
{
ShellCommandResult *result = new (std::nothrow) ShellCommandResult();
if (result && !result->ReadFromParcel(parcel)) {
delete result;
result = nullptr;
}
return result;
}
} // namespace AAFwk
} // namespace OHOS

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2021 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 "system_time.h"
#include "hilog_wrapper.h"
#include "inner_event.h"
namespace OHOS {
namespace AAFwk {
using namespace OHOS::AppExecFwk;
int64_t SystemTime::GetNowSysTime()
{
HILOG_INFO("enter");
InnerEvent::TimePoint nowSys = InnerEvent::Clock::now();
auto epoch = nowSys.time_since_epoch();
auto value = std::chrono::duration_cast<std::chrono::milliseconds>(epoch);
int64_t duration = value.count();
return duration;
}
} // namespace AAFwk
} // namespace OHOS

View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2021 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 "test_observer.h"
#include <iostream>
#include <thread>
#include <unistd.h>
#include "hilog_wrapper.h"
#include "system_time.h"
namespace OHOS {
namespace AAFwk {
TestObserver::TestObserver()
: isFinished_(false)
{}
TestObserver::~TestObserver()
{}
void TestObserver::TestStatus(const std::string &msg, const int &resultCode)
{
HILOG_INFO("enter");
std::cout << "TestStatus-resultCode: " + std::to_string(resultCode) << std::endl;
std::cout << "TestStatus-resultMsg: " + msg << std::endl;
}
void TestObserver::TestFinished(const std::string &msg, const int &resultCode)
{
HILOG_INFO("enter");
std::cout << "TestFinished-resultCode: " + std::to_string(resultCode) << std::endl;
std::cout << "TestFinished-resultMsg: " + msg << std::endl;
isFinished_ = true;
}
ShellCommandResult TestObserver::ExecuteShellCommand(const std::string &cmd, const int64_t timeoutMs)
{
HILOG_INFO("enter");
ShellCommandResult result;
if (cmd.empty()) {
return result;
}
FILE *file = popen(cmd.c_str(), "r");
if (!file) {
return result;
}
int64_t timeout = (timeoutMs <= 0) ? SHELL_COMMAND_TIMEOUT_MAX : timeoutMs;
std::this_thread::sleep_for(std::chrono::microseconds(timeout));
char commandResult[1024] = {0};
while ((fgets(commandResult, sizeof(commandResult), file)) != nullptr) {
result.stdResult.append(commandResult);
std::cout << commandResult;
}
result.exitCode = pclose(file);
file = nullptr;
return result;
}
bool TestObserver::waitForFinish(const int64_t &timeoutMs)
{
HILOG_INFO("enter");
int64_t startTime = SystemTime::GetNowSysTime();
while (!isFinished_) {
int64_t nowSysTime = SystemTime::GetNowSysTime();
if (timeoutMs && (nowSysTime - startTime > timeoutMs)) {
return false;
}
sleep(1);
}
return true;
}
} // namespace AAFwk
} // namespace OHOS

View File

@ -0,0 +1,136 @@
/*
* Copyright (c) 2021 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 "test_observer_proxy.h"
#include "hilog_wrapper.h"
namespace OHOS {
namespace AAFwk {
TestObserverProxy::TestObserverProxy(const sptr<IRemoteObject> &object) : IRemoteProxy<ITestObserver>(object)
{
HILOG_INFO("test observer proxy instance is created");
}
TestObserverProxy::~TestObserverProxy()
{
HILOG_INFO("test observer proxy is destoryed");
}
void TestObserverProxy::TestStatus(const std::string &msg, const int &resultCode)
{
HILOG_INFO("start");
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_ASYNC);
sptr<IRemoteObject> remote = Remote();
if (remote == nullptr) {
HILOG_ERROR("Failed to send cmd to service due to remote objetc is null");
return;
}
if (!data.WriteString(msg)) {
HILOG_ERROR("Failed to write string msg");
return;
}
if (!data.WriteInt32(resultCode)) {
HILOG_ERROR("Failed to write resultCode");
return;
}
int32_t result = remote->SendRequest(
static_cast<uint32_t>(ITestObserver::Message::AA_TEST_STATUS), data, reply, option);
if (result != OHOS::NO_ERROR) {
HILOG_ERROR("Failed to SendRequest, error code: %{public}d", result);
return;
}
}
void TestObserverProxy::TestFinished(const std::string &msg, const int &resultCode)
{
HILOG_INFO("start");
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_ASYNC);
sptr<IRemoteObject> remote = Remote();
if (remote == nullptr) {
HILOG_ERROR("Failed to send cmd to service due to remote objetc is null");
return;
}
if (!data.WriteString(msg)) {
HILOG_ERROR("Failed to write string msg");
return;
}
if (!data.WriteInt32(resultCode)) {
HILOG_ERROR("Failed to write resultCode");
return;
}
int32_t result = remote->SendRequest(
static_cast<uint32_t>(ITestObserver::Message::AA_TEST_FINISHED), data, reply, option);
if (result != OHOS::NO_ERROR) {
HILOG_ERROR("Failed to SendRequest, error code: %{public}d", result);
return;
}
}
ShellCommandResult TestObserverProxy::ExecuteShellCommand(
const std::string &cmd, const int64_t timeoutMs)
{
HILOG_INFO("start");
ShellCommandResult result;
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_SYNC);
sptr<IRemoteObject> remote = Remote();
if (remote == nullptr) {
HILOG_ERROR("Failed to send cmd to service due to remote objetc is null");
return result;
}
if (!data.WriteString(cmd)) {
HILOG_ERROR("Failed to write string cmd");
return result;
}
if (!data.WriteInt64(timeoutMs)) {
HILOG_ERROR("Failed to write timeoutMs");
return result;
}
int32_t ret = remote->SendRequest(
static_cast<uint32_t>(ITestObserver::Message::AA_EXECUTE_SHELL_COMMAND), data, reply, option);
if (ret != OHOS::NO_ERROR) {
HILOG_ERROR("Failed to SendRequest, error code: %{public}d", ret);
return result;
}
ShellCommandResult *resultPtr = reply.ReadParcelable<ShellCommandResult>();
if (!resultPtr) {
HILOG_ERROR("Failed to read result");
return result;
}
result = *resultPtr;
return result;
}
} // namespace AAFwk
} // namespace OHOS

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2021 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 "test_observer_stub.h"
#include "hilog_wrapper.h"
namespace OHOS {
namespace AAFwk {
TestObserverStub::TestObserverStub()
{
HILOG_INFO("test observer stub instance is created");
}
TestObserverStub::~TestObserverStub()
{
HILOG_INFO("test observer stub instance is destroyed");
}
int TestObserverStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
{
switch (code) {
case static_cast<uint32_t>(ITestObserver::Message::AA_TEST_STATUS): {
std::string msg = data.ReadString();
int resultCode = data.ReadInt32();
TestStatus(msg, resultCode);
break;
}
case static_cast<uint32_t>(ITestObserver::Message::AA_TEST_FINISHED): {
std::string msg = data.ReadString();
int resultCode = data.ReadInt32();
TestFinished(msg, resultCode);
break;
}
case static_cast<uint32_t>(ITestObserver::Message::AA_EXECUTE_SHELL_COMMAND): {
std::string cmd = data.ReadString();
int64_t timeoutMs = data.ReadInt64();
ShellCommandResult result = ExecuteShellCommand(cmd, timeoutMs);
if (!reply.WriteParcelable(&result)) {
HILOG_ERROR("Failed to write reply ShellCommandResult!");
return ERR_INVALID_VALUE;
}
break;
}
default:
HILOG_WARN("event receive stub receives unknown code, code = %{public}u", code);
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
return NO_ERROR;
}
} // namespace AAFwk
} // namespace OHOS

View File

@ -214,6 +214,33 @@ public:
virtual void DumpSysState(
const std::string& args, std::vector<std::string>& info, bool isClient, bool isUserID, int UserID) override
{}
virtual int StartUserTest(const Want &want, const sptr<IRemoteObject> &observer) override
{
return 0;
}
virtual int FinishUserTest(const std::string &msg, const int &resultCode,
const std::string &bundleName, const sptr<IRemoteObject> &observer) override
{
return 0;
}
virtual int GetCurrentTopAbility(sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int DelegatorDoAbilityForeground(const sptr<IRemoteObject> &token) override
{
return 0;
}
virtual int DelegatorDoAbilityBackground(const sptr<IRemoteObject> &token) override
{
return 0;
}
public:
std::string powerState_;
};