mirror of
https://github.com/openharmony/ability_ability_runtime.git
synced 2026-08-24 22:21:36 -04:00
merge
Signed-off-by: chenyuyan <chenyuyan3@huawei.com> Change-Id: I25ada8e039aff171148e86911067da6e1c0b4101
This commit is contained in:
+2
-10
@@ -162,7 +162,8 @@
|
||||
"header_base": "//foundation/ability/ability_runtime/js_environment/interfaces/inner_api",
|
||||
"header_files": [
|
||||
"js_environment.h",
|
||||
"js_environment_impl.h"
|
||||
"js_environment_impl.h",
|
||||
"source_map.h"
|
||||
]
|
||||
},
|
||||
"name": "//foundation/ability/ability_runtime/js_environment/frameworks/js_environment:js_environment"
|
||||
@@ -177,15 +178,6 @@
|
||||
},
|
||||
"name": "//foundation/ability/ability_runtime/interfaces/inner_api/runtime:runtime"
|
||||
},
|
||||
{
|
||||
"header": {
|
||||
"header_base": "//foundation/ability/ability_runtime/interfaces/inner_api/runtime/include/",
|
||||
"header_files": [
|
||||
"source_map.h"
|
||||
]
|
||||
},
|
||||
"name": "//foundation/ability/ability_runtime/interfaces/inner_api/runtime:source_map"
|
||||
},
|
||||
{
|
||||
"header": {
|
||||
"header_base": "//foundation/ability/ability_runtime/interfaces/inner_api/napi_base_context/include",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@@ -235,6 +235,21 @@ class Caller {
|
||||
this.__call_obj__.onRelease(callback);
|
||||
}
|
||||
|
||||
onRemoteStateChange(callback) {
|
||||
console.log("Caller onRemoteStateChange jscallback called.");
|
||||
if (typeof callback !== 'function') {
|
||||
console.log("Caller onRemoteStateChange " + typeof callback);
|
||||
throw new BusinessError(ERROR_CODE_INVALID_PARAM);
|
||||
}
|
||||
|
||||
if (this.releaseState == true) {
|
||||
console.log("Caller onRemoteStateChange remoteObj releaseState is true");
|
||||
throw new BusinessError(ERROR_CODE_CALLER_RELEASED);
|
||||
}
|
||||
|
||||
this.__call_obj__.onRemoteStateChange(callback);
|
||||
}
|
||||
|
||||
on(type, callback) {
|
||||
console.log("Caller onRelease jscallback called.");
|
||||
if (typeof type !== 'string' || type !== "release") {
|
||||
|
||||
@@ -92,6 +92,7 @@ bool ConnectionManager::MatchConnection(
|
||||
if (!connectReceiver.GetElement().GetAbilityName().empty()) {
|
||||
return connectCaller == connection.first.connectCaller &&
|
||||
connectReceiver.GetElement().GetBundleName() == connection.first.connectReceiver.GetBundleName() &&
|
||||
connectReceiver.GetElement().GetModuleName() == connection.first.connectReceiver.GetModuleName() &&
|
||||
connectReceiver.GetElement().GetAbilityName() == connection.first.connectReceiver.GetAbilityName();
|
||||
} else {
|
||||
// ImplicitConnect
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@@ -170,6 +170,19 @@ void LocalCallContainer::OnAbilityDisconnectDone(const AppExecFwk::ElementName&
|
||||
{
|
||||
}
|
||||
|
||||
void LocalCallContainer::OnRemoteStateChanged(const AppExecFwk::ElementName &element, int32_t abilityState)
|
||||
{
|
||||
HILOG_DEBUG("LocalCallContainer::OnRemoteStateChanged start %{public}s .", element.GetURI().c_str());
|
||||
std::shared_ptr<LocalCallRecord> localCallRecord;
|
||||
if (GetCallLocalRecord(element, localCallRecord)) {
|
||||
localCallRecord->NotifyRemoteStateChanged(abilityState);
|
||||
HILOG_DEBUG("call NotifyRemoteStateChanged.");
|
||||
}
|
||||
|
||||
HILOG_DEBUG("LocalCallContainer::OnRemoteStateChanged end. abilityState:%{public}d.", abilityState);
|
||||
return;
|
||||
}
|
||||
|
||||
bool LocalCallContainer::GetCallLocalRecord(
|
||||
const AppExecFwk::ElementName& elementName, std::shared_ptr<LocalCallRecord>& localCallRecord)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@@ -18,6 +18,10 @@
|
||||
|
||||
namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
namespace {
|
||||
constexpr int32_t FOREGROUND = 2;
|
||||
constexpr int32_t BACKGROUND = 4;
|
||||
}
|
||||
int64_t LocalCallRecord::callRecordId = 0;
|
||||
LocalCallRecord::LocalCallRecord(const AppExecFwk::ElementName& elementName)
|
||||
{
|
||||
@@ -120,6 +124,29 @@ void LocalCallRecord::InvokeCallBack() const
|
||||
HILOG_DEBUG("finish callback with remote object.");
|
||||
}
|
||||
|
||||
void LocalCallRecord::NotifyRemoteStateChanged(int32_t abilityState)
|
||||
{
|
||||
if (remoteObject_ == nullptr) {
|
||||
HILOG_ERROR("remote object is nullptr, can't notify.");
|
||||
return;
|
||||
}
|
||||
std::string state = "";
|
||||
if (abilityState == FOREGROUND) {
|
||||
state = "foreground";
|
||||
} else if (abilityState == BACKGROUND) {
|
||||
state = "background";
|
||||
}
|
||||
HILOG_DEBUG("NotifyRemoteStateChanged, state = %{public}s.", state.c_str());
|
||||
|
||||
for (auto& callBack : callers_) {
|
||||
if (callBack != nullptr && callBack->IsCallBack()) {
|
||||
HILOG_INFO("callback is not nullptr, and is callbcak ");
|
||||
callBack->InvokeOnNotify(state);
|
||||
}
|
||||
}
|
||||
HILOG_DEBUG("finish notify remote state changed.");
|
||||
}
|
||||
|
||||
sptr<IRemoteObject> LocalCallRecord::GetRemoteObject() const
|
||||
{
|
||||
return remoteObject_;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@@ -52,8 +52,8 @@ public:
|
||||
explicit JsCallerComplex(
|
||||
NativeEngine& engine, ReleaseCallFunc releaseCallFunc, sptr<IRemoteObject> callee,
|
||||
std::shared_ptr<CallerCallBack> callerCallBack) : releaseCallFunc_(releaseCallFunc),
|
||||
callee_(callee), releaseCallBackEngine_(engine),
|
||||
callerCallBackObj_(callerCallBack), jsReleaseCallBackObj_(nullptr)
|
||||
callee_(callee), releaseCallBackEngine_(engine), remoteStateChanegdEngine_(engine),
|
||||
callerCallBackObj_(callerCallBack), jsReleaseCallBackObj_(nullptr), jsRemoteStateChangedObj_(nullptr)
|
||||
{
|
||||
AddJsCallerComplex(this);
|
||||
handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
|
||||
@@ -150,6 +150,24 @@ public:
|
||||
return object->SetOnReleaseCallBackInner(*engine, *info);
|
||||
}
|
||||
|
||||
static NativeValue* JsSetOnRemoteStateChanged(NativeEngine* engine, NativeCallbackInfo* info)
|
||||
{
|
||||
if (engine == nullptr || info == nullptr) {
|
||||
HILOG_ERROR("JsCallerComplex::%{public}s is called, but input parameters %{public}s is nullptr",
|
||||
__func__,
|
||||
((engine == nullptr) ? "engine" : "info"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto object = CheckParamsAndGetThis<JsCallerComplex>(engine, info);
|
||||
if (object == nullptr) {
|
||||
HILOG_ERROR("JsCallerComplex::%{public}s is called, CheckParamsAndGetThis return nullptr", __func__);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return object->SetOnRemoteStateChangedInner(*engine, *info);
|
||||
}
|
||||
|
||||
static bool AddJsCallerComplex(JsCallerComplex* ptr)
|
||||
{
|
||||
if (ptr == nullptr) {
|
||||
@@ -310,6 +328,42 @@ private:
|
||||
HILOG_DEBUG("OnReleaseNotifyTask end");
|
||||
}
|
||||
|
||||
void OnRemoteStateChangedNotify(const std::string &str)
|
||||
{
|
||||
HILOG_DEBUG("OnRemoteStateChangedNotify begin");
|
||||
if (handler_ == nullptr) {
|
||||
HILOG_ERROR("handler parameters error");
|
||||
return;
|
||||
}
|
||||
|
||||
auto task = [notify = this, &str] () {
|
||||
if (!FindJsCallerComplex(notify)) {
|
||||
HILOG_ERROR("ptr not found, address error");
|
||||
return;
|
||||
}
|
||||
notify->OnRemoteStateChangedNotifyTask(str);
|
||||
};
|
||||
handler_->PostSyncTask(task, "OnRemoteStateChangedNotify");
|
||||
HILOG_DEBUG("OnRemoteStateChangedNotify end");
|
||||
}
|
||||
|
||||
void OnRemoteStateChangedNotifyTask(const std::string &str)
|
||||
{
|
||||
HILOG_DEBUG("OnRemoteStateChangedNotifyTask begin");
|
||||
if (jsRemoteStateChangedObj_ == nullptr) {
|
||||
HILOG_ERROR("JsCallerComplex::%{public}s, jsRemoteStateChangedObj is nullptr", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
NativeValue* value = jsRemoteStateChangedObj_->Get();
|
||||
NativeValue* callback = jsRemoteStateChangedObj_->Get();
|
||||
NativeValue* args[] = { CreateJsValue(remoteStateChanegdEngine_, str) };
|
||||
remoteStateChanegdEngine_.CallFunction(value, callback, args, 1);
|
||||
HILOG_DEBUG("OnRemoteStateChangedNotifyTask CallFunction call done");
|
||||
StateReset();
|
||||
HILOG_DEBUG("OnRemoteStateChangedNotifyTask end");
|
||||
}
|
||||
|
||||
NativeValue* ReleaseCallInner(NativeEngine& engine, NativeCallbackInfo& info)
|
||||
{
|
||||
HILOG_DEBUG("JsCallerComplex::%{public}s, called", __func__);
|
||||
@@ -370,12 +424,53 @@ private:
|
||||
return engine.CreateUndefined();
|
||||
}
|
||||
|
||||
NativeValue* SetOnRemoteStateChangedInner(NativeEngine& engine, NativeCallbackInfo& info)
|
||||
{
|
||||
HILOG_DEBUG("JsCallerComplex::%{public}s, begin", __func__);
|
||||
constexpr size_t argcOne = 1;
|
||||
if (info.argc < argcOne) {
|
||||
HILOG_ERROR("JsCallerComplex::%{public}s, Invalid input params", __func__);
|
||||
ThrowTooFewParametersError(engine);
|
||||
}
|
||||
if (!info.argv[0]->IsCallable()) {
|
||||
HILOG_ERROR("JsCallerComplex::%{public}s, IsCallable is %{public}s.",
|
||||
__func__, ((info.argv[0]->IsCallable()) ? "true" : "false"));
|
||||
ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
|
||||
}
|
||||
|
||||
if (callerCallBackObj_ == nullptr) {
|
||||
HILOG_ERROR("JsCallerComplex::%{public}s, CallBacker is nullptr", __func__);
|
||||
ThrowError(engine, AbilityErrorCode::ERROR_CODE_INNER);
|
||||
}
|
||||
|
||||
auto param1 = info.argv[0];
|
||||
if (param1 == nullptr) {
|
||||
HILOG_ERROR("JsCallerComplex::%{public}s, param1 is nullptr", __func__);
|
||||
ThrowError(engine, AbilityErrorCode::ERROR_CODE_INNER);
|
||||
}
|
||||
|
||||
jsRemoteStateChangedObj_.reset(remoteStateChanegdEngine_.CreateReference(param1, 1));
|
||||
auto task = [notify = this] (const std::string &str) {
|
||||
HILOG_INFO("state changed");
|
||||
if (!FindJsCallerComplexAndChangeState(notify, OBJSTATE::OBJ_EXECUTION)) {
|
||||
HILOG_ERROR("ptr not found, address error");
|
||||
return;
|
||||
}
|
||||
notify->OnRemoteStateChangedNotify(str);
|
||||
};
|
||||
callerCallBackObj_->SetOnRemoteStateChanged(task);
|
||||
HILOG_DEBUG("JsCallerComplex::%{public}s, end", __func__);
|
||||
return engine.CreateUndefined();
|
||||
}
|
||||
|
||||
private:
|
||||
ReleaseCallFunc releaseCallFunc_;
|
||||
sptr<IRemoteObject> callee_;
|
||||
NativeEngine& releaseCallBackEngine_;
|
||||
NativeEngine& remoteStateChanegdEngine_;
|
||||
std::shared_ptr<CallerCallBack> callerCallBackObj_;
|
||||
std::unique_ptr<NativeReference> jsReleaseCallBackObj_;
|
||||
std::unique_ptr<NativeReference> jsRemoteStateChangedObj_;
|
||||
std::shared_ptr<AppExecFwk::EventHandler> handler_;
|
||||
std::mutex stateMechanismMutex_;
|
||||
OBJSTATE currentState_;
|
||||
@@ -415,6 +510,7 @@ NativeValue* CreateJsCallerComplex(
|
||||
const char *moduleName = "JsCallerComplex";
|
||||
BindNativeFunction(engine, *object, "release", moduleName, JsCallerComplex::JsReleaseCall);
|
||||
BindNativeFunction(engine, *object, "onRelease", moduleName, JsCallerComplex::JsSetOnReleaseCallBack);
|
||||
BindNativeFunction(engine, *object, "onRemoteStateChange", moduleName, JsCallerComplex::JsSetOnRemoteStateChanged);
|
||||
|
||||
HILOG_DEBUG("JsCallerComplex::%{public}s, end", __func__);
|
||||
return objValue;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "js_free_install_observer.h"
|
||||
|
||||
#include "hilog_wrapper.h"
|
||||
#include "hitrace_meter.h"
|
||||
#include "js_error_utils.h"
|
||||
#include "js_runtime.h"
|
||||
#include "js_runtime_utils.h"
|
||||
@@ -61,6 +62,7 @@ void JsFreeInstallObserver::HandleOnInstallFinished(const std::string &bundleNam
|
||||
it = jsObserverObjectList_.erase(it);
|
||||
continue;
|
||||
}
|
||||
FinishAsyncTrace(HITRACE_TAG_ABILITY_MANAGER, "StartFreeInstall", atoi(startTime.c_str()));
|
||||
NativeValue* value = (it->callback)->Get();
|
||||
NativeValue* argv[] = { CreateJsErrorByNativeErr(engine_, resultCode) };
|
||||
CallJsFunction(value, argv, ARGC_ONE);
|
||||
@@ -98,6 +100,7 @@ void JsFreeInstallObserver::AddJsObserverObject(const std::string &bundleName, c
|
||||
}
|
||||
}
|
||||
|
||||
StartAsyncTrace(HITRACE_TAG_ABILITY_MANAGER, "StartFreeInstall", atoi(startTime.c_str()));
|
||||
JsFreeInstallObserverObject object;
|
||||
object.bundleName = bundleName;
|
||||
object.abilityName = abilityName;
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "systemcapability.h"
|
||||
#include "commonlibrary/ets_utils/js_sys_module/timer/timer.h"
|
||||
#include "commonlibrary/ets_utils/js_sys_module/console/console.h"
|
||||
#include "source_map.h"
|
||||
|
||||
#ifdef SUPPORT_GRAPHICS
|
||||
#include "declarative_module_preloader.h"
|
||||
@@ -68,6 +69,7 @@ constexpr uint8_t SYSCAP_MAX_SIZE = 64;
|
||||
constexpr int64_t DEFAULT_GC_POOL_SIZE = 0x10000000; // 256MB
|
||||
const std::string SANDBOX_ARK_CACHE_PATH = "/data/storage/ark-cache/";
|
||||
const std::string SANDBOX_ARK_PROIFILE_PATH = "/data/storage/ark-profile";
|
||||
const std::string MEGER_SOURCE_MAP_PATH = "ets/sourceMaps.map";
|
||||
#ifdef APP_USE_ARM
|
||||
constexpr char ARK_DEBUGGER_LIB_PATH[] = "/system/lib/libark_debugger.z.so";
|
||||
#else
|
||||
@@ -505,9 +507,9 @@ bool JsRuntime::Initialize(const Options& options)
|
||||
HILOG_ERROR("Initialize loop failed.");
|
||||
return false;
|
||||
}
|
||||
auto bindSourceMaps =
|
||||
std::make_shared<AbilityRuntime::ModSourceMap>(options.bundleCodeDir, options.isStageModel);
|
||||
auto operatorImpl = std::make_shared<JsSourceMapOperatorImpl>(options.hapPath, bindSourceMaps);
|
||||
auto bindSourceMaps = std::make_shared<JsEnv::SourceMap>();
|
||||
bool isModular = !panda::JSNApi::IsBundle(vm);
|
||||
auto operatorImpl = std::make_shared<JsSourceMapOperatorImpl>(options.hapPath, isModular, bindSourceMaps);
|
||||
InitSourceMap(operatorImpl);
|
||||
|
||||
if (options.isUnique) {
|
||||
@@ -628,6 +630,7 @@ void JsRuntime::InitSourceMap(const std::shared_ptr<JsEnv::SourceMapOperatorImpl
|
||||
{
|
||||
CHECK_POINTER(jsEnv_);
|
||||
jsEnv_->InitSourceMap(operatorImpl);
|
||||
JsEnv::SourceMap::RegisterReadSourceMapCallback(JsRuntime::ReadSourceMapData);
|
||||
}
|
||||
|
||||
void JsRuntime::Deinitialize()
|
||||
@@ -980,5 +983,28 @@ void JsRuntime::RegisterQuickFixQueryFunc(const std::map<std::string, std::strin
|
||||
panda::JSNApi::RegisterQuickFixQueryFunc(vm, JsQuickfixCallback(moduleAndPath));
|
||||
}
|
||||
}
|
||||
|
||||
bool JsRuntime::ReadSourceMapData(const std::string& hapPath, std::string& content)
|
||||
{
|
||||
if (hapPath.empty()) {
|
||||
HILOG_ERROR("hapPath is empty");
|
||||
return false;
|
||||
}
|
||||
bool newCreate = false;
|
||||
std::shared_ptr<Extractor> extractor = ExtractorUtil::GetExtractor(
|
||||
ExtractorUtil::GetLoadFilePath(hapPath), newCreate);
|
||||
if (extractor == nullptr) {
|
||||
HILOG_ERROR("hap's path: %{public}s, get extractor failed", hapPath.c_str());
|
||||
return false;
|
||||
}
|
||||
std::unique_ptr<uint8_t[]> dataPtr = nullptr;
|
||||
size_t len = 0;
|
||||
if (!extractor->ExtractToBufByName(MEGER_SOURCE_MAP_PATH, dataPtr, len)) {
|
||||
HILOG_ERROR("get mergeSourceMapData fileBuffer failed");
|
||||
return false;
|
||||
}
|
||||
content = reinterpret_cast<char*>(dataPtr.get());
|
||||
return true;
|
||||
}
|
||||
} // namespace AbilityRuntime
|
||||
} // namespace OHOS
|
||||
|
||||
@@ -14,12 +14,21 @@
|
||||
*/
|
||||
|
||||
#include "js_source_map_operator.h"
|
||||
#include "hilog_wrapper.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
std::string JsSourceMapOperatorImpl::TranslateBySourceMap(const std::string& stackStr)
|
||||
{
|
||||
return AbilityRuntime::ModSourceMap::TranslateBySourceMap(stackStr, *bindSourceMaps_, hapPath_);
|
||||
if (bindSourceMaps_ == nullptr) {
|
||||
HILOG_ERROR("Source map is invalid.");
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string sourceMapData;
|
||||
JsEnv::SourceMap::ReadSourceMapData(hapPath_, sourceMapData);
|
||||
bindSourceMaps_->Init(isModular_, sourceMapData);
|
||||
return bindSourceMaps_->TranslateBySourceMap(stackStr);
|
||||
}
|
||||
} // namespace AbilityRuntime
|
||||
} // namespace OHOS
|
||||
|
||||
@@ -23,9 +23,8 @@ namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
class JsSourceMapOperatorImpl : public JsEnv::SourceMapOperatorImpl {
|
||||
public:
|
||||
JsSourceMapOperatorImpl(const std::string hapPath,
|
||||
std::shared_ptr<AbilityRuntime::ModSourceMap> bindSourceMaps)
|
||||
: hapPath_(hapPath), bindSourceMaps_(bindSourceMaps)
|
||||
JsSourceMapOperatorImpl(const std::string hapPath, bool isModular, std::shared_ptr<JsEnv::SourceMap> bindSourceMaps)
|
||||
: hapPath_(hapPath), isModular_(isModular), bindSourceMaps_(bindSourceMaps)
|
||||
{}
|
||||
|
||||
~JsSourceMapOperatorImpl() = default;
|
||||
@@ -34,7 +33,8 @@ std::string TranslateBySourceMap(const std::string& stackStr) override;
|
||||
|
||||
private:
|
||||
std::string hapPath_;
|
||||
std::shared_ptr<AbilityRuntime::ModSourceMap> bindSourceMaps_ = nullptr;
|
||||
bool isModular_ = false;
|
||||
std::shared_ptr<JsEnv::SourceMap> bindSourceMaps_ = nullptr;
|
||||
};
|
||||
} // namespace AbilityRuntime
|
||||
} // namespace OHOS
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-2023 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
|
||||
@@ -54,7 +54,9 @@ public:
|
||||
ON_ABILITY_CONNECT_DONE = 1,
|
||||
|
||||
// ipc id for OnAbilityDisConnectDone
|
||||
ON_ABILITY_DISCONNECT_DONE
|
||||
ON_ABILITY_DISCONNECT_DONE,
|
||||
|
||||
ON_REMOTE_STATE_CHANGED
|
||||
};
|
||||
};
|
||||
} // namespace AAFwk
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-2023 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
|
||||
@@ -36,6 +36,9 @@ public:
|
||||
virtual int OnRemoteRequest(
|
||||
uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
|
||||
|
||||
virtual void OnRemoteStateChanged(const AppExecFwk::ElementName &element, int32_t abilityState)
|
||||
{
|
||||
}
|
||||
private:
|
||||
DISALLOW_COPY_AND_MOVE(AbilityConnectionStub);
|
||||
};
|
||||
|
||||
@@ -313,6 +313,11 @@ enum {
|
||||
* Result(2097210) for ecological rule control.
|
||||
*/
|
||||
ERR_ECOLOGICAL_CONTROL_STATUS,
|
||||
|
||||
/**
|
||||
* Result(2097211) for app jump interceptor.
|
||||
*/
|
||||
ERR_APP_JUMP_INTERCEPTOR_STATUS,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
||||
@@ -64,7 +64,6 @@ ohos_shared_library("runtime") {
|
||||
"${ability_runtime_native_path}/runtime/ohos_js_env_logger.cpp",
|
||||
"${ability_runtime_native_path}/runtime/ohos_js_environment_impl.cpp",
|
||||
"${ability_runtime_native_path}/runtime/runtime.cpp",
|
||||
"${ability_runtime_native_path}/runtime/source_map.cpp",
|
||||
]
|
||||
|
||||
configs = [ ":runtime_config" ]
|
||||
@@ -122,28 +121,3 @@ ohos_shared_library("runtime") {
|
||||
subsystem_name = "ability"
|
||||
part_name = "ability_runtime"
|
||||
}
|
||||
|
||||
config("source_map_config") {
|
||||
include_dirs = [ "${ability_runtime_services_path}/common/include" ]
|
||||
}
|
||||
|
||||
config("source_map_public_config") {
|
||||
include_dirs = [ "include" ]
|
||||
}
|
||||
|
||||
ohos_shared_library("source_map") {
|
||||
sources = [ "${ability_runtime_native_path}/runtime/source_map.cpp" ]
|
||||
|
||||
configs = [ ":source_map_config" ]
|
||||
|
||||
public_configs = [ ":source_map_public_config" ]
|
||||
|
||||
external_deps = [
|
||||
"ability_base:extractortool",
|
||||
"c_utils:utils",
|
||||
"hiviewdfx_hilog_native:libhilog",
|
||||
]
|
||||
|
||||
subsystem_name = "ability"
|
||||
part_name = "ability_runtime"
|
||||
}
|
||||
|
||||
@@ -25,7 +25,10 @@
|
||||
|
||||
#include "native_engine/native_engine.h"
|
||||
#include "runtime.h"
|
||||
#include "source_map.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
class EcmaVM;
|
||||
} // namespace panda::ecmascript
|
||||
namespace OHOS {
|
||||
namespace AppExecFwk {
|
||||
class EventHandler;
|
||||
@@ -45,7 +48,6 @@ using AppLibPathMap = std::map<std::string, std::vector<std::string>>;
|
||||
|
||||
namespace AbilityRuntime {
|
||||
class TimerTask;
|
||||
class ModSourceMap;
|
||||
|
||||
inline void *DetachCallbackFunc(NativeEngine *engine, void *value, void *)
|
||||
{
|
||||
@@ -61,16 +63,13 @@ public:
|
||||
|
||||
static void SetAppLibPath(const AppLibPathMap& appLibPaths);
|
||||
|
||||
static bool ReadSourceMapData(const std::string& hapPath, std::string& content);
|
||||
|
||||
JsRuntime();
|
||||
~JsRuntime() override;
|
||||
|
||||
NativeEngine& GetNativeEngine() const;
|
||||
|
||||
ModSourceMap& GetSourceMap() const
|
||||
{
|
||||
return *bindSourceMaps_;
|
||||
}
|
||||
|
||||
Language GetLanguage() const override
|
||||
{
|
||||
return Language::JS;
|
||||
@@ -119,7 +118,6 @@ private:
|
||||
bool debugMode_ = false;
|
||||
bool preloaded_ = false;
|
||||
bool isBundle_ = true;
|
||||
std::unique_ptr<ModSourceMap> bindSourceMaps_;
|
||||
std::string codePath_;
|
||||
std::string moduleName_;
|
||||
std::unique_ptr<NativeReference> methodRequireNapiRef_;
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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_ABILITY_RUNTIME_SOURCE_MAP_H
|
||||
#define FOUNDATION_ABILITY_RUNTIME_SOURCE_MAP_H
|
||||
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <limits.h>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
namespace panda::ecmascript {
|
||||
class EcmaVM;
|
||||
} // namespace panda::ecmascript
|
||||
namespace OHOS::AbilityRuntime {
|
||||
using ErrorPos = std::pair<uint32_t, uint32_t>;
|
||||
using panda::ecmascript::EcmaVM;
|
||||
struct SourceMapInfo {
|
||||
int32_t beforeRow = 0;
|
||||
int32_t beforeColumn = 0;
|
||||
int32_t afterRow = 0;
|
||||
int32_t afterColumn = 0;
|
||||
int32_t sourcesVal = 0;
|
||||
int32_t namesVal = 0;
|
||||
};
|
||||
|
||||
struct MappingInfo {
|
||||
int32_t row = 0;
|
||||
int32_t col = 0;
|
||||
std::string sources;
|
||||
};
|
||||
|
||||
class SourceMapData final {
|
||||
public:
|
||||
SourceMapData() = default;
|
||||
~SourceMapData() = default;
|
||||
|
||||
SourceMapInfo nowPos_;
|
||||
std::vector<std::string> files_;
|
||||
std::vector<std::string> sources_;
|
||||
std::vector<std::string> names_;
|
||||
std::vector<std::string> mappings_;
|
||||
std::vector<SourceMapInfo> afterPos_;
|
||||
|
||||
inline SourceMapData GetSourceMapData() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
class ModSourceMap final {
|
||||
public:
|
||||
explicit ModSourceMap() = default;
|
||||
explicit ModSourceMap(const bool isStageModel) : isStageModel(isStageModel) {};
|
||||
explicit ModSourceMap(const std::string& bundleCodeDir, const bool isStageModel) : isStageModel(isStageModel),
|
||||
bundleCodeDir_(bundleCodeDir) {};
|
||||
~ModSourceMap() = default;
|
||||
|
||||
static std::string TranslateBySourceMap(const std::string& stackStr, ModSourceMap& targetMaps,
|
||||
const std::string& hapPath);
|
||||
static std::string GetOriginalNames(std::shared_ptr<SourceMapData> targetMapData,
|
||||
const std::string& sourceCode, uint32_t& errorPos);
|
||||
static ErrorPos GetErrorPos(const std::string& rawStack);
|
||||
static void NonModularLoadSourceMap(ModSourceMap& targetMaps, const std::string& targetMap);
|
||||
|
||||
bool isStageModel = true;
|
||||
|
||||
private:
|
||||
static void Init(const std::string& sourceMap, SourceMapData& curMap);
|
||||
static MappingInfo Find(int32_t row, int32_t col, const SourceMapData& targetMap, const std::string& key);
|
||||
static void ExtractKeyInfo(const std::string& sourceMap, std::vector<std::string>& sourceKeyInfo);
|
||||
static void GetPosInfo(const std::string& temp, int32_t start, std::string& line, std::string& column);
|
||||
static int32_t StringToInt(const std::string& value);
|
||||
static std::string GetRelativePath(const std::string& sources);
|
||||
static std::string GetSourceInfo(const std::string& line, const std::string& column,
|
||||
const SourceMapData& targetMap, const std::string& key);
|
||||
static bool ReadSourceMapData(const std::string& hapPath, std::string& content);
|
||||
static std::vector<std::string> HandleMappings(const std::string& mapping);
|
||||
static uint32_t Base64CharToInt(char charCode);
|
||||
static bool VlqRevCode(const std::string& vStr, std::vector<int32_t>& ans);
|
||||
|
||||
std::string bundleCodeDir_;
|
||||
std::map<std::string, SourceMapData> sourceMaps_;
|
||||
std::shared_ptr<SourceMapData> nonModularMap_;
|
||||
};
|
||||
} // namespace OHOS::AbilityRuntime
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_COMMON_UTILS_SOURCE_MAP_H
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@@ -31,6 +31,7 @@ public:
|
||||
/* Caller's callback object */
|
||||
using CallBackClosure = std::function<void(const sptr<IRemoteObject> &)>;
|
||||
using OnReleaseClosure = std::function<void(const std::string &)>;
|
||||
using OnRemoteStateChangedClosure = std::function<void(const std::string &)>;
|
||||
|
||||
CallerCallBack() = default;
|
||||
virtual ~CallerCallBack() = default;
|
||||
@@ -43,6 +44,10 @@ public:
|
||||
{
|
||||
onRelease_ = onRelease;
|
||||
};
|
||||
void SetOnRemoteStateChanged(OnRemoteStateChangedClosure onRemoteStateChanged)
|
||||
{
|
||||
onRemoteStateChanged_ = onRemoteStateChanged;
|
||||
};
|
||||
void InvokeCallBack(const sptr<IRemoteObject> &remoteObject)
|
||||
{
|
||||
if (callback_) {
|
||||
@@ -56,6 +61,12 @@ public:
|
||||
onRelease_(key);
|
||||
}
|
||||
};
|
||||
void InvokeOnNotify(const std::string &state)
|
||||
{
|
||||
if (onRemoteStateChanged_) {
|
||||
onRemoteStateChanged_(state);
|
||||
}
|
||||
};
|
||||
bool IsCallBack() const
|
||||
{
|
||||
return isCallBack_;
|
||||
@@ -64,6 +75,7 @@ public:
|
||||
private:
|
||||
CallBackClosure callback_ = {};
|
||||
OnReleaseClosure onRelease_ = {};
|
||||
OnRemoteStateChangedClosure onRemoteStateChanged_ = {};
|
||||
bool isCallBack_ = false;
|
||||
};
|
||||
} // namespace AbilityRuntime
|
||||
|
||||
@@ -42,6 +42,7 @@ public:
|
||||
|
||||
virtual void OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode) override;
|
||||
|
||||
void OnRemoteStateChanged(const AppExecFwk::ElementName &element, int32_t abilityState) override;
|
||||
private:
|
||||
bool GetCallLocalRecord(
|
||||
const AppExecFwk::ElementName &elementName, std::shared_ptr<LocalCallRecord> &localCallRecord);
|
||||
|
||||
@@ -36,6 +36,7 @@ public:
|
||||
void AddCaller(const std::shared_ptr<CallerCallBack> &callback);
|
||||
bool RemoveCaller(const std::shared_ptr<CallerCallBack> &callback);
|
||||
void OnCallStubDied(const wptr<IRemoteObject> &remote);
|
||||
void NotifyRemoteStateChanged(int32_t abilityState);
|
||||
sptr<IRemoteObject> GetRemoteObject() const;
|
||||
void InvokeCallBack() const;
|
||||
AppExecFwk::ElementName GetElementName() const;
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#define ABILITY_LIBRARY_LOADER
|
||||
|
||||
class Runtime;
|
||||
class ModSourceMap;
|
||||
namespace OHOS {
|
||||
namespace AppExecFwk {
|
||||
using namespace OHOS::Global;
|
||||
|
||||
@@ -29,6 +29,7 @@ ohos_shared_library("js_environment") {
|
||||
sources = [
|
||||
"${utils_path}/src/js_env_logger.cpp",
|
||||
"src/js_environment.cpp",
|
||||
"src/source_map.cpp",
|
||||
"src/uncaught_exception_callback.cpp",
|
||||
]
|
||||
|
||||
@@ -42,7 +43,6 @@ ohos_shared_library("js_environment") {
|
||||
deps = [ "${arkui_path}/napi:ace_napi_ark" ]
|
||||
|
||||
external_deps = [
|
||||
"ability_runtime:source_map",
|
||||
"ets_runtime:libark_jsruntime",
|
||||
"napi:ace_napi",
|
||||
]
|
||||
|
||||
@@ -115,8 +115,10 @@ void JsEnvironment::InitSourceMap(const std::shared_ptr<SourceMapOperatorImpl> o
|
||||
void JsEnvironment::RegisterUncaughtExceptionHandler(JsEnv::UncaughtExceptionInfo uncaughtExceptionInfo)
|
||||
{
|
||||
if (engine_ == nullptr) {
|
||||
JSENV_LOG_E("Invalid Native Engine.");
|
||||
return;
|
||||
}
|
||||
|
||||
engine_->RegisterUncaughtExceptionHandler(UncaughtExceptionCallback(uncaughtExceptionInfo.uncaughtTask,
|
||||
sourceMapOperator_));
|
||||
}
|
||||
|
||||
+278
-284
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2023 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
|
||||
@@ -22,15 +22,11 @@
|
||||
#include <vector>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "extractor.h"
|
||||
#include "hilog_wrapper.h"
|
||||
|
||||
using namespace OHOS::AbilityBase;
|
||||
using Extractor = OHOS::AbilityBase::Extractor;
|
||||
#include "js_env_logger.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
|
||||
namespace JsEnv {
|
||||
namespace {
|
||||
constexpr char SOURCES[] = "sources";
|
||||
constexpr char NAMES[] = "names";
|
||||
constexpr char MAPPINGS[] = "mappings";
|
||||
@@ -41,9 +37,7 @@ constexpr char DELIMITER_COMMA = ',';
|
||||
constexpr char DELIMITER_SEMICOLON = ';';
|
||||
constexpr char DOUBLE_SLASH = '\\';
|
||||
constexpr char WEBPACK[] = "webpack:///";
|
||||
const std::string REALPATH_FLAG = "/temprary/";
|
||||
const std::string MEGER_SOURCE_MAP_PATH = "ets/sourceMaps.map";
|
||||
const std::string NOT_FOUNDMAP = "Cannot get SourceMap info, dump raw stack:\n";
|
||||
constexpr int32_t INDEX_ONE = 1;
|
||||
constexpr int32_t INDEX_TWO = 2;
|
||||
constexpr int32_t INDEX_THREE = 3;
|
||||
constexpr int32_t INDEX_FOUR = 4;
|
||||
@@ -51,35 +45,248 @@ constexpr int32_t ANS_MAP_SIZE = 5;
|
||||
constexpr int32_t NUM_TWENTY = 20;
|
||||
constexpr int32_t NUM_TWENTYSIX = 26;
|
||||
constexpr int32_t DIGIT_NUM = 64;
|
||||
const std::string NOT_FOUNDMAP = "Cannot get SourceMap info, dump raw stack:\n";
|
||||
} // namespace
|
||||
ReadSourceMapCallback SourceMap::readSourceMapFunc_ = nullptr;
|
||||
|
||||
bool ModSourceMap::ReadSourceMapData(const std::string& hapPath, std::string& content)
|
||||
int32_t StringToInt(const std::string& value)
|
||||
{
|
||||
if (hapPath.empty()) {
|
||||
HILOG_ERROR("hapPath is empty");
|
||||
return false;
|
||||
errno = 0;
|
||||
char* pEnd = nullptr;
|
||||
int64_t result = std::strtol(value.c_str(), &pEnd, 10);
|
||||
if (pEnd == value.c_str() || (result < INT_MIN || result > INT_MAX) || errno == ERANGE) {
|
||||
return 0;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
bool newCreate = false;
|
||||
std::shared_ptr<Extractor> extractor = ExtractorUtil::GetExtractor(
|
||||
ExtractorUtil::GetLoadFilePath(hapPath), newCreate);
|
||||
if (extractor == nullptr) {
|
||||
HILOG_ERROR("hapPath %{public}s GetExtractor failed", hapPath.c_str());
|
||||
return false;
|
||||
}
|
||||
std::unique_ptr<uint8_t[]> dataPtr = nullptr;
|
||||
size_t len = 0;
|
||||
if (!extractor->ExtractToBufByName(MEGER_SOURCE_MAP_PATH, dataPtr, len)) {
|
||||
HILOG_ERROR("get mergeSourceMapData fileBuffer failed");
|
||||
return false;
|
||||
}
|
||||
content = reinterpret_cast<char *>(dataPtr.get());
|
||||
return true;
|
||||
}
|
||||
|
||||
MappingInfo ModSourceMap::Find(int32_t row, int32_t col, const SourceMapData& targetMap, const std::string& key)
|
||||
uint32_t Base64CharToInt(char charCode)
|
||||
{
|
||||
if (row < 1 || col < 1) {
|
||||
HILOG_ERROR("the input pos is wrong");
|
||||
return MappingInfo {};
|
||||
if ('A' <= charCode && charCode <= 'Z') {
|
||||
// 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
return charCode - 'A';
|
||||
} else if ('a' <= charCode && charCode <= 'z') {
|
||||
// 26 - 51: abcdefghijklmnopqrstuvwxyz
|
||||
return charCode - 'a' + 26;
|
||||
} else if ('0' <= charCode && charCode <= '9') {
|
||||
// 52 - 61: 0123456789
|
||||
return charCode - '0' + 52;
|
||||
} else if (charCode == '+') {
|
||||
// 62: +
|
||||
return 62;
|
||||
} else if (charCode == '/') {
|
||||
// 63: /
|
||||
return 63;
|
||||
}
|
||||
return DIGIT_NUM;
|
||||
};
|
||||
|
||||
void SourceMap::Init(bool isModular, const std::string& sourceMap)
|
||||
{
|
||||
isModular_ = isModular;
|
||||
SplitSourceMap(sourceMap);
|
||||
}
|
||||
|
||||
std::string SourceMap::TranslateBySourceMap(const std::string& stackStr)
|
||||
{
|
||||
std::string closeBrace = ")";
|
||||
std::string openBrace = "(";
|
||||
std::string ans = "";
|
||||
|
||||
// find per line of stack
|
||||
std::vector<std::string> res;
|
||||
ExtractStackInfo(stackStr, res);
|
||||
|
||||
// collect error info first
|
||||
bool needGetErrorPos = false;
|
||||
uint32_t i = 0;
|
||||
std::string codeStart = "SourceCode (";
|
||||
std::string sourceCode = "";
|
||||
if (!res.empty()) {
|
||||
std::string fristLine = res[0];
|
||||
uint32_t codeStartLen = codeStart.length();
|
||||
if (fristLine.substr(0, codeStartLen).compare(codeStart) == 0) {
|
||||
sourceCode = fristLine.substr(codeStartLen, fristLine.length() - codeStartLen - 1);
|
||||
i = 1; // 1 means Convert from the second line
|
||||
needGetErrorPos = true;
|
||||
}
|
||||
}
|
||||
|
||||
// collect error info first
|
||||
for (; i < res.size(); i++) {
|
||||
std::string temp = res[i];
|
||||
size_t start = temp.find(openBrace);
|
||||
size_t end = temp.find(":");
|
||||
if (end <= start) {
|
||||
continue;
|
||||
}
|
||||
std::string key = temp.substr(start + 1, end - start - 1);
|
||||
auto closeBracePos = static_cast<int32_t>(temp.find(closeBrace));
|
||||
auto openBracePos = static_cast<int32_t>(temp.find(openBrace));
|
||||
std::string line;
|
||||
std::string column;
|
||||
GetPosInfo(temp, closeBracePos, line, column);
|
||||
if (line.empty() || column.empty()) {
|
||||
JSENV_LOG_W("the stack without line info");
|
||||
break;
|
||||
}
|
||||
std::string sourceInfo;
|
||||
if (isModular_) {
|
||||
auto iter = sourceMaps_.find(key);
|
||||
if (iter != sourceMaps_.end()) {
|
||||
sourceInfo = GetSourceInfo(line, column, *(iter->second), key);
|
||||
}
|
||||
} else {
|
||||
sourceInfo = GetSourceInfo(line, column, *nonModularMap_, key);
|
||||
}
|
||||
if (sourceInfo.empty()) {
|
||||
break;
|
||||
}
|
||||
temp.replace(openBracePos, closeBracePos - openBracePos + 1, sourceInfo);
|
||||
replace(temp.begin(), temp.end(), '\\', '/');
|
||||
ans = ans + temp + "\n";
|
||||
}
|
||||
if (ans.empty()) {
|
||||
return (NOT_FOUNDMAP + stackStr + "\n");
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
void SourceMap::SplitSourceMap(const std::string& sourceMapData)
|
||||
{
|
||||
if (!isModular_) {
|
||||
if (!nonModularMap_) {
|
||||
nonModularMap_ = std::make_shared<SourceMapData>();
|
||||
}
|
||||
return ExtractSourceMapData(sourceMapData, nonModularMap_);
|
||||
}
|
||||
|
||||
size_t leftBracket = 0;
|
||||
size_t rightBracket = 0;
|
||||
std::string value;
|
||||
while ((leftBracket = sourceMapData.find(": {", rightBracket)) != std::string::npos) {
|
||||
std::string left = sourceMapData.substr(leftBracket);
|
||||
rightBracket = sourceMapData.find("},", leftBracket);
|
||||
uint32_t subLeftBracket = leftBracket;
|
||||
uint32_t subRightBracket = rightBracket;
|
||||
value = sourceMapData.substr(subLeftBracket + INDEX_ONE, subRightBracket - subLeftBracket + INDEX_TWO);
|
||||
std::size_t sources = value.find("\"sources\": [");
|
||||
if (sources == std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
std::size_t names = value.find("],");
|
||||
if (names == std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
// Intercept the sourcemap file path as the key
|
||||
std::string key = value.substr(sources + NUM_TWENTY, names - sources - NUM_TWENTYSIX);
|
||||
std::shared_ptr<SourceMapData> modularMap = std::make_shared<SourceMapData>();
|
||||
ExtractSourceMapData(value, modularMap);
|
||||
sourceMaps_.emplace(key, modularMap);
|
||||
}
|
||||
}
|
||||
|
||||
void SourceMap::ExtractStackInfo(const std::string& stackStr, std::vector<std::string>& res)
|
||||
{
|
||||
std::string tempStr;
|
||||
for (uint32_t i = 0; i < stackStr.length(); i++) {
|
||||
if (stackStr[i] == '\n') {
|
||||
res.push_back(tempStr);
|
||||
tempStr = "";
|
||||
} else {
|
||||
tempStr += stackStr[i];
|
||||
}
|
||||
}
|
||||
if (!tempStr.empty()) {
|
||||
res.push_back(tempStr);
|
||||
}
|
||||
}
|
||||
|
||||
void SourceMap::ExtractSourceMapData(const std::string& sourceMapData, std::shared_ptr<SourceMapData>& curMapData)
|
||||
{
|
||||
std::vector<std::string> sourceKey;
|
||||
ExtractKeyInfo(sourceMapData, sourceKey);
|
||||
|
||||
std::string mark = "";
|
||||
for (auto sourceKeyInfo : sourceKey) {
|
||||
if (sourceKeyInfo == SOURCES || sourceKeyInfo == NAMES ||
|
||||
sourceKeyInfo == MAPPINGS || sourceKeyInfo == FILE ||
|
||||
sourceKeyInfo == SOURCE_CONTENT || sourceKeyInfo == SOURCE_ROOT) {
|
||||
mark = sourceKeyInfo;
|
||||
} else if (mark == SOURCES) {
|
||||
curMapData->sources_.push_back(sourceKeyInfo);
|
||||
} else if (mark == NAMES) {
|
||||
curMapData->names_.push_back(sourceKeyInfo);
|
||||
} else if (mark == MAPPINGS) {
|
||||
curMapData->mappings_.push_back(sourceKeyInfo);
|
||||
} else if (mark == FILE) {
|
||||
curMapData->files_.push_back(sourceKeyInfo);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (curMapData->mappings_.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// transform to vector for mapping easily
|
||||
curMapData->mappings_ = HandleMappings(curMapData->mappings_[0]);
|
||||
|
||||
// the first bit: the column after transferring.
|
||||
// the second bit: the source file.
|
||||
// the third bit: the row before transferring.
|
||||
// the fourth bit: the column before transferring.
|
||||
// the fifth bit: the variable name.
|
||||
for (const auto& mapping : curMapData->mappings_) {
|
||||
if (mapping == ";") {
|
||||
// plus a line for each semicolon
|
||||
curMapData->nowPos_.afterRow++,
|
||||
curMapData->nowPos_.afterColumn = 0;
|
||||
continue;
|
||||
}
|
||||
std::vector<int32_t> ans;
|
||||
|
||||
if (!VlqRevCode(mapping, ans)) {
|
||||
JSENV_LOG_E("decode code fail");
|
||||
return;
|
||||
}
|
||||
if (ans.empty()) {
|
||||
JSENV_LOG_E("decode sourcemap fail, mapping: %{public}s", mapping.c_str());
|
||||
break;
|
||||
}
|
||||
if (ans.size() == 1) {
|
||||
curMapData->nowPos_.afterColumn += ans[0];
|
||||
continue;
|
||||
}
|
||||
// after decode, assgin each value to the position
|
||||
curMapData->nowPos_.afterColumn += ans[0];
|
||||
curMapData->nowPos_.sourcesVal += ans[INDEX_ONE];
|
||||
curMapData->nowPos_.beforeRow += ans[INDEX_TWO];
|
||||
curMapData->nowPos_.beforeColumn += ans[INDEX_THREE];
|
||||
if (ans.size() == ANS_MAP_SIZE) {
|
||||
curMapData->nowPos_.namesVal += ans[INDEX_FOUR];
|
||||
}
|
||||
curMapData->afterPos_.push_back({
|
||||
curMapData->nowPos_.beforeRow,
|
||||
curMapData->nowPos_.beforeColumn,
|
||||
curMapData->nowPos_.afterRow,
|
||||
curMapData->nowPos_.afterColumn,
|
||||
curMapData->nowPos_.sourcesVal,
|
||||
curMapData->nowPos_.namesVal
|
||||
});
|
||||
}
|
||||
curMapData->mappings_.clear();
|
||||
curMapData->mappings_.shrink_to_fit();
|
||||
sourceKey.clear();
|
||||
sourceKey.shrink_to_fit();
|
||||
}
|
||||
|
||||
MappingInfo SourceMap::Find(int32_t row, int32_t col, const SourceMapData& targetMap, const std::string& key)
|
||||
{
|
||||
if (row < 1 || col < 1 || targetMap.afterPos_.empty()) {
|
||||
return MappingInfo {0, 0, ""};
|
||||
}
|
||||
row--;
|
||||
col--;
|
||||
@@ -113,7 +320,7 @@ MappingInfo ModSourceMap::Find(int32_t row, int32_t col, const SourceMapData& ta
|
||||
};
|
||||
}
|
||||
|
||||
void ModSourceMap::ExtractKeyInfo(const std::string& sourceMap, std::vector<std::string>& sourceKeyInfo)
|
||||
void SourceMap::ExtractKeyInfo(const std::string& sourceMap, std::vector<std::string>& sourceKeyInfo)
|
||||
{
|
||||
uint32_t cnt = 0;
|
||||
std::string tempStr;
|
||||
@@ -140,7 +347,7 @@ void ModSourceMap::ExtractKeyInfo(const std::string& sourceMap, std::vector<std:
|
||||
}
|
||||
}
|
||||
|
||||
void ModSourceMap::GetPosInfo(const std::string& temp, int32_t start, std::string& line, std::string& column)
|
||||
void SourceMap::GetPosInfo(const std::string& temp, int32_t start, std::string& line, std::string& column)
|
||||
{
|
||||
// 0 for colum, 1 for row
|
||||
int32_t flag = 0;
|
||||
@@ -160,19 +367,7 @@ void ModSourceMap::GetPosInfo(const std::string& temp, int32_t start, std::strin
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ModSourceMap::StringToInt(const std::string& value)
|
||||
{
|
||||
errno = 0;
|
||||
char* pEnd = nullptr;
|
||||
int64_t result = std::strtol(value.c_str(), &pEnd, 10);
|
||||
if (pEnd == value.c_str() || (result < INT_MIN || result > INT_MAX) || errno == ERANGE) {
|
||||
return 0;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
std::string ModSourceMap::GetRelativePath(const std::string& sources)
|
||||
std::string SourceMap::GetRelativePath(const std::string& sources)
|
||||
{
|
||||
std::string temp = sources;
|
||||
std::size_t splitPos = std::string::npos;
|
||||
@@ -193,86 +388,7 @@ std::string ModSourceMap::GetRelativePath(const std::string& sources)
|
||||
return sources;
|
||||
}
|
||||
|
||||
void ModSourceMap::Init(const std::string& sourceMap, SourceMapData& curMapData)
|
||||
{
|
||||
std::vector<std::string> sourceKeyInfo;
|
||||
std::string mark = "";
|
||||
|
||||
ExtractKeyInfo(sourceMap, sourceKeyInfo);
|
||||
|
||||
// first: find the key info and record the temp key info
|
||||
// second: add the detail into the keyinfo
|
||||
for (auto keyInfo : sourceKeyInfo) {
|
||||
if (keyInfo == SOURCES || keyInfo == NAMES || keyInfo == MAPPINGS || keyInfo == FILE ||
|
||||
keyInfo == SOURCE_CONTENT || keyInfo == SOURCE_ROOT) {
|
||||
// record the temp key info
|
||||
mark = keyInfo;
|
||||
} else if (mark == SOURCES) {
|
||||
curMapData.sources_.push_back(keyInfo);
|
||||
} else if (mark == NAMES) {
|
||||
curMapData.names_.push_back(keyInfo);
|
||||
} else if (mark == MAPPINGS) {
|
||||
curMapData.mappings_.push_back(keyInfo);
|
||||
} else if (mark == FILE) {
|
||||
curMapData.files_.push_back(keyInfo);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// transform to vector for mapping easily
|
||||
curMapData.mappings_ = HandleMappings(curMapData.mappings_[0]);
|
||||
|
||||
// the first bit: the column after transferring.
|
||||
// the second bit: the source file.
|
||||
// the third bit: the row before transferring.
|
||||
// the fourth bit: the column before transferring.
|
||||
// the fifth bit: the variable name.
|
||||
for (const auto& mapping : curMapData.mappings_) {
|
||||
if (mapping == ";") {
|
||||
// plus a line for each semicolon
|
||||
curMapData.nowPos_.afterRow++,
|
||||
curMapData.nowPos_.afterColumn = 0;
|
||||
continue;
|
||||
}
|
||||
// decode each mapping ";QAABC"
|
||||
std::vector<int32_t> ans;
|
||||
if (!VlqRevCode(mapping, ans)) {
|
||||
HILOG_ERROR("decode code fail");
|
||||
return;
|
||||
}
|
||||
if (ans.size() == 0) {
|
||||
HILOG_ERROR("decode sourcemap fail, mapping: %{public}s", mapping.c_str());
|
||||
break;
|
||||
}
|
||||
if (ans.size() == 1) {
|
||||
curMapData.nowPos_.afterColumn += ans[0];
|
||||
continue;
|
||||
}
|
||||
// after decode, assgin each value to the position
|
||||
curMapData.nowPos_.afterColumn += ans[0];
|
||||
curMapData.nowPos_.sourcesVal += ans[1];
|
||||
curMapData.nowPos_.beforeRow += ans[INDEX_TWO];
|
||||
curMapData.nowPos_.beforeColumn += ans[INDEX_THREE];
|
||||
if (ans.size() == ANS_MAP_SIZE) {
|
||||
curMapData.nowPos_.namesVal += ans[INDEX_FOUR];
|
||||
}
|
||||
curMapData.afterPos_.push_back({
|
||||
curMapData.nowPos_.beforeRow,
|
||||
curMapData.nowPos_.beforeColumn,
|
||||
curMapData.nowPos_.afterRow,
|
||||
curMapData.nowPos_.afterColumn,
|
||||
curMapData.nowPos_.sourcesVal,
|
||||
curMapData.nowPos_.namesVal
|
||||
});
|
||||
}
|
||||
curMapData.mappings_.clear();
|
||||
curMapData.mappings_.shrink_to_fit();
|
||||
sourceKeyInfo.clear();
|
||||
sourceKeyInfo.shrink_to_fit();
|
||||
};
|
||||
|
||||
std::vector<std::string> ModSourceMap::HandleMappings(const std::string& mapping)
|
||||
std::vector<std::string> SourceMap::HandleMappings(const std::string& mapping)
|
||||
{
|
||||
std::vector<std::string> keyInfo;
|
||||
std::string tempStr;
|
||||
@@ -296,28 +412,7 @@ std::vector<std::string> ModSourceMap::HandleMappings(const std::string& mapping
|
||||
return keyInfo;
|
||||
};
|
||||
|
||||
uint32_t ModSourceMap::Base64CharToInt(char charCode)
|
||||
{
|
||||
if ('A' <= charCode && charCode <= 'Z') {
|
||||
// 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
return charCode - 'A';
|
||||
} else if ('a' <= charCode && charCode <= 'z') {
|
||||
// 26 - 51: abcdefghijklmnopqrstuvwxyz
|
||||
return charCode - 'a' + 26;
|
||||
} else if ('0' <= charCode && charCode <= '9') {
|
||||
// 52 - 61: 0123456789
|
||||
return charCode - '0' + 52;
|
||||
} else if (charCode == '+') {
|
||||
// 62: +
|
||||
return 62;
|
||||
} else if (charCode == '/') {
|
||||
// 63: /
|
||||
return 63;
|
||||
}
|
||||
return DIGIT_NUM;
|
||||
};
|
||||
|
||||
bool ModSourceMap::VlqRevCode(const std::string& vStr, std::vector<int32_t>& ans)
|
||||
bool SourceMap::VlqRevCode(const std::string& vStr, std::vector<int32_t>& ans)
|
||||
{
|
||||
const int32_t VLQ_BASE_SHIFT = 5;
|
||||
// binary: 100000
|
||||
@@ -353,113 +448,7 @@ bool ModSourceMap::VlqRevCode(const std::string& vStr, std::vector<int32_t>& ans
|
||||
return true;
|
||||
};
|
||||
|
||||
std::string ModSourceMap::TranslateBySourceMap(const std::string& stackStr, ModSourceMap& bindSourceMaps,
|
||||
const std::string& hapPath)
|
||||
{
|
||||
const std::string closeBrace = ")";
|
||||
const std::string openBrace = "(";
|
||||
std::string ans = "";
|
||||
std::string tempStack = stackStr;
|
||||
|
||||
// find per line of stack
|
||||
std::vector<std::string> res;
|
||||
std::string tempStr = "";
|
||||
for (uint32_t i = 0; i < tempStack.length(); i++) {
|
||||
if (tempStack[i] == '\n') {
|
||||
res.push_back(tempStr);
|
||||
tempStr = "";
|
||||
} else {
|
||||
tempStr += tempStack[i];
|
||||
}
|
||||
}
|
||||
if (!tempStr.empty()) {
|
||||
res.push_back(tempStr);
|
||||
}
|
||||
|
||||
// collect error info first
|
||||
bool needGetErrorPos = false;
|
||||
uint32_t i = 0;
|
||||
std::string codeStart = "SourceCode (";
|
||||
std::string sourceCode = "";
|
||||
if (res.size() >= 1) {
|
||||
std::string fristLine = res[0];
|
||||
uint32_t codeStartLen = codeStart.length();
|
||||
if (fristLine.substr(0, codeStartLen).compare(codeStart) == 0) {
|
||||
sourceCode = fristLine.substr(codeStartLen, fristLine.length() - codeStartLen - 1);
|
||||
i = 1; // 1 means Convert from the second line
|
||||
needGetErrorPos = true;
|
||||
}
|
||||
}
|
||||
std::string curSourceMap;
|
||||
if (!ReadSourceMapData(hapPath, curSourceMap)) {
|
||||
HILOG_ERROR("ReadSourceMapData fail");
|
||||
return stackStr;
|
||||
}
|
||||
std::size_t s = 0;
|
||||
std::size_t j = 0;
|
||||
std::string value;
|
||||
std::string key;
|
||||
std::map<std::string, std::string> MapData;
|
||||
while ((s = curSourceMap.find(": {", j)) != std::string::npos) {
|
||||
j = curSourceMap.find("},", s);
|
||||
uint32_t q = s;
|
||||
uint32_t jj = j;
|
||||
value = curSourceMap.substr(q + 1, jj - q + INDEX_TWO);
|
||||
size_t sources = value.find("\"sources\": [");
|
||||
size_t names = value.find("],");
|
||||
key = value.substr(sources + NUM_TWENTY, names - sources - NUM_TWENTYSIX);
|
||||
MapData.insert(std::pair<std::string, std::string>(key, value));
|
||||
}
|
||||
|
||||
for (; i < res.size(); i++) {
|
||||
std::string temp = res[i];
|
||||
size_t start = temp.find("(");
|
||||
size_t end = temp.find(":");
|
||||
std::string key = temp.substr(start + 1, end - start - 1);
|
||||
int32_t closeBracePos = static_cast<int32_t>(temp.find(closeBrace));
|
||||
int32_t openBracePos = static_cast<int32_t>(temp.find(openBrace));
|
||||
|
||||
std::string line = "";
|
||||
std::string column = "";
|
||||
GetPosInfo(temp, closeBracePos, line, column);
|
||||
if (needGetErrorPos) {
|
||||
needGetErrorPos = false;
|
||||
}
|
||||
if (line.empty() || column.empty()) {
|
||||
break;
|
||||
}
|
||||
static SourceMapData curMapData;
|
||||
if (!bindSourceMaps.isStageModel) {
|
||||
if (i == 1) { // The non module scenario initializes curmapdata only at the first traversal
|
||||
if (!bindSourceMaps.nonModularMap_) {
|
||||
return NOT_FOUNDMAP + stackStr;
|
||||
}
|
||||
curMapData = *bindSourceMaps.nonModularMap_;
|
||||
}
|
||||
} else {
|
||||
auto iter = MapData.find(key);
|
||||
if (iter != MapData.end()) {
|
||||
Init(iter->second, curMapData);
|
||||
} else {
|
||||
ans += NOT_FOUNDMAP + temp + "\n";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const std::string sourceInfo = GetSourceInfo(line, column, curMapData, key);
|
||||
if (sourceInfo.empty()) {
|
||||
break;
|
||||
}
|
||||
temp.replace(openBracePos, closeBracePos - openBracePos + 1, sourceInfo);
|
||||
ans += temp + "\n";
|
||||
}
|
||||
|
||||
if (ans.empty()) {
|
||||
return tempStack;
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
std::string ModSourceMap::GetSourceInfo(const std::string& line, const std::string& column,
|
||||
std::string SourceMap::GetSourceInfo(const std::string& line, const std::string& column,
|
||||
const SourceMapData& targetMap, const std::string& key)
|
||||
{
|
||||
int32_t offSet = 0;
|
||||
@@ -478,15 +467,27 @@ std::string ModSourceMap::GetSourceInfo(const std::string& line, const std::stri
|
||||
return sourceInfo;
|
||||
}
|
||||
|
||||
void ModSourceMap::NonModularLoadSourceMap(ModSourceMap& targetMaps, const std::string& targetMap)
|
||||
ErrorPos SourceMap::GetErrorPos(const std::string& rawStack)
|
||||
{
|
||||
if (!targetMaps.nonModularMap_) {
|
||||
targetMaps.nonModularMap_ = std::make_shared<SourceMapData>();
|
||||
size_t findLineEnd = rawStack.find("\n");
|
||||
if (findLineEnd == std::string::npos) {
|
||||
return std::make_pair(0, 0);
|
||||
}
|
||||
Init(targetMap, *targetMaps.nonModularMap_);
|
||||
int32_t lineEnd = findLineEnd - 1;
|
||||
if (lineEnd < 1 || rawStack[lineEnd - 1] == '?') {
|
||||
return std::make_pair(0, 0);
|
||||
}
|
||||
|
||||
uint32_t secondPos = rawStack.rfind(':', lineEnd);
|
||||
uint32_t fristPos = rawStack.rfind(':', secondPos - 1);
|
||||
|
||||
std::string lineStr = rawStack.substr(fristPos + 1, secondPos - 1 - fristPos);
|
||||
std::string columnStr = rawStack.substr(secondPos + 1, lineEnd - 1 - secondPos);
|
||||
|
||||
return std::make_pair(StringToInt(lineStr), StringToInt(columnStr));
|
||||
}
|
||||
|
||||
std::string ModSourceMap::GetOriginalNames(std::shared_ptr<SourceMapData> targetMapData,
|
||||
std::string SourceMap::GetOriginalNames(std::shared_ptr<SourceMapData> targetMapData,
|
||||
const std::string& sourceCode, uint32_t& errorPos)
|
||||
{
|
||||
if (sourceCode.empty() || sourceCode.find("SourceCode:\n") == std::string::npos) {
|
||||
@@ -494,7 +495,7 @@ std::string ModSourceMap::GetOriginalNames(std::shared_ptr<SourceMapData> target
|
||||
}
|
||||
std::vector<std::string> names = targetMapData->names_;
|
||||
if (names.size() % INDEX_TWO != 0) {
|
||||
HILOG_ERROR("Names in sourcemap is wrong.");
|
||||
JSENV_LOG_E("Names in sourcemap is wrong.");
|
||||
return sourceCode;
|
||||
}
|
||||
|
||||
@@ -516,14 +517,14 @@ std::string ModSourceMap::GetOriginalNames(std::shared_ptr<SourceMapData> target
|
||||
}
|
||||
auto lineBreakPos = jsCode.rfind('\n', jsCode.length() - 2);
|
||||
if (lineBreakPos == std::string::npos) {
|
||||
HILOG_WARN("There is something wrong in source code of summaryBody.");
|
||||
JSENV_LOG_W("There is something wrong in source code of summaryBody.");
|
||||
return jsCode;
|
||||
}
|
||||
// adjust position of ^ in dump file
|
||||
if (posDiff < 0) {
|
||||
int32_t flagPos = static_cast<int32_t>(lineBreakPos) + static_cast<int32_t>(errorPos);
|
||||
if (lineBreakPos > 0 && errorPos > 0 && flagPos < 0) {
|
||||
HILOG_WARN("Add overflow of sourceCode.");
|
||||
JSENV_LOG_W("Add overflow of sourceCode.");
|
||||
return jsCode;
|
||||
}
|
||||
if (flagPos < static_cast<int32_t>(jsCode.length()) && jsCode[flagPos] == '^' && flagPos + posDiff - 1 > 0) {
|
||||
@@ -537,24 +538,17 @@ std::string ModSourceMap::GetOriginalNames(std::shared_ptr<SourceMapData> target
|
||||
return jsCode;
|
||||
}
|
||||
|
||||
ErrorPos ModSourceMap::GetErrorPos(const std::string& rawStack)
|
||||
void SourceMap::RegisterReadSourceMapCallback(ReadSourceMapCallback readFunc)
|
||||
{
|
||||
size_t findLineEnd = rawStack.find("\n");
|
||||
if (findLineEnd == std::string::npos) {
|
||||
return std::make_pair(0, 0);
|
||||
}
|
||||
int32_t lineEnd = findLineEnd - 1;
|
||||
if (lineEnd < 1 || rawStack[lineEnd - 1] == '?') {
|
||||
return std::make_pair(0, 0);
|
||||
}
|
||||
|
||||
uint32_t secondPos = rawStack.rfind(':', lineEnd);
|
||||
uint32_t fristPos = rawStack.rfind(':', secondPos - 1);
|
||||
|
||||
std::string lineStr = rawStack.substr(fristPos + 1, secondPos - 1 - fristPos);
|
||||
std::string columnStr = rawStack.substr(secondPos + 1, lineEnd - 1 - secondPos);
|
||||
|
||||
return std::make_pair(StringToInt(lineStr), StringToInt(columnStr));
|
||||
readSourceMapFunc_ = readFunc;
|
||||
}
|
||||
} // namespace AbilityRuntime
|
||||
|
||||
bool SourceMap::ReadSourceMapData(const std::string& hapPath, std::string& content)
|
||||
{
|
||||
if (readSourceMapFunc_) {
|
||||
return readSourceMapFunc_(hapPath, content);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace JsEnv
|
||||
} // namespace OHOS
|
||||
@@ -69,8 +69,7 @@ void UncaughtExceptionCallback::operator()(NativeValue* value)
|
||||
JSENV_LOG_E("errorStack is empty");
|
||||
return;
|
||||
}
|
||||
|
||||
auto errorPos = AbilityRuntime::ModSourceMap::GetErrorPos(errorStack);
|
||||
auto errorPos = SourceMap::GetErrorPos(errorStack);
|
||||
std::string error;
|
||||
if (obj != nullptr) {
|
||||
NativeValue* value = obj->GetProperty("errorfunc");
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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_JS_ENVIRONMENT_SOURCE_MAP_H
|
||||
#define OHOS_ABILITY_JS_ENVIRONMENT_SOURCE_MAP_H
|
||||
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <limits.h>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
namespace OHOS {
|
||||
namespace JsEnv {
|
||||
using ErrorPos = std::pair<uint32_t, uint32_t>;
|
||||
struct SourceMapInfo {
|
||||
int32_t beforeRow = 0;
|
||||
int32_t beforeColumn = 0;
|
||||
int32_t afterRow = 0;
|
||||
int32_t afterColumn = 0;
|
||||
int32_t sourcesVal = 0;
|
||||
int32_t namesVal = 0;
|
||||
};
|
||||
|
||||
struct MappingInfo {
|
||||
int32_t row = 0;
|
||||
int32_t col = 0;
|
||||
std::string sources;
|
||||
};
|
||||
|
||||
class SourceMapData final {
|
||||
public:
|
||||
SourceMapData() = default;
|
||||
~SourceMapData() = default;
|
||||
|
||||
SourceMapInfo nowPos_;
|
||||
std::vector<std::string> files_;
|
||||
std::vector<std::string> sources_;
|
||||
std::vector<std::string> names_;
|
||||
std::vector<std::string> mappings_;
|
||||
std::vector<SourceMapInfo> afterPos_;
|
||||
|
||||
inline SourceMapData GetSourceMapData() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
using ReadSourceMapCallback = std::function<bool(const std::string& hapPath, std::string& content)>;
|
||||
|
||||
class SourceMap final {
|
||||
public:
|
||||
SourceMap() = default;
|
||||
~SourceMap() = default;
|
||||
|
||||
void Init(bool isModular, const std::string& sourceMap);
|
||||
std::string TranslateBySourceMap(const std::string& stackStr);
|
||||
|
||||
static std::string GetOriginalNames(std::shared_ptr<SourceMapData> targetMapData,
|
||||
const std::string& sourceCode, uint32_t& errorPos);
|
||||
static ErrorPos GetErrorPos(const std::string& rawStack);
|
||||
static void RegisterReadSourceMapCallback(ReadSourceMapCallback readFunc);
|
||||
static bool ReadSourceMapData(const std::string& hapPath, std::string& content);
|
||||
|
||||
private:
|
||||
void SplitSourceMap(const std::string& sourceMapData);
|
||||
void ExtractSourceMapData(const std::string& sourceMapData, std::shared_ptr<SourceMapData>& curMapData);
|
||||
void ExtractStackInfo(const std::string& stackStr, std::vector<std::string>& res);
|
||||
void ExtractKeyInfo(const std::string& sourceMap, std::vector<std::string>& sourceKeyInfo);
|
||||
std::vector<std::string> HandleMappings(const std::string& mapping);
|
||||
bool VlqRevCode(const std::string& vStr, std::vector<int32_t>& ans);
|
||||
MappingInfo Find(int32_t row, int32_t col, const SourceMapData& targetMap, const std::string& key);
|
||||
void GetPosInfo(const std::string& temp, int32_t start, std::string& line, std::string& column);
|
||||
std::string GetRelativePath(const std::string& sources);
|
||||
std::string GetSourceInfo(const std::string& line, const std::string& column,
|
||||
const SourceMapData& targetMap, const std::string& key);
|
||||
|
||||
private:
|
||||
bool isModular_ = true;
|
||||
std::unordered_map<std::string, std::shared_ptr<SourceMapData>> sourceMaps_;
|
||||
std::shared_ptr<SourceMapData> nonModularMap_;
|
||||
static ReadSourceMapCallback readSourceMapFunc_;
|
||||
};
|
||||
} // namespace JsEnv
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_ABILITY_JS_ENVIRONMENT_SOURCE_MAP_H
|
||||
@@ -20,5 +20,6 @@ group("unittest") {
|
||||
deps = [
|
||||
"js_env_log_unit_test:unittest",
|
||||
"js_environment_test:unittest",
|
||||
"source_map_test:unittest",
|
||||
]
|
||||
}
|
||||
|
||||
+3
-11
@@ -14,7 +14,7 @@
|
||||
import("//build/test.gni")
|
||||
import("//foundation/ability/ability_runtime/ability_runtime.gni")
|
||||
|
||||
module_output_path = "ability_runtime/ability_test"
|
||||
module_output_path = "ability_runtime/js_environment"
|
||||
|
||||
ohos_unittest("source_map_test") {
|
||||
module_out_path = module_output_path
|
||||
@@ -23,27 +23,19 @@ ohos_unittest("source_map_test") {
|
||||
# configs = [ ":module_private_config" ]
|
||||
|
||||
deps = [
|
||||
"${ability_runtime_innerkits_path}/ability_manager:ability_manager",
|
||||
"${ability_runtime_native_path}/ability/native:abilitykit_native",
|
||||
"${ability_runtime_native_path}/appkit:app_context",
|
||||
"${distributedschedule_path}/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
|
||||
"${global_path}/resource_management/frameworks/resmgr:global_resmgr",
|
||||
"//third_party/googletest:gmock_main",
|
||||
"//third_party/googletest:gtest_main",
|
||||
]
|
||||
|
||||
external_deps = [
|
||||
"ability_runtime:js_environment",
|
||||
"ability_base:want",
|
||||
"ability_runtime:runtime",
|
||||
"bundle_framework:appexecfwk_base",
|
||||
"c_utils:utils",
|
||||
"eventhandler:libeventhandler",
|
||||
"hiviewdfx_hilog_native:libhilog",
|
||||
"ipc:ipc_core",
|
||||
]
|
||||
|
||||
if (ability_runtime_graphics) {
|
||||
external_deps += [ "input:libmmi-client" ]
|
||||
}
|
||||
}
|
||||
|
||||
group("unittest") {
|
||||
@@ -0,0 +1,394 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 <gtest/gtest.h>
|
||||
|
||||
#define private public
|
||||
#define protected public
|
||||
#include "source_map.h"
|
||||
#undef private
|
||||
#undef protected
|
||||
|
||||
namespace OHOS {
|
||||
namespace JsEnv {
|
||||
using namespace testing::ext;
|
||||
|
||||
class SourceMapTest : public testing::Test {
|
||||
public:
|
||||
static void SetUpTestCase(void);
|
||||
static void TearDownTestCase(void);
|
||||
void SetUp();
|
||||
void TearDown();
|
||||
};
|
||||
|
||||
void SourceMapTest::SetUpTestCase(void)
|
||||
{
|
||||
}
|
||||
|
||||
void SourceMapTest::TearDownTestCase(void)
|
||||
{
|
||||
}
|
||||
|
||||
void SourceMapTest::SetUp(void)
|
||||
{
|
||||
}
|
||||
|
||||
void SourceMapTest::TearDown(void)
|
||||
{
|
||||
}
|
||||
|
||||
bool ReadSourceMapData(const std::string& hapPath, std::string& content)
|
||||
{
|
||||
if (hapPath.empty()) {
|
||||
return false;
|
||||
}
|
||||
content = "abc";
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: JsEnv_SourceMap_0100
|
||||
* @tc.type: FUNC
|
||||
* @tc.desc: Test get original names from sourceCode which is empty string.
|
||||
* @tc.require: #I6T4K1
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, JsEnv_SourceMap_0100, TestSize.Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_0100 start";
|
||||
std::string sourceCode = "123";
|
||||
uint32_t errorPos = 0;
|
||||
std::shared_ptr<SourceMapData> targetMapData = std::make_shared<SourceMapData>();
|
||||
targetMapData->names_.emplace_back("abc.ets");
|
||||
|
||||
std::string result = SourceMap::GetOriginalNames(targetMapData, sourceCode, errorPos);
|
||||
EXPECT_EQ(result, sourceCode);
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_0100 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: JsEnv_SourceMap_0200
|
||||
* @tc.type: FUNC
|
||||
* @tc.desc: Test get original names from sourceCode which has "SourceCode:\n".
|
||||
* @tc.require: #I6T4K1
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, JsEnv_SourceMap_0200, TestSize.Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_0200 start";
|
||||
std::string sourceCode = "SourceCode:\n/pages/Index.ets:111:13";
|
||||
uint32_t errorPos = 0;
|
||||
std::shared_ptr<SourceMapData> targetMapData = std::make_shared<SourceMapData>();
|
||||
targetMapData->names_.emplace_back("Index.js");
|
||||
targetMapData->names_.emplace_back("Index.ets");
|
||||
|
||||
std::string result = SourceMap::GetOriginalNames(targetMapData, sourceCode, errorPos);
|
||||
EXPECT_EQ(result, sourceCode);
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_0200 end" << result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: JsEnv_SourceMap_0300
|
||||
* @tc.name: GetErrorPos
|
||||
* @tc.desc: Verifying GetErrorPos succeeded.
|
||||
* @tc.require: #I6T4K1
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, JsEnv_SourceMap_0300, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_0300 start";
|
||||
std::string rawStack = "at AssertException (/mnt/assets/ets/TestAbility/TestAbility_.js:5779:5)\n";
|
||||
auto pos = SourceMap::GetErrorPos(rawStack);
|
||||
EXPECT_EQ(pos.first, 5779);
|
||||
EXPECT_EQ(pos.second, 5);
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_0300 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: JsEnv_SourceMap_0400
|
||||
* @tc.name: GetErrorPos
|
||||
* @tc.desc: Verifying GetErrorPos succeeded.
|
||||
* @tc.require: #I6T4K1
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, JsEnv_SourceMap_0400, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_0400 start";
|
||||
std::string rawStack = "\n";
|
||||
auto pos = SourceMap::GetErrorPos(rawStack);
|
||||
EXPECT_EQ(pos.first, 0);
|
||||
EXPECT_EQ(pos.second, 0);
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_0400 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: JsEnv_SourceMap_0500
|
||||
* @tc.name: GetErrorPos
|
||||
* @tc.desc: Verifying GetErrorPos succeeded.
|
||||
* @tc.require: #I6T4K1
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, JsEnv_SourceMap_0500, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_0500 start";
|
||||
std::string rawStack = "?\n";
|
||||
auto pos = SourceMap::GetErrorPos(rawStack);
|
||||
EXPECT_EQ(pos.first, 0);
|
||||
EXPECT_EQ(pos.second, 0);
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_0500 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: JsEnv_SourceMap_0600
|
||||
* @tc.name: ReadSourceMapData
|
||||
* @tc.desc: Verifying ReadSourceMapData Failed.
|
||||
* @tc.require: #I6T4K1
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, JsEnv_SourceMap_0600, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_0600 start";
|
||||
auto modSourceMap = std::make_shared<SourceMap>();
|
||||
std::string filePath = "./abc.map";
|
||||
std::string context;
|
||||
EXPECT_FALSE(modSourceMap->ReadSourceMapData(filePath, context));
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_0600 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: JsEnv_SourceMap_0700
|
||||
* @tc.name: ReadSourceMapData
|
||||
* @tc.desc: Verifying ReadSourceMapData succeeded.
|
||||
* @tc.require: #I6T4K1
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, JsEnv_SourceMap_0700, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_0700 start";
|
||||
SourceMap::RegisterReadSourceMapCallback(ReadSourceMapData);
|
||||
auto modSourceMap = std::make_shared<SourceMap>();
|
||||
std::string filePath = "./abc.map";
|
||||
std::string context;
|
||||
modSourceMap->ReadSourceMapData(filePath, context);
|
||||
EXPECT_STREQ(context.c_str(), "abc");
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_0700 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: JsEnv_SourceMap_0800
|
||||
* @tc.name: Find
|
||||
* @tc.desc: Verifying Find succeeded.
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, JsEnv_SourceMap_0800, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_0800 start";
|
||||
auto modSourceMap = std::make_shared<SourceMap>();
|
||||
int32_t row = 0;
|
||||
int32_t col = 1;
|
||||
SourceMapData targetMap;
|
||||
std::string key = "";
|
||||
auto info = modSourceMap->Find(row, col, targetMap, key);
|
||||
EXPECT_TRUE(info.sources.empty());
|
||||
|
||||
row = 1;
|
||||
col = 0;
|
||||
info = modSourceMap->Find(row, col, targetMap, key);
|
||||
EXPECT_TRUE(info.sources.empty());
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_0800 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: JsEnv_SourceMap_0900
|
||||
* @tc.name: Find
|
||||
* @tc.desc: Verifying Find succeeded.
|
||||
* @tc.require: #I6T4K1
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, JsEnv_SourceMap_0900, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_0900 start";
|
||||
auto modSourceMap = std::make_shared<SourceMap>();
|
||||
int32_t row = 3;
|
||||
int32_t col = 3;
|
||||
SourceMapData targetMap;
|
||||
targetMap.files_.emplace_back("file");
|
||||
|
||||
SourceMapInfo mapInfo;
|
||||
mapInfo.beforeRow = 0;
|
||||
mapInfo.beforeColumn = 0;
|
||||
mapInfo.afterRow = 1;
|
||||
mapInfo.afterColumn = 0;
|
||||
mapInfo.sourcesVal = 0;
|
||||
mapInfo.namesVal = 0;
|
||||
targetMap.afterPos_.emplace_back(mapInfo);
|
||||
std::string key = "";
|
||||
auto info = modSourceMap->Find(row, col, targetMap, key);
|
||||
EXPECT_STREQ(info.sources.c_str(), "file");
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_0900 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: JsEnv_SourceMap_1100
|
||||
* @tc.name: Find
|
||||
* @tc.desc: Verify binary search.
|
||||
* @tc.require: #I6T4K1
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, JsEnv_SourceMap_1100, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_1100 start";
|
||||
auto modSourceMap = std::make_shared<SourceMap>();
|
||||
int32_t row = 3;
|
||||
int32_t col = 3;
|
||||
SourceMapData targetMap;
|
||||
targetMap.files_.emplace_back("file");
|
||||
|
||||
for (int32_t i = 0; i < 10; i++) {
|
||||
for (int32_t j = 0; j < 5; j++) {
|
||||
SourceMapInfo mapInfo;
|
||||
mapInfo.beforeRow = 0;
|
||||
mapInfo.beforeColumn = 0;
|
||||
mapInfo.afterRow = i;
|
||||
mapInfo.afterColumn = j;
|
||||
targetMap.afterPos_.emplace_back(mapInfo);
|
||||
}
|
||||
}
|
||||
|
||||
std::string key = "";
|
||||
auto info = modSourceMap->Find(row, col, targetMap, key);
|
||||
EXPECT_EQ(info.row, 1);
|
||||
EXPECT_EQ(info.col, 1);
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_1100 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: JsEnv_SourceMap_1200
|
||||
* @tc.name: Find
|
||||
* @tc.desc: Verify binary search.
|
||||
* @tc.require: #I6T4K1
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, JsEnv_SourceMap_1200, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_1200 start";
|
||||
auto modSourceMap = std::make_shared<SourceMap>();
|
||||
int32_t row = 7;
|
||||
int32_t col = 1;
|
||||
SourceMapData targetMap;
|
||||
targetMap.files_.emplace_back("file");
|
||||
|
||||
for (int32_t i = 0; i < 10; i++) {
|
||||
SourceMapInfo mapInfo;
|
||||
mapInfo.beforeRow = 0;
|
||||
mapInfo.beforeColumn = 0;
|
||||
mapInfo.afterRow = i;
|
||||
mapInfo.afterColumn = 1;
|
||||
targetMap.afterPos_.emplace_back(mapInfo);
|
||||
}
|
||||
|
||||
std::string key = "aaawebpack:///bbb";
|
||||
auto info = modSourceMap->Find(row, col, targetMap, key);
|
||||
EXPECT_EQ(info.row, 1);
|
||||
EXPECT_EQ(info.col, 1);
|
||||
EXPECT_STREQ(info.sources.c_str(), "aaabbb");
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_1200 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: JsEnv_SourceMap_1300
|
||||
* @tc.name: GetPosInfo
|
||||
* @tc.desc: Verifying GetPosInfo succeeded.
|
||||
* @tc.require: #I6T4K1
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, JsEnv_SourceMap_1300, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_1300 start";
|
||||
auto modSourceMap = std::make_shared<SourceMap>();
|
||||
|
||||
std::string temp = "TestAbility.js:5779:5";
|
||||
int32_t start = 22;
|
||||
std::string line;
|
||||
std::string column;
|
||||
modSourceMap->GetPosInfo(temp, start, line, column);
|
||||
EXPECT_STREQ(line.c_str(), "5779");
|
||||
EXPECT_STREQ(column.c_str(), "5");
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_1300 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: JsEnv_SourceMap_1400
|
||||
* @tc.name: GetRelativePath
|
||||
* @tc.desc: Verifying GetRelativePath succeeded.
|
||||
* @tc.require: #I6T4K1
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, JsEnv_SourceMap_1400, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_1400 start";
|
||||
auto modSourceMap = std::make_shared<SourceMap>();
|
||||
|
||||
std::string sources = "TEST:/data/app/MainAbility.js";
|
||||
auto res = modSourceMap->GetRelativePath(sources);
|
||||
EXPECT_STREQ(res.c_str(), "/data/app/MainAbility.js");
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_1400 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: JsEnv_SourceMap_1500
|
||||
* @tc.name: GetPosInfo
|
||||
* @tc.desc: Verifying GetPosInfo succeeded.
|
||||
* @tc.require: #I6T4K1
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, JsEnv_SourceMap_1500, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_1500 start";
|
||||
std::string sourceMaps = "{"
|
||||
"\"entry/src/main/ets/pages/Index.ets\": {"
|
||||
"\"version\": 3,"
|
||||
"\"file\": \"Index.ets\","
|
||||
"\"sourceRoot\": \"\","
|
||||
"\"sources\": ["
|
||||
"\"entry/src/main/ets/pages/Index.ets\""
|
||||
"],"
|
||||
"\"names\": [],"
|
||||
"\"mappings\": \";;;;AAAA,OAAO,kBAAkB,MAAM,0BAA0B,CAAC;MAInD,KAAK;IAFZ;;oDAG2B,aAAa;QAEtC,mBAAmB;QACnB,"
|
||||
"sBAAsB;QACtB,gBAAgB;QAChB,GAAG;;;KAVqD;;;;;;;;;;QAKjD,OAAO;;;QAAP,OAAO;;;IAEd,mBAAmB;IACnB,sBAAsB;IACtB,"
|
||||
"gBAAgB;IAChB,GAAG;IACH;QACE,GAAG,UA8CY;QA9Cf,GAAG,CA8CF,MAAM,CAAC,MAAM;QA7CZ,MAAM,UA2CQ;QA3Cd,MAAM,CA2CL,"
|
||||
"KAAK,CAAC,MAAM;QA1CX,MAAM,mBAYa;QAZnB,MAAM,CAKL,IAAI,CAAC,UAAU,CAAC,OAAO;QALxB,MAAM,CAML,MAAM,CAAC;YACN,"
|
||||
"GAAG,EAAE,EAAE;SACR;QARD,MAAM,CASL,eAAe,CAAC,SAAS;QAT1B,MAAM,CAUL,KAAK,CAAC,KAAK;QAVZ,MAAM,CAWL,MAAM,"
|
||||
"CAAC,IAAI;QAXZ,MAAM,CAYL,OAAO,CAAC,SAAS;QAXhB,IAAI,QAAC,MAAM,EAEmB;QAF9B,IAAI,CACD,QAAQ,CAAC,EAAE;QADd,"
|
||||
"IAAI,CAED,UAAU,CAAC,UAAU,CAAC,IAAI;QAF7B,IAAI,OAE0B;QAHhC,MAAM,OAYa;QAEnB,MAAM,mBAYW;QAZjB,MAAM,CAKL,"
|
||||
"IAAI,CAAC,UAAU,CAAC,OAAO;QALxB,MAAM,CAML,MAAM,CAAC;YACN,GAAG,EAAE,EAAE;SACR;QARD,MAAM,CASL,eAAe,CAAC,"
|
||||
"SAAS;QAT1B,MAAM,CAUL,KAAK,CAAC,KAAK;QAVZ,MAAM,CAWL,MAAM,CAAC,IAAI;QAXZ,MAAM,CAYL,OAAO,CAAC,OAAO;QAXd,"
|
||||
"IAAI,QAAC,MAAM,EAEmB;QAF9B,IAAI,CACD,QAAQ,CAAC,EAAE;QADd,IAAI,CAED,UAAU,CAAC,UAAU,CAAC,IAAI;QAF7B,IAAI,"
|
||||
"OAE0B;QAHhC,MAAM,OAYW;QAEjB,MAAM,mBAYU;QAZhB,MAAM,CAKL,IAAI,CAAC,UAAU,CAAC,OAAO;QALxB,MAAM,CAML,MAAM,"
|
||||
"CAAC;YACN,GAAG,EAAE,EAAE;SACR;QARD,MAAM,CASL,eAAe,CAAC,SAAS;QAT1B,MAAM,CAUL,KAAK,CAAC,KAAK;QAVZ,MAAM,"
|
||||
"CAWL,MAAM,CAAC,IAAI;QAXZ,MAAM,CAYL,OAAO,CAAC,MAAM;QAXb,IAAI,QAAC,MAAM,EAEmB;QAF9B,IAAI,CACD,QAAQ,"
|
||||
"CAAC,EAAE;QADd,IAAI,CAED,UAAU,CAAC,UAAU,CAAC,IAAI;QAF7B,IAAI,OAE0B;QAHhC,MAAM,OAYU;QAzClB,MAAM,OA2CQ;"
|
||||
"QA5ChB,GAAG,OA8CY;KAChB;;AAEH,IAAI,YAAY,CAAC;AACjB,SAAS,SAAS;IAChB,kBAAkB,CAAC,gBAAgB,CAAC,EAAC,MAAM,"
|
||||
"EAAE,CAAE,cAAc,CAAE,EAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE;QACtF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,"
|
||||
"CAAC,KAAK,CAAC,CAAC,CAAA;QAClC,IAAI,KAAK,EAAE;YACT,OAAO,CAAC,IAAI,CAAC,2BAA2B,GAAG,IAAI,CAAC,SAAS,CAAC,"
|
||||
"KAAK,CAAC,CAAC,CAAC;SACnE;aAAM;YACL,OAAO,CAAC,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,"
|
||||
"CAAC;YAChE,YAAY,GAAG,UAAU,CAAA;YACzB,kBAAkB,CAAC,SAAS,CAAC,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE;"
|
||||
"gBAC1E,IAAI,KAAK,EAAE;oBACT,OAAO,CAAC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;iBAC3D;"
|
||||
"qBAAM;oBACL,OAAO,CAAC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC;iBACrE;YACH,CAAC,CAAC,"
|
||||
"CAAC;SACJ;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,OAAO;IACd,IAAI,MAAM,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;"
|
||||
"IAC/B,kBAAkB,CAAC,OAAO,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;QAC3D,IAAI,KAAK,CAAC,IAAI,EAAE;YACd,"
|
||||
"OAAO,CAAC,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;SAChE;aAAM;YACL,OAAO,CAAC,IAAI,"
|
||||
"CAAC,gBAAgB,CAAC,CAAC;SAChC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AAGD,SAAS,MAAM;IACb,kBAAkB,CAAC,uBAAuB,CAAC,cAAc,"
|
||||
"EAAE,CAAC,KAAK,EAAE,EAAE;QACnE,IAAI,KAAK,EAAE;YACT,OAAO,CAAC,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,"
|
||||
"CAAC,CAAC,CAAC;SAC/D;aAAM;YACL,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;SAC/B;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"
|
||||
"}"
|
||||
"}";
|
||||
std::string stackStr = "entry/src/main/ets/pages/Index.ets:111:13";
|
||||
|
||||
auto mapObj = std::make_shared<SourceMap>();
|
||||
mapObj->Init(true, sourceMaps);
|
||||
std::string stack = mapObj->TranslateBySourceMap(stackStr);
|
||||
EXPECT_STREQ(stack.c_str(), "entry/src/main/ets/pages/Index.ets:111:13");
|
||||
|
||||
GTEST_LOG_(INFO) << "JsEnv_SourceMap_1500 end" << stack.c_str();
|
||||
}
|
||||
} // namespace AppExecFwk
|
||||
} // namespace OHOS
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "ability_util.h"
|
||||
#include "erms_mgr_param.h"
|
||||
#include "erms_mgr_interface.h"
|
||||
#include "in_process_call_wrapper.h"
|
||||
#include "want.h"
|
||||
|
||||
namespace OHOS {
|
||||
@@ -63,6 +64,24 @@ public:
|
||||
private:
|
||||
bool CheckRule(const Want &want, ErmsCallerInfo &callerInfo, ExperienceRule &rule);
|
||||
};
|
||||
|
||||
// ability jump interceptor
|
||||
class AbilityJumpInterceptor : public AbilityInterceptor {
|
||||
public:
|
||||
AbilityJumpInterceptor();
|
||||
~AbilityJumpInterceptor();
|
||||
ErrCode DoProcess(const Want &want, int requestCode, int32_t userId, bool isForeground) override;
|
||||
|
||||
private:
|
||||
bool CheckControl(sptr<AppExecFwk::IBundleMgr> &bms, const Want &want, int32_t userId,
|
||||
AppExecFwk::AppJumpControlRule &controlRule);
|
||||
bool CheckIfIntercept(sptr<AppExecFwk::IBundleMgr> &bms, AppExecFwk::AppJumpControlRule &controlRule,
|
||||
int32_t userId);
|
||||
bool VerifyPermissionByBundleName(sptr<AppExecFwk::IBundleMgr> &bms, const std::string &bundleName,
|
||||
const std::string &permission, int32_t userId);
|
||||
bool LoadAppLabelInfo(sptr<AppExecFwk::IBundleMgr> &bms, Want &want, AppExecFwk::AppJumpControlRule &controlRule,
|
||||
int32_t userId);
|
||||
};
|
||||
} // namespace AAFwk
|
||||
} // namespace OHOS
|
||||
#endif // OHOS_ABILITY_RUNTIME_ABILITY_INTERCEPTOR_H
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "ability_config.h"
|
||||
#include "ability_manager_errors.h"
|
||||
#include "ability_manager_client.h"
|
||||
#include "app_jump_control_rule.h"
|
||||
#include "bundlemgr/bundle_mgr_interface.h"
|
||||
#include "erms_mgr_interface.h"
|
||||
#include "hilog_wrapper.h"
|
||||
@@ -44,6 +45,7 @@ constexpr const char* DLP_PARAMS_MODULE_NAME = "ohos.dlp.params.moduleName";
|
||||
constexpr const char* DLP_PARAMS_ABILITY_NAME = "ohos.dlp.params.abilityName";
|
||||
const std::string MARKET_BUNDLE_NAME = "com.huawei.hmos.appgallery";
|
||||
const std::string BUNDLE_NAME_SELECTOR_DIALOG = "com.ohos.amsdialog";
|
||||
const std::string JUMP_INTERCEPTOR_DIALOG_CALLER_PKG = "interceptor_callerPkg";
|
||||
// dlp White list
|
||||
const std::unordered_set<std::string> WHITE_LIST_DLP_SET = { BUNDLE_NAME_SELECTOR_DIALOG };
|
||||
|
||||
@@ -208,6 +210,49 @@ static constexpr int64_t MICROSECONDS = 1000000; // MICROSECONDS mean 10^6 mi
|
||||
return iface_cast<AppExecFwk::IEcologicalRuleManager>(remoteObject);
|
||||
}
|
||||
|
||||
[[maybe_unused]] static bool ParseJumpInterceptorWant(Want &targetWant, const std::string callerPkg)
|
||||
{
|
||||
if (callerPkg.empty()) {
|
||||
HILOG_ERROR("%{public}s error, get empty callerPkg.", __func__);
|
||||
return false;
|
||||
}
|
||||
targetWant.SetParam(JUMP_INTERCEPTOR_DIALOG_CALLER_PKG, callerPkg);
|
||||
return true;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static bool CheckJumpInterceptorWant(const Want &targetWant, std::string &callerPkg,
|
||||
std::string &targetPkg)
|
||||
{
|
||||
if (!targetWant.HasParameter(JUMP_INTERCEPTOR_DIALOG_CALLER_PKG)) {
|
||||
HILOG_ERROR("%{public}s error, the interceptor parameter invalid.", __func__);
|
||||
return false;
|
||||
}
|
||||
callerPkg = targetWant.GetStringParam(JUMP_INTERCEPTOR_DIALOG_CALLER_PKG);
|
||||
targetPkg = targetWant.GetElement().GetBundleName();
|
||||
return !callerPkg.empty() && !targetPkg.empty();
|
||||
}
|
||||
|
||||
[[maybe_unused]] static bool AddAbilityJumpRuleToBms(const std::string &callerPkg, const std::string &targetPkg,
|
||||
int32_t userId)
|
||||
{
|
||||
if (callerPkg.empty() || targetPkg.empty()) {
|
||||
HILOG_ERROR("get invalid inputs");
|
||||
return false;
|
||||
}
|
||||
auto bms = AbilityUtil::GetBundleManager();
|
||||
if (!bms) {
|
||||
HILOG_ERROR("GetBundleManager failed");
|
||||
return false;
|
||||
}
|
||||
auto appControlMgr = bms->GetAppControlProxy();
|
||||
if (appControlMgr == nullptr) {
|
||||
HILOG_ERROR("Get appControlMgr failed");
|
||||
return false;
|
||||
}
|
||||
int ret = IN_PROCESS_CALL(appControlMgr->ConfirmAppJumpControlRule(callerPkg, targetPkg, userId));
|
||||
return ret == ERR_OK;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static bool HandleDlpApp(Want &want)
|
||||
{
|
||||
if (WHITE_LIST_DLP_SET.find(want.GetBundle()) != WHITE_LIST_DLP_SET.end()) {
|
||||
|
||||
@@ -39,8 +39,8 @@ public:
|
||||
int ImplicitStartAbility(AbilityRequest &request, int32_t userId);
|
||||
|
||||
private:
|
||||
int GenerateAbilityRequestByAction(int32_t userId,
|
||||
AbilityRequest &request, std::vector<DialogAppInfo> &dialogAppInfos);
|
||||
int GenerateAbilityRequestByAction(int32_t userId, AbilityRequest &request,
|
||||
std::vector<DialogAppInfo> &dialogAppInfos, std::string &deviceType, bool isMoreHapList);
|
||||
|
||||
sptr<AppExecFwk::IBundleMgr> GetBundleManager();
|
||||
|
||||
@@ -55,6 +55,7 @@ private:
|
||||
|
||||
bool FilterAbilityList(const Want &want, std::vector<AppExecFwk::AbilityInfo> &abilityInfos,
|
||||
std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos);
|
||||
sptr<AppExecFwk::IDefaultApp> GetDefaultAppProxy();
|
||||
|
||||
private:
|
||||
const static std::vector<std::string> blackList;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@@ -26,6 +26,7 @@ enum class DialogType {
|
||||
DIALOG_ANR = 0,
|
||||
DIALOG_TIPS,
|
||||
DIALOG_SELECTOR,
|
||||
DIALOG_JUMP_INTERCEPTOR,
|
||||
};
|
||||
enum class DialogAlign {
|
||||
TOP = 0,
|
||||
@@ -66,18 +67,28 @@ public:
|
||||
virtual ~SystemDialogScheduler() = default;
|
||||
|
||||
bool GetANRDialogWant(int userId, int pid, AAFwk::Want &want);
|
||||
Want GetPcSelectorDialogWant(const std::vector<DialogAppInfo> &dialogAppInfos, Want &targetWant,
|
||||
const std::string &type, int32_t userId, const sptr<IRemoteObject> &callerToken);
|
||||
Want GetSelectorDialogWant(const std::vector<DialogAppInfo> &dialogAppInfos, Want &targetWant,
|
||||
const sptr<IRemoteObject> &callerToken);
|
||||
Want GetTipsDialogWant(const sptr<IRemoteObject> &callerToken);
|
||||
Want GetJumpInterceptorDialogWant(Want &targetWant);
|
||||
|
||||
void SetDeviceType(const std::string &deviceType)
|
||||
{
|
||||
deviceType_ = deviceType;
|
||||
}
|
||||
|
||||
const std::string GetDeviceType()
|
||||
{
|
||||
return deviceType_;
|
||||
}
|
||||
|
||||
private:
|
||||
const std::string GetAnrParams(const DialogPosition position, const std::string &appName) const;
|
||||
const std::string GetSelectorParams(const std::vector<DialogAppInfo> &infos) const;
|
||||
const std::string GetPcSelectorParams(const std::vector<DialogAppInfo> &infos,
|
||||
const std::string &type, int32_t userId, const std::string &action) const;
|
||||
const std::string GetDialogPositionParams(const DialogPosition position) const;
|
||||
|
||||
void InitDialogPosition(DialogType type, DialogPosition &position) const;
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
*ControlInterceptor*;
|
||||
*CrowdTestInterceptor*;
|
||||
*EcologicalRuleInterceptor*;
|
||||
*AbilityJumpInterceptor*;
|
||||
*DataAbilityManager*;
|
||||
*FreeInstallManager*;
|
||||
*FreeInstallObserverManager*;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-2023 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
|
||||
@@ -111,12 +110,12 @@ int AbilityConnectionStub::OnRemoteRequest(
|
||||
}
|
||||
|
||||
auto element = data.ReadParcelable<AppExecFwk::ElementName>();
|
||||
if (element == nullptr) {
|
||||
HILOG_ERROR("callback stub receive element is nullptr");
|
||||
return ERR_INVALID_VALUE;
|
||||
}
|
||||
switch (code) {
|
||||
case IAbilityConnection::ON_ABILITY_CONNECT_DONE: {
|
||||
if (element == nullptr) {
|
||||
HILOG_ERROR("callback stub receive element is nullptr");
|
||||
return ERR_INVALID_VALUE;
|
||||
}
|
||||
auto remoteObject = data.ReadRemoteObject();
|
||||
if (remoteObject == nullptr) {
|
||||
HILOG_ERROR("callback stub receive remoteObject is nullptr");
|
||||
@@ -129,15 +128,17 @@ int AbilityConnectionStub::OnRemoteRequest(
|
||||
return NO_ERROR;
|
||||
}
|
||||
case IAbilityConnection::ON_ABILITY_DISCONNECT_DONE: {
|
||||
if (element == nullptr) {
|
||||
HILOG_ERROR("callback stub receive element is nullptr");
|
||||
return ERR_INVALID_VALUE;
|
||||
}
|
||||
auto resultCode = data.ReadInt32();
|
||||
OnAbilityDisconnectDone(*element, resultCode);
|
||||
delete element;
|
||||
return NO_ERROR;
|
||||
}
|
||||
case IAbilityConnection::ON_REMOTE_STATE_CHANGED: {
|
||||
int32_t abilityState = data.ReadInt32();
|
||||
OnRemoteStateChanged(*element, abilityState);
|
||||
delete element;
|
||||
return NO_ERROR;
|
||||
}
|
||||
default: {
|
||||
if (element != nullptr) {
|
||||
delete element;
|
||||
|
||||
@@ -16,19 +16,22 @@
|
||||
#include "ability_interceptor.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
||||
#include "ability_manager_errors.h"
|
||||
#include "accesstoken_kit.h"
|
||||
#include "app_jump_control_rule.h"
|
||||
#include "app_running_control_rule_result.h"
|
||||
#include "bundlemgr/bundle_mgr_interface.h"
|
||||
#include "bundle_constants.h"
|
||||
#include "erms_mgr_param.h"
|
||||
#include "erms_mgr_interface.h"
|
||||
#include "erms_mgr_param.h"
|
||||
#include "hilog_wrapper.h"
|
||||
#include "in_process_call_wrapper.h"
|
||||
#include "ipc_skeleton.h"
|
||||
#include "permission_constants.h"
|
||||
#include "permission_verification.h"
|
||||
#include "system_dialog_scheduler.h"
|
||||
#include "want.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace AAFwk {
|
||||
using ErmsCallerInfo = OHOS::AppExecFwk::ErmsParams::CallerInfo;
|
||||
@@ -37,6 +40,11 @@ using ExperienceRule = OHOS::AppExecFwk::ErmsParams::ExperienceRule;
|
||||
const std::string ACTION_MARKET_CROWDTEST = "ohos.want.action.marketCrowdTest";
|
||||
const std::string ACTION_MARKET_DISPOSED = "ohos.want.action.marketDisposed";
|
||||
const std::string PERMISSION_MANAGE_DISPOSED_APP_STATUS = "ohos.permission.MANAGE_DISPOSED_APP_STATUS";
|
||||
const std::string JUMP_DIALOG_CALLER_BUNDLE_NAME= "interceptor_callerBundleName";
|
||||
const std::string JUMP_DIALOG_CALLER_MODULE_NAME= "interceptor_callerModuleName";
|
||||
const std::string JUMP_DIALOG_CALLER_LABEL_ID= "interceptor_callerLabelId";
|
||||
const std::string JUMP_DIALOG_TARGET_MODULE_NAME= "interceptor_targetModuleName";
|
||||
const std::string JUMP_DIALOG_TARGET_LABEL_ID= "interceptor_targetLabelId";
|
||||
|
||||
AbilityInterceptor::~AbilityInterceptor()
|
||||
{}
|
||||
@@ -208,5 +216,142 @@ bool EcologicalRuleInterceptor::CheckRule(const Want &want, ErmsCallerInfo &call
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
AbilityJumpInterceptor::AbilityJumpInterceptor()
|
||||
{}
|
||||
|
||||
AbilityJumpInterceptor::~AbilityJumpInterceptor()
|
||||
{}
|
||||
|
||||
ErrCode AbilityJumpInterceptor::DoProcess(const Want &want, int requestCode, int32_t userId, bool isForeground)
|
||||
{
|
||||
int callerUid = IPCSkeleton::GetCallingUid();
|
||||
bool isStartIncludeAtomicService = AbilityUtil::IsStartIncludeAtomicService(want, callerUid);
|
||||
if (isStartIncludeAtomicService) {
|
||||
HILOG_INFO("This startup contain atomic service, keep going.");
|
||||
return ERR_OK;
|
||||
}
|
||||
// get bms
|
||||
auto bms = AbilityUtil::GetBundleManager();
|
||||
if (!bms) {
|
||||
HILOG_ERROR("GetBundleManager failed");
|
||||
return ERR_OK;
|
||||
}
|
||||
AppExecFwk::AppJumpControlRule controlRule;
|
||||
if (CheckControl(bms, want, userId, controlRule)) {
|
||||
#ifdef SUPPORT_GRAPHICS
|
||||
HILOG_INFO("app jump need to be intercepted, caller:%{public}s, target:%{public}s",
|
||||
controlRule.callerPkg.c_str(), controlRule.targetPkg.c_str());
|
||||
auto sysDialogScheduler = DelayedSingleton<SystemDialogScheduler>::GetInstance();
|
||||
Want targetWant = want;
|
||||
Want dialogWant = sysDialogScheduler->GetJumpInterceptorDialogWant(targetWant);
|
||||
AbilityUtil::ParseJumpInterceptorWant(dialogWant, controlRule.callerPkg);
|
||||
LoadAppLabelInfo(bms, dialogWant, controlRule, userId);
|
||||
int ret = IN_PROCESS_CALL(AbilityManagerClient::GetInstance()->StartAbility(dialogWant,
|
||||
userId, requestCode));
|
||||
if (ret != ERR_OK) {
|
||||
HILOG_INFO("AppInterceptor Dialog StartAbility error, ret:%{public}d", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
return ERR_APP_JUMP_INTERCEPTOR_STATUS;
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
bool AbilityJumpInterceptor::CheckControl(sptr<AppExecFwk::IBundleMgr> &bms, const Want &want, int32_t userId,
|
||||
AppExecFwk::AppJumpControlRule &controlRule)
|
||||
{
|
||||
int callerUid = IPCSkeleton::GetCallingUid();
|
||||
std::string callerBundleName;
|
||||
bool result = IN_PROCESS_CALL(bms->GetBundleNameForUid(callerUid, callerBundleName));
|
||||
std::string targetBundleName = want.GetBundle();
|
||||
controlRule.callerPkg = callerBundleName;
|
||||
controlRule.targetPkg = targetBundleName;
|
||||
if (!result) {
|
||||
HILOG_ERROR("GetBundleNameForUid from bms fail.");
|
||||
return false;
|
||||
}
|
||||
if (CheckIfIntercept(bms, controlRule, userId)) {
|
||||
HILOG_INFO("jump from or to system or exempt apps");
|
||||
return false;
|
||||
}
|
||||
// get disposed status
|
||||
auto appControlMgr = bms->GetAppControlProxy();
|
||||
if (appControlMgr == nullptr) {
|
||||
HILOG_ERROR("Get appControlMgr failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IN_PROCESS_CALL(appControlMgr->GetAppJumpControlRule(callerBundleName, targetBundleName,
|
||||
userId, controlRule)) != ERR_OK) {
|
||||
HILOG_INFO("no jump control rule found");
|
||||
return true;
|
||||
}
|
||||
HILOG_INFO("get appJumpControlRule, jumpMode:%d", controlRule.jumpMode);
|
||||
return controlRule.jumpMode != AppExecFwk::AbilityJumpMode::DIRECT;
|
||||
}
|
||||
|
||||
bool AbilityJumpInterceptor::CheckIfIntercept(sptr<AppExecFwk::IBundleMgr> &bms,
|
||||
AppExecFwk::AppJumpControlRule &controlRule, int32_t userId)
|
||||
{
|
||||
int callerUid = IPCSkeleton::GetCallingUid();
|
||||
if (bms->CheckIsSystemAppByUid(callerUid)) {
|
||||
HILOG_INFO("Jump From SystemApp, No need to intercept");
|
||||
return true;
|
||||
}
|
||||
if (VerifyPermissionByBundleName(bms, controlRule.callerPkg,
|
||||
PermissionConstants::PERMISSION_EXEMPT_AS_CALLER, userId)) {
|
||||
HILOG_INFO("Jump From exempt caller app, No need to intercept");
|
||||
return true;
|
||||
}
|
||||
int targetUid = bms->GetUidByBundleName(controlRule.targetPkg, userId);
|
||||
if (bms->CheckIsSystemAppByUid(targetUid)) {
|
||||
HILOG_INFO("Jump To SystemApp, No need to intercept");
|
||||
return true;
|
||||
}
|
||||
if (VerifyPermissionByBundleName(bms, controlRule.targetPkg,
|
||||
PermissionConstants::PERMISSION_EXEMPT_AS_TARGET, userId)) {
|
||||
HILOG_INFO("Jump From exempt target app, No need to intercept");
|
||||
return true;
|
||||
}
|
||||
HILOG_INFO("Third-party apps jump to third-party apps");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AbilityJumpInterceptor::VerifyPermissionByBundleName(sptr<AppExecFwk::IBundleMgr> &bms,
|
||||
const std::string &bundleName, const std::string &permission, int32_t userId)
|
||||
{
|
||||
AppExecFwk::ApplicationInfo appInfo;
|
||||
if (!IN_PROCESS_CALL(bms->GetApplicationInfo(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT,
|
||||
userId, appInfo))) {
|
||||
HILOG_DEBUG("VerifyPermission failed to get application info");
|
||||
return false;
|
||||
}
|
||||
int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(appInfo.accessTokenId, permission);
|
||||
if (ret == Security::AccessToken::PermissionState::PERMISSION_DENIED) {
|
||||
HILOG_DEBUG("VerifyPermission %{public}d: PERMISSION_DENIED", appInfo.accessTokenId);
|
||||
return false;
|
||||
}
|
||||
HILOG_INFO("bundle:%{public}s verify permission:%{public}s successed", bundleName.c_str(), permission.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AbilityJumpInterceptor::LoadAppLabelInfo(sptr<AppExecFwk::IBundleMgr> &bms, Want &want,
|
||||
AppExecFwk::AppJumpControlRule &controlRule, int32_t userId)
|
||||
{
|
||||
AppExecFwk::ApplicationInfo callerAppInfo;
|
||||
int result = IN_PROCESS_CALL(bms->GetApplicationInfo(controlRule.callerPkg,
|
||||
AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, userId, callerAppInfo));
|
||||
AppExecFwk::ApplicationInfo targetAppInfo;
|
||||
result = IN_PROCESS_CALL(bms->GetApplicationInfo(controlRule.targetPkg,
|
||||
AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, userId, targetAppInfo));
|
||||
want.SetParam(JUMP_DIALOG_CALLER_BUNDLE_NAME, controlRule.callerPkg);
|
||||
want.SetParam(JUMP_DIALOG_CALLER_MODULE_NAME, callerAppInfo.labelResource.moduleName);
|
||||
want.SetParam(JUMP_DIALOG_CALLER_LABEL_ID, callerAppInfo.labelId);
|
||||
want.SetParam(JUMP_DIALOG_TARGET_MODULE_NAME, targetAppInfo.labelResource.moduleName);
|
||||
want.SetParam(JUMP_DIALOG_TARGET_LABEL_ID, targetAppInfo.labelId);
|
||||
return true;
|
||||
}
|
||||
} // namespace AAFwk
|
||||
} // namespace OHOS
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "string_ex.h"
|
||||
#include "system_ability_definition.h"
|
||||
#include "os_account_manager_wrapper.h"
|
||||
#include "parameters.h"
|
||||
#include "permission_constants.h"
|
||||
#include "uri_permission_manager_client.h"
|
||||
#include "xcollie/watchdog.h"
|
||||
@@ -302,6 +303,15 @@ bool AbilityManagerService::Init()
|
||||
interceptorExecuter_->AddInterceptor(std::make_shared<CrowdTestInterceptor>());
|
||||
interceptorExecuter_->AddInterceptor(std::make_shared<ControlInterceptor>());
|
||||
interceptorExecuter_->AddInterceptor(std::make_shared<EcologicalRuleInterceptor>());
|
||||
bool isAppJumpEnabled = OHOS::system::GetBoolParameter(
|
||||
OHOS::AppExecFwk::PARAMETER_APP_JUMP_INTERCEPTOR_ENABLE, false);
|
||||
HILOG_ERROR("GetBoolParameter -> isAppJumpEnabled:%{public}s", (isAppJumpEnabled ? "true" : "false"));
|
||||
if (isAppJumpEnabled) {
|
||||
HILOG_INFO("App jump intercetor enabled, add AbilityJumpInterceptor to Executer");
|
||||
interceptorExecuter_->AddInterceptor(std::make_shared<AbilityJumpInterceptor>());
|
||||
} else {
|
||||
HILOG_INFO("App jump intercetor disabled");
|
||||
}
|
||||
|
||||
auto startResidentAppsTask = [aams = shared_from_this()]() { aams->StartResidentApps(); };
|
||||
handler_->PostTask(startResidentAppsTask, "StartResidentApps");
|
||||
@@ -414,7 +424,13 @@ int AbilityManagerService::StartAbilityAsCaller(const Want &want, const sptr<IRe
|
||||
|
||||
HILOG_INFO("Start ability come, ability is %{public}s, userId is %{public}d",
|
||||
want.GetElement().GetAbilityName().c_str(), userId);
|
||||
|
||||
std::string callerPkg;
|
||||
std::string targetPkg;
|
||||
if (AbilityUtil::CheckJumpInterceptorWant(want, callerPkg, targetPkg)) {
|
||||
HILOG_INFO("the call is from interceptor dialog, callerPkg:%{public}s, targetPkg:%{public}s",
|
||||
callerPkg.c_str(), targetPkg.c_str());
|
||||
AbilityUtil::AddAbilityJumpRuleToBms(callerPkg, targetPkg, GetUserId());
|
||||
}
|
||||
int32_t ret = StartAbilityInner(want, callerToken, requestCode, -1, userId, true);
|
||||
if (ret != ERR_OK) {
|
||||
eventInfo.errCode = ret;
|
||||
@@ -4176,6 +4192,11 @@ int AbilityManagerService::StartRemoteAbilityByCall(const Want &want, const sptr
|
||||
HILOG_ERROR("%{public}s AddStartControlParam failed.", __func__);
|
||||
return ERR_INVALID_VALUE;
|
||||
}
|
||||
int32_t missionId = GetMissionIdByAbilityToken(callerToken);
|
||||
if (missionId < 0) {
|
||||
return ERR_INVALID_VALUE;
|
||||
}
|
||||
remoteWant.SetParam(DMS_MISSION_ID, missionId);
|
||||
DistributedClient dmsClient;
|
||||
return dmsClient.StartRemoteAbilityByCall(remoteWant, connect);
|
||||
}
|
||||
@@ -6280,6 +6301,7 @@ std::shared_ptr<AbilityRecord> AbilityManagerService::GetFocusAbility()
|
||||
|
||||
int AbilityManagerService::AddFreeInstallObserver(const sptr<AbilityRuntime::IFreeInstallObserver> &observer)
|
||||
{
|
||||
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
|
||||
if (freeInstallManager_ == nullptr) {
|
||||
HILOG_ERROR("freeInstallManager_ is nullptr.");
|
||||
return ERR_INVALID_VALUE;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "distributed_client.h"
|
||||
#include "free_install_observer_manager.h"
|
||||
#include "hilog_wrapper.h"
|
||||
#include "hitrace_meter.h"
|
||||
#include "in_process_call_wrapper.h"
|
||||
|
||||
namespace OHOS {
|
||||
@@ -82,6 +83,7 @@ bool FreeInstallManager::IsTopAbility(const sptr<IRemoteObject> &callerToken)
|
||||
int FreeInstallManager::StartFreeInstall(const Want &want, int32_t userId, int requestCode,
|
||||
const sptr<IRemoteObject> &callerToken, bool isAsync)
|
||||
{
|
||||
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
|
||||
HILOG_INFO("StartFreeInstall called");
|
||||
auto isSaCall = AAFwk::PermissionVerification::GetInstance()->IsSACall();
|
||||
if (!isSaCall && !IsTopAbility(callerToken)) {
|
||||
@@ -196,6 +198,7 @@ int FreeInstallManager::StartRemoteFreeInstall(const Want &want, int requestCode
|
||||
|
||||
int FreeInstallManager::NotifyDmsCallback(const Want &want, int resultCode)
|
||||
{
|
||||
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
|
||||
std::lock_guard<std::mutex> autoLock(distributedFreeInstallLock_);
|
||||
if (dmsFreeInstallCbs_.empty()) {
|
||||
HILOG_ERROR("Has no dms callback.");
|
||||
@@ -242,6 +245,7 @@ int FreeInstallManager::NotifyDmsCallback(const Want &want, int resultCode)
|
||||
|
||||
void FreeInstallManager::NotifyFreeInstallResult(const Want &want, int resultCode, bool isAsync)
|
||||
{
|
||||
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
|
||||
std::lock_guard<std::mutex> lock(freeInstallListLock_);
|
||||
if (freeInstallList_.empty()) {
|
||||
HILOG_INFO("Has no app callback.");
|
||||
@@ -377,6 +381,7 @@ std::time_t FreeInstallManager::GetTimeStamp()
|
||||
|
||||
void FreeInstallManager::OnInstallFinished(int resultCode, const Want &want, int32_t userId, bool isAsync)
|
||||
{
|
||||
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
|
||||
HILOG_INFO("%{public}s resultCode = %{public}d", __func__, resultCode);
|
||||
if (isAsync) {
|
||||
// remove timeout task
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@@ -14,8 +14,11 @@
|
||||
*/
|
||||
#include "implicit_start_processor.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "ability_manager_service.h"
|
||||
#include "ability_util.h"
|
||||
#include "default_app_interface.h"
|
||||
#include "errors.h"
|
||||
#include "event_report.h"
|
||||
#include "hilog_wrapper.h"
|
||||
@@ -27,6 +30,8 @@ namespace AAFwk {
|
||||
using ErmsCallerInfo = OHOS::AppExecFwk::ErmsParams::CallerInfo;
|
||||
|
||||
const std::string BLACK_ACTION_SELECT_DATA = "ohos.want.action.select";
|
||||
const std::string STR_PC = "pc";
|
||||
const std::string TYPE_ONLY_MATCH_WILDCARD = "reserved/wildcard";
|
||||
|
||||
const std::vector<std::string> ImplicitStartProcessor::blackList = {
|
||||
std::vector<std::string>::value_type(BLACK_ACTION_SELECT_DATA),
|
||||
@@ -59,12 +64,12 @@ bool ImplicitStartProcessor::IsImplicitStartAction(const Want &want)
|
||||
int ImplicitStartProcessor::ImplicitStartAbility(AbilityRequest &request, int32_t userId)
|
||||
{
|
||||
HILOG_INFO("implicit start ability by type: %{public}d", request.callType);
|
||||
|
||||
auto sysDialogScheduler = DelayedSingleton<SystemDialogScheduler>::GetInstance();
|
||||
CHECK_POINTER_AND_RETURN(sysDialogScheduler, ERR_INVALID_VALUE);
|
||||
|
||||
std::vector<DialogAppInfo> dialogAppInfos;
|
||||
auto ret = GenerateAbilityRequestByAction(userId, request, dialogAppInfos);
|
||||
auto deviceType = sysDialogScheduler->GetDeviceType();
|
||||
auto ret = GenerateAbilityRequestByAction(userId, request, dialogAppInfos, deviceType, false);
|
||||
if (ret != ERR_OK) {
|
||||
HILOG_ERROR("generate ability request by action failed.");
|
||||
return ret;
|
||||
@@ -85,30 +90,58 @@ int ImplicitStartProcessor::ImplicitStartAbility(AbilityRequest &request, int32_
|
||||
};
|
||||
return imp->CallStartAbilityInner(userId, targetWant, callBack, request.callType);
|
||||
};
|
||||
if (dialogAppInfos.size() == 0) {
|
||||
|
||||
AAFwk::Want want;
|
||||
auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
|
||||
if (dialogAppInfos.size() == 0 && deviceType != STR_PC) {
|
||||
HILOG_ERROR("implicit query ability infos failed, show tips dialog.");
|
||||
Want want = sysDialogScheduler->GetTipsDialogWant(request.callerToken);
|
||||
auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
|
||||
want = sysDialogScheduler->GetTipsDialogWant(request.callerToken);
|
||||
abilityMgr->StartAbility(want);
|
||||
return ERR_IMPLICIT_START_ABILITY_FAIL;
|
||||
} else if (dialogAppInfos.size() == 0 && deviceType == STR_PC) {
|
||||
std::vector<DialogAppInfo> dialogAllAppInfos;
|
||||
bool isMoreHapList = true;
|
||||
ret = GenerateAbilityRequestByAction(userId, request, dialogAllAppInfos, deviceType, isMoreHapList);
|
||||
if (ret != ERR_OK) {
|
||||
HILOG_ERROR("generate ability request by action failed.");
|
||||
return ret;
|
||||
}
|
||||
if (dialogAllAppInfos.size() == 0) {
|
||||
Want want = sysDialogScheduler->GetTipsDialogWant(request.callerToken);
|
||||
abilityMgr->StartAbility(want);
|
||||
return ERR_IMPLICIT_START_ABILITY_FAIL;
|
||||
}
|
||||
want = sysDialogScheduler->GetPcSelectorDialogWant(dialogAllAppInfos, request.want,
|
||||
TYPE_ONLY_MATCH_WILDCARD, userId, request.callerToken);
|
||||
IPCSkeleton::SetCallingIdentity(identity);
|
||||
return abilityMgr->StartAbility(want, request.callerToken);
|
||||
}
|
||||
|
||||
//There is a default opening method or Only one application supports
|
||||
if (dialogAppInfos.size() == 1) {
|
||||
auto info = dialogAppInfos.front();
|
||||
HILOG_INFO("ImplicitQueryInfos success, target ability: %{public}s", info.abilityName.data());
|
||||
return IN_PROCESS_CALL(startAbilityTask(info.bundleName, info.abilityName));
|
||||
}
|
||||
|
||||
HILOG_INFO("ImplicitQueryInfos success, Multiple apps to choose.");
|
||||
Want want = sysDialogScheduler->GetSelectorDialogWant(dialogAppInfos, request.want, request.callerToken);
|
||||
auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
|
||||
if (deviceType != STR_PC) {
|
||||
HILOG_INFO("ImplicitQueryInfos success, Multiple apps to choose.");
|
||||
want = sysDialogScheduler->GetSelectorDialogWant(dialogAppInfos, request.want, request.callerToken);
|
||||
// reset calling indentity
|
||||
IPCSkeleton::SetCallingIdentity(identity);
|
||||
return abilityMgr->StartAbility(want, request.callerToken);
|
||||
}
|
||||
|
||||
HILOG_INFO("ImplicitQueryInfos success, Multiple apps to choose in pc.");
|
||||
auto type = request.want.GetType();
|
||||
want = sysDialogScheduler->GetPcSelectorDialogWant(dialogAppInfos, request.want, type, userId, request.callerToken);
|
||||
// reset calling indentity
|
||||
IPCSkeleton::SetCallingIdentity(identity);
|
||||
return abilityMgr->StartAbility(want, request.callerToken);
|
||||
}
|
||||
|
||||
int ImplicitStartProcessor::GenerateAbilityRequestByAction(int32_t userId,
|
||||
AbilityRequest &request, std::vector<DialogAppInfo> &dialogAppInfos)
|
||||
AbilityRequest &request, std::vector<DialogAppInfo> &dialogAppInfos, std::string &deviceType, bool isMoreHapList)
|
||||
{
|
||||
HILOG_DEBUG("%{public}s", __func__);
|
||||
// get abilityinfos from bms
|
||||
@@ -133,10 +166,51 @@ int ImplicitStartProcessor::GenerateAbilityRequestByAction(int32_t userId,
|
||||
|
||||
auto isExtension = request.callType == AbilityCallType::START_EXTENSION_TYPE;
|
||||
|
||||
Want implicitwant;
|
||||
implicitwant.SetAction(request.want.GetAction());
|
||||
implicitwant.SetType(TYPE_ONLY_MATCH_WILDCARD);
|
||||
std::vector<AppExecFwk::AbilityInfo> implicitAbilityInfos;
|
||||
std::vector<AppExecFwk::ExtensionAbilityInfo> implicitExtensionInfos;
|
||||
std::vector<std::string> infoNames;
|
||||
if (deviceType == STR_PC) {
|
||||
IN_PROCESS_CALL_WITHOUT_RET(bms->ImplicitQueryInfos(
|
||||
implicitwant, abilityInfoFlag, userId, implicitAbilityInfos, implicitExtensionInfos));
|
||||
if (implicitAbilityInfos.size() != 0 && request.want.GetType() != TYPE_ONLY_MATCH_WILDCARD) {
|
||||
for (auto implicitAbilityInfo : implicitAbilityInfos) {
|
||||
infoNames.emplace_back(implicitAbilityInfo.bundleName + "#" +
|
||||
implicitAbilityInfo.moduleName + "#" + implicitAbilityInfo.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const auto &info : abilityInfos) {
|
||||
if (isExtension && info.type != AbilityType::EXTENSION) {
|
||||
continue;
|
||||
}
|
||||
if (deviceType == STR_PC) {
|
||||
auto defaultMgr = GetDefaultAppProxy();
|
||||
AppExecFwk::BundleInfo bundleInfo;
|
||||
auto isDefaultFlag = false;
|
||||
ErrCode ret =
|
||||
IN_PROCESS_CALL(defaultMgr->GetDefaultApplication(userId, request.want.GetType(), bundleInfo));
|
||||
if (ret == ERR_OK) {
|
||||
if (bundleInfo.abilityInfos.size() == 1) {
|
||||
HILOG_INFO("find default ability.");
|
||||
isDefaultFlag = true;
|
||||
} else if (bundleInfo.extensionInfos.size() == 1) {
|
||||
HILOG_INFO("find default extension.");
|
||||
isDefaultFlag = true;
|
||||
} else {
|
||||
HILOG_INFO("GetDefaultApplication failed.");
|
||||
}
|
||||
}
|
||||
if (!isMoreHapList && !isDefaultFlag) {
|
||||
if (std::find(infoNames.begin(), infoNames.end(),
|
||||
(info.bundleName + "#" + info.moduleName + "#" + info.name)) != infoNames.end()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DialogAppInfo dialogAppInfo;
|
||||
dialogAppInfo.abilityName = info.name;
|
||||
dialogAppInfo.bundleName = info.bundleName;
|
||||
@@ -251,6 +325,17 @@ sptr<AppExecFwk::IBundleMgr> ImplicitStartProcessor::GetBundleManager()
|
||||
return iBundleManager_;
|
||||
}
|
||||
|
||||
sptr<AppExecFwk::IDefaultApp> ImplicitStartProcessor::GetDefaultAppProxy()
|
||||
{
|
||||
auto bundleMgr = GetBundleManager();
|
||||
auto defaultAppProxy = bundleMgr->GetDefaultAppProxy();
|
||||
if (defaultAppProxy == nullptr) {
|
||||
HILOG_ERROR("GetDefaultAppProxy failed.");
|
||||
return nullptr;
|
||||
}
|
||||
return defaultAppProxy;
|
||||
}
|
||||
|
||||
bool ImplicitStartProcessor::FilterAbilityList(const Want &want,
|
||||
std::vector<AppExecFwk::AbilityInfo> &abilityInfos, std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@@ -38,16 +38,21 @@ const int32_t UI_SELECTOR_DIALOG_PHONE_H1 = 240 * 2;
|
||||
const int32_t UI_SELECTOR_DIALOG_PHONE_H2 = 340 * 2;
|
||||
const int32_t UI_SELECTOR_DIALOG_PHONE_H3 = 350 * 2;
|
||||
const int32_t UI_SELECTOR_DIALOG_PC_H0 = 1;
|
||||
const int32_t UI_SELECTOR_DIALOG_PC_H2 = (70 * 2 + 85 + 2) * 2;
|
||||
const int32_t UI_SELECTOR_DIALOG_PC_H3 = (70 * 3 + 85 + 2) * 2;
|
||||
const int32_t UI_SELECTOR_DIALOG_PC_H4 = (70 * 4 + 85 + 2) * 2;
|
||||
const int32_t UI_SELECTOR_DIALOG_PC_H5 = (70 * 4 + 85 + 38) * 2;
|
||||
const int32_t UI_SELECTOR_DIALOG_PC_H2 = (64 * 2 + 56 + 48 + 54 + 64 + 48 + 2) * 2;
|
||||
const int32_t UI_SELECTOR_DIALOG_PC_H3 = (64 * 3 + 56 + 48 + 54 + 64 + 48 + 2) * 2;
|
||||
const int32_t UI_SELECTOR_DIALOG_PC_H4 = (64 * 4 + 56 + 48 + 54 + 64 + 48 + 2) * 2;
|
||||
const int32_t UI_SELECTOR_DIALOG_PC_H5 = (64 * 4 + 56 + 48 + 54 + 64 + 48 + 58 + 2) * 2;
|
||||
|
||||
const int32_t UI_TIPS_DIALOG_WIDTH = 328 * 2;
|
||||
const int32_t UI_TIPS_DIALOG_HEIGHT = 135 * 2;
|
||||
const int32_t UI_TIPS_DIALOG_HEIGHT_NARROW = 135 * 2;
|
||||
const int32_t UI_TIPS_DIALOG_WIDTH_NARROW = 328 * 2;
|
||||
|
||||
const int32_t UI_JUMP_INTERCEPTOR_DIALOG_WIDTH = 328 * 2;
|
||||
const int32_t UI_JUMP_INTERCEPTOR_DIALOG_HEIGHT = 135 * 2;
|
||||
const int32_t UI_JUMP_INTERCEPTOR_DIALOG_HEIGHT_NARROW = 135 * 2;
|
||||
const int32_t UI_JUMP_INTERCEPTOR_DIALOG_WIDTH_NARROW = 328 * 2;
|
||||
|
||||
const int32_t UI_ANR_DIALOG_WIDTH = 328 * 2;
|
||||
const int32_t UI_ANR_DIALOG_HEIGHT = 192 * 2;
|
||||
const std::string APP_NAME = "appName";
|
||||
@@ -56,6 +61,8 @@ const std::string OFF_SET_X = "offsetX";
|
||||
const std::string OFF_SET_Y = "offsetY";
|
||||
const std::string WIDTH = "width";
|
||||
const std::string HEIGHT = "height";
|
||||
const std::string MODEL_FLAG = "modelFlag";
|
||||
const std::string ACTION = "action";
|
||||
|
||||
const int32_t UI_HALF = 2;
|
||||
const int32_t UI_DEFAULT_BUTTOM_CLIP = 100;
|
||||
@@ -68,6 +75,7 @@ const std::string STR_PC = "pc";
|
||||
const std::string DIALOG_NAME_ANR = "dialog_anr_service";
|
||||
const std::string DIALOG_NAME_TIPS = "dialog_tips_service";
|
||||
const std::string DIALOG_SELECTOR_NAME = "dialog_selector_service";
|
||||
const std::string DIALOG_JUMP_INTERCEPTOR_NAME = "dialog_jump_interceptor_service";
|
||||
|
||||
const std::string BUNDLE_NAME = "bundleName";
|
||||
const std::string BUNDLE_NAME_DIALOG = "com.ohos.amsdialog";
|
||||
@@ -77,6 +85,8 @@ const std::string ABILITY_NAME_ANR_DIALOG = "AnrDialog";
|
||||
const std::string ABILITY_NAME_TIPS_DIALOG = "TipsDialog";
|
||||
const std::string ABILITY_NAME_SELECTOR_DIALOG = "SelectorDialog";
|
||||
const std::string CALLER_TOKEN = "callerToken";
|
||||
const std::string ABILITY_NAME_JUMP_INTERCEPTOR_DIALOG = "JumpInterceptorDialog";
|
||||
const std::string TYPE_ONLY_MATCH_WILDCARD = "reserved/wildcard";
|
||||
|
||||
const int32_t LINE_NUMS_ZERO = 0;
|
||||
const int32_t LINE_NUMS_TWO = 2;
|
||||
@@ -141,6 +151,27 @@ Want SystemDialogScheduler::GetTipsDialogWant(const sptr<IRemoteObject> &callerT
|
||||
return want;
|
||||
}
|
||||
|
||||
Want SystemDialogScheduler::GetJumpInterceptorDialogWant(Want &targetWant)
|
||||
{
|
||||
HILOG_DEBUG("GetJumpInterceptorDialogWant start");
|
||||
|
||||
DialogPosition position;
|
||||
GetDialogPositionAndSize(DialogType::DIALOG_JUMP_INTERCEPTOR, position);
|
||||
|
||||
nlohmann::json jsonObj;
|
||||
jsonObj[DEVICE_TYPE] = deviceType_;
|
||||
jsonObj["bundleName"] = targetWant.GetElement().GetBundleName();
|
||||
jsonObj["abilityName"] = targetWant.GetElement().GetAbilityName();
|
||||
jsonObj["moduleName"] = targetWant.GetElement().GetModuleName();
|
||||
const std::string params = jsonObj.dump();
|
||||
|
||||
targetWant.SetElementName(BUNDLE_NAME_DIALOG, ABILITY_NAME_JUMP_INTERCEPTOR_DIALOG);
|
||||
targetWant.SetParam(DIALOG_POSITION, GetDialogPositionParams(position));
|
||||
targetWant.SetParam(DIALOG_PARAMS, params);
|
||||
targetWant.GetStringParam(DIALOG_PARAMS);
|
||||
return targetWant;
|
||||
}
|
||||
|
||||
Want SystemDialogScheduler::GetSelectorDialogWant(const std::vector<DialogAppInfo> &dialogAppInfos, Want &targetWant,
|
||||
const sptr<IRemoteObject> &callerToken)
|
||||
{
|
||||
@@ -182,6 +213,57 @@ const std::string SystemDialogScheduler::GetSelectorParams(const std::vector<Dia
|
||||
return jsonObject.dump();
|
||||
}
|
||||
|
||||
Want SystemDialogScheduler::GetPcSelectorDialogWant(const std::vector<DialogAppInfo> &dialogAppInfos,
|
||||
Want &targetWant, const std::string &type, int32_t userId, const sptr<IRemoteObject> &callerToken)
|
||||
{
|
||||
HILOG_DEBUG("GetPcSelectorDialogWant start");
|
||||
DialogPosition position;
|
||||
GetDialogPositionAndSize(DialogType::DIALOG_SELECTOR, position, static_cast<int>(dialogAppInfos.size()));
|
||||
|
||||
std::string params = GetPcSelectorParams(dialogAppInfos, type, userId, targetWant.GetAction());
|
||||
targetWant.SetElementName(BUNDLE_NAME_DIALOG, ABILITY_NAME_SELECTOR_DIALOG);
|
||||
targetWant.SetParam(DIALOG_POSITION, GetDialogPositionParams(position));
|
||||
targetWant.SetParam(DIALOG_PARAMS, params);
|
||||
targetWant.SetParam(CALLER_TOKEN, callerToken);
|
||||
|
||||
return targetWant;
|
||||
}
|
||||
|
||||
const std::string SystemDialogScheduler::GetPcSelectorParams(const std::vector<DialogAppInfo> &infos,
|
||||
const std::string &type, int32_t userId, const std::string &action) const
|
||||
{
|
||||
HILOG_DEBUG("GetPcSelectorParams start");
|
||||
if (infos.empty()) {
|
||||
HILOG_WARN("Invalid abilityInfos.");
|
||||
return {};
|
||||
}
|
||||
|
||||
nlohmann::json jsonObject;
|
||||
jsonObject[DEVICE_TYPE] = deviceType_;
|
||||
jsonObject[ACTION] = action;
|
||||
if (type == TYPE_ONLY_MATCH_WILDCARD) {
|
||||
jsonObject[MODEL_FLAG] = true;
|
||||
} else {
|
||||
jsonObject[MODEL_FLAG] = false;
|
||||
}
|
||||
|
||||
nlohmann::json hapListObj = nlohmann::json::array();
|
||||
for (const auto &info : infos) {
|
||||
nlohmann::json aObj;
|
||||
aObj["label"] = std::to_string(info.labelId);
|
||||
aObj["icon"] = std::to_string(info.iconId);
|
||||
aObj["bundle"] = info.bundleName;
|
||||
aObj["ability"] = info.abilityName;
|
||||
aObj["module"] = info.moduleName;
|
||||
aObj["type"] = type;
|
||||
aObj["userId"] = std::to_string(userId);
|
||||
hapListObj.emplace_back(aObj);
|
||||
}
|
||||
jsonObject["hapList"] = hapListObj;
|
||||
|
||||
return jsonObject.dump();
|
||||
}
|
||||
|
||||
const std::string SystemDialogScheduler::GetDialogPositionParams(const DialogPosition position) const
|
||||
{
|
||||
nlohmann::json dialogPositionData;
|
||||
@@ -228,6 +310,12 @@ void SystemDialogScheduler::InitDialogPosition(DialogType type, DialogPosition &
|
||||
position.width_narrow = UI_TIPS_DIALOG_WIDTH_NARROW;
|
||||
position.height_narrow = UI_TIPS_DIALOG_HEIGHT_NARROW;
|
||||
break;
|
||||
case DialogType::DIALOG_JUMP_INTERCEPTOR:
|
||||
position.width = UI_JUMP_INTERCEPTOR_DIALOG_WIDTH;
|
||||
position.height = UI_JUMP_INTERCEPTOR_DIALOG_HEIGHT;
|
||||
position.width_narrow = UI_JUMP_INTERCEPTOR_DIALOG_WIDTH_NARROW;
|
||||
position.height_narrow = UI_JUMP_INTERCEPTOR_DIALOG_HEIGHT_NARROW;
|
||||
break;
|
||||
default:
|
||||
position.width = UI_DEFAULT_WIDTH;
|
||||
position.height = UI_DEFAULT_HEIGHT;
|
||||
@@ -240,7 +328,7 @@ void SystemDialogScheduler::InitDialogPosition(DialogType type, DialogPosition &
|
||||
void SystemDialogScheduler::DialogPositionAdaptive(DialogPosition &position, int lineNums) const
|
||||
{
|
||||
if (position.wideScreen) {
|
||||
if (lineNums == LINE_NUMS_TWO) {
|
||||
if (lineNums <= LINE_NUMS_TWO) {
|
||||
position.height = UI_SELECTOR_DIALOG_PC_H2;
|
||||
} else if (lineNums == LINE_NUMS_THREE) {
|
||||
position.height = UI_SELECTOR_DIALOG_PC_H3;
|
||||
|
||||
@@ -66,6 +66,7 @@ public:
|
||||
int32_t GetHostUid() const;
|
||||
std::string GetHostBundleName() const;
|
||||
std::string GetRenderParam() const;
|
||||
std::string GetProcessName() const;
|
||||
int32_t GetIpcFd() const;
|
||||
int32_t GetSharedFd() const;
|
||||
int32_t GetCrashFd() const;
|
||||
@@ -79,12 +80,14 @@ public:
|
||||
private:
|
||||
void SetHostUid(const int32_t hostUid);
|
||||
void SetHostBundleName(const std::string &hostBundleName);
|
||||
void SetProcessName(const std::string &hostProcessName);
|
||||
|
||||
pid_t pid_ = 0;
|
||||
pid_t hostPid_ = 0;
|
||||
int32_t hostUid_ = 0;
|
||||
std::string hostBundleName_;
|
||||
std::string renderParam_;
|
||||
std::string processName_;
|
||||
int32_t ipcFd_ = 0;
|
||||
int32_t sharedFd_ = 0;
|
||||
int32_t crashFd_ = 0;
|
||||
|
||||
@@ -56,7 +56,7 @@ std::shared_ptr<RenderRecord> RenderRecord::CreateRenderRecord(
|
||||
hostPid, renderParam, ipcFd, sharedFd, crashFd, host);
|
||||
renderRecord->SetHostUid(host->GetUid());
|
||||
renderRecord->SetHostBundleName(host->GetBundleName());
|
||||
|
||||
renderRecord->SetProcessName(host->GetProcessName());
|
||||
return renderRecord;
|
||||
}
|
||||
|
||||
@@ -95,6 +95,16 @@ std::string RenderRecord::GetHostBundleName() const
|
||||
return hostBundleName_;
|
||||
}
|
||||
|
||||
void RenderRecord::SetProcessName(const std::string &hostProcessName)
|
||||
{
|
||||
processName_ = hostProcessName;
|
||||
}
|
||||
|
||||
std::string RenderRecord::GetProcessName() const
|
||||
{
|
||||
return processName_;
|
||||
}
|
||||
|
||||
std::string RenderRecord::GetRenderParam() const
|
||||
{
|
||||
return renderParam_;
|
||||
@@ -1215,6 +1225,10 @@ std::shared_ptr<UserTestRecord> AppRunningRecord::GetUserTestInfo()
|
||||
|
||||
void AppRunningRecord::SetProcessAndExtensionType(const std::shared_ptr<AbilityInfo> &abilityInfo)
|
||||
{
|
||||
if (abilityInfo == nullptr) {
|
||||
HILOG_ERROR("abilityInfo is nullptr");
|
||||
return;
|
||||
}
|
||||
extensionType_ = abilityInfo->extensionAbilityType;
|
||||
if (extensionType_ == ExtensionAbilityType::UNSPECIFIED) {
|
||||
processType_ = ProcessType::NORMAL;
|
||||
|
||||
@@ -522,7 +522,7 @@ ProcessData AppStateObserverManager::WrapRenderProcessData(const std::shared_ptr
|
||||
processData.bundleName = renderRecord->GetHostBundleName();
|
||||
processData.pid = renderRecord->GetPid();
|
||||
processData.uid = renderRecord->GetHostUid();
|
||||
processData.processName = renderRecord->GetHostRecord()->GetProcessName();
|
||||
processData.processName = renderRecord->GetProcessName();
|
||||
processData.processType = renderRecord->GetProcessType();
|
||||
return processData;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ constexpr const char* PERMISSION_START_ABILIIES_FROM_BACKGROUND = "ohos.permissi
|
||||
constexpr const char* PERMISSION_ABILITY_BACKGROUND_COMMUNICATION = "ohos.permission.ABILITY_BACKGROUND_COMMUNICATION";
|
||||
constexpr const char* PERMISSION_MANAGER_ABILITY_FROM_GATEWAY = "ohos.permission.MANAGER_ABILITY_FROM_GATEWAY";
|
||||
constexpr const char* PERMISSION_PROXY_AUTHORIZATION_URI = "ohos.permission.PROXY_AUTHORIZATION_URI";
|
||||
constexpr const char* PERMISSION_EXEMPT_AS_CALLER = "ohos.permission.EXEMPT_AS_CALLER";
|
||||
constexpr const char* PERMISSION_EXEMPT_AS_TARGET = "ohos.permission.EXEMPT_AS_TARGET";
|
||||
} // namespace PermissionConstants
|
||||
} // namespace AAFwk
|
||||
} // namespace OHOS
|
||||
|
||||
@@ -35,6 +35,8 @@ struct VerificationInfo {
|
||||
PermissionVerification() = default;
|
||||
~PermissionVerification() = default;
|
||||
|
||||
bool VerifyPermissionByTokenId(const int &tokenId, const std::string &permissionName) const;
|
||||
|
||||
bool VerifyCallingPermission(const std::string &permissionName) const;
|
||||
|
||||
bool IsSACall() const;
|
||||
|
||||
@@ -26,6 +26,18 @@ namespace AAFwk {
|
||||
const std::string DLP_PARAMS_INDEX = "ohos.dlp.params.index";
|
||||
const std::string DLP_PARAMS_SECURITY_FLAG = "ohos.dlp.params.securityFlag";
|
||||
const std::string DMS_PROCESS_NAME = "distributedsched";
|
||||
bool PermissionVerification::VerifyPermissionByTokenId(const int &tokenId, const std::string &permissionName) const
|
||||
{
|
||||
HILOG_DEBUG("VerifyPermissionByTokenId permission %{public}s", permissionName.c_str());
|
||||
int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, permissionName);
|
||||
if (ret == Security::AccessToken::PermissionState::PERMISSION_DENIED) {
|
||||
HILOG_ERROR("permission %{public}s: PERMISSION_DENIED", permissionName.c_str());
|
||||
return false;
|
||||
}
|
||||
HILOG_DEBUG("verify AccessToken success");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PermissionVerification::VerifyCallingPermission(const std::string &permissionName) const
|
||||
{
|
||||
HILOG_DEBUG("VerifyCallingPermission permission %{public}s", permissionName.c_str());
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
+105
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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 deviceInfo from '@ohos.deviceInfo';
|
||||
import display from '@ohos.display';
|
||||
import extension from '@ohos.app.ability.ServiceExtensionAbility';
|
||||
import window from '@ohos.window';
|
||||
|
||||
const TAG = "JumpInterceptorDialog_Service";
|
||||
|
||||
var winNum = 1;
|
||||
var win;
|
||||
|
||||
export default class JumpInterceptorServiceExtAbility extends extension {
|
||||
onCreate(want) {
|
||||
console.debug(TAG, "onCreate, want: " + JSON.stringify(want));
|
||||
globalThis.jumpInterceptorExtensionContext = this.context;
|
||||
}
|
||||
|
||||
async onRequest(want, startId) {
|
||||
globalThis.abilityWant = want;
|
||||
globalThis.params = JSON.parse(want["parameters"]["params"]);
|
||||
globalThis.position = JSON.parse(want["parameters"]["position"]);
|
||||
globalThis.interceptor_callerBundleName = want["parameters"]["interceptor_callerBundleName"];
|
||||
globalThis.interceptor_callerModuleName = want["parameters"]["interceptor_callerModuleName"];
|
||||
globalThis.interceptor_callerLabelId = want["parameters"]["interceptor_callerLabelId"];
|
||||
globalThis.interceptor_targetModuleName = want["parameters"]["interceptor_targetModuleName"];
|
||||
globalThis.interceptor_targetLabelId = want["parameters"]["interceptor_targetLabelId"];
|
||||
await this.getHapResource();
|
||||
display.getDefaultDisplay().then(dis => {
|
||||
let navigationBarRect = {
|
||||
left: globalThis.position.offsetX,
|
||||
top: globalThis.position.offsetY,
|
||||
width: globalThis.position.width,
|
||||
height: globalThis.position.height
|
||||
};
|
||||
if (winNum > 1) {
|
||||
win.destroy();
|
||||
winNum--;
|
||||
}
|
||||
if (deviceInfo.deviceType == "phone") {
|
||||
this.createWindow("JumpInterceptorDialog" + startId, window.WindowType.TYPE_SYSTEM_ALERT, navigationBarRect);
|
||||
} else {
|
||||
this.createWindow("JumpInterceptorDialog" + startId, window.WindowType.TYPE_FLOAT, navigationBarRect);
|
||||
}
|
||||
winNum++;
|
||||
});
|
||||
}
|
||||
|
||||
async getHapResource() {
|
||||
console.debug(TAG, "start getHapResource");
|
||||
globalThis.callerAppName = await this.loadAppName(
|
||||
globalThis.interceptor_callerBundleName,
|
||||
globalThis.interceptor_callerModuleName,
|
||||
globalThis.interceptor_callerLabelId
|
||||
);
|
||||
globalThis.targetAppName = await this.loadAppName(
|
||||
globalThis.params.bundleName,
|
||||
globalThis.interceptor_targetModuleName,
|
||||
globalThis.interceptor_targetLabelId
|
||||
);
|
||||
console.debug(TAG, "getHapResource load finished");
|
||||
}
|
||||
|
||||
async loadAppName(bundleName: string, moduleName: string, labelId: number) {
|
||||
let moduleContext = globalThis.jumpInterceptorExtensionContext.createModuleContext(bundleName, moduleName);
|
||||
let appName: string = "";
|
||||
try {
|
||||
appName = await moduleContext.resourceManager.getString(labelId);
|
||||
} catch (error) {
|
||||
console.error(TAG, `getMediaBase64 error:${JSON.stringify(error)}`);
|
||||
}
|
||||
return appName;
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
console.info(TAG, "onDestroy.");
|
||||
}
|
||||
|
||||
private async createWindow(name: string, windowType: number, rect) {
|
||||
console.info(TAG, "create window");
|
||||
try {
|
||||
win = await window.create(globalThis.jumpInterceptorExtensionContext, name, windowType);
|
||||
await win.moveTo(rect.left, rect.top);
|
||||
await win.resetSize(rect.width, rect.height);
|
||||
await win.loadContent('pages/jumpInterceptorDialog');
|
||||
await win.setBackgroundColor("#00000000");
|
||||
await win.show();
|
||||
} catch {
|
||||
console.error(TAG, "window create failed!");
|
||||
}
|
||||
}
|
||||
};
|
||||
+21
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@@ -17,6 +17,8 @@ import extension from '@ohos.app.ability.ServiceExtensionAbility';
|
||||
import window from '@ohos.window';
|
||||
import display from '@ohos.display';
|
||||
import deviceInfo from '@ohos.deviceInfo';
|
||||
import defaultAppManager from '@ohos.bundle.defaultAppManager';
|
||||
import bundleManager from '@ohos.bundle.bundleManager';
|
||||
|
||||
const TAG = "SelectorDialog_Service";
|
||||
|
||||
@@ -27,6 +29,8 @@ export default class SelectorServiceExtensionAbility extends extension {
|
||||
onCreate(want) {
|
||||
console.debug(TAG, "onCreate, want: " + JSON.stringify(want));
|
||||
globalThis.selectExtensionContext = this.context;
|
||||
globalThis.defaultAppManager = defaultAppManager;
|
||||
globalThis.bundleManager = bundleManager;
|
||||
}
|
||||
|
||||
async getPhoneShowHapList() {
|
||||
@@ -62,6 +66,12 @@ export default class SelectorServiceExtensionAbility extends extension {
|
||||
let abilityName = hap.ability;
|
||||
let appName = "";
|
||||
let appIcon = "";
|
||||
let type = "";
|
||||
let userId = Number("0");
|
||||
if (globalThis.params.deviceType == "pc") {
|
||||
type = hap.type;
|
||||
userId = Number(hap.userId);
|
||||
}
|
||||
let lableId = Number(hap.label);
|
||||
let moduleContext = globalThis.selectExtensionContext.createModuleContext(bundleName, moduleName);
|
||||
await moduleContext.resourceManager.getString(lableId).then(value => {
|
||||
@@ -76,7 +86,8 @@ export default class SelectorServiceExtensionAbility extends extension {
|
||||
}).catch(error => {
|
||||
console.error(TAG, "getMediaBase64 error:" + JSON.stringify(error));
|
||||
});
|
||||
showHapList.push(bundleName + "#" + abilityName + "#" + appName + "#" + appIcon + "#" + moduleName);
|
||||
showHapList.push(bundleName + "#" + abilityName + "#" + appName +
|
||||
"#" + appIcon + "#" + moduleName + "#" + type + "#" + userId);
|
||||
}
|
||||
|
||||
async onRequest(want, startId) {
|
||||
@@ -84,10 +95,15 @@ export default class SelectorServiceExtensionAbility extends extension {
|
||||
globalThis.abilityWant = want;
|
||||
globalThis.params = JSON.parse(want["parameters"]["params"]);
|
||||
globalThis.position = JSON.parse(want["parameters"]["position"]);
|
||||
console.debug(TAG, "onRequest, want: " + JSON.stringify(want));
|
||||
console.debug(TAG, "onRequest, params: " + JSON.stringify(globalThis.params));
|
||||
globalThis.callerToken = want["parameters"]["callerToken"];
|
||||
console.debug(TAG, "onRequest, params: " + JSON.stringify(globalThis.params));
|
||||
console.debug(TAG, "onRequest, position: " + JSON.stringify(globalThis.position));
|
||||
|
||||
if (globalThis.params.deviceType == "pc") {
|
||||
globalThis.modelFlag = Boolean(globalThis.params.modelFlag)
|
||||
globalThis.action = Boolean(globalThis.params.action)
|
||||
}
|
||||
if (globalThis.params.deviceType == "phone") {
|
||||
await this.getPhoneShowHapList();
|
||||
} else {
|
||||
@@ -108,6 +124,7 @@ export default class SelectorServiceExtensionAbility extends extension {
|
||||
if (deviceInfo.deviceType == "phone") {
|
||||
this.createWindow("SelectorDialog" + startId, window.WindowType.TYPE_SYSTEM_ALERT, navigationBarRect);
|
||||
} else {
|
||||
console.debug(TAG, "onRequest, params: " + JSON.stringify(globalThis.params));
|
||||
this.createWindow("SelectorDialog" + startId, window.WindowType.TYPE_DIALOG, navigationBarRect);
|
||||
}
|
||||
winNum++;
|
||||
@@ -142,4 +159,4 @@ export default class SelectorServiceExtensionAbility extends extension {
|
||||
console.error(TAG, "window create failed: " + JSON.stringify(e));
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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.
|
||||
*/
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct JumpInterceptorDialog {
|
||||
@State private deviceType: string = "phone";
|
||||
@State private btn: any = { color: "#FFFFFF" }
|
||||
private TAG = "JumpInterceptorDialog_Page"
|
||||
|
||||
aboutToAppear() {
|
||||
console.log(this.TAG, "dialog page appears");
|
||||
this.deviceType = globalThis.params.deviceType
|
||||
if (this.deviceType == "pc") {
|
||||
this.btn.color = "#F2F2F2";
|
||||
}
|
||||
}
|
||||
|
||||
onCloseApp() {
|
||||
globalThis.jumpInterceptorExtensionContext.terminateSelf();
|
||||
}
|
||||
|
||||
onJumpApp() {
|
||||
globalThis.abilityWant.bundleName = globalThis.params.bundleName;
|
||||
globalThis.abilityWant.abilityName = globalThis.params.abilityName;
|
||||
globalThis.abilityWant.moduleName = globalThis.params.moduleName;
|
||||
globalThis.jumpInterceptorExtensionContext.startAbilityAsCaller(globalThis.abilityWant, (data, error) => {
|
||||
if (error) {
|
||||
console.error(this.TAG + "startAbility finish, error: " + JSON.stringify(error));
|
||||
return;
|
||||
}
|
||||
console.log(this.TAG + "startAbility finish, data: " + JSON.stringify(data));
|
||||
globalThis.jumpInterceptorExtensionContext.terminateSelf();
|
||||
});
|
||||
}
|
||||
|
||||
build() {
|
||||
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
Text($r('app.string.message_title_jump_interceptor', globalThis.callerAppName, globalThis.targetAppName))
|
||||
.fontSize(22)
|
||||
.fontWeight(FontWeight.Medium)
|
||||
.height("29%")
|
||||
.textOverflow({overflow: TextOverflow.Ellipsis})
|
||||
.maxLines(2)
|
||||
.textAlign(TextAlign.Center)
|
||||
}
|
||||
Flex({ justifyContent: FlexAlign.Center }) {
|
||||
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
Text($r('app.string.message_cancel_jump'))
|
||||
.fontSize("21fp")
|
||||
.fontColor("#0A59F7")
|
||||
.fontWeight(FontWeight.Regular)
|
||||
.textAlign(TextAlign.Center)
|
||||
}
|
||||
.width(175)
|
||||
.height(50)
|
||||
.borderRadius(28)
|
||||
.backgroundColor(this.btn.color)
|
||||
.onClick(() => {
|
||||
this.onCloseApp();
|
||||
})
|
||||
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
Text($r('app.string.message_confirm_jump'))
|
||||
.fontSize("21fp")
|
||||
.fontColor("#0A59F7")
|
||||
.fontWeight(FontWeight.Regular)
|
||||
.textAlign(TextAlign.Center)
|
||||
}
|
||||
.width(175)
|
||||
.height(50)
|
||||
.borderRadius(28)
|
||||
.backgroundColor(this.btn.color)
|
||||
.onClick(() => {
|
||||
this.onJumpApp();
|
||||
})
|
||||
}.margin({ top: 10})
|
||||
}
|
||||
.borderRadius(20)
|
||||
.borderWidth(1)
|
||||
.borderColor("#e9e9e9")
|
||||
.backgroundColor("#FFFFFF")
|
||||
}
|
||||
}
|
||||
+384
-100
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@@ -31,12 +31,46 @@ interface HapInfo {
|
||||
struct SelectorPcDialog {
|
||||
@State private pcSelectorlist: SelectorPc = { width: "100%", height: "240vp"};
|
||||
@State private hapList: HapInfo[] = [];
|
||||
@State private pcShowMoreHapList: HapInfo[] = [];
|
||||
private TAG = "SelectorDialog_Pc_Page";
|
||||
@State private moreOpenModeVisiable: number = 0;
|
||||
@State private moreOpenModeAreaHigh: number = 54;
|
||||
@State private moreAppsVisiable: number = 2;
|
||||
@State private moreAppsAreaHigh: number = 0;
|
||||
@State private recommendAppsVisiable: number = 0;
|
||||
@State private checkboxVisiable: number = 0;
|
||||
@State private moreHapListVisibility:number = 2;
|
||||
@State private totalHigh: number = 0;
|
||||
@State private isCheckSelected: boolean = false;
|
||||
@State private scrollbarCtrl: number = 0;
|
||||
@State private action: string = "";
|
||||
@State public hapListBackGround: number[] = [0xffffff];
|
||||
@State public hapListPngVisibility: number[] = [];
|
||||
@State public moreHapListBackGround: number[] = [0xffffff];
|
||||
@State public moreHapListPngVisibility: number[] = [];
|
||||
public moreHapListType: string = "reserved/wildcard";
|
||||
private selectItem;
|
||||
|
||||
aboutToAppear(): void {
|
||||
console.log(this.TAG, "dialog page appears");
|
||||
this.hapList = globalThis.params.hapList;
|
||||
this.action = globalThis.params.action;
|
||||
this.getHapListStyle();
|
||||
this.cleanFirstListColorAndVisibility()
|
||||
}
|
||||
|
||||
cleanFirstListColorAndVisibility() {
|
||||
for(let n = 0; n <= globalThis.pcShowHapList.length; n++) {
|
||||
this.hapListBackGround[n] = 0xffffff;
|
||||
this.hapListPngVisibility[n] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
cleanSecondListColorAndVisibility() {
|
||||
for(let n = 0; n <= this.pcShowMoreHapList.length; n++) {
|
||||
this.moreHapListBackGround[n] = 0xffffff;
|
||||
this.moreHapListPngVisibility[n] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
onSelectApp(item) {
|
||||
@@ -49,25 +83,149 @@ struct SelectorPcDialog {
|
||||
return;
|
||||
}
|
||||
console.log(this.TAG + " startAbility finish, data: " + JSON.stringify(data));
|
||||
globalThis.selectExtensionContext.terminateSelf();
|
||||
});
|
||||
let userId = item.split("#")[6];
|
||||
let elementName = {
|
||||
bundleName: globalThis.abilityWant.bundleName,
|
||||
moduleName: globalThis.abilityWant.moduleName,
|
||||
abilityName: globalThis.abilityWant.abilityName,
|
||||
}
|
||||
if (this.isCheckSelected) {
|
||||
console.log(this.TAG + "setDefaultApplication type:" + JSON.stringify(globalThis.abilityWant.type));
|
||||
globalThis.defaultAppManager.setDefaultApplication(globalThis.abilityWant.type, elementName);
|
||||
}
|
||||
globalThis.selectExtensionContext.terminateSelf();
|
||||
}
|
||||
|
||||
getHapListStyle() {
|
||||
let heightTotalVp = 1;
|
||||
let heightVal = 120;
|
||||
if (this.hapList.length == 2) {
|
||||
heightTotalVp = this.hapList.length * heightVal;
|
||||
} else if (this.hapList.length == 3) {
|
||||
heightTotalVp = this.hapList.length * heightVal;
|
||||
} else if (this.hapList.length == 4) {
|
||||
heightTotalVp = this.hapList.length * heightVal;
|
||||
} else if (this.hapList.length > 4) {
|
||||
heightTotalVp = 4 * heightVal + 20;
|
||||
} else {
|
||||
;
|
||||
onClickMoreApp() {
|
||||
try {
|
||||
globalThis.bundleManager.queryAbilityInfo({
|
||||
action: this.action,
|
||||
type : this.moreHapListType,
|
||||
}, 0, (err, data) =>{
|
||||
if (data != undefined) {
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
this.getHapResource(data[i], this.pcShowMoreHapList, i);
|
||||
}
|
||||
this.getMoreHapListStyle()
|
||||
console.debug("pcShowMoreHapList: " + JSON.stringify(this.pcShowMoreHapList));
|
||||
}
|
||||
});
|
||||
} catch { error => {
|
||||
console.error("queryAbilityInfo error:" + JSON.stringify(error));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getHapResource(hap, showHapList, n) {
|
||||
this.moreHapListBackGround[n] = 0xffffff;
|
||||
this.moreHapListPngVisibility[n] = 1
|
||||
let bundleName = hap.bundleName;
|
||||
let moduleName = hap.moduleName;
|
||||
let abilityName = hap.name;
|
||||
let appName = "";
|
||||
let appIcon = "";
|
||||
let lableId = Number(hap.labelId);
|
||||
let type = hap.uri;
|
||||
let userId = Number(hap.userId);
|
||||
let moduleContext = globalThis.selectExtensionContext.createModuleContext(bundleName, moduleName);
|
||||
moduleContext.resourceManager.getString(lableId).then(value => {
|
||||
appName = value;
|
||||
let iconId = Number(hap.iconId);
|
||||
moduleContext.resourceManager.getMediaBase64(iconId).then(value => {
|
||||
appIcon = value;
|
||||
let moreHapList = ""
|
||||
moreHapList = bundleName + abilityName + moduleName
|
||||
if (globalThis.params.hapList.find(item => String(item.bundleName + item.ability + item.moduleName) ==
|
||||
String(moreHapList)) == undefined) {
|
||||
showHapList.push(bundleName + "#" + abilityName + "#" + appName +
|
||||
"#" + appIcon + "#" + moduleName + "#" + type + "#" + userId);
|
||||
this.getMoreHapListStyle()
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error("getMediaBase64 error:" + JSON.stringify(error));
|
||||
});
|
||||
}).catch(error => {
|
||||
console.error("getString error:" + JSON.stringify(error));
|
||||
});
|
||||
}
|
||||
|
||||
getMoreHapListStyle() {
|
||||
let heightTotalVp = 200;
|
||||
let heightVal = 64;
|
||||
let recommendAppAreaHigh = 48;
|
||||
let openModeHigh = 54;
|
||||
let morelist = 0;
|
||||
this.scrollbarCtrl = 2;
|
||||
morelist ++;
|
||||
if (this.hapList.length == 2) {
|
||||
if(morelist == 1) {
|
||||
this.totalHigh = 447;
|
||||
heightTotalVp = 262;
|
||||
}else if(morelist >= 2) {
|
||||
this.totalHigh = 511;
|
||||
heightTotalVp = 326;
|
||||
} else {
|
||||
;
|
||||
}
|
||||
} else if (this.hapList.length == 3) {
|
||||
this.totalHigh = 479;
|
||||
if (morelist >= 1) {
|
||||
this.totalHigh = 511;
|
||||
heightTotalVp = 326;
|
||||
}
|
||||
} else if (this.hapList.length == 4) {
|
||||
this.totalHigh = 543;
|
||||
this.scrollbarCtrl = 0;
|
||||
heightTotalVp = this.hapList.length * heightVal + recommendAppAreaHigh + openModeHigh;
|
||||
if(morelist != 0) {
|
||||
this.scrollbarCtrl = 2;
|
||||
} else {
|
||||
this.scrollbarCtrl = 0;
|
||||
}
|
||||
} else if (this.hapList.length > 4) {
|
||||
this.totalHigh = 543;
|
||||
heightTotalVp = 4 * heightVal + recommendAppAreaHigh + openModeHigh - 32;
|
||||
}
|
||||
this.pcSelectorlist = {
|
||||
width: "100%",
|
||||
height: heightTotalVp + "vp",
|
||||
};
|
||||
}
|
||||
|
||||
getHapListStyle() {
|
||||
let heightTotalVp = 0;
|
||||
let heightVal = 64;
|
||||
let recommendAppAreaHigh = 48;
|
||||
let openModeHigh = 54;
|
||||
let titleAreaHigh = 56;
|
||||
let buttonAreaHigh = 81;
|
||||
if (globalThis.modelFlag == true) {
|
||||
this.recommendAppsVisiable = 2;
|
||||
this.moreOpenModeVisiable = 2;
|
||||
this.checkboxVisiable = 2;
|
||||
heightTotalVp = this.hapList.length * heightVal;
|
||||
this.totalHigh = this.hapList.length * heightVal + titleAreaHigh + buttonAreaHigh;
|
||||
if(this.hapList.length > 6) {
|
||||
heightTotalVp = 6 * heightVal;
|
||||
this.totalHigh = 6 * heightVal + titleAreaHigh + buttonAreaHigh;
|
||||
this.scrollbarCtrl = 2;
|
||||
}
|
||||
}
|
||||
if(globalThis.modelFlag == false) {
|
||||
heightTotalVp = this.hapList.length * heightVal + recommendAppAreaHigh + openModeHigh;
|
||||
if (this.hapList.length == 2) {
|
||||
this.totalHigh = 415;
|
||||
} else if (this.hapList.length == 3) {
|
||||
this.totalHigh = 479;
|
||||
} else if (this.hapList.length == 4) {
|
||||
this.totalHigh = 543;
|
||||
} else if (this.hapList.length > 4) {
|
||||
this.totalHigh = 543;
|
||||
heightTotalVp = 4 * heightVal + recommendAppAreaHigh + openModeHigh - 32;
|
||||
this.scrollbarCtrl = 2;
|
||||
}
|
||||
}
|
||||
this.pcSelectorlist = {
|
||||
width: "100%",
|
||||
height: heightTotalVp + "vp",
|
||||
@@ -75,94 +233,220 @@ struct SelectorPcDialog {
|
||||
}
|
||||
|
||||
build() {
|
||||
Flex({ direction: FlexDirection.Column }) {
|
||||
Flex({ direction: FlexDirection.Column }) {
|
||||
Text($r("app.string.message_title_selector"))
|
||||
.fontSize(22)
|
||||
.fontWeight(FontWeight.Medium)
|
||||
.textAlign(TextAlign.Start)
|
||||
.margin({ top: 25, left: 20 })
|
||||
}
|
||||
.height(120)
|
||||
|
||||
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
List() {
|
||||
ForEach(globalThis.pcShowHapList, (item: any) => {
|
||||
Flex({ direction: FlexDirection.Column , justifyContent: FlexAlign.Center , alignItems: ItemAlign.Center }) {
|
||||
Column() {
|
||||
Text($r("app.string.message_title_pc_selector"))
|
||||
.fontSize(22)
|
||||
.fontWeight(FontWeight.Medium)
|
||||
.textAlign(TextAlign.Start)
|
||||
.margin({ left: 48 })
|
||||
.width(394)
|
||||
.height(56)
|
||||
List() {
|
||||
ListItem() {
|
||||
Flex({ direction: FlexDirection.Row }) {
|
||||
if (item.split("#")[3] != "") {
|
||||
Image(item.split("#")[3])
|
||||
.height(70)
|
||||
.width(70)
|
||||
.alignSelf(ItemAlign.Center)
|
||||
.margin({ left: 16 })
|
||||
} else {
|
||||
Image($r("app.media.app_icon"))
|
||||
.height(70)
|
||||
.width(70)
|
||||
.alignSelf(ItemAlign.Center)
|
||||
.margin({ left: 16 })
|
||||
Text($r("app.string.message_recommendApps_selector"))
|
||||
.fontSize(14)
|
||||
.fontWeight(FontWeight.Medium)
|
||||
.width(394)
|
||||
.height(48)
|
||||
.visibility(this.recommendAppsVisiable)
|
||||
}
|
||||
ForEach(globalThis.pcShowHapList, (item: any, current) => {
|
||||
ListItem() {
|
||||
Flex({ direction: FlexDirection.Row }) {
|
||||
if (item.split("#")[3] != "") {
|
||||
Image(item.split("#")[3])
|
||||
.height(48)
|
||||
.width(48)
|
||||
.alignSelf(ItemAlign.Center)
|
||||
.margin({ left : 16 })
|
||||
.borderRadius(12)
|
||||
} else {
|
||||
Image($r("app.media.app_icon"))
|
||||
.height(48)
|
||||
.width(48)
|
||||
.alignSelf(ItemAlign.Center)
|
||||
.margin({ left : 16 })
|
||||
.borderRadius(12)
|
||||
}
|
||||
if (item.split("#")[2] != "") {
|
||||
Text(item.split("#")[2])
|
||||
.fontSize(16)
|
||||
.width("60%")
|
||||
.height(64)
|
||||
.alignSelf(ItemAlign.Center)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
.margin({ left : 16 })
|
||||
} else {
|
||||
Text(item.split("#")[0])
|
||||
.fontSize(16)
|
||||
.width("60%")
|
||||
.height(64)
|
||||
.alignSelf(ItemAlign.Center)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
.margin({ left : 16 })
|
||||
}
|
||||
Image($r("app.media.selectedMark"))
|
||||
.height(24)
|
||||
.width(24)
|
||||
.alignSelf(ItemAlign.Center)
|
||||
.margin({ right : 16 })
|
||||
.visibility(this.hapListPngVisibility[current])
|
||||
}
|
||||
if (item.split("#")[2] != "") {
|
||||
Text(item.split("#")[2])
|
||||
.fontSize(16)
|
||||
.width("80%")
|
||||
.height(60)
|
||||
.alignSelf(ItemAlign.Center)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
.margin({ left: 16 })
|
||||
} else {
|
||||
Text(item.split("#")[0])
|
||||
.fontSize(16)
|
||||
.width("80%")
|
||||
.height(60)
|
||||
.alignSelf(ItemAlign.Center)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
.margin({ left: 16 })
|
||||
}
|
||||
}.onClick(() => {
|
||||
this.onSelectApp(item)
|
||||
.onClick(() => {
|
||||
this.cleanFirstListColorAndVisibility();
|
||||
this.cleanSecondListColorAndVisibility();
|
||||
this.selectItem = item;
|
||||
this.hapListBackGround[current] = 0x1A0A59F7;
|
||||
this.hapListPngVisibility[current] = 0;
|
||||
})
|
||||
}
|
||||
.backgroundColor(this.hapListBackGround[current])
|
||||
.borderRadius(12)
|
||||
.height(64)
|
||||
.width(346)
|
||||
}, item => item)
|
||||
ListItem() {
|
||||
Button($r("app.string.message_moreOpenMode_selector"),{ type: ButtonType.Capsule })
|
||||
.fontSize(16)
|
||||
.backgroundColor('#ffffffff')
|
||||
.fontWeight(FontWeight.Medium)
|
||||
.width(128)
|
||||
.height(40)
|
||||
.fontColor('#0A59F7')
|
||||
.margin({ right : 218 })
|
||||
.onClick(() => {
|
||||
this.onClickMoreApp()
|
||||
this.moreOpenModeVisiable = 2
|
||||
this.moreOpenModeAreaHigh = 0
|
||||
this.moreHapListVisibility = 0
|
||||
this.moreAppsVisiable = 0
|
||||
this.moreAppsAreaHigh = 48
|
||||
})
|
||||
}.margin({ top: 4, bottom: 4 }).backgroundColor("#ffffff")
|
||||
}, item => item)
|
||||
}
|
||||
.margin({ left: 1, right: 1 })
|
||||
.backgroundColor("#ffffff")
|
||||
.scrollBar(globalThis.pcShowHapList.length > 4 ? BarState.Auto : BarState.Off)
|
||||
.divider({ strokeWidth: 1 })
|
||||
}
|
||||
.visibility(this.moreOpenModeVisiable)
|
||||
.width(346)
|
||||
.height(this.moreOpenModeAreaHigh)
|
||||
ListItem() {
|
||||
Text($r("app.string.message_moreApps_selector"))
|
||||
.fontSize(14)
|
||||
.fontWeight(FontWeight.Medium)
|
||||
.visibility(this.moreAppsVisiable)
|
||||
.margin({ right : 234 })
|
||||
}
|
||||
.width(346)
|
||||
.height(this.moreAppsAreaHigh)
|
||||
ForEach(this.pcShowMoreHapList, (item: any, current) => {
|
||||
ListItem() {
|
||||
Flex({ direction: FlexDirection.Row }) {
|
||||
if (item.split("#")[3] != "") {
|
||||
Image(item.split("#")[3])
|
||||
.height(48)
|
||||
.width(48)
|
||||
.alignSelf(ItemAlign.Center)
|
||||
.margin({ left : 16 })
|
||||
.borderRadius(12)
|
||||
} else {
|
||||
Image($r("app.media.app_icon"))
|
||||
.height(48)
|
||||
.width(48)
|
||||
.alignSelf(ItemAlign.Center)
|
||||
.margin({ left : 16 })
|
||||
.borderRadius(12)
|
||||
}
|
||||
if (item.split("#")[2] != "") {
|
||||
Text(item.split("#")[2])
|
||||
.fontSize(16)
|
||||
.width("60%")
|
||||
.height(64)
|
||||
.alignSelf(ItemAlign.Center)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
.margin({ left : 16 })
|
||||
} else {
|
||||
Text(item.split("#")[0])
|
||||
.fontSize(16)
|
||||
.width("60%")
|
||||
.height(64)
|
||||
.alignSelf(ItemAlign.Center)
|
||||
.height(56)
|
||||
.width(394)
|
||||
}
|
||||
Image($r("app.media.selectedMark"))
|
||||
.height(24)
|
||||
.width(24)
|
||||
.alignSelf(ItemAlign.Center)
|
||||
.margin({ right : 16 })
|
||||
.visibility(this.moreHapListPngVisibility[current])
|
||||
}
|
||||
.onClick(() => {
|
||||
this.cleanFirstListColorAndVisibility();
|
||||
this.cleanSecondListColorAndVisibility();
|
||||
this.selectItem = item;
|
||||
this.moreHapListBackGround[current] = 0x1A0A59F7;
|
||||
this.moreHapListPngVisibility[current] = 0;
|
||||
})
|
||||
}
|
||||
.backgroundColor(this.moreHapListBackGround[current])
|
||||
.borderRadius(12)
|
||||
.height(64)
|
||||
.width(346)
|
||||
.visibility(this.moreHapListVisibility)
|
||||
}, item => item)
|
||||
}
|
||||
.edgeEffect(EdgeEffect.None)
|
||||
.height(this.pcSelectorlist.height)
|
||||
.backgroundColor("#ffffff")
|
||||
.scrollBar(this.scrollbarCtrl)
|
||||
.width(346)
|
||||
Flex({ direction: FlexDirection.Row }) {
|
||||
Checkbox({name: 'checkbox'})
|
||||
.select(this.isCheckSelected)
|
||||
.selectedColor(0x39a2db)
|
||||
.margin({ left : 8 })
|
||||
.onChange((value: boolean) => {
|
||||
this.isCheckSelected = value;
|
||||
})
|
||||
Text($r("app.string.message_openThisWay_selector"))
|
||||
.fontSize(14)
|
||||
.fontColor('#000000')
|
||||
.fontWeight(FontWeight.Regular)
|
||||
}
|
||||
.visibility(this.checkboxVisiable)
|
||||
.height(48)
|
||||
.width(394)
|
||||
Flex({ direction: FlexDirection.Row }) {
|
||||
Button($r("app.string.message_cancel_selector"), { type: ButtonType.Capsule })
|
||||
.backgroundColor('#0d000000')
|
||||
.fontColor('#0A59F7')
|
||||
.fontWeight(FontWeight.Medium)
|
||||
.width(157)
|
||||
.height(40)
|
||||
.fontSize(16)
|
||||
.borderRadius(20)
|
||||
.margin({ top : 16 , left : 16 })
|
||||
.onClick(() => { globalThis.selectExtensionContext.terminateSelf(); })
|
||||
Button($r("app.string.message_sure_selector"), { type: ButtonType.Capsule })
|
||||
.backgroundColor('#0d000000')
|
||||
.fontColor('#0A59F7')
|
||||
.fontWeight(FontWeight.Medium)
|
||||
.width(157)
|
||||
.height(40)
|
||||
.fontSize(16)
|
||||
.borderRadius(20)
|
||||
.margin({ top : 16 , left : 48 })
|
||||
.onClick(() => { this.onSelectApp(this.selectItem) })
|
||||
}
|
||||
}
|
||||
.backgroundColor("#ffffff")
|
||||
.width("90%")
|
||||
.height(this.pcSelectorlist.height)
|
||||
.margin({ bottom: 10 })
|
||||
|
||||
Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
Text($r("app.string.message_cancel_selector"))
|
||||
.fontSize("21fp")
|
||||
.fontColor("#0A59F7")
|
||||
.fontWeight(FontWeight.Regular)
|
||||
.textAlign(TextAlign.Center)
|
||||
}
|
||||
.width("90%")
|
||||
.height(50)
|
||||
.margin({ top: 10 })
|
||||
.borderRadius(28)
|
||||
.backgroundColor("#F2F2F2")
|
||||
}
|
||||
.width("90%")
|
||||
.margin({ left: 15, bottom: 20 })
|
||||
.backgroundColor("#ffffff")
|
||||
.borderRadius(20)
|
||||
.onClick(() => {
|
||||
globalThis.selectExtensionContext.terminateSelf();
|
||||
})
|
||||
.height(this.totalHigh)
|
||||
.align(Alignment.Center)
|
||||
.borderRadius(24)
|
||||
.borderWidth(1)
|
||||
.borderColor('#e9e9e9')
|
||||
.width(394)
|
||||
.backgroundColor('#ffffffff')
|
||||
}
|
||||
.borderRadius(24)
|
||||
.borderWidth(1)
|
||||
.borderColor("#e9e9e9")
|
||||
.backgroundColor("#ffffff")
|
||||
.width("100%")
|
||||
.height("100%")
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.backgroundColor('#00ffffff')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ struct SelectorPhoneDialog {
|
||||
}
|
||||
|
||||
onSelectApp(item) {
|
||||
console.log(this.TAG, "onSelectApp - start ");
|
||||
globalThis.abilityWant.bundleName = item.split("#")[0];
|
||||
globalThis.abilityWant.abilityName = item.split("#")[1];
|
||||
globalThis.abilityWant.moduleName = item.split("#")[4];
|
||||
|
||||
@@ -32,6 +32,15 @@
|
||||
"label":"$string:TipsServiceExtAbility_label",
|
||||
"visible": true,
|
||||
"type": "service"
|
||||
},
|
||||
{
|
||||
"name": "JumpInterceptorDialog",
|
||||
"srcEntrance": "./ets/ServiceExtAbility/JumpInterceptorServiceExtAbility.ts",
|
||||
"description": "$string:JumpInterceptorServiceExtAbility_desc",
|
||||
"icon": "$media:icon",
|
||||
"label":"$string:JumpInterceptorServiceExtAbility_label",
|
||||
"visible": true,
|
||||
"type": "service"
|
||||
}
|
||||
],
|
||||
"metadata": [
|
||||
@@ -46,6 +55,9 @@
|
||||
},
|
||||
{
|
||||
"name": "ohos.permission.START_ABILITIES_FROM_BACKGROUND"
|
||||
},
|
||||
{
|
||||
"name": "ohos.permission.SET_DEFAULT_APPLICATION"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+20
@@ -35,6 +35,26 @@
|
||||
{
|
||||
"name": "message_close_tips",
|
||||
"value": "Got it"
|
||||
},
|
||||
{
|
||||
"name": "message_title_jump_interceptor",
|
||||
"value": "\"%s\" wants to open \"%s\""
|
||||
},
|
||||
{
|
||||
"name": "message_confirm_jump",
|
||||
"value": "Open"
|
||||
},
|
||||
{
|
||||
"name": "message_cancel_jump",
|
||||
"value": "Cancel"
|
||||
},
|
||||
{
|
||||
"name": "JumpInterceptorServiceExtAbility_desc",
|
||||
"value": "JumpInterceptorDialog"
|
||||
},
|
||||
{
|
||||
"name": "JumpInterceptorServiceExtAbility_label",
|
||||
"value": "JumpInterceptorDialog"
|
||||
}
|
||||
]
|
||||
}
|
||||
+2
-1
@@ -2,6 +2,7 @@
|
||||
"src": [
|
||||
"pages/selectorPhoneDialog",
|
||||
"pages/selectorPcDialog",
|
||||
"pages/tipsDialog"
|
||||
"pages/tipsDialog",
|
||||
"pages/jumpInterceptorDialog"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
"name": "message_title_selector",
|
||||
"value": "使用以下方式打开"
|
||||
},
|
||||
{
|
||||
"name": "message_title_pc_selector",
|
||||
"value": "选择打开方式"
|
||||
},
|
||||
{
|
||||
"name": "message_cancel_selector",
|
||||
"value": "取消"
|
||||
@@ -35,6 +39,46 @@
|
||||
{
|
||||
"name": "message_close_tips",
|
||||
"value": "知道了"
|
||||
},
|
||||
{
|
||||
"name": "message_title_jump_interceptor",
|
||||
"value": "“%s”想要打开“%s”"
|
||||
},
|
||||
{
|
||||
"name": "message_confirm_jump",
|
||||
"value": "打开"
|
||||
},
|
||||
{
|
||||
"name": "message_cancel_jump",
|
||||
"value": "取消"
|
||||
},
|
||||
{
|
||||
"name": "JumpInterceptorServiceExtAbility_desc",
|
||||
"value": "JumpInterceptorDialog"
|
||||
},
|
||||
{
|
||||
"name": "JumpInterceptorServiceExtAbility_label",
|
||||
"value": "JumpInterceptorDialog"
|
||||
},
|
||||
{
|
||||
"name": "message_recommendApps_selector",
|
||||
"value": "推荐的应用"
|
||||
},
|
||||
{
|
||||
"name": "message_openThisWay_selector",
|
||||
"value": "始终用此方式打开"
|
||||
},
|
||||
{
|
||||
"name": "message_sure_selector",
|
||||
"value": "确定"
|
||||
},
|
||||
{
|
||||
"name": "message_moreOpenMode_selector",
|
||||
"value": "更多打开方式"
|
||||
},
|
||||
{
|
||||
"name": "message_moreApps_selector",
|
||||
"value": "更多的应用"
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
+10
-1
@@ -19,7 +19,6 @@
|
||||
#include "want.h"
|
||||
#include <gmock/gmock.h>
|
||||
#include "foundation/bundlemanager/bundle_framework/interfaces/inner_api/appexecfwk_core/include/app_control/app_control_interface.h"
|
||||
#include "app_running_control_rule_result.h"
|
||||
#include "iremote_proxy.h"
|
||||
|
||||
namespace OHOS {
|
||||
@@ -50,6 +49,16 @@ public:
|
||||
virtual ErrCode GetAppRunningControlRule(
|
||||
const std::string& bundleName, int32_t userId, AppRunningControlRuleResult& controlRuleResult) override;
|
||||
|
||||
virtual ErrCode ConfirmAppJumpControlRule(const std::string &callerBundleName, const std::string &targetBundleName,
|
||||
int32_t userId) override;
|
||||
virtual ErrCode AddAppJumpControlRule(const std::vector<AppJumpControlRule> &controlRules, int32_t userId) override;
|
||||
virtual ErrCode DeleteAppJumpControlRule(const std::vector<AppJumpControlRule> &controlRules,
|
||||
int32_t userId) override;
|
||||
virtual ErrCode DeleteRuleByCallerBundleName(const std::string &callerBundleName, int32_t userId) override;
|
||||
virtual ErrCode DeleteRuleByTargetBundleName(const std::string &targetBundleName, int32_t userId) override;
|
||||
virtual ErrCode GetAppJumpControlRule(const std::string &callerBundleName, const std::string &targetBundleName,
|
||||
int32_t userId, AppJumpControlRule &controlRule) override;
|
||||
|
||||
virtual ErrCode SetDisposedStatus(const std::string& appId, const Want& want) override;
|
||||
virtual ErrCode DeleteDisposedStatus(const std::string& appId) override;
|
||||
virtual ErrCode GetDisposedStatus(const std::string& appId, Want& want) override;
|
||||
|
||||
+32
@@ -90,6 +90,38 @@ ErrCode AppControlProxy::GetAppRunningControlRule(
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
ErrCode AppControlProxy::ConfirmAppJumpControlRule(const std::string &callerBundleName,
|
||||
const std::string &targetBundleName, int32_t userId)
|
||||
{
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
ErrCode AppControlProxy::AddAppJumpControlRule(const std::vector<AppJumpControlRule> &controlRules, int32_t userId)
|
||||
{
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
ErrCode AppControlProxy::DeleteAppJumpControlRule(const std::vector<AppJumpControlRule> &controlRules, int32_t userId)
|
||||
{
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
ErrCode AppControlProxy::DeleteRuleByCallerBundleName(const std::string &callerBundleName, int32_t userId)
|
||||
{
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
ErrCode AppControlProxy::DeleteRuleByTargetBundleName(const std::string &targetBundleName, int32_t userId)
|
||||
{
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
ErrCode AppControlProxy::GetAppJumpControlRule(const std::string &callerBundleName,
|
||||
const std::string &targetBundleName, int32_t userId, AppJumpControlRule &controlRule)
|
||||
{
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
ErrCode AppControlProxy::SetDisposedStatus(const std::string& appId, const Want& want)
|
||||
{
|
||||
return ERR_OK;
|
||||
|
||||
@@ -360,7 +360,6 @@ group("unittest") {
|
||||
"frameworks_kits_ability_ability_runtime_test:unittest",
|
||||
"frameworks_kits_ability_native_test:unittest",
|
||||
"frameworks_kits_appkit_native_test:unittest",
|
||||
"frameworks_kits_runtime_native_test:unittest",
|
||||
"free_install_manager_test:unittest",
|
||||
"image_info_test:unittest",
|
||||
"implicit_start_processor_test:unittest",
|
||||
|
||||
+70
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@@ -374,6 +374,75 @@ HWTEST_F(LocalCallContainerTest, Local_Call_Container_OnAbilityConnectDone_0300,
|
||||
EXPECT_EQ(callback->isCallBack_, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: Local_Call_Container_OnRemoteStateChanged_0100
|
||||
* @tc.name: OnRemoteStateChanged
|
||||
* @tc.desc: Local Call Container to process OnRemoteStateChanged, and the result is success resultCode == ERR_OK.
|
||||
*/
|
||||
HWTEST_F(LocalCallContainerTest, Local_Call_Container_OnRemoteStateChanged_0100, Function | MediumTest | Level1)
|
||||
{
|
||||
LocalCallContainer localCallContainer;
|
||||
|
||||
std::shared_ptr<CallerCallBack> callback = std::make_shared<CallerCallBack>();
|
||||
callback->SetCallBack([](const sptr<IRemoteObject>&) {});
|
||||
AppExecFwk::ElementName elementName("DemoDeviceId", "DemoBundleName", "DemoAbilityName");
|
||||
std::shared_ptr<LocalCallRecord> localCallRecord = std::make_shared<LocalCallRecord>(elementName);
|
||||
localCallRecord->AddCaller(callback);
|
||||
localCallRecord->callers_.emplace_back(callback);
|
||||
|
||||
std::string uri = elementName.GetURI();
|
||||
localCallContainer.callProxyRecords_.emplace(uri, localCallRecord);
|
||||
OHOS::sptr<OHOS::IRemoteObject> remoteObject = new (std::nothrow) MockServiceAbilityManagerService();
|
||||
localCallContainer.OnAbilityConnectDone(elementName, remoteObject, 0);
|
||||
|
||||
localCallContainer.OnRemoteStateChanged(elementName, 0);
|
||||
EXPECT_EQ(callback->isCallBack_, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: Local_Call_Container_OnRemoteStateChanged_0200
|
||||
* @tc.name: OnRemoteStateChanged
|
||||
* @tc.desc: Local Call Container to process OnRemoteStateChanged success when resultCode != ERR_OK.
|
||||
*/
|
||||
HWTEST_F(LocalCallContainerTest, Local_Call_Container_OnRemoteStateChanged_0200, Function | MediumTest | Level1)
|
||||
{
|
||||
LocalCallContainer localCallContainer;
|
||||
|
||||
std::shared_ptr<CallerCallBack> callback = std::make_shared<CallerCallBack>();
|
||||
callback->SetCallBack([](const sptr<IRemoteObject>&) {});
|
||||
AppExecFwk::ElementName elementName("DemoDeviceId", "DemoBundleName", "DemoAbilityName");
|
||||
std::shared_ptr<LocalCallRecord> localCallRecord = std::make_shared<LocalCallRecord>(elementName);
|
||||
localCallRecord->AddCaller(callback);
|
||||
localCallRecord->callers_.emplace_back(callback);
|
||||
|
||||
std::string uri = elementName.GetURI();
|
||||
localCallContainer.callProxyRecords_.emplace(uri, localCallRecord);
|
||||
OHOS::sptr<OHOS::IRemoteObject> remoteObject = new (std::nothrow) MockServiceAbilityManagerService();
|
||||
localCallContainer.OnAbilityConnectDone(elementName, remoteObject, 0);
|
||||
|
||||
localCallContainer.OnRemoteStateChanged(elementName, -1);
|
||||
EXPECT_EQ(callback->isCallBack_, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: Local_Call_Container_OnRemoteStateChanged_0300
|
||||
* @tc.name: OnRemoteStateChanged
|
||||
* @tc.desc: Local Call Container to process OnRemoteStateChanged fail because localCallRecord is null.
|
||||
*/
|
||||
HWTEST_F(LocalCallContainerTest, Local_Call_Container_OnRemoteStateChanged_0300, Function | MediumTest | Level1)
|
||||
{
|
||||
LocalCallContainer localCallContainer;
|
||||
|
||||
std::shared_ptr<CallerCallBack> callback = std::make_shared<CallerCallBack>();
|
||||
EXPECT_EQ(callback->isCallBack_, false);
|
||||
AppExecFwk::ElementName elementName("DemoDeviceId", "DemoBundleName", "DemoAbilityName");
|
||||
std::shared_ptr<LocalCallRecord> localCallRecord = std::make_shared<LocalCallRecord>(elementName);
|
||||
localCallRecord->AddCaller(callback);
|
||||
|
||||
localCallContainer.OnRemoteStateChanged(elementName, 0);
|
||||
EXPECT_EQ(callback->isCallBack_, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: Local_Call_Container_GetCallLocalRecord_0100
|
||||
* @tc.name: GetCallLocalRecord
|
||||
|
||||
+74
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@@ -29,6 +29,8 @@ using namespace testing::ext;
|
||||
using namespace OHOS::AbilityRuntime;
|
||||
|
||||
namespace {
|
||||
constexpr int32_t FOREGROUND = 2;
|
||||
constexpr int32_t BACKGROUND = 4;
|
||||
}
|
||||
|
||||
class LocalCallRecordTest : public testing::Test {
|
||||
@@ -273,6 +275,77 @@ HWTEST_F(LocalCallRecordTest, Local_Call_Record_InvokeCallBack_0400, Function |
|
||||
EXPECT_TRUE(callback->IsCallBack() == false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: Local_Call_Record_NotifyRemoteStateChanged_0100
|
||||
* @tc.name: NotifyRemoteStateChanged
|
||||
* @tc.desc: LocalCallRecord to process NotifyRemoteStateChanged success.
|
||||
*/
|
||||
HWTEST_F(LocalCallRecordTest, Local_Call_Record_NotifyRemoteStateChanged_0100, Function | MediumTest | Level1)
|
||||
{
|
||||
AppExecFwk::ElementName elementName("DemoDeviceId", "DemoBundleName", "DemoAbilityName");
|
||||
LocalCallRecord localCallRecord(elementName);
|
||||
localCallRecord.remoteObject_ = new (std::nothrow) MockServiceAbilityManagerService();
|
||||
std::shared_ptr<CallerCallBack> callback = std::make_shared<CallerCallBack>();
|
||||
callback->SetCallBack([](const sptr<IRemoteObject>&) {});
|
||||
EXPECT_TRUE(callback->IsCallBack() == false);
|
||||
localCallRecord.callers_.emplace_back(callback);
|
||||
localCallRecord.InvokeCallBack();
|
||||
int32_t abilityState = FOREGROUND;
|
||||
localCallRecord.NotifyRemoteStateChanged(abilityState);
|
||||
EXPECT_TRUE(callback->IsCallBack() == true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: Local_Call_Record_NotifyRemoteStateChanged_0200
|
||||
* @tc.name: NotifyRemoteStateChanged
|
||||
* @tc.desc: LocalCallRecord to process NotifyRemoteStateChanged fail because remote is null.
|
||||
*/
|
||||
HWTEST_F(LocalCallRecordTest, Local_Call_Record_NotifyRemoteStateChanged_0200, Function | MediumTest | Level1)
|
||||
{
|
||||
AppExecFwk::ElementName elementName("DemoDeviceId", "DemoBundleName", "DemoAbilityName");
|
||||
LocalCallRecord localCallRecord(elementName);
|
||||
std::shared_ptr<CallerCallBack> callback = std::make_shared<CallerCallBack>();
|
||||
EXPECT_TRUE(callback->IsCallBack() == false);
|
||||
int32_t abilityState = FOREGROUND;
|
||||
localCallRecord.NotifyRemoteStateChanged(abilityState);
|
||||
EXPECT_TRUE(callback->IsCallBack() == false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: Local_Call_Record_NotifyRemoteStateChanged_0300
|
||||
* @tc.name: NotifyRemoteStateChanged
|
||||
* @tc.desc: LocalCallRecord to process NotifyRemoteStateChanged fail because callers_ is empty.
|
||||
*/
|
||||
HWTEST_F(LocalCallRecordTest, Local_Call_Record_NotifyRemoteStateChanged_0300, Function | MediumTest | Level1)
|
||||
{
|
||||
AppExecFwk::ElementName elementName("DemoDeviceId", "DemoBundleName", "DemoAbilityName");
|
||||
LocalCallRecord localCallRecord(elementName);
|
||||
localCallRecord.remoteObject_ = new (std::nothrow) MockServiceAbilityManagerService();
|
||||
std::shared_ptr<CallerCallBack> callback = std::make_shared<CallerCallBack>();
|
||||
EXPECT_TRUE(callback->IsCallBack() == false);
|
||||
int32_t abilityState = BACKGROUND;
|
||||
localCallRecord.NotifyRemoteStateChanged(abilityState);
|
||||
EXPECT_TRUE(callback->IsCallBack() == false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: Local_Call_Record_NotifyRemoteStateChanged_0400
|
||||
* @tc.name: NotifyRemoteStateChanged
|
||||
* @tc.desc: LocalCallRecord to process NotifyRemoteStateChanged fail because call back is null.
|
||||
*/
|
||||
HWTEST_F(LocalCallRecordTest, Local_Call_Record_NotifyRemoteStateChanged_0400, Function | MediumTest | Level1)
|
||||
{
|
||||
AppExecFwk::ElementName elementName("DemoDeviceId", "DemoBundleName", "DemoAbilityName");
|
||||
LocalCallRecord localCallRecord(elementName);
|
||||
localCallRecord.remoteObject_ = new (std::nothrow) MockServiceAbilityManagerService();
|
||||
std::shared_ptr<CallerCallBack> callback = std::make_shared<CallerCallBack>();
|
||||
EXPECT_TRUE(callback->IsCallBack() == false);
|
||||
localCallRecord.callers_.emplace_back(nullptr);
|
||||
int32_t abilityState = 0;
|
||||
localCallRecord.NotifyRemoteStateChanged(abilityState);
|
||||
EXPECT_TRUE(callback->IsCallBack() == false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: Local_Call_Record_GetRemoteObject_0100
|
||||
* @tc.name: GetRemoteObject
|
||||
|
||||
@@ -1,431 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 <gtest/gtest.h>
|
||||
|
||||
#define private public
|
||||
#define protected public
|
||||
#include "source_map.h"
|
||||
#undef private
|
||||
#undef protected
|
||||
|
||||
namespace OHOS {
|
||||
namespace AppExecFwk {
|
||||
using namespace testing::ext;
|
||||
using namespace OHOS;
|
||||
using namespace OHOS::AppExecFwk;
|
||||
using namespace OHOS::AbilityRuntime;
|
||||
|
||||
class SourceMapTest : public testing::Test {
|
||||
public:
|
||||
static void SetUpTestCase(void);
|
||||
static void TearDownTestCase(void);
|
||||
void SetUp();
|
||||
void TearDown();
|
||||
};
|
||||
|
||||
void SourceMapTest::SetUpTestCase(void)
|
||||
{
|
||||
}
|
||||
|
||||
void SourceMapTest::TearDownTestCase(void)
|
||||
{
|
||||
}
|
||||
|
||||
void SourceMapTest::SetUp(void)
|
||||
{
|
||||
}
|
||||
|
||||
void SourceMapTest::TearDown(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AaFwk_SourceMap_0100
|
||||
* @tc.name: Base64CharToInt
|
||||
* @tc.desc: Verify int values from A to Z.
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, AaFwk_SourceMap_0100, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_0100 start";
|
||||
auto modSourceMap = std::make_shared<AbilityRuntime::ModSourceMap>();
|
||||
char charCode = 'A';
|
||||
uint32_t value = modSourceMap->Base64CharToInt(charCode);
|
||||
EXPECT_EQ(static_cast<int32_t>(value), 0);
|
||||
|
||||
charCode = 'Z';
|
||||
value = modSourceMap->Base64CharToInt(charCode);
|
||||
EXPECT_EQ(static_cast<int32_t>(value), 25);
|
||||
|
||||
charCode = 'C';
|
||||
value = modSourceMap->Base64CharToInt(charCode);
|
||||
EXPECT_EQ(static_cast<int32_t>(value), 2);
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_0100 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AaFwk_SourceMap_0200
|
||||
* @tc.name: Base64CharToInt
|
||||
* @tc.desc: Verify int values from a to z.
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, AaFwk_SourceMap_0200, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_0200 start";
|
||||
auto modSourceMap = std::make_shared<AbilityRuntime::ModSourceMap>();
|
||||
char charCode = 'a';
|
||||
uint32_t value = modSourceMap->Base64CharToInt(charCode);
|
||||
EXPECT_EQ(static_cast<int32_t>(value), 26);
|
||||
|
||||
charCode = 'z';
|
||||
value = modSourceMap->Base64CharToInt(charCode);
|
||||
EXPECT_EQ(static_cast<int32_t>(value), 51);
|
||||
|
||||
charCode = 'c';
|
||||
value = modSourceMap->Base64CharToInt(charCode);
|
||||
EXPECT_EQ(static_cast<int32_t>(value), 28);
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_0200 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AaFwk_SourceMap_0300
|
||||
* @tc.name: Base64CharToInt
|
||||
* @tc.desc: Verify int values from 0 to 9.
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, AaFwk_SourceMap_0300, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_0300 start";
|
||||
auto modSourceMap = std::make_shared<AbilityRuntime::ModSourceMap>();
|
||||
char charCode = '0';
|
||||
uint32_t value = modSourceMap->Base64CharToInt(charCode);
|
||||
EXPECT_EQ(static_cast<int32_t>(value), 52);
|
||||
|
||||
charCode = '9';
|
||||
value = modSourceMap->Base64CharToInt(charCode);
|
||||
EXPECT_EQ(static_cast<int32_t>(value), 61);
|
||||
|
||||
charCode = '2';
|
||||
value = modSourceMap->Base64CharToInt(charCode);
|
||||
EXPECT_EQ(static_cast<int32_t>(value), 54);
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_0300 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AaFwk_SourceMap_0400
|
||||
* @tc.name: Base64CharToInt
|
||||
* @tc.desc: Verify int values for + and / or other symbols.
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, AaFwk_SourceMap_0400, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_0400 start";
|
||||
auto modSourceMap = std::make_shared<AbilityRuntime::ModSourceMap>();
|
||||
char charCode = '+';
|
||||
uint32_t value = modSourceMap->Base64CharToInt(charCode);
|
||||
EXPECT_EQ(static_cast<int32_t>(value), 62);
|
||||
|
||||
charCode = '/';
|
||||
value = modSourceMap->Base64CharToInt(charCode);
|
||||
EXPECT_EQ(static_cast<int32_t>(value), 63);
|
||||
|
||||
charCode = '&';
|
||||
value = modSourceMap->Base64CharToInt(charCode);
|
||||
EXPECT_EQ(static_cast<int32_t>(value), 64);
|
||||
|
||||
charCode = '@';
|
||||
value = modSourceMap->Base64CharToInt(charCode);
|
||||
EXPECT_EQ(static_cast<int32_t>(value), 64);
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_0400 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AaFwk_SourceMap_0500
|
||||
* @tc.name: GetErrorPos
|
||||
* @tc.desc: Verifying GetErrorPos succeeded.
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, AaFwk_SourceMap_0500, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_0500 start";
|
||||
auto modSourceMap = std::make_shared<AbilityRuntime::ModSourceMap>();
|
||||
std::string rawStack = "at AssertException (/mnt/assets/ets/TestAbility/TestAbility_.js:5779:5)\n";
|
||||
auto pos = modSourceMap->GetErrorPos(rawStack);
|
||||
EXPECT_EQ(pos.first, 5779);
|
||||
EXPECT_EQ(pos.second, 5);
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_0500 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AaFwk_SourceMap_0600
|
||||
* @tc.name: GetErrorPos
|
||||
* @tc.desc: Verifying GetErrorPos succeeded.
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, AaFwk_SourceMap_0600, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_0600 start";
|
||||
auto modSourceMap = std::make_shared<AbilityRuntime::ModSourceMap>();
|
||||
std::string rawStack = "\n";
|
||||
auto pos = modSourceMap->GetErrorPos(rawStack);
|
||||
EXPECT_EQ(pos.first, 0);
|
||||
EXPECT_EQ(pos.second, 0);
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_0600 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AaFwk_SourceMap_0700
|
||||
* @tc.name: GetErrorPos
|
||||
* @tc.desc: Verifying GetErrorPos succeeded.
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, AaFwk_SourceMap_0700, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_0700 start";
|
||||
auto modSourceMap = std::make_shared<AbilityRuntime::ModSourceMap>();
|
||||
std::string rawStack = "?\n";
|
||||
auto pos = modSourceMap->GetErrorPos(rawStack);
|
||||
EXPECT_EQ(pos.first, 0);
|
||||
EXPECT_EQ(pos.second, 0);
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_0700 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AaFwk_SourceMap_0800
|
||||
* @tc.name: ReadSourceMapData
|
||||
* @tc.desc: Verifying ReadSourceMapData Failed.
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, AaFwk_SourceMap_0800, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_0800 start";
|
||||
auto modSourceMap = std::make_shared<AbilityRuntime::ModSourceMap>();
|
||||
std::string filePath = "./source_map_test";
|
||||
std::string context;
|
||||
EXPECT_FALSE(modSourceMap->ReadSourceMapData(filePath, context));
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_0800 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AaFwk_SourceMap_0900
|
||||
* @tc.name: ReadSourceMapData
|
||||
* @tc.desc: Verifying ReadSourceMapData succeeded.
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, AaFwk_SourceMap_0900, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_0900 start";
|
||||
auto modSourceMap = std::make_shared<AbilityRuntime::ModSourceMap>();
|
||||
std::string filePath = "./abc.map";
|
||||
std::string context;
|
||||
modSourceMap->ReadSourceMapData(filePath, context);
|
||||
EXPECT_TRUE(context.empty());
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_0900 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AaFwk_SourceMap_1000
|
||||
* @tc.name: Find
|
||||
* @tc.desc: Verifying Find succeeded.
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, AaFwk_SourceMap_1000, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_1000 start";
|
||||
auto modSourceMap = std::make_shared<AbilityRuntime::ModSourceMap>();
|
||||
int32_t row = 0;
|
||||
int32_t col = 1;
|
||||
SourceMapData targetMap;
|
||||
std::string key = "";
|
||||
auto info = modSourceMap->Find(row, col, targetMap, key);
|
||||
EXPECT_TRUE(info.sources.empty());
|
||||
|
||||
row = 1;
|
||||
col = 0;
|
||||
info = modSourceMap->Find(row, col, targetMap, key);
|
||||
EXPECT_TRUE(info.sources.empty());
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_1000 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AaFwk_SourceMap_1100
|
||||
* @tc.name: Find
|
||||
* @tc.desc: Verifying Find succeeded.
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, AaFwk_SourceMap_1100, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_1100 start";
|
||||
auto modSourceMap = std::make_shared<AbilityRuntime::ModSourceMap>();
|
||||
int32_t row = 0;
|
||||
int32_t col = 1;
|
||||
SourceMapData targetMap;
|
||||
std::string key = "";
|
||||
auto info = modSourceMap->Find(row, col, targetMap, key);
|
||||
EXPECT_TRUE(info.sources.empty());
|
||||
|
||||
row = 1;
|
||||
col = 0;
|
||||
info = modSourceMap->Find(row, col, targetMap, key);
|
||||
EXPECT_TRUE(info.sources.empty());
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_1100 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AaFwk_SourceMap_1200
|
||||
* @tc.name: Find
|
||||
* @tc.desc: Verifying Find succeeded.
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, AaFwk_SourceMap_1200, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_1200 start";
|
||||
auto modSourceMap = std::make_shared<AbilityRuntime::ModSourceMap>();
|
||||
int32_t row = 3;
|
||||
int32_t col = 3;
|
||||
SourceMapData targetMap;
|
||||
targetMap.files_.emplace_back("file");
|
||||
|
||||
SourceMapInfo mapInfo;
|
||||
mapInfo.beforeRow = 0;
|
||||
mapInfo.beforeColumn = 0;
|
||||
mapInfo.afterRow = 1;
|
||||
mapInfo.afterColumn = 0;
|
||||
mapInfo.sourcesVal = 0;
|
||||
mapInfo.namesVal = 0;
|
||||
targetMap.afterPos_.emplace_back(mapInfo);
|
||||
std::string key = "";
|
||||
auto info = modSourceMap->Find(row, col, targetMap, key);
|
||||
EXPECT_STREQ(info.sources.c_str(), "file");
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_1200 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AaFwk_SourceMap_1300
|
||||
* @tc.name: Find
|
||||
* @tc.desc: Verify binary search.
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, AaFwk_SourceMap_1300, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_1300 start";
|
||||
auto modSourceMap = std::make_shared<AbilityRuntime::ModSourceMap>();
|
||||
int32_t row = 3;
|
||||
int32_t col = 3;
|
||||
SourceMapData targetMap;
|
||||
targetMap.files_.emplace_back("file");
|
||||
|
||||
for (int32_t i = 0; i < 10; i++) {
|
||||
for (int32_t j = 0; j < 5; j++) {
|
||||
SourceMapInfo mapInfo;
|
||||
mapInfo.beforeRow = 0;
|
||||
mapInfo.beforeColumn = 0;
|
||||
mapInfo.afterRow = i;
|
||||
mapInfo.afterColumn = j;
|
||||
targetMap.afterPos_.emplace_back(mapInfo);
|
||||
}
|
||||
}
|
||||
|
||||
std::string key = "";
|
||||
auto info = modSourceMap->Find(row, col, targetMap, key);
|
||||
EXPECT_EQ(info.row, 1);
|
||||
EXPECT_EQ(info.col, 1);
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_1300 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AaFwk_SourceMap_1400
|
||||
* @tc.name: Find
|
||||
* @tc.desc: Verify binary search.
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, AaFwk_SourceMap_1400, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_1400 start";
|
||||
auto modSourceMap = std::make_shared<AbilityRuntime::ModSourceMap>();
|
||||
int32_t row = 7;
|
||||
int32_t col = 1;
|
||||
SourceMapData targetMap;
|
||||
targetMap.files_.emplace_back("file");
|
||||
|
||||
for (int32_t i = 0; i < 10; i++) {
|
||||
SourceMapInfo mapInfo;
|
||||
mapInfo.beforeRow = 0;
|
||||
mapInfo.beforeColumn = 0;
|
||||
mapInfo.afterRow = i;
|
||||
mapInfo.afterColumn = 1;
|
||||
targetMap.afterPos_.emplace_back(mapInfo);
|
||||
}
|
||||
|
||||
std::string key = "aaawebpack:///bbb";
|
||||
auto info = modSourceMap->Find(row, col, targetMap, key);
|
||||
EXPECT_EQ(info.row, 1);
|
||||
EXPECT_EQ(info.col, 1);
|
||||
EXPECT_STREQ(info.sources.c_str(), "aaabbb");
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_1400 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AaFwk_SourceMap_1500
|
||||
* @tc.name: GetPosInfo
|
||||
* @tc.desc: Verifying GetPosInfo succeeded.
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, AaFwk_SourceMap_1500, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_1500 start";
|
||||
auto modSourceMap = std::make_shared<AbilityRuntime::ModSourceMap>();
|
||||
|
||||
std::string temp = "TestAbility.js:5779:5";
|
||||
int32_t start = 22;
|
||||
std::string line;
|
||||
std::string column;
|
||||
modSourceMap->GetPosInfo(temp, start, line, column);
|
||||
EXPECT_STREQ(line.c_str(), "5779");
|
||||
EXPECT_STREQ(column.c_str(), "5");
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_1500 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AaFwk_SourceMap_1600
|
||||
* @tc.name: StringToInt
|
||||
* @tc.desc: Verifying StringToInt succeeded.
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, AaFwk_SourceMap_1600, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_1600 start";
|
||||
auto modSourceMap = std::make_shared<AbilityRuntime::ModSourceMap>();
|
||||
|
||||
std::string value = "2030300 This is test";
|
||||
auto res = modSourceMap->StringToInt(value);
|
||||
EXPECT_EQ(res, 2030300);
|
||||
|
||||
value = "2147483648 This is test";
|
||||
res = modSourceMap->StringToInt(value);
|
||||
EXPECT_EQ(res, 0);
|
||||
|
||||
value = "";
|
||||
res = modSourceMap->StringToInt(value);
|
||||
EXPECT_EQ(res, 0);
|
||||
|
||||
value = "-2147483649 This is test";
|
||||
res = modSourceMap->StringToInt(value);
|
||||
EXPECT_EQ(res, 0);
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_1600 end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: AaFwk_SourceMap_1700
|
||||
* @tc.name: GetRelativePath
|
||||
* @tc.desc: Verifying GetRelativePath succeeded.
|
||||
*/
|
||||
HWTEST_F(SourceMapTest, AaFwk_SourceMap_1700, Function | MediumTest | Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_1700 start";
|
||||
auto modSourceMap = std::make_shared<AbilityRuntime::ModSourceMap>();
|
||||
|
||||
std::string sources = "TEST:/data/app/MainAbility.js";
|
||||
auto res = modSourceMap->GetRelativePath(sources);
|
||||
EXPECT_STREQ(res.c_str(), "/data/app/MainAbility.js");
|
||||
GTEST_LOG_(INFO) << "AaFwk_SourceMap_1700 end";
|
||||
}
|
||||
} // namespace AppExecFwk
|
||||
} // namespace OHOS
|
||||
@@ -376,28 +376,6 @@ HWTEST_F(JsRuntimeTest, JsRuntimeLoadSystemModuleTest_0100, TestSize.Level0)
|
||||
HILOG_INFO("LoadSystemModule end");
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: JsRuntimeGetSourceMapTest_0100
|
||||
* @tc.desc: JsRuntime test for GetSourceMap.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(JsRuntimeTest, JsRuntimeGetSourceMapTest_0100, TestSize.Level0)
|
||||
{
|
||||
HILOG_INFO("GetSourceMap start");
|
||||
|
||||
std::unique_ptr<JsRuntime> jsRuntime = std::make_unique<MockJsRuntime>();
|
||||
EXPECT_TRUE(jsRuntime != nullptr);
|
||||
|
||||
options_.bundleCodeDir = TEST_CODE_PATH;
|
||||
options_.isStageModel = true;
|
||||
jsRuntime->bindSourceMaps_ = std::make_unique<ModSourceMap>(options_.bundleCodeDir, options_.isStageModel);
|
||||
|
||||
auto& sourceMap = jsRuntime->GetSourceMap();
|
||||
EXPECT_NE(&sourceMap, nullptr);
|
||||
|
||||
HILOG_INFO("GetSourceMap end");
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: JsRuntimePostTaskTest_0100
|
||||
* @tc.desc: JsRuntime test for PostTask.
|
||||
|
||||
Reference in New Issue
Block a user