diff --git a/bundle.json b/bundle.json index ce49bbf3c6..a74ccc59d6 100644 --- a/bundle.json +++ b/bundle.json @@ -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", diff --git a/frameworks/js/napi/caller/caller.js b/frameworks/js/napi/caller/caller.js index 36eadfe457..a5a5342fd1 100644 --- a/frameworks/js/napi/caller/caller.js +++ b/frameworks/js/napi/caller/caller.js @@ -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") { diff --git a/frameworks/native/ability/ability_runtime/connection_manager.cpp b/frameworks/native/ability/ability_runtime/connection_manager.cpp index 52e2782412..cb6cc83d16 100644 --- a/frameworks/native/ability/ability_runtime/connection_manager.cpp +++ b/frameworks/native/ability/ability_runtime/connection_manager.cpp @@ -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 diff --git a/frameworks/native/ability/ability_runtime/local_call_container.cpp b/frameworks/native/ability/ability_runtime/local_call_container.cpp index ea6d000008..91bfcc54e4 100644 --- a/frameworks/native/ability/ability_runtime/local_call_container.cpp +++ b/frameworks/native/ability/ability_runtime/local_call_container.cpp @@ -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; + 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) { diff --git a/frameworks/native/ability/ability_runtime/local_call_record.cpp b/frameworks/native/ability/ability_runtime/local_call_record.cpp index b44fcd2dd1..94d0b5f81c 100644 --- a/frameworks/native/ability/ability_runtime/local_call_record.cpp +++ b/frameworks/native/ability/ability_runtime/local_call_record.cpp @@ -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 LocalCallRecord::GetRemoteObject() const { return remoteObject_; diff --git a/frameworks/native/ability/native/ability_runtime/js_caller_complex.cpp b/frameworks/native/ability/native/ability_runtime/js_caller_complex.cpp index a387f15f9f..b2698f4e92 100644 --- a/frameworks/native/ability/native/ability_runtime/js_caller_complex.cpp +++ b/frameworks/native/ability/native/ability_runtime/js_caller_complex.cpp @@ -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 callee, std::shared_ptr 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::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(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 callee_; NativeEngine& releaseCallBackEngine_; + NativeEngine& remoteStateChanegdEngine_; std::shared_ptr callerCallBackObj_; std::unique_ptr jsReleaseCallBackObj_; + std::unique_ptr jsRemoteStateChangedObj_; std::shared_ptr 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; diff --git a/frameworks/native/ability/native/js_free_install_observer.cpp b/frameworks/native/ability/native/js_free_install_observer.cpp index 4330b7ca8a..4d2c6d69b6 100644 --- a/frameworks/native/ability/native/js_free_install_observer.cpp +++ b/frameworks/native/ability/native/js_free_install_observer.cpp @@ -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; diff --git a/frameworks/native/runtime/js_runtime.cpp b/frameworks/native/runtime/js_runtime.cpp index d0d43e9127..b2ded103ff 100644 --- a/frameworks/native/runtime/js_runtime.cpp +++ b/frameworks/native/runtime/js_runtime.cpp @@ -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(options.bundleCodeDir, options.isStageModel); - auto operatorImpl = std::make_shared(options.hapPath, bindSourceMaps); + auto bindSourceMaps = std::make_shared(); + bool isModular = !panda::JSNApi::IsBundle(vm); + auto operatorImpl = std::make_shared(options.hapPath, isModular, bindSourceMaps); InitSourceMap(operatorImpl); if (options.isUnique) { @@ -628,6 +630,7 @@ void JsRuntime::InitSourceMap(const std::shared_ptrInitSourceMap(operatorImpl); + JsEnv::SourceMap::RegisterReadSourceMapCallback(JsRuntime::ReadSourceMapData); } void JsRuntime::Deinitialize() @@ -980,5 +983,28 @@ void JsRuntime::RegisterQuickFixQueryFunc(const std::map 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 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(dataPtr.get()); + return true; +} } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/native/runtime/js_source_map_operator.cpp b/frameworks/native/runtime/js_source_map_operator.cpp index 9fcbc86802..e908c7f454 100644 --- a/frameworks/native/runtime/js_source_map_operator.cpp +++ b/frameworks/native/runtime/js_source_map_operator.cpp @@ -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 diff --git a/frameworks/native/runtime/js_source_map_operator.h b/frameworks/native/runtime/js_source_map_operator.h index 1172137c51..5a00c74a43 100644 --- a/frameworks/native/runtime/js_source_map_operator.h +++ b/frameworks/native/runtime/js_source_map_operator.h @@ -23,9 +23,8 @@ namespace OHOS { namespace AbilityRuntime { class JsSourceMapOperatorImpl : public JsEnv::SourceMapOperatorImpl { public: - JsSourceMapOperatorImpl(const std::string hapPath, - std::shared_ptr bindSourceMaps) - : hapPath_(hapPath), bindSourceMaps_(bindSourceMaps) + JsSourceMapOperatorImpl(const std::string hapPath, bool isModular, std::shared_ptr 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 bindSourceMaps_ = nullptr; + bool isModular_ = false; + std::shared_ptr bindSourceMaps_ = nullptr; }; } // namespace AbilityRuntime } // namespace OHOS diff --git a/interfaces/inner_api/ability_manager/include/ability_connect_callback_interface.h b/interfaces/inner_api/ability_manager/include/ability_connect_callback_interface.h index e981caf8c1..60cce8c17b 100644 --- a/interfaces/inner_api/ability_manager/include/ability_connect_callback_interface.h +++ b/interfaces/inner_api/ability_manager/include/ability_connect_callback_interface.h @@ -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 diff --git a/interfaces/inner_api/ability_manager/include/ability_connect_callback_stub.h b/interfaces/inner_api/ability_manager/include/ability_connect_callback_stub.h index 0f2c5c5e7e..05fdf8db42 100644 --- a/interfaces/inner_api/ability_manager/include/ability_connect_callback_stub.h +++ b/interfaces/inner_api/ability_manager/include/ability_connect_callback_stub.h @@ -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); }; diff --git a/interfaces/inner_api/ability_manager/include/ability_manager_errors.h b/interfaces/inner_api/ability_manager/include/ability_manager_errors.h index 89505b7e2a..a85d2c28c8 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_errors.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_errors.h @@ -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 { diff --git a/interfaces/inner_api/runtime/BUILD.gn b/interfaces/inner_api/runtime/BUILD.gn index aab0aa9b10..0f3fbef2b7 100644 --- a/interfaces/inner_api/runtime/BUILD.gn +++ b/interfaces/inner_api/runtime/BUILD.gn @@ -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" -} diff --git a/interfaces/inner_api/runtime/include/js_runtime.h b/interfaces/inner_api/runtime/include/js_runtime.h index 18480734ff..f2e0525b5c 100644 --- a/interfaces/inner_api/runtime/include/js_runtime.h +++ b/interfaces/inner_api/runtime/include/js_runtime.h @@ -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>; 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 bindSourceMaps_; std::string codePath_; std::string moduleName_; std::unique_ptr methodRequireNapiRef_; diff --git a/interfaces/inner_api/runtime/include/source_map.h b/interfaces/inner_api/runtime/include/source_map.h deleted file mode 100644 index 310b7966dc..0000000000 --- a/interfaces/inner_api/runtime/include/source_map.h +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include - -namespace panda::ecmascript { -class EcmaVM; -} // namespace panda::ecmascript -namespace OHOS::AbilityRuntime { -using ErrorPos = std::pair; -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 files_; - std::vector sources_; - std::vector names_; - std::vector mappings_; - std::vector 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 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& 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 HandleMappings(const std::string& mapping); - static uint32_t Base64CharToInt(char charCode); - static bool VlqRevCode(const std::string& vStr, std::vector& ans); - - std::string bundleCodeDir_; - std::map sourceMaps_; - std::shared_ptr nonModularMap_; -}; -} // namespace OHOS::AbilityRuntime - -#endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_COMMON_UTILS_SOURCE_MAP_H diff --git a/interfaces/kits/native/ability/ability_runtime/caller_callback.h b/interfaces/kits/native/ability/ability_runtime/caller_callback.h index 1b7ca45fd9..0ff41b923a 100644 --- a/interfaces/kits/native/ability/ability_runtime/caller_callback.h +++ b/interfaces/kits/native/ability/ability_runtime/caller_callback.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 &)>; using OnReleaseClosure = std::function; + using OnRemoteStateChangedClosure = std::function; CallerCallBack() = default; virtual ~CallerCallBack() = default; @@ -43,6 +44,10 @@ public: { onRelease_ = onRelease; }; + void SetOnRemoteStateChanged(OnRemoteStateChangedClosure onRemoteStateChanged) + { + onRemoteStateChanged_ = onRemoteStateChanged; + }; void InvokeCallBack(const sptr &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 diff --git a/interfaces/kits/native/ability/ability_runtime/local_call_container.h b/interfaces/kits/native/ability/ability_runtime/local_call_container.h index c410a44361..f80145676c 100644 --- a/interfaces/kits/native/ability/ability_runtime/local_call_container.h +++ b/interfaces/kits/native/ability/ability_runtime/local_call_container.h @@ -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); diff --git a/interfaces/kits/native/ability/ability_runtime/local_call_record.h b/interfaces/kits/native/ability/ability_runtime/local_call_record.h index cf6e437fcc..0b5ff873df 100644 --- a/interfaces/kits/native/ability/ability_runtime/local_call_record.h +++ b/interfaces/kits/native/ability/ability_runtime/local_call_record.h @@ -36,6 +36,7 @@ public: void AddCaller(const std::shared_ptr &callback); bool RemoveCaller(const std::shared_ptr &callback); void OnCallStubDied(const wptr &remote); + void NotifyRemoteStateChanged(int32_t abilityState); sptr GetRemoteObject() const; void InvokeCallBack() const; AppExecFwk::ElementName GetElementName() const; diff --git a/interfaces/kits/native/appkit/app/main_thread.h b/interfaces/kits/native/appkit/app/main_thread.h index 5ad8bc794f..84dac42a19 100644 --- a/interfaces/kits/native/appkit/app/main_thread.h +++ b/interfaces/kits/native/appkit/app/main_thread.h @@ -37,7 +37,6 @@ #define ABILITY_LIBRARY_LOADER class Runtime; -class ModSourceMap; namespace OHOS { namespace AppExecFwk { using namespace OHOS::Global; diff --git a/js_environment/frameworks/js_environment/BUILD.gn b/js_environment/frameworks/js_environment/BUILD.gn index 06cd2a643a..cbf39e6cbf 100644 --- a/js_environment/frameworks/js_environment/BUILD.gn +++ b/js_environment/frameworks/js_environment/BUILD.gn @@ -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", ] diff --git a/js_environment/frameworks/js_environment/src/js_environment.cpp b/js_environment/frameworks/js_environment/src/js_environment.cpp index f412fc2c08..35624d29ab 100644 --- a/js_environment/frameworks/js_environment/src/js_environment.cpp +++ b/js_environment/frameworks/js_environment/src/js_environment.cpp @@ -115,8 +115,10 @@ void JsEnvironment::InitSourceMap(const std::shared_ptr o void JsEnvironment::RegisterUncaughtExceptionHandler(JsEnv::UncaughtExceptionInfo uncaughtExceptionInfo) { if (engine_ == nullptr) { + JSENV_LOG_E("Invalid Native Engine."); return; } + engine_->RegisterUncaughtExceptionHandler(UncaughtExceptionCallback(uncaughtExceptionInfo.uncaughtTask, sourceMapOperator_)); } diff --git a/frameworks/native/runtime/source_map.cpp b/js_environment/frameworks/js_environment/src/source_map.cpp similarity index 63% rename from frameworks/native/runtime/source_map.cpp rename to js_environment/frameworks/js_environment/src/source_map.cpp index 8fd43de2c8..d60ca98a24 100644 --- a/frameworks/native/runtime/source_map.cpp +++ b/js_environment/frameworks/js_environment/src/source_map.cpp @@ -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 #include -#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 = ExtractorUtil::GetExtractor( - ExtractorUtil::GetLoadFilePath(hapPath), newCreate); - if (extractor == nullptr) { - HILOG_ERROR("hapPath %{public}s GetExtractor failed", hapPath.c_str()); - return false; - } - std::unique_ptr 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(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 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(temp.find(closeBrace)); + auto openBracePos = static_cast(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(); + } + 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 modularMap = std::make_shared(); + ExtractSourceMapData(value, modularMap); + sourceMaps_.emplace(key, modularMap); + } +} + +void SourceMap::ExtractStackInfo(const std::string& stackStr, std::vector& 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& curMapData) +{ + std::vector 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 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& sourceKeyInfo) +void SourceMap::ExtractKeyInfo(const std::string& sourceMap, std::vector& sourceKeyInfo) { uint32_t cnt = 0; std::string tempStr; @@ -140,7 +347,7 @@ void ModSourceMap::ExtractKeyInfo(const std::string& sourceMap, std::vector 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 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 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 ModSourceMap::HandleMappings(const std::string& mapping) +std::vector SourceMap::HandleMappings(const std::string& mapping) { std::vector keyInfo; std::string tempStr; @@ -296,28 +412,7 @@ std::vector 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& ans) +bool SourceMap::VlqRevCode(const std::string& vStr, std::vector& ans) { const int32_t VLQ_BASE_SHIFT = 5; // binary: 100000 @@ -353,113 +448,7 @@ bool ModSourceMap::VlqRevCode(const std::string& vStr, std::vector& 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 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 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(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(temp.find(closeBrace)); - int32_t openBracePos = static_cast(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(); + 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 targetMapData, +std::string SourceMap::GetOriginalNames(std::shared_ptr 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 target } std::vector 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 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(lineBreakPos) + static_cast(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(jsCode.length()) && jsCode[flagPos] == '^' && flagPos + posDiff - 1 > 0) { @@ -537,24 +538,17 @@ std::string ModSourceMap::GetOriginalNames(std::shared_ptr 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 diff --git a/js_environment/frameworks/js_environment/src/uncaught_exception_callback.cpp b/js_environment/frameworks/js_environment/src/uncaught_exception_callback.cpp index f315bbb836..cbdb78d81b 100644 --- a/js_environment/frameworks/js_environment/src/uncaught_exception_callback.cpp +++ b/js_environment/frameworks/js_environment/src/uncaught_exception_callback.cpp @@ -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"); diff --git a/js_environment/interfaces/inner_api/source_map.h b/js_environment/interfaces/inner_api/source_map.h new file mode 100644 index 0000000000..556433b01a --- /dev/null +++ b/js_environment/interfaces/inner_api/source_map.h @@ -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 +#include +#include +#include +#include +#include +#include + +namespace OHOS { +namespace JsEnv { +using ErrorPos = std::pair; +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 files_; + std::vector sources_; + std::vector names_; + std::vector mappings_; + std::vector afterPos_; + + inline SourceMapData GetSourceMapData() const + { + return *this; + } +}; + +using ReadSourceMapCallback = std::function; + +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 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& curMapData); + void ExtractStackInfo(const std::string& stackStr, std::vector& res); + void ExtractKeyInfo(const std::string& sourceMap, std::vector& sourceKeyInfo); + std::vector HandleMappings(const std::string& mapping); + bool VlqRevCode(const std::string& vStr, std::vector& 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> sourceMaps_; + std::shared_ptr nonModularMap_; + static ReadSourceMapCallback readSourceMapFunc_; +}; +} // namespace JsEnv +} // namespace OHOS + +#endif // OHOS_ABILITY_JS_ENVIRONMENT_SOURCE_MAP_H diff --git a/js_environment/test/unittest/BUILD.gn b/js_environment/test/unittest/BUILD.gn index 257ac46252..68d637e8a9 100644 --- a/js_environment/test/unittest/BUILD.gn +++ b/js_environment/test/unittest/BUILD.gn @@ -20,5 +20,6 @@ group("unittest") { deps = [ "js_env_log_unit_test:unittest", "js_environment_test:unittest", + "source_map_test:unittest", ] } diff --git a/test/unittest/frameworks_kits_runtime_native_test/BUILD.gn b/js_environment/test/unittest/source_map_test/BUILD.gn similarity index 69% rename from test/unittest/frameworks_kits_runtime_native_test/BUILD.gn rename to js_environment/test/unittest/source_map_test/BUILD.gn index 8c2ba5d2cd..b418d9267c 100644 --- a/test/unittest/frameworks_kits_runtime_native_test/BUILD.gn +++ b/js_environment/test/unittest/source_map_test/BUILD.gn @@ -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") { diff --git a/js_environment/test/unittest/source_map_test/source_map_test.cpp b/js_environment/test/unittest/source_map_test/source_map_test.cpp new file mode 100644 index 0000000000..c13cb238e6 --- /dev/null +++ b/js_environment/test/unittest/source_map_test/source_map_test.cpp @@ -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 + +#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 targetMapData = std::make_shared(); + 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 targetMapData = std::make_shared(); + 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(); + 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(); + 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(); + 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(); + 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(); + 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(); + 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(); + + 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(); + + 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(); + 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 diff --git a/services/abilitymgr/include/ability_interceptor.h b/services/abilitymgr/include/ability_interceptor.h index 0e8664c01b..fd49227da4 100644 --- a/services/abilitymgr/include/ability_interceptor.h +++ b/services/abilitymgr/include/ability_interceptor.h @@ -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 &bms, const Want &want, int32_t userId, + AppExecFwk::AppJumpControlRule &controlRule); + bool CheckIfIntercept(sptr &bms, AppExecFwk::AppJumpControlRule &controlRule, + int32_t userId); + bool VerifyPermissionByBundleName(sptr &bms, const std::string &bundleName, + const std::string &permission, int32_t userId); + bool LoadAppLabelInfo(sptr &bms, Want &want, AppExecFwk::AppJumpControlRule &controlRule, + int32_t userId); +}; } // namespace AAFwk } // namespace OHOS #endif // OHOS_ABILITY_RUNTIME_ABILITY_INTERCEPTOR_H diff --git a/services/abilitymgr/include/ability_util.h b/services/abilitymgr/include/ability_util.h index 94d193efc1..f2ffcbea8b 100644 --- a/services/abilitymgr/include/ability_util.h +++ b/services/abilitymgr/include/ability_util.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 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(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()) { diff --git a/services/abilitymgr/include/implicit_start_processor.h b/services/abilitymgr/include/implicit_start_processor.h index 4c709232fd..80d530cd2d 100644 --- a/services/abilitymgr/include/implicit_start_processor.h +++ b/services/abilitymgr/include/implicit_start_processor.h @@ -39,8 +39,8 @@ public: int ImplicitStartAbility(AbilityRequest &request, int32_t userId); private: - int GenerateAbilityRequestByAction(int32_t userId, - AbilityRequest &request, std::vector &dialogAppInfos); + int GenerateAbilityRequestByAction(int32_t userId, AbilityRequest &request, + std::vector &dialogAppInfos, std::string &deviceType, bool isMoreHapList); sptr GetBundleManager(); @@ -55,6 +55,7 @@ private: bool FilterAbilityList(const Want &want, std::vector &abilityInfos, std::vector extensionInfos); + sptr GetDefaultAppProxy(); private: const static std::vector blackList; diff --git a/services/abilitymgr/include/system_dialog_scheduler.h b/services/abilitymgr/include/system_dialog_scheduler.h index 96ba21ddbf..f2c33aef5e 100644 --- a/services/abilitymgr/include/system_dialog_scheduler.h +++ b/services/abilitymgr/include/system_dialog_scheduler.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 @@ -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 &dialogAppInfos, Want &targetWant, + const std::string &type, int32_t userId, const sptr &callerToken); Want GetSelectorDialogWant(const std::vector &dialogAppInfos, Want &targetWant, const sptr &callerToken); Want GetTipsDialogWant(const sptr &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 &infos) const; + const std::string GetPcSelectorParams(const std::vector &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; diff --git a/services/abilitymgr/libabilityms.map b/services/abilitymgr/libabilityms.map index bf0a5bc9a7..b9db15b47a 100644 --- a/services/abilitymgr/libabilityms.map +++ b/services/abilitymgr/libabilityms.map @@ -42,6 +42,7 @@ *ControlInterceptor*; *CrowdTestInterceptor*; *EcologicalRuleInterceptor*; + *AbilityJumpInterceptor*; *DataAbilityManager*; *FreeInstallManager*; *FreeInstallObserverManager*; diff --git a/services/abilitymgr/src/ability_connect_callback_stub.cpp b/services/abilitymgr/src/ability_connect_callback_stub.cpp index 16fcde181b..d807ed2254 100644 --- a/services/abilitymgr/src/ability_connect_callback_stub.cpp +++ b/services/abilitymgr/src/ability_connect_callback_stub.cpp @@ -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(); + 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; diff --git a/services/abilitymgr/src/ability_interceptor.cpp b/services/abilitymgr/src/ability_interceptor.cpp index ec8382c76a..4bef993170 100644 --- a/services/abilitymgr/src/ability_interceptor.cpp +++ b/services/abilitymgr/src/ability_interceptor.cpp @@ -16,19 +16,22 @@ #include "ability_interceptor.h" #include -#include #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::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 &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 &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 &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 &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 diff --git a/services/abilitymgr/src/ability_manager_service.cpp b/services/abilitymgr/src/ability_manager_service.cpp index 230cd81f41..cb95bea739 100644 --- a/services/abilitymgr/src/ability_manager_service.cpp +++ b/services/abilitymgr/src/ability_manager_service.cpp @@ -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()); interceptorExecuter_->AddInterceptor(std::make_shared()); interceptorExecuter_->AddInterceptor(std::make_shared()); + 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()); + } 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 AbilityManagerService::GetFocusAbility() int AbilityManagerService::AddFreeInstallObserver(const sptr &observer) { + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); if (freeInstallManager_ == nullptr) { HILOG_ERROR("freeInstallManager_ is nullptr."); return ERR_INVALID_VALUE; diff --git a/services/abilitymgr/src/free_install_manager.cpp b/services/abilitymgr/src/free_install_manager.cpp index c02a20e70a..dac22b81d4 100644 --- a/services/abilitymgr/src/free_install_manager.cpp +++ b/services/abilitymgr/src/free_install_manager.cpp @@ -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 &callerToken) int FreeInstallManager::StartFreeInstall(const Want &want, int32_t userId, int requestCode, const sptr &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 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 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 diff --git a/services/abilitymgr/src/implicit_start_processor.cpp b/services/abilitymgr/src/implicit_start_processor.cpp index 8e6dfc9c50..0333fa0480 100644 --- a/services/abilitymgr/src/implicit_start_processor.cpp +++ b/services/abilitymgr/src/implicit_start_processor.cpp @@ -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 + #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 ImplicitStartProcessor::blackList = { std::vector::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::GetInstance(); CHECK_POINTER_AND_RETURN(sysDialogScheduler, ERR_INVALID_VALUE); std::vector 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::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::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 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::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 &dialogAppInfos) + AbilityRequest &request, std::vector &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 implicitAbilityInfos; + std::vector implicitExtensionInfos; + std::vector 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 ImplicitStartProcessor::GetBundleManager() return iBundleManager_; } +sptr 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 &abilityInfos, std::vector extensionInfos) { diff --git a/services/abilitymgr/src/system_dialog_scheduler.cpp b/services/abilitymgr/src/system_dialog_scheduler.cpp index 72cb1374cf..1acde0dc6b 100644 --- a/services/abilitymgr/src/system_dialog_scheduler.cpp +++ b/services/abilitymgr/src/system_dialog_scheduler.cpp @@ -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 &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 &dialogAppInfos, Want &targetWant, const sptr &callerToken) { @@ -182,6 +213,57 @@ const std::string SystemDialogScheduler::GetSelectorParams(const std::vector &dialogAppInfos, + Want &targetWant, const std::string &type, int32_t userId, const sptr &callerToken) +{ + HILOG_DEBUG("GetPcSelectorDialogWant start"); + DialogPosition position; + GetDialogPositionAndSize(DialogType::DIALOG_SELECTOR, position, static_cast(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 &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; diff --git a/services/appmgr/include/app_running_record.h b/services/appmgr/include/app_running_record.h index 45e9ca8c91..10e442273d 100644 --- a/services/appmgr/include/app_running_record.h +++ b/services/appmgr/include/app_running_record.h @@ -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; diff --git a/services/appmgr/src/app_running_record.cpp b/services/appmgr/src/app_running_record.cpp index 84dedb21ca..d54bb679b6 100644 --- a/services/appmgr/src/app_running_record.cpp +++ b/services/appmgr/src/app_running_record.cpp @@ -56,7 +56,7 @@ std::shared_ptr 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 AppRunningRecord::GetUserTestInfo() void AppRunningRecord::SetProcessAndExtensionType(const std::shared_ptr &abilityInfo) { + if (abilityInfo == nullptr) { + HILOG_ERROR("abilityInfo is nullptr"); + return; + } extensionType_ = abilityInfo->extensionAbilityType; if (extensionType_ == ExtensionAbilityType::UNSPECIFIED) { processType_ = ProcessType::NORMAL; diff --git a/services/appmgr/src/app_state_observer_manager.cpp b/services/appmgr/src/app_state_observer_manager.cpp index e5e41c3ee8..9260f66197 100644 --- a/services/appmgr/src/app_state_observer_manager.cpp +++ b/services/appmgr/src/app_state_observer_manager.cpp @@ -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; } diff --git a/services/common/include/permission_constants.h b/services/common/include/permission_constants.h index 940be3c9f0..cfe93074dd 100644 --- a/services/common/include/permission_constants.h +++ b/services/common/include/permission_constants.h @@ -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 diff --git a/services/common/include/permission_verification.h b/services/common/include/permission_verification.h index c5c586b6dc..db2006d922 100644 --- a/services/common/include/permission_verification.h +++ b/services/common/include/permission_verification.h @@ -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; diff --git a/services/common/src/permission_verification.cpp b/services/common/src/permission_verification.cpp index 8d9d7f444b..226b15d670 100644 --- a/services/common/src/permission_verification.cpp +++ b/services/common/src/permission_verification.cpp @@ -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()); diff --git a/services/dialog_ui/ams_system_dialog/AppScope/resources/base/media/selectedMark.png b/services/dialog_ui/ams_system_dialog/AppScope/resources/base/media/selectedMark.png new file mode 100644 index 0000000000..2b11708e16 Binary files /dev/null and b/services/dialog_ui/ams_system_dialog/AppScope/resources/base/media/selectedMark.png differ diff --git a/services/dialog_ui/ams_system_dialog/entry/src/main/ets/ServiceExtAbility/JumpInterceptorServiceExtAbility.ts b/services/dialog_ui/ams_system_dialog/entry/src/main/ets/ServiceExtAbility/JumpInterceptorServiceExtAbility.ts new file mode 100644 index 0000000000..afac5e469c --- /dev/null +++ b/services/dialog_ui/ams_system_dialog/entry/src/main/ets/ServiceExtAbility/JumpInterceptorServiceExtAbility.ts @@ -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!"); + } + } +}; diff --git a/services/dialog_ui/ams_system_dialog/entry/src/main/ets/ServiceExtAbility/SelectorServiceExtAbility.ts b/services/dialog_ui/ams_system_dialog/entry/src/main/ets/ServiceExtAbility/SelectorServiceExtAbility.ts index e56384ae0d..4316872978 100644 --- a/services/dialog_ui/ams_system_dialog/entry/src/main/ets/ServiceExtAbility/SelectorServiceExtAbility.ts +++ b/services/dialog_ui/ams_system_dialog/entry/src/main/ets/ServiceExtAbility/SelectorServiceExtAbility.ts @@ -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)); } } -}; +}; \ No newline at end of file diff --git a/services/dialog_ui/ams_system_dialog/entry/src/main/ets/pages/jumpInterceptorDialog.ets b/services/dialog_ui/ams_system_dialog/entry/src/main/ets/pages/jumpInterceptorDialog.ets new file mode 100644 index 0000000000..0f2f433fe4 --- /dev/null +++ b/services/dialog_ui/ams_system_dialog/entry/src/main/ets/pages/jumpInterceptorDialog.ets @@ -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") + } +} \ No newline at end of file diff --git a/services/dialog_ui/ams_system_dialog/entry/src/main/ets/pages/selectorPcDialog.ets b/services/dialog_ui/ams_system_dialog/entry/src/main/ets/pages/selectorPcDialog.ets index 63d2d3eb83..7380bb5760 100644 --- a/services/dialog_ui/ams_system_dialog/entry/src/main/ets/pages/selectorPcDialog.ets +++ b/services/dialog_ui/ams_system_dialog/entry/src/main/ets/pages/selectorPcDialog.ets @@ -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') } -} \ No newline at end of file +} diff --git a/services/dialog_ui/ams_system_dialog/entry/src/main/ets/pages/selectorPhoneDialog.ets b/services/dialog_ui/ams_system_dialog/entry/src/main/ets/pages/selectorPhoneDialog.ets index 1a6822e8f1..a7e2a56076 100644 --- a/services/dialog_ui/ams_system_dialog/entry/src/main/ets/pages/selectorPhoneDialog.ets +++ b/services/dialog_ui/ams_system_dialog/entry/src/main/ets/pages/selectorPhoneDialog.ets @@ -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]; diff --git a/services/dialog_ui/ams_system_dialog/entry/src/main/module.json b/services/dialog_ui/ams_system_dialog/entry/src/main/module.json index 38abaf9c89..7a04b596c8 100644 --- a/services/dialog_ui/ams_system_dialog/entry/src/main/module.json +++ b/services/dialog_ui/ams_system_dialog/entry/src/main/module.json @@ -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" } ] } diff --git a/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/element/string.json b/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/element/string.json index 1d25d6231a..c5dd3baf74 100644 --- a/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/element/string.json +++ b/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/element/string.json @@ -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" } ] } \ No newline at end of file diff --git a/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/profile/main_pages.json b/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/profile/main_pages.json index c940236017..ff2738d384 100644 --- a/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/profile/main_pages.json +++ b/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/profile/main_pages.json @@ -2,6 +2,7 @@ "src": [ "pages/selectorPhoneDialog", "pages/selectorPcDialog", - "pages/tipsDialog" + "pages/tipsDialog", + "pages/jumpInterceptorDialog" ] } diff --git a/services/dialog_ui/ams_system_dialog/entry/src/main/resources/zh/element/string.json b/services/dialog_ui/ams_system_dialog/entry/src/main/resources/zh/element/string.json index 1419229d9b..9fadf8610a 100644 --- a/services/dialog_ui/ams_system_dialog/entry/src/main/resources/zh/element/string.json +++ b/services/dialog_ui/ams_system_dialog/entry/src/main/resources/zh/element/string.json @@ -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": "更多的应用" } ] } \ No newline at end of file diff --git a/services/dialog_ui/ams_system_dialog/signature/openharmony_sx.p7b b/services/dialog_ui/ams_system_dialog/signature/openharmony_sx.p7b index a8da879d22..7c294c3af4 100644 Binary files a/services/dialog_ui/ams_system_dialog/signature/openharmony_sx.p7b and b/services/dialog_ui/ams_system_dialog/signature/openharmony_sx.p7b differ diff --git a/test/mock/services_abilitymgr_test/libs/appexecfwk_core/include/bundlemgr/mock_app_control_manager.h b/test/mock/services_abilitymgr_test/libs/appexecfwk_core/include/bundlemgr/mock_app_control_manager.h index 2b4e94e23b..f62539db01 100644 --- a/test/mock/services_abilitymgr_test/libs/appexecfwk_core/include/bundlemgr/mock_app_control_manager.h +++ b/test/mock/services_abilitymgr_test/libs/appexecfwk_core/include/bundlemgr/mock_app_control_manager.h @@ -19,7 +19,6 @@ #include "want.h" #include #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 &controlRules, int32_t userId) override; + virtual ErrCode DeleteAppJumpControlRule(const std::vector &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; diff --git a/test/mock/services_abilitymgr_test/libs/appexecfwk_core/src/bundlemgr/mock_app_control_manager.cpp b/test/mock/services_abilitymgr_test/libs/appexecfwk_core/src/bundlemgr/mock_app_control_manager.cpp index e3b34e0517..435a4b0400 100644 --- a/test/mock/services_abilitymgr_test/libs/appexecfwk_core/src/bundlemgr/mock_app_control_manager.cpp +++ b/test/mock/services_abilitymgr_test/libs/appexecfwk_core/src/bundlemgr/mock_app_control_manager.cpp @@ -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 &controlRules, int32_t userId) +{ + return ERR_OK; +} + +ErrCode AppControlProxy::DeleteAppJumpControlRule(const std::vector &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; diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index b20977729d..400ffebe2d 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -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", diff --git a/test/unittest/frameworks_kits_ability_ability_runtime_test/local_call_container_ut_test.cpp b/test/unittest/frameworks_kits_ability_ability_runtime_test/local_call_container_ut_test.cpp index 3afe362cc2..96644e72ea 100644 --- a/test/unittest/frameworks_kits_ability_ability_runtime_test/local_call_container_ut_test.cpp +++ b/test/unittest/frameworks_kits_ability_ability_runtime_test/local_call_container_ut_test.cpp @@ -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 callback = std::make_shared(); + callback->SetCallBack([](const sptr&) {}); + AppExecFwk::ElementName elementName("DemoDeviceId", "DemoBundleName", "DemoAbilityName"); + std::shared_ptr localCallRecord = std::make_shared(elementName); + localCallRecord->AddCaller(callback); + localCallRecord->callers_.emplace_back(callback); + + std::string uri = elementName.GetURI(); + localCallContainer.callProxyRecords_.emplace(uri, localCallRecord); + OHOS::sptr 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 callback = std::make_shared(); + callback->SetCallBack([](const sptr&) {}); + AppExecFwk::ElementName elementName("DemoDeviceId", "DemoBundleName", "DemoAbilityName"); + std::shared_ptr localCallRecord = std::make_shared(elementName); + localCallRecord->AddCaller(callback); + localCallRecord->callers_.emplace_back(callback); + + std::string uri = elementName.GetURI(); + localCallContainer.callProxyRecords_.emplace(uri, localCallRecord); + OHOS::sptr 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 callback = std::make_shared(); + EXPECT_EQ(callback->isCallBack_, false); + AppExecFwk::ElementName elementName("DemoDeviceId", "DemoBundleName", "DemoAbilityName"); + std::shared_ptr localCallRecord = std::make_shared(elementName); + localCallRecord->AddCaller(callback); + + localCallContainer.OnRemoteStateChanged(elementName, 0); + EXPECT_EQ(callback->isCallBack_, false); +} + /** * @tc.number: Local_Call_Container_GetCallLocalRecord_0100 * @tc.name: GetCallLocalRecord diff --git a/test/unittest/frameworks_kits_ability_ability_runtime_test/local_call_record_ut_test.cpp b/test/unittest/frameworks_kits_ability_ability_runtime_test/local_call_record_ut_test.cpp index e70f3d40c2..bb7767885d 100644 --- a/test/unittest/frameworks_kits_ability_ability_runtime_test/local_call_record_ut_test.cpp +++ b/test/unittest/frameworks_kits_ability_ability_runtime_test/local_call_record_ut_test.cpp @@ -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 callback = std::make_shared(); + callback->SetCallBack([](const sptr&) {}); + 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 callback = std::make_shared(); + 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 callback = std::make_shared(); + 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 callback = std::make_shared(); + 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 diff --git a/test/unittest/frameworks_kits_runtime_native_test/source_map_test.cpp b/test/unittest/frameworks_kits_runtime_native_test/source_map_test.cpp deleted file mode 100644 index 15db847ab0..0000000000 --- a/test/unittest/frameworks_kits_runtime_native_test/source_map_test.cpp +++ /dev/null @@ -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 - -#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(); - char charCode = 'A'; - uint32_t value = modSourceMap->Base64CharToInt(charCode); - EXPECT_EQ(static_cast(value), 0); - - charCode = 'Z'; - value = modSourceMap->Base64CharToInt(charCode); - EXPECT_EQ(static_cast(value), 25); - - charCode = 'C'; - value = modSourceMap->Base64CharToInt(charCode); - EXPECT_EQ(static_cast(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(); - char charCode = 'a'; - uint32_t value = modSourceMap->Base64CharToInt(charCode); - EXPECT_EQ(static_cast(value), 26); - - charCode = 'z'; - value = modSourceMap->Base64CharToInt(charCode); - EXPECT_EQ(static_cast(value), 51); - - charCode = 'c'; - value = modSourceMap->Base64CharToInt(charCode); - EXPECT_EQ(static_cast(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(); - char charCode = '0'; - uint32_t value = modSourceMap->Base64CharToInt(charCode); - EXPECT_EQ(static_cast(value), 52); - - charCode = '9'; - value = modSourceMap->Base64CharToInt(charCode); - EXPECT_EQ(static_cast(value), 61); - - charCode = '2'; - value = modSourceMap->Base64CharToInt(charCode); - EXPECT_EQ(static_cast(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(); - char charCode = '+'; - uint32_t value = modSourceMap->Base64CharToInt(charCode); - EXPECT_EQ(static_cast(value), 62); - - charCode = '/'; - value = modSourceMap->Base64CharToInt(charCode); - EXPECT_EQ(static_cast(value), 63); - - charCode = '&'; - value = modSourceMap->Base64CharToInt(charCode); - EXPECT_EQ(static_cast(value), 64); - - charCode = '@'; - value = modSourceMap->Base64CharToInt(charCode); - EXPECT_EQ(static_cast(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(); - 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(); - 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(); - 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(); - 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(); - 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(); - 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(); - 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(); - 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(); - 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(); - 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(); - - 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(); - - 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(); - - 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 diff --git a/test/unittest/runtime_test/js_runtime_test.cpp b/test/unittest/runtime_test/js_runtime_test.cpp index 21461647ed..876d0416d3 100755 --- a/test/unittest/runtime_test/js_runtime_test.cpp +++ b/test/unittest/runtime_test/js_runtime_test.cpp @@ -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 = std::make_unique(); - EXPECT_TRUE(jsRuntime != nullptr); - - options_.bundleCodeDir = TEST_CODE_PATH; - options_.isStageModel = true; - jsRuntime->bindSourceMaps_ = std::make_unique(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.