Signed-off-by: chenyuyan <chenyuyan3@huawei.com>
Change-Id: I25ada8e039aff171148e86911067da6e1c0b4101
This commit is contained in:
chenyuyan
2023-04-10 16:43:41 +08:00
63 changed files with 2383 additions and 1061 deletions
+2 -10
View File
@@ -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",
+16 -1
View File
@@ -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;
+29 -3
View File
@@ -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 {
-26
View File
@@ -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_));
}
@@ -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
+1
View File
@@ -20,5 +20,6 @@ group("unittest") {
deps = [
"js_env_log_unit_test:unittest",
"js_environment_test:unittest",
"source_map_test:unittest",
]
}
@@ -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;
+1
View File
@@ -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;
+148 -3
View File
@@ -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;
+15 -1
View File
@@ -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

@@ -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!");
}
}
};
@@ -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));
}
}
};
};
@@ -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")
}
}
@@ -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"
}
]
}
@@ -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,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": "更多的应用"
}
]
}
@@ -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;
@@ -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;
-1
View File
@@ -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",
@@ -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
@@ -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.