Signed-off-by: zhongjianfei <zhongjianfei@huawei.com>
Change-Id: I8ab754447faa0d8e1b796c0037196037b6fa3d8b
This commit is contained in:
zhongjianfei 2021-09-15 00:11:09 +08:00
parent 108e66ba93
commit fc0265f84f
38 changed files with 567 additions and 343 deletions

View File

@ -18,8 +18,7 @@ ace_flutter_engine_root = "//third_party/flutter"
ace_test_output_root = "ace_engine_standard"
objcopy_arm = "//prebuilts/gcc/linux-x86/arm/gcc-linaro-7.5.0-arm-linux-gnueabi/arm-linux-gnueabi/bin/objcopy"
objcopy_aarch64 = "//prebuilts/gcc/linux-x86/aarch64/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/bin/objcopy"
objcopy_aarch64 = "//prebuilts/gcc/linux-x86/arm/gcc-linaro-7.5.0-arm-linux-gnueabi/arm-linux-gnueabi/bin/objcopy"
objcopy_x86_64 = ""
ark_tools_root = "//prebuilts/ace-toolkit/ace-loader/panda"
node_js_path = "//prebuilts/ace-toolkit/nodejs/node-v12.18.4-linux-x64/bin/"

View File

@ -164,12 +164,93 @@ const std::string AceAbility::PAGE_URI = "url";
const std::string AceAbility::CONTINUE_PARAMS_KEY = "__remoteData";
REGISTER_AA(AceAbility)
int32_t g_dialogId = 1;
const std::string WINDOW_DIALOG_DOUBLE_BUTTON = "pages/dialog/dialog.js";
void showDialog(OHOS::sptr<OHOS::Window> window, std::string jsBoudle, std::string param, DialogCallback callback)
{
LOGI("showDialog");
SetHwIcuDirectory();
// create container
Platform::AceContainer::CreateContainer(
g_dialogId, FrontendType::JS, false, nullptr,
std::make_unique<AcePlatformEventCallback>([]() {
//TerminateAbility();
}));
Platform::AceContainer::SetDialogCallback(g_dialogId, callback);
// create view.
auto flutterAceView = Platform::FlutterAceView::CreateView(g_dialogId);
// window->Resize(460, 700);
auto&& touchEventCallback = [aceView = flutterAceView](OHOS::TouchEvent event) -> bool {
LOGD("RegistOnTouchCb touchEventCallback called");
return aceView->DispatchTouchEvent(aceView, event);
};
window->OnTouch(touchEventCallback);
// register surface change callback
auto&& surfaceChangedCallBack = [flutterAceView](uint32_t width, uint32_t height) {
LOGD("RegistWindowInfoChangeCb surfaceChangedCallBack called");
flutter::ViewportMetrics metrics;
metrics.physical_width = width;
metrics.physical_height = height;
Platform::FlutterAceView::SetViewportMetrics(flutterAceView, metrics);
Platform::FlutterAceView::SurfaceChanged(flutterAceView, width, height, 0);
};
window->OnSizeChange(surfaceChangedCallBack);
Platform::FlutterAceView::SurfaceCreated(flutterAceView, window);
// set metrics
BufferRequestConfig windowConfig = {
.width = window->GetSurface()->GetDefaultWidth(),
.height = window->GetSurface()->GetDefaultHeight(),
.strideAlignment = 0x8,
.format = PIXEL_FMT_RGBA_8888,
.usage = window->GetSurface()->GetDefaultUsage(),
};
LOGI("AceAbility: windowConfig: width: %{public}d, height: %{public}d", windowConfig.width, windowConfig.height);
flutter::ViewportMetrics metrics;
metrics.physical_width = windowConfig.width;
metrics.physical_height = windowConfig.height;
Platform::FlutterAceView::SetViewportMetrics(flutterAceView, metrics);
// add asset path.
auto packagePathStr = "system/dialog/";
auto assetBasePathStr = { std::string("assets/js/default/"), std::string("assets/js/share/") };
Platform::AceContainer::AddAssetPath(g_dialogId, packagePathStr, assetBasePathStr);
// set view
Platform::AceContainer::SetView(flutterAceView, 1.0f, windowConfig.width, windowConfig.height);
Platform::FlutterAceView::SurfaceChanged(flutterAceView, windowConfig.width, windowConfig.height, 0);
// set window id
auto context = Platform::AceContainer::GetContainer(g_dialogId)->GetPipelineContext();
if (context != nullptr) {
context->SetWindowId(window->GetID());
}
// run page.
Platform::AceContainer::RunPage(
g_dialogId, Platform::AceContainer::GetContainer(g_dialogId)->GeneratePageId(),
jsBoudle, param);
g_dialogId++;
}
void DialogHandle1(std::string event, std::string param)
{
LOGI("DialogHandle1 event=%{public}s, param=%{public}s", event.c_str(), param.c_str());
}
void AceAbility::OnStart(const Want& want)
{
Ability::OnStart(want);
LOGI("AceAbility::OnStart called");
SetHwIcuDirectory();
bool isSystemUI = false;
std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
auto resourceManager = GetResourceManager();
@ -194,6 +275,10 @@ void AceAbility::OnStart(const Want& want)
if (moduleInfo != nullptr) {
packagePathStr += "/" + moduleInfo->name + "/";
}
if ((packagePathStr.find("systemui") != -1) || (packagePathStr.find("launcher") != -1)) {
isSystemUI = true;
}
FrontendType frontendType = GetFrontendTypeFromManifest(packagePathStr);
bool isArkApp = GetIsArkFromConfig(packagePathStr);
@ -295,6 +380,12 @@ void AceAbility::OnStart(const Want& want)
parsedPageUrl, want.GetStringParam(START_PARAMS_KEY));
Platform::AceContainer::OnRestoreData(abilityId_, remoteData_);
if (!isSystemUI && (moduleInfo->name.find("ohos.istone.system.dialog")) != -1) {
std::string dialogParam = "{\"title\":\"Alert!\", \"message\":\"Two button style!\"," \
"\"button1\":\"Got it!\", \"button2\":\"Cancel!\"}";
showDialog(Ability::GetWindow(), WINDOW_DIALOG_DOUBLE_BUTTON, dialogParam, DialogHandle1);
return;
}
LOGI("AceAbility::OnStart called End");
}

View File

@ -23,6 +23,8 @@
#include "want.h"
namespace OHOS::Ace {
using DialogCallback = std::function<void(std::string event, std::string param)>;
void showDialog(OHOS::sptr<OHOS::Window> window, std::string jsBoudle, std::string param, DialogCallback callback);
class AceAbility final : public OHOS::AppExecFwk::Ability {
public:

View File

@ -666,4 +666,16 @@ void AceContainer::SetWindowStyle(int32_t instanceId, WindowModal windowModal, C
container->SetWindowModal(windowModal);
container->SetColorScheme(colorScheme);
}
void AceContainer::SetDialogCallback(int32_t instanceId, DialogCallback callback)
{
auto container = AceEngine::Get().GetContainer(instanceId);
if (!container) {
return;
}
auto front = container->GetFrontend();
if (front && front->GetType() == FrontendType::JS) {
front->SetDialogCallback(callback);
}
}
} // namespace OHOS::Ace::Platform

View File

@ -25,6 +25,7 @@
#include "base/utils/noncopyable.h"
#include "core/common/ace_view.h"
#include "core/common/container.h"
#include "core/common/frontend.h"
#include "core/common/js_message_dispatcher.h"
namespace OHOS::Ace::Platform {
@ -157,7 +158,7 @@ public:
static RefPtr<AceContainer> GetContainer(int32_t instanceId);
static bool UpdatePage(int32_t instanceId, int32_t pageId, const std::string& content);
static void SetDialogCallback(int32_t instanceId, DialogCallback callback);
private:
void InitializeFrontend();
void InitializeCallback();

View File

@ -51,12 +51,38 @@ private:
FormPlatformFinish onFinish_;
};
int64_t AceFormAbility::instanceId_ = 0;
const std::string AceFormAbility::START_PARAMS_KEY = "__startParams";
const std::string AceFormAbility::URI = "url";
REGISTER_AA(AceFormAbility)
void AceFormAbility::OnStart(const OHOS::AAFwk::Want &want)
{
LOGI("AceFormAbility::OnStart start");
Ability::OnStart(want);
return;
}
void AceFormAbility::OnStop()
{
LOGI("AceFormAbility::OnStop start ");
Ability::OnStop();
return;
}
sptr<IRemoteObject> AceFormAbility::OnConnect(const Want &want)
{
LOGI("AceFormAbility::OnConnect start");
Ability::OnConnect(want);
return GetFormRemoteObject();
}
void AceFormAbility::OnDisconnect(const Want &want)
{
LOGI("AceFormAbility::OnDisconnect start");
Ability::OnDisconnect(want);
return;
}
OHOS::AppExecFwk::FormProviderInfo AceFormAbility::OnCreate(const OHOS::AAFwk::Want& want)
{
LOGI("AceFormAbility::OnCreate called");
@ -130,32 +156,4 @@ void AceFormAbility::OnAcquireState(const OHOS::AAFwk::Want& want)
Platform::PaContainer::OnAcquireState(want);
}
void AceFormAbility::OnStart(const OHOS::AAFwk::Want &want)
{
LOGI("AceFormAbility::OnStart start");
Ability::OnStart(want);
return;
}
void AceFormAbility::OnStop()
{
LOGI("AceFormAbility::OnStop start ");
Ability::OnStop();
return;
}
sptr<IRemoteObject> AceFormAbility::OnConnect(const Want &want)
{
LOGI("AceFormAbility::OnConnect start");
Ability::OnConnect(want);
return GetFormRemoteObject();
}
void AceFormAbility::OnDisconnect(const Want &want)
{
LOGI("AceFormAbility::OnDisconnect start");
Ability::OnDisconnect(want);
return;
}
} // namespace OHOS::Ace

View File

@ -28,8 +28,6 @@ class AceFormAbility final : public OHOS::AppExecFwk::Ability {
public:
AceFormAbility()
{
abilityId_ = instanceId_;
instanceId_++;
}
virtual ~AceFormAbility() = default;
void OnStart(const OHOS::AAFwk::Want& want) override;
@ -37,75 +35,16 @@ public:
sptr<IRemoteObject> OnConnect(const OHOS::AAFwk::Want &want) override;
void OnDisconnect(const OHOS::AAFwk::Want &want) override;
/**
* @brief Called to return a FormProviderInfo object.
*
* <p>You must override this method if your ability will serve as a form provider to provide a form for clients.
* The default implementation returns nullptr. </p>
*
* @param want Indicates the detailed information for creating a FormProviderInfo.
* The Want object must include the form ID, form name of the form,
* which can be obtained from Ability#PARAM_FORM_IDENTITY_KEY,
* Ability#PARAM_FORM_NAME_KEY, and Ability#PARAM_FORM_DIMENSION_KEY,
* respectively. Such form information must be managed as persistent data for further form
* acquisition, update, and deletion.
*
* @return Returns the created FormProviderInfo object.
*/
virtual OHOS::AppExecFwk::FormProviderInfo OnCreate(const OHOS::AAFwk::Want &want) override;
/**
* @brief Called to notify the form provider that a specified form has been deleted. Override this method if
* you want your application, as the form provider, to be notified of form deletion.
*
* @param formId Indicates the ID of the deleted form.
* @return None.
*/
virtual void OnDelete(const int64_t formId) override;
/**
* @brief Called to notify the form provider to update a specified form.
*
* @param formId Indicates the ID of the form to update.
* @param message Form event message.
*/
virtual void OnTriggerEvent(const int64_t formId, const std::string &message) override;
/**
* @brief Called to notify the form provider to update a specified form.
*
* @param formId Indicates the ID of the form to update.
* @return none.
*/
virtual void OnUpdate(const int64_t formId) override;
/**
* @brief Called when the form provider is notified that a temporary form is successfully converted to
* a normal form.
*
* @param formId Indicates the ID of the form.
* @return None.
*/
virtual void OnCastTemptoNormal(const int64_t formId) override;
/**
* @brief Called when the form provider receives form events from the fms.
*
* @param formEventsMap Indicates the form events occurred. The key in the Map object indicates the form ID,
* and the value indicates the event type, which can be either FORM_VISIBLE
* or FORM_INVISIBLE. FORM_VISIBLE means that the form becomes visible,
* and FORM_INVISIBLE means that the form becomes invisible.
* @return none.
*/
virtual void OnVisibilityChanged(const std::map<int64_t, int32_t>& formEventsMap) override;
// Wait for AAfwk support this callback.
virtual void OnAcquireState(const OHOS::AAFwk::Want &want);
private:
int64_t abilityId_ = 0;
static int64_t instanceId_;
static const std::string START_PARAMS_KEY;
static const std::string URI;
};
} // namespace OHOS::Ace

View File

@ -63,11 +63,6 @@ void AceServiceAbility::OnStart(const OHOS::AAFwk::Want &want)
Ability::OnStart(want);
LOGI("AceServiceAbility::OnStart called");
if (type_ == BackendType::FORM) {
LOGI("AceServiceAbility::OnStart is form");
return;
}
// get url
std::string parsedUrl;
if (want.HasParameter(URI)) {
@ -118,10 +113,6 @@ void AceServiceAbility::OnStop()
sptr<IRemoteObject> AceServiceAbility::OnConnect(const Want &want)
{
LOGI("AceServiceAbility::OnConnect start");
if (type_ == BackendType::FORM) {
LOGI("AceServiceAbility::OnConnect is form");
return GetFormRemoteObject();
}
Ability::OnConnect(want);
auto ret = Platform::PaContainer::OnConnect(abilityId_, want);
if (ret == nullptr) {
@ -140,82 +131,5 @@ void AceServiceAbility::OnDisconnect(const Want &want)
LOGI("AceServiceAbility::OnDisconnect end");
}
OHOS::AppExecFwk::FormProviderInfo AceServiceAbility::OnCreate(const OHOS::AAFwk::Want& want)
{
LOGI("AceServiceAbility::OnCreate called");
// get url
std::string parsedUrl;
if (want.HasParameter(URI)) {
parsedUrl = want.GetStringParam(URI);
} else {
parsedUrl = "app.js";
}
int32_t wantId = abilityId_;
if (want.HasParameter(AppExecFwk::Constants::PARAM_FORM_IDENTITY_KEY)) {
std::string wantIdStr = want.GetStringParam(AppExecFwk::Constants::PARAM_FORM_IDENTITY_KEY);
wantId = atoi(wantIdStr.c_str());
LOGI("AceServiceAbility:: wantId = %{public}s, %{public}d", wantIdStr.c_str(), wantId);
} else {
LOGE("AceServiceAbility:: has not formId in want");
}
// init service
BackendType backendType = BackendType::FORM;
Platform::PaContainer::CreateContainer(
wantId, backendType, this,
std::make_unique<ServicePlatformEventCallback>([this]() {
TerminateAbility();
}));
// get asset
auto packagePathStr = GetBundleCodePath();
auto moduleInfo = GetHapModuleInfo();
if (moduleInfo != nullptr) {
packagePathStr += "/" + moduleInfo->name + "/";
}
auto assetBasePathStr = {std::string("assets/js/default/"), std::string("assets/js/share/")};
Platform::PaContainer::AddAssetPath(wantId, packagePathStr, assetBasePathStr);
// run service
Platform::PaContainer::RunPa(wantId, parsedUrl, want);
OHOS::AppExecFwk::FormProviderInfo formProviderInfo;
formProviderInfo.SetFormData(Platform::PaContainer::GetFormData(wantId));
std::string formData = formProviderInfo.GetFormData().GetDataString();
LOGI("AceServiceAbility::OnCreate return ok, formData: %{public}s", formData.c_str());
return formProviderInfo;
}
void AceServiceAbility::OnDelete(const int64_t formId)
{
Platform::PaContainer::OnDelete(formId);
}
void AceServiceAbility::OnTriggerEvent(const int64_t formId, const std::string& message)
{
Platform::PaContainer::OnTriggerEvent(formId, message);
}
void AceServiceAbility::OnUpdate(const int64_t formId)
{
Platform::PaContainer::OnUpdate(formId);
}
void AceServiceAbility::OnCastTemptoNormal(const int64_t formId)
{
Platform::PaContainer::OnCastTemptoNormal(formId);
}
void AceServiceAbility::OnVisibilityChanged(const std::map<int64_t, int32_t>& formEventsMap)
{
Platform::PaContainer::OnVisibilityChanged(formEventsMap);
}
void AceServiceAbility::OnAcquireState(const OHOS::AAFwk::Want& want)
{
Platform::PaContainer::OnAcquireState(want);
}
}
} // namespace OHOS::Ace

View File

@ -39,21 +39,12 @@ public:
sptr<IRemoteObject> OnConnect(const OHOS::AAFwk::Want &want) override;
void OnDisconnect(const OHOS::AAFwk::Want &want) override;
virtual OHOS::AppExecFwk::FormProviderInfo OnCreate(const OHOS::AAFwk::Want &want) override;
virtual void OnDelete(const int64_t formId) override;
virtual void OnTriggerEvent(const int64_t formId, const std::string &message) override;
virtual void OnUpdate(const int64_t formId) override;
virtual void OnCastTemptoNormal(const int64_t formId) override;
virtual void OnVisibilityChanged(const std::map<int64_t, int32_t>& formEventsMap) override;
virtual void OnAcquireState(const OHOS::AAFwk::Want &want);
private:
int32_t abilityId_ = 100000;
static int32_t instanceId_;
static const std::string START_PARAMS_KEY;
static const std::string URI;
BackendType type_ = BackendType::FORM;
};
} // namespace OHOS::Ace
#endif // FOUNDATION_ACE_ACE_ENGINE_ADAPTER_OHOS_CPP_ACE_SERVICE_ABILITY_H

View File

@ -59,6 +59,8 @@ static napi_value JSPromptShowToast(napi_env env, napi_callback_info info)
napi_value messageNApi = nullptr;
napi_value durationNApi = nullptr;
napi_value bottomNApi = nullptr;
std::string messageString;
std::string bottomString;
napi_valuetype valueType = napi_undefined;
napi_typeof(env, argv, &valueType);
@ -66,20 +68,34 @@ static napi_value JSPromptShowToast(napi_env env, napi_callback_info info)
napi_get_named_property(env, argv, "message", &messageNApi);
napi_get_named_property(env, argv, "duration", &durationNApi);
napi_get_named_property(env, argv, "bottom", &bottomNApi);
} else {
return nullptr;
}
size_t ret = 0;
size_t messageLen = GetParamLen(messageNApi);
std::unique_ptr<char[]> message(new char[messageLen] { 0 });
napi_get_value_string_utf8(env, messageNApi, message.get(), messageLen, &ret);
size_t bottomLen = GetParamLen(bottomNApi);
std::unique_ptr<char[]> bottom(new char[messageLen] { 0 });
napi_get_value_string_utf8(env, bottomNApi, bottom.get(), bottomLen, &ret);
napi_typeof(env, messageNApi, &valueType);
if (valueType == napi_string) {
size_t messageLen = GetParamLen(messageNApi) + 1;
std::unique_ptr<char[]> message = std::make_unique<char[]>(messageLen);
napi_get_value_string_utf8(env, messageNApi, message.get(), messageLen, &ret);
messageString = message.get();
} else {
LOGE("The paramter type is incorrect");
return nullptr;
}
int32_t duration = -1;
napi_get_value_int32(env, bottomNApi, &duration);
std::string messageString = message.get();
std::string bottomString = bottom.get();
napi_typeof(env, durationNApi, &valueType);
if (valueType == napi_number) {
napi_get_value_int32(env, durationNApi, &duration);
}
napi_typeof(env, bottomNApi, &valueType);
if (valueType == napi_string) {
size_t bottomLen = GetParamLen(bottomNApi) + 1;
std::unique_ptr<char[]> message = std::make_unique<char[]>(bottomLen);
napi_get_value_string_utf8(env, bottomNApi, message.get(), bottomLen, &ret);
bottomString = message.get();
}
OHOS::Ace::Framework::JsEngine* jsEngine = nullptr;
napi_get_jsEngine(env, (void**)&jsEngine);

View File

@ -11,6 +11,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import("//ark/ts2abc/ts2panda/ts2abc_config.gni")
import("//build/ohos.gni")
import("//foundation/ace/ace_engine/ace_config.gni")
@ -581,22 +582,67 @@ gen_obj("js_enum_style") {
snapshot_dep = []
}
# compile stateMgmt.js, jsEnumStyle.js to stateMgmt.abc, jsEnumStyle.abc.
action("gen_stateMgmt_abc") {
visibility = [ ":*" ]
deps = [ "//ark/ts2abc/ts2panda:ark_ts2abc_build" ]
script = "//ark/ts2abc/ts2panda/scripts/generate_js_bytecode.py"
args = [
"--src-js",
rebase_path(
"//foundation/ace/ace_engine/frameworks/bridge/declarative_frontend/engine/stateMgmt.js"),
"--dst-file",
rebase_path(base_output_path + "/stateMgmt.abc"),
"--node",
rebase_path("${node_path}"),
"--frontend-tool-path",
rebase_path("${ts2abc_build_path}"),
"--node-modules",
rebase_path("${node_modules}"),
]
inputs = [ "//foundation/ace/ace_engine/frameworks/bridge/declarative_frontend/engine/stateMgmt.js" ]
outputs = [ base_output_path + "/stateMgmt.abc" ]
}
action("gen_jsEnumStyle_abc") {
visibility = [ ":*" ]
deps = [ "//ark/ts2abc/ts2panda:ark_ts2abc_build" ]
script = "//ark/ts2abc/ts2panda/scripts/generate_js_bytecode.py"
args = [
"--src-js",
rebase_path(
"//foundation/ace/ace_engine/frameworks/bridge/declarative_frontend/engine/jsEnumStyle.js"),
"--dst-file",
rebase_path(base_output_path + "/jsEnumStyle.abc"),
"--node",
rebase_path("${node_path}"),
"--frontend-tool-path",
rebase_path("${ts2abc_build_path}"),
"--node-modules",
rebase_path("${node_modules}"),
]
inputs = [ "//foundation/ace/ace_engine/frameworks/bridge/declarative_frontend/engine/jsEnumStyle.js" ]
outputs = [ base_output_path + "/jsEnumStyle.abc" ]
}
gen_obj("abc_proxyclass") {
input = "declarative_frontend/engine/stateMgmt.abc"
if (use_mac) {
abcproxyclass_obj_path = base_output_path + "/js_proxy_class.c"
}
input = base_output_path + "/stateMgmt.abc"
output = abcproxyclass_obj_path
snapshot_dep = []
snapshot_dep = [ ":gen_stateMgmt_abc" ]
}
gen_obj("abc_enum_style") {
input = "declarative_frontend/engine/jsEnumStyle.abc"
if (use_mac) {
abcenumstyle_obj_path = base_output_path + "/js_enum_style.c"
}
input = base_output_path + "/jsEnumStyle.abc"
output = abcenumstyle_obj_path
snapshot_dep = []
snapshot_dep = [ ":gen_jsEnumStyle_abc" ]
}
gen_obj("js_mock_system_plugin") {
@ -775,7 +821,10 @@ template("declarative_js_engine") {
defines += [ "APP_USE_ARM" ]
}
deps += [ "//ark/js_runtime:libark_jsruntime" ]
deps += [
"//ark/js_runtime:libark_jsruntime",
"//third_party/jsframework:ark_build",
]
configs += [
"//ark/runtime_core/libpandabase:arkbase_public_config",
@ -928,8 +977,7 @@ template("js_backend_engine") {
"appexecfwk_standard:appexecfwk_core",
"appexecfwk_standard:libeventhandler",
"ipc:ipc_core",
#"ipc_js:rpc",
"ipc_js:rpc",
"napi:ace_napi",
"samgr_L2:samgr_proxy",
]

View File

@ -136,6 +136,7 @@ private:
static JSGCMarkCallback<C> jsGcMark_;
static std::string className_;
static panda::Global<panda::FunctionRef> classFunction_;
static std::vector<shared_ptr<int32_t>> functionIds_;
};
template<typename T>

View File

@ -43,6 +43,9 @@ std::string JsiClass<C>::className_;
template<typename C>
panda::Global<panda::FunctionRef> JsiClass<C>::classFunction_;
template<typename C>
std::vector<shared_ptr<int32_t>> JsiClass<C>::functionIds_;
template<typename C>
void JsiClass<C>::Declare(const char* name)
{
@ -58,6 +61,7 @@ void JsiClass<C>::Method(const char* name, R (Base::*func)(Args...), int id)
auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetJsRuntime());
auto vm = runtime->GetEcmaVm();
auto funcId = std::make_shared<int32_t>(id);
functionIds_.emplace_back(funcId);
customFunctions_.emplace(name, panda::FunctionRef::New(vm, MethodCallback<Base, R, Args...>, funcId.get()));
}
@ -68,6 +72,7 @@ void JsiClass<C>::CustomMethod(const char* name, MemberFunctionCallback<T> callb
auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetJsRuntime());
auto vm = runtime->GetEcmaVm();
auto funcId = std::make_shared<int32_t>(id);
functionIds_.emplace_back(funcId);
customFunctions_.emplace(
name, panda::FunctionRef::New(vm,
InternalMemberFunctionCallback<T, panda::EcmaVM*, panda::Local<panda::JSValueRef>,
@ -90,6 +95,7 @@ void JsiClass<C>::CustomMethod(const char* name, JSMemberFunctionCallback<T> cal
auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetJsRuntime());
auto vm = runtime->GetEcmaVm();
auto funcId = std::make_shared<int32_t>(id);
functionIds_.emplace_back(funcId);
customFunctions_.emplace(name, panda::FunctionRef::New(vm, InternalJSMemberFunctionCallback<T>, funcId.get()));
}
@ -100,7 +106,8 @@ void JsiClass<C>::StaticMethod(const char* name, R (*func)(Args...), int id)
auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetJsRuntime());
auto vm = runtime->GetEcmaVm();
auto funcId = std::make_shared<int32_t>(id);
customFunctions_.emplace(name, panda::FunctionRef::New(vm, StaticMethodCallback<R, Args...>, funcId.get()));
functionIds_.emplace_back(funcId);
staticFunctions_.emplace(name, panda::FunctionRef::New(vm, StaticMethodCallback<R, Args...>, funcId.get()));
}
template<typename C>
@ -109,6 +116,7 @@ void JsiClass<C>::StaticMethod(const char* name, JSFunctionCallback func, int id
auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetJsRuntime());
auto vm = runtime->GetEcmaVm();
auto funcId = std::make_shared<int32_t>(id);
functionIds_.emplace_back(funcId);
staticFunctions_.emplace(name, panda::FunctionRef::New(vm, JSStaticMethodCallback, funcId.get()));
}
@ -142,6 +150,8 @@ void JsiClass<C>::Bind(BindingTarget t, FunctionCallback ctor)
vm, panda::FunctionRef::NewClassFunction(vm, ConstructorInterceptor, nullptr, nullptr));
classFunction_->SetName(vm, StringRef::NewFromUtf8(vm, className_.c_str()));
auto prototype = Local<ObjectRef>(classFunction_->GetFunctionPrototype(vm));
prototype->Set(vm, panda::StringRef::NewFromUtf8(vm, "constructor"),
panda::Local<panda::JSValueRef>(classFunction_.ToLocal(vm)));
for (const auto& [name, val] : staticFunctions_) {
classFunction_->Set(vm, panda::StringRef::NewFromUtf8(vm, name.c_str()), val);
}
@ -164,6 +174,8 @@ void JsiClass<C>::Bind(
vm, panda::FunctionRef::NewClassFunction(vm, JSConstructorInterceptor, nullptr, nullptr));
classFunction_->SetName(vm, StringRef::NewFromUtf8(vm, className_.c_str()));
auto prototype = panda::Local<panda::ObjectRef>(classFunction_->GetFunctionPrototype(vm));
prototype->Set(vm, panda::StringRef::NewFromUtf8(vm, "constructor"),
panda::Local<panda::JSValueRef>(classFunction_.ToLocal(vm)));
for (const auto& [name, val] : staticFunctions_) {
classFunction_->Set(vm, panda::StringRef::NewFromUtf8(vm, name.c_str()), val);
}
@ -186,6 +198,8 @@ void JsiClass<C>::Bind(BindingTarget t, JSDestructorCallback<C> dtor, JSGCMarkCa
vm, panda::FunctionRef::NewClassFunction(vm, InternalConstructor<Args...>, nullptr, nullptr));
classFunction_->SetName(vm, StringRef::NewFromUtf8(vm, className_.c_str()));
auto prototype = panda::Local<panda::ObjectRef>(classFunction_->GetFunctionPrototype(vm));
prototype->Set(vm, panda::StringRef::NewFromUtf8(vm, "constructor"),
panda::Local<panda::JSValueRef>(classFunction_.ToLocal(vm)));
for (const auto& [name, val] : staticFunctions_) {
classFunction_->Set(vm, panda::StringRef::NewFromUtf8(vm, name.c_str()), val);
}
@ -200,15 +214,15 @@ template<typename C>
template<typename Base>
void JsiClass<C>::Inherit()
{
auto& staticFunctions = GetStaticFunctions();
auto& staticFunctions = JsiClass<Base>::GetStaticFunctions();
for (auto& [name, function] : staticFunctions) {
if (staticFunctions_.find(name) != staticFunctions_.end()) {
continue;
}
staticFunctions_.emplace(name, function);
}
auto& customFunctions_ = GetCustomFunctions();
for (auto& [name, function] : customFunctions_) {
auto& customFunctions = JsiClass<Base>::GetCustomFunctions();
for (auto& [name, function] : customFunctions) {
if (customFunctions_.find(name) != customFunctions_.end()) {
continue;
}
@ -385,11 +399,17 @@ panda::Local<panda::JSValueRef> JsiClass<C>::InternalConstructor(panda::EcmaVM*
panda::Local<panda::JSValueRef> thisObj, panda::Local<JSValueRef> newTarget,
const panda::Local<panda::JSValueRef> argv[], int32_t argc, void* data)
{
JsiCallbackInfo info(vm, thisObj, argc, argv);
if (!newTarget->IsFunction()) {
return panda::Local<panda::JSValueRef>(panda::JSValueRef::Undefined(vm));
}
auto function = panda::Local<panda::FunctionRef>(newTarget);
auto proto = function->GetFunctionPrototype(vm);
JsiCallbackInfo info(vm, proto, argc, argv);
auto tuple = __detail__::ToTuple<std::decay_t<Args>...>(argv);
C* instance = FunctionUtils::ConstructFromTuple<C>(tuple);
Local<ObjectRef>(thisObj)->SetNativePointerFieldCount(1);
panda::Local<panda::ObjectRef>(thisObj)->SetNativePointerField(0, static_cast<void*>(instance));
return panda::Local<panda::JSValueRef>(panda::JSValueRef::Undefined(vm));
return thisObj;
}
template<typename C>
@ -404,7 +424,12 @@ panda::Local<panda::JSValueRef> JsiClass<C>::ConstructorInterceptor(panda::EcmaV
panda::Local<panda::JSValueRef> thisObj, panda::Local<panda::JSValueRef> newTarget,
const panda::Local<panda::JSValueRef> argv[], int32_t argc, void* data)
{
return constructor_(vm, thisObj, argv, argc, data);
if (!newTarget->IsFunction()) {
return panda::Local<panda::JSValueRef>(panda::JSValueRef::Undefined(vm));
}
auto function = panda::Local<panda::FunctionRef>(newTarget);
auto proto = function->GetFunctionPrototype(vm);
return constructor_(vm, proto, argv, argc, data);
}
template<typename C>
@ -412,8 +437,24 @@ panda::Local<panda::JSValueRef> JsiClass<C>::JSConstructorInterceptor(panda::Ecm
panda::Local<panda::JSValueRef> thisObj, panda::Local<panda::JSValueRef> newTarget,
const panda::Local<panda::JSValueRef> argv[], int32_t argc, void* data)
{
JsiCallbackInfo info(vm, thisObj, argc, argv);
jsConstructor_(info);
if (newTarget->IsFunction()) {
auto function = panda::Local<panda::FunctionRef>(newTarget);
auto proto = function->GetFunctionPrototype(vm);
JsiCallbackInfo info(vm, proto, argc, argv);
jsConstructor_(info);
auto retVal = info.GetReturnValue();
if (retVal.valueless_by_exception()) {
LOGE("Constructor of %s must return a value!", ThisJSClass::JSName());
return panda::Local<panda::JSValueRef>(panda::JSValueRef::Undefined(vm));
}
auto instance = std::get_if<void*>(&retVal);
if (instance) {
Local<ObjectRef>(thisObj)->SetNativePointerFieldCount(1);
Local<ObjectRef>(thisObj)->SetNativePointerField(0, *instance);
LOGD("Constructed %s", ThisJSClass::JSName());
return thisObj;
}
}
return panda::Local<panda::JSValueRef>(panda::JSValueRef::Undefined(vm));
}

View File

@ -458,11 +458,14 @@ void JsiDeclarativeEngineInstance::RootViewHandle(const shared_ptr<JsRuntime>& r
LOGE("jsRuntime is nullptr");
return;
}
auto arkRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
panda::Global<panda::ObjectRef> globalValue = panda::Global<ObjectRef>(arkRuntime->GetEcmaVm(), value);
RefPtr<JsAcePage> page = JsiDeclarativeEngineInstance::GetStagingPage(runtime);
if (page != nullptr) {
rootViewMap_.emplace(page->GetPageId(), globalValue);
auto arkRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime_);
if (!arkRuntime) {
LOGE("ark engine is null");
return;
}
rootViewMap_.emplace(page->GetPageId(), panda::Global<panda::ObjectRef>(arkRuntime->GetEcmaVm(), value));
}
}
@ -470,7 +473,12 @@ void JsiDeclarativeEngineInstance::DestroyRootViewHandle(int32_t pageId)
{
CHECK_RUN_ON(JS);
if (rootViewMap_.count(pageId) != 0) {
panda::Global<panda::ObjectRef> rootView = rootViewMap_[pageId];
auto arkRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime_);
if (!arkRuntime) {
LOGE("ark engine is null");
return;
}
panda::Local<panda::ObjectRef> rootView = rootViewMap_[pageId].ToLocal(arkRuntime->GetEcmaVm());
JSView* jsView = static_cast<JSView*>(rootView->GetNativePointerField(0));
jsView->Destroy(nullptr);
rootViewMap_.erase(pageId);
@ -483,8 +491,13 @@ void JsiDeclarativeEngineInstance::DestroyAllRootViewHandle()
if (rootViewMap_.size() > 0) {
LOGI("DestroyAllRootViewHandle release left %{private}zu views ", rootViewMap_.size());
}
auto arkRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime_);
if (!arkRuntime) {
LOGE("ark engine is null");
return;
}
for (const auto& pair : rootViewMap_) {
panda::Global<panda::ObjectRef> rootView = pair.second;
panda::Local<panda::ObjectRef> rootView = pair.second.ToLocal(arkRuntime->GetEcmaVm());
JSView* jsView = static_cast<JSView*>(rootView->GetNativePointerField(0));
jsView->Destroy(nullptr);
}
@ -635,7 +648,7 @@ bool JsiDeclarativeEngine::Initialize(const RefPtr<FrontendDelegate>& delegate)
nativeEngine_ = new ArkNativeEngine(const_cast<EcmaVM*>(vm), static_cast<void*>(this));
ACE_DCHECK(delegate);
delegate->AddTaskObserver([nativeEngine = nativeEngine_](){
nativeEngine->Loop(LOOP_DEFAULT);
nativeEngine->Loop(LOOP_NOWAIT);
});
return result;

View File

@ -78,7 +78,8 @@ public:
template<typename... Args>
static JsiRef<T> Make(Args&&... args)
{
return JsiRef<T>::Claim(T { std::forward<Args>(args)... });
auto obj = T { args... };
return JsiRef<T>(obj);
}
static JsiRef<T> Claim(T&& val)

View File

@ -27,48 +27,83 @@ JsiValue::JsiValue(panda::Local<panda::JSValueRef> val) : JsiType(val) {}
bool JsiValue::IsEmpty() const
{
return GetHandle().IsEmpty();
if (GetHandle().IsEmpty()) {
return true;
}
return GetHandle()->IsUndefined() || GetHandle()->IsNull();
}
bool JsiValue::IsFunction() const
{
return GetHandle()->IsFunction();
if (GetHandle().IsEmpty()) {
return false;
} else {
return GetHandle()->IsFunction();
}
}
bool JsiValue::IsNumber() const
{
return GetHandle()->IsNumber();
if (GetHandle().IsEmpty()) {
return false;
} else {
return GetHandle()->IsNumber();
}
}
bool JsiValue::IsString() const
{
return GetHandle()->IsString();
if (GetHandle().IsEmpty()) {
return false;
} else {
return GetHandle()->IsString();
}
}
bool JsiValue::IsBoolean() const
{
return GetHandle()->IsBoolean();
if (GetHandle().IsEmpty()) {
return false;
} else {
return GetHandle()->IsBoolean();
}
}
bool JsiValue::IsObject() const
{
return GetHandle()->IsObject();
if (GetHandle().IsEmpty()) {
return false;
} else {
return GetHandle()->IsObject();
}
}
bool JsiValue::IsArray() const
{
auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetJsRuntime());
return GetHandle()->IsArray(runtime->GetEcmaVm());
if (GetHandle().IsEmpty()) {
return false;
} else {
return GetHandle()->IsArray(runtime->GetEcmaVm());
}
}
bool JsiValue::IsUndefined() const
{
return GetHandle()->IsUndefined();
if (GetHandle().IsEmpty()) {
return true;
} else {
return GetHandle()->IsUndefined();
}
}
bool JsiValue::IsNull() const
{
return GetHandle()->IsNull();
if (GetHandle().IsEmpty()) {
return true;
} else {
return GetHandle()->IsNull();
}
}
std::string JsiValue::ToString() const
@ -124,7 +159,10 @@ JsiRef<JsiValue> JsiObject::GetProperty(const char* prop) const
{
auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetJsRuntime());
auto stringRef = panda::StringRef::NewFromUtf8(runtime->GetEcmaVm(), prop);
return JsiRef<JsiValue>::Make(GetHandle()->Get(runtime->GetEcmaVm(), stringRef));
auto value = GetHandle()->Get(runtime->GetEcmaVm(), stringRef);
auto func = JsiValue(value);
auto refValue = JsiRef<JsiValue>(func);
return refValue;
}
void JsiObject::SetPropertyJsonObject(const char* prop, const char* value) const
@ -158,7 +196,6 @@ JsiFunction::JsiFunction(panda::Local<panda::FunctionRef> val) : JsiType(val)
JsiRef<JsiValue> JsiFunction::Call(JsiRef<JsiValue> thisVal, int argc, JsiRef<JsiValue> argv[]) const
{
panda::LocalScope scope(vm_);
std::vector<panda::Local<panda::JSValueRef>> arguments;
for (int i = 0; i < argc; ++i) {
arguments.emplace_back(argv[i].Get().GetHandle());
@ -211,7 +248,9 @@ JsiRef<JsiValue> JsiCallbackInfo::operator[](size_t index) const
JsiRef<JsiObject> JsiCallbackInfo::This() const
{
return JsiRef<JsiObject>::Make(thisObj_);
auto obj = JsiObject { thisObj_ };
auto ref = JsiRef<JsiObject>(obj);
return ref;
}
int JsiCallbackInfo::Length() const

View File

@ -40,30 +40,40 @@ JsiType<T>::JsiType(panda::Local<S> val)
}
template<typename T>
JsiType<T>::JsiType(panda::Global<T> other) : handle_(other)
{}
template<typename T>
JsiType<T>::JsiType(const JsiType<T>& rhs) : handle_(rhs.handle_)
{}
template<typename T>
JsiType<T>::JsiType(JsiType<T>&& rhs) : handle_(std::move(rhs.handle_))
JsiType<T>::JsiType(panda::Global<T> other)
{
auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetJsRuntime());
handle_ = Global<T>(runtime->GetEcmaVm(), other.ToLocal(runtime->GetEcmaVm()));
}
template<typename T>
JsiType<T>::JsiType(const JsiType<T>& rhs)
{
auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetJsRuntime());
handle_ = Global<T>(runtime->GetEcmaVm(), rhs.handle_.ToLocal(runtime->GetEcmaVm()));
}
template<typename T>
JsiType<T>::JsiType(JsiType<T>&& rhs)
{
auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetJsRuntime());
handle_ = Global<T>(runtime->GetEcmaVm(), rhs.handle_.ToLocal(runtime->GetEcmaVm()));
rhs.handle_.FreeGlobalHandleAddr();
}
template<typename T>
JsiType<T>& JsiType<T>::operator=(const JsiType<T>& rhs)
{
handle_ = rhs.handle_;
auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetJsRuntime());
handle_ = Global<T>(runtime->GetEcmaVm(), rhs.handle_.ToLocal(runtime->GetEcmaVm()));
return *this;
}
template<typename T>
JsiType<T>& JsiType<T>::operator=(JsiType<T>&& rhs)
{
handle_ = std::move(rhs.handle_);
auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetJsRuntime());
handle_ = Global<T>(runtime->GetEcmaVm(), rhs.handle_.ToLocal(runtime->GetEcmaVm()));
rhs.handle_.FreeGlobalHandleAddr();
return *this;
}

View File

@ -18,9 +18,7 @@
#include<vector>
#include "bridge/declarative_frontend/jsview/js_view_common_def.h"
#include "bridge/declarative_frontend/view_stack_processor.h"
#include "core/components/text_field/render_text_field.h"
#include "core/components/text_field/text_field_component.h"
#include "core/components/text_field/text_field_element.h"
#include "frameworks/bridge/declarative_frontend/engine/functions/js_function.h"
#include "frameworks/bridge/declarative_frontend/jsview/js_container_base.h"
#include "frameworks/bridge/declarative_frontend/jsview/js_interactable_view.h"
@ -205,4 +203,4 @@ void JSTextArea::SetOnChange(const JSCallbackInfo& info)
info.ReturnSelf();
}
} // namespace OHOS::Ace::Framework
} // namespace OHOS::Ace::Framework

View File

@ -15,14 +15,12 @@
#include "frameworks/bridge/declarative_frontend/jsview/js_textinput.h"
#include<vector>
#include <vector>
#include "frameworks/bridge/declarative_frontend/engine/functions/js_function.h"
#include "frameworks/bridge/declarative_frontend/jsview/js_view_common_def.h"
#include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
#include "frameworks/core/components/text_field/render_text_field.h"
#include "frameworks/core/components/text_field/text_field_component.h"
#include "frameworks/core/components/text_field/text_field_element.h"
#include "frameworks/core/common/ime/text_input_action.h"
namespace OHOS::Ace::Framework {
@ -258,4 +256,4 @@ void JSTextInput::SetOnChange(const JSCallbackInfo& info)
info.ReturnSelf();
}
} // namespace OHOS::Ace::Framework
} // namespace OHOS::Ace::Framework

View File

@ -152,6 +152,15 @@ public:
instanceName_ = name;
}
void SetDialogCallback(const DialogCallback callback)
{
dialogCallback_ = callback;
}
DialogCallback GetDialogCallback() const
{
return dialogCallback_;
}
void AddExtraNativeObject(const std::string& key, void* value)
{
extraNativeObject_[key] = value;
@ -194,6 +203,7 @@ private:
std::string instanceName_;
std::unordered_map<std::string, void*> extraNativeObject_;
DialogCallback dialogCallback_;
};
} // namespace OHOS::Ace::Framework

View File

@ -37,6 +37,7 @@
#include "base/utils/utils.h"
#include "core/common/ace_application_info.h"
#include "core/common/container.h"
#include "core/common/frontend.h"
#include "core/event/ace_event_helper.h"
#include "core/event/back_end_event_manager.h"
#include "frameworks/bridge/common/dom/dom_type.h"
@ -79,6 +80,7 @@ constexpr int32_t ARGS_READ_RESOURCE_LENGTH = 2;
constexpr int32_t MAX_READ_TEXT_LENGTH = 4096;
const std::regex URI_PARTTEN("^\\/([a-z0-9A-Z_]+\\/)*[a-z0-9A-Z_]+\\.?[a-z0-9A-Z_]*$");
static int32_t globalNodeId = 50000;
const std::string WINDOW_DIALOG_DOUBLE_BUTTON = "pages/dialog/dialog.js";
int32_t CallEvalBuf(
JSContext* ctx, const char* buf, size_t bufLen, const char* filename, int32_t evalFlags, int32_t instanceId)
@ -2448,6 +2450,33 @@ JSValue JsLoadLocaleData(JSContext* ctx, JSValueConst value, int32_t argc, JSVal
}
}
std::map<int32_t, JsEngine *> g_JsEngindMap;
JSValue JSWindowCallBack(JSContext* ctx, JSValueConst value, int32_t argc, JSValueConst* argv)
{
ACE_SCOPED_TRACE("QjsEngine::JSWindowCallBack");
LOGI("JSWindowCallBack");
JSValue globalObj = JS_GetGlobalObject(ctx);
JSValue id = JS_GetPropertyStr(ctx, globalObj, "dialogId");
int32_t global_id;
JS_ToInt32(ctx, &global_id, id);
for (auto& iter : g_JsEngindMap) {
if (iter.first == id) {
JsEngine* jsEngine = iter.second;
if (jsEngine == nullptr) {
return JS_NULL;
}
DialogCallback dialogCallback = jsEngine->GetDialogCallback();
if (dialogCallback) {
dialogCallback("OK", "");
}
}
}
return JS_NULL;
}
// Follow definition in quickjs.
#define JS_CFUNC_DEF_CPP(name, length, func) \
{ \
@ -2515,6 +2544,7 @@ void InitJsConsoleObject(JSContext* ctx, const JSValue& globalObj)
JS_SetPropertyStr(ctx, aceConsole, "warn", JS_NewCFunction(ctx, JsWarnLogPrint, "warn", 1));
JS_SetPropertyStr(ctx, aceConsole, "error", JS_NewCFunction(ctx, JsErrorLogPrint, "error", 1));
JS_SetPropertyStr(ctx, globalObj, "aceConsole", aceConsole);
JS_SetPropertyStr(ctx, globalObj, "dialogCallback", JS_NewCFunction(ctx, JSWindowCallBack, "dialogCallback", 1));
}
void InitJsDocumentObject(JSContext* ctx, const JSValue& globalObj)
@ -2910,6 +2940,7 @@ bool QjsEngine::Initialize(const RefPtr<FrontendDelegate>& delegate)
ACE_SCOPED_TRACE("QjsEngine::Initialize");
LOGI("Initialize");
g_JsEngindMap[instanceId_] = this;
JSRuntime* runtime = nullptr;
JSContext* context = nullptr;
@ -3113,6 +3144,9 @@ void QjsEngine::LoadJs(const std::string& url, const RefPtr<JsAcePage>& page, bo
JS_SetContextOpaque(ctx, reinterpret_cast<void*>(AceType::RawPtr(engineInstance_)));
JSValue globalObj = JS_GetGlobalObject(ctx);
if((url.compare(WINDOW_DIALOG_DOUBLE_BUTTON)) == 0){
JS_SetPropertyStr(ctx, globalObj, "dialogId", JS_NewInt32(ctx, instanceId_));
}
JSValue createInstanceFunc = QJSUtils::GetPropertyStr(ctx, globalObj, "createInstance");
if (!JS_IsFunction(ctx, createInstanceFunc)) {
LOGD("createInstance is not found, cannot load js!");

View File

@ -157,6 +157,10 @@ void FrontendDelegateImpl::RunPage(const std::string& url, const std::string& pa
} else {
mainPagePath_ = manifestParser_->GetRouter()->GetEntry();
}
if ((url.find("pages/dialog/dialog.js")) != -1) {
mainPagePath_ = url;
}
LoadPage(GenerateNextPageId(), mainPagePath_, true, params);
}
@ -1306,10 +1310,12 @@ void FrontendDelegateImpl::PopPage()
return;
}
auto ability = static_cast<AppExecFwk::Ability*>(delegate->ability_);
std::shared_ptr<AppExecFwk::AbilityInfo> info = ability->GetAbilityInfo();
if (info != nullptr && info->isLauncherAbility) {
LOGW("launcher ability, return");
return;
if (ability) {
std::shared_ptr<AppExecFwk::AbilityInfo> info = ability->GetAbilityInfo();
if (info != nullptr && info->isLauncherAbility) {
LOGW("launcher ability, return");
return;
}
}
#if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM)
delegate->OnPageHide();

View File

@ -163,6 +163,12 @@ public:
ability_ = ability;
}
void SetDialogCallback(DialogCallback callback) override
{
if (jsEngine_) {
jsEngine_->SetDialogCallback(callback);
}
}
private:
void InitializeFrontendDelegate(const RefPtr<TaskExecutor>& taskExecutor);

View File

@ -21,11 +21,9 @@
#include <unistd.h>
#include <unordered_map>
/*
#include "napi/native_node_api.h"
#include "napi_common_want.h"
#include "napi_remote_object.h"
*/
#include "third_party/quickjs/message_server.h"
@ -525,13 +523,10 @@ void QjsPaEngine::LoadJs(const std::string& url, const OHOS::AAFwk::Want &want)
return;
}
/*
napi_value napiWant = OHOS::AppExecFwk::WrapWant(reinterpret_cast<napi_env>(nativeEngine_), want);
NativeValue* nativeWant = reinterpret_cast<NativeValue*>(napiWant);
JSValue jsWant = (JSValue)*nativeWant;
JSValueConst argv[] = { jsWant };
*/
JSValueConst argv[] = {};
JSValue retVal = QJSUtils::Call(ctx, paStartFunc, paObj, countof(argv), argv);
if (JS_IsException(retVal)) {
LOGE("PA: QjsPaEngine QJSUtils::Call IsException");
@ -1066,7 +1061,6 @@ Uri QjsPaEngine::DenormalizeUri(const Uri& uri)
sptr<IRemoteObject> QjsPaEngine::OnConnectService(const OHOS::AAFwk::Want &want)
{
/*
LOGI("OnConnectService");
JSContext *ctx = engineInstance_->GetQjsContext();
ACE_DCHECK(ctx);
@ -1103,13 +1097,10 @@ sptr<IRemoteObject> QjsPaEngine::OnConnectService(const OHOS::AAFwk::Want &want)
JS_FreeValue(ctx, retVal);
return remoteObj;
}
*/
return nullptr;
}
void QjsPaEngine::OnDisconnectService(const OHOS::AAFwk::Want &want)
{
/*
LOGI("OnDisconnectService");
JSContext *ctx = engineInstance_->GetQjsContext();
ACE_DCHECK(ctx);
@ -1136,7 +1127,6 @@ void QjsPaEngine::OnDisconnectService(const OHOS::AAFwk::Want &want)
LOGE("Qjs OnDisconnectService FAILED!");
}
JS_FreeValue(ctx, globalObj);
*/
}
void QjsPaEngine::OnDelete(const int64_t formId)
@ -1258,13 +1248,10 @@ void QjsPaEngine::OnAcquireState(const OHOS::AAFwk::Want &want)
QJSHandleScope handleScope(ctx);
JSValue paFunc = GetPaFunc("onAcquireState");
/*
napi_value napiWant = OHOS::AppExecFwk::WrapWant(reinterpret_cast<napi_env>(nativeEngine_), want);
NativeValue* nativeWant = reinterpret_cast<NativeValue*>(napiWant);
JSValue jsWant = (JSValue)*nativeWant;
JSValueConst argv[] = { jsWant };
*/
JSValueConst argv[] = {};
JSValue retVal = QJSUtils::Call(ctx, paFunc, JS_UNDEFINED, countof(argv), argv);
if (JS_IsException(retVal)) {
LOGE("PA: OnAcquireState FAILED!");

View File

@ -32,6 +32,7 @@ constexpr int32_t DEFAULT_DESIGN_WIDTH = 720;
#else
constexpr int32_t DEFAULT_DESIGN_WIDTH = 454;
#endif
using DialogCallback = std::function<void(std::string event, std::string param)>;
// Window config of frontend.
struct WindowConfig {
@ -170,7 +171,7 @@ public:
// navigator component call router
virtual void NavigatePage(uint8_t type, const PageTarget& target, const std::string& params) {};
virtual void SetDialogCallback(DialogCallback callback) {};
virtual void NotifyAppStorage(const std::string& key, const std::string& value) {};
// Disallow pop last page

View File

@ -22,4 +22,8 @@ build_component("box") {
"render_box.cpp",
"render_box_base.cpp",
]
external_deps = [
"inputmethod_native:inputmethod_ability",
"inputmethod_native:inputmethod_client",
]
}

View File

@ -225,7 +225,7 @@ sptr<Surface> CameraCallback::createSubWindowSurface()
void CameraCallback::MarkTreeRender(const RefPtr<RenderNode>& root)
{
root->MarkNeedRender();
LOGE("Hole: MarkTreeRender %{public}s", AceType::TypeName(Referenced::RawPtr(root)));
LOGI("Hole: MarkTreeRender %{public}s", AceType::TypeName(Referenced::RawPtr(root)));
for (auto child: root->GetChildren()){
MarkTreeRender(child);
}
@ -248,7 +248,7 @@ void CameraCallback::MarkWholeRender(const WeakPtr<RenderNode>& nodeWeak)
for(auto child: parent->GetChildren()) {
if (child == node){
LOGE("Hole: MarkWholeRender meet barrier");
LOGI("Hole: MarkWholeRender meet barrier");
break;
}
MarkTreeRender(child);
@ -519,13 +519,12 @@ void CameraCallback::Release()
LOGI("CameraCallback: Destroy subWindow.");
subwindow_ = nullptr;
auto context = context_.Upgrade();
LOGE("Hole: Release x=0, y=0, w=0, h=0");
LOGI("Hole: Release x=0, y=0, w=0, h=0");
context->SetClipHole(0, 0, 0, 0);
auto renderNode = renderNode_.Upgrade();
if (renderNode) {
renderNode->SetHasSubWindow(false);
}
context->MarkForcedRefresh();
}
LOGI("CameraCallback: Release end.");
}

View File

@ -20,4 +20,9 @@ build_component("search") {
"search_component.cpp",
"search_element.cpp",
]
external_deps = [
"inputmethod_native:inputmethod_ability",
"inputmethod_native:inputmethod_client",
]
}

View File

@ -20,4 +20,9 @@ build_component("stack") {
"stack_component.cpp",
"stack_element.cpp",
]
external_deps = [
"inputmethod_native:inputmethod_ability",
"inputmethod_native:inputmethod_client",
]
}

View File

@ -21,4 +21,9 @@ build_component("text_field") {
"text_field_controller.cpp",
"text_field_element.cpp",
]
external_deps = [
"inputmethod_native:inputmethod_ability",
"inputmethod_native:inputmethod_client",
]
}

View File

@ -25,6 +25,7 @@
#include "core/components/text_overlay/text_overlay_component.h"
#include "core/components/text_overlay/text_overlay_element.h"
#include "core/event/ace_event_helper.h"
#include "unistd.h"
namespace OHOS::Ace {
namespace {
@ -55,6 +56,65 @@ constexpr Dimension DEFLATE_RADIUS_FOCUS = 3.0_vp;
} // namespace
void OnTextChangedListenerImpl::InsertText(const std::u16string& text) {
if (text.length() <= 0) {
LOGE("the text is null");
return;
}
auto renderTextField = field_.Upgrade();
if (!renderTextField) {
return;
}
auto value = renderTextField->GetEditingValue();
std::shared_ptr<TextEditingValue> textEditingValue = std::shared_ptr<TextEditingValue>(new TextEditingValue());
textEditingValue->text = value.GetBeforeSelection() + StringUtils::Str16ToStr8(text) + value.GetAfterSelection();
textEditingValue->UpdateSelection(std::max(value.selection.GetStart(), 0) + text.length());
renderTextField->UpdateEditingValue(textEditingValue, true);
}
void OnTextChangedListenerImpl::DeleteBackward(int32_t length) {
if (length <= 0) {
LOGE("Delete nothing.");
return;
}
auto renderTextField = field_.Upgrade();
if (!renderTextField) {
return;
}
auto value = renderTextField->GetEditingValue();
auto start = value.selection.GetStart();
auto end = value.selection.GetEnd();
std::shared_ptr<TextEditingValue> textEditingValue = std::shared_ptr<TextEditingValue>(new TextEditingValue());
textEditingValue->text = value.text;
textEditingValue->UpdateSelection(start, end);
if (start > 0 && end > 0) {
textEditingValue->Delete(start == end ? start - length : start, end);
}
renderTextField->UpdateEditingValue(textEditingValue, true);
}
void OnTextChangedListenerImpl::SetKeyboardStatus(bool status) {
auto renderTextField = field_.Upgrade();
if (!renderTextField) {
return;
}
LOGE("aaainputmethod:SetKeyboardStatus, status=%{public}d", status);
if (status) {
renderTextField->SetInputMethodStatus(true);
} else {
MiscServices::InputMethodController::GetInstance()->Close();
renderTextField->SetInputMethodStatus(false);
}
}
RenderTextField::RenderTextField()
: twinklingInterval(TWINKLING_INTERVAL_MS), controller_(AceType::MakeRefPtr<TextEditController>())
{}
@ -78,8 +138,7 @@ RenderTextField::~RenderTextField()
// If soft keyboard is still exist, close it.
if (HasConnection()) {
connection_->Close(GetInstanceId());
connection_ = nullptr;
MiscServices::InputMethodController::GetInstance()->Close();
}
}
@ -685,15 +744,12 @@ bool RenderTextField::RequestKeyboard(bool isFocusViewChanged, bool needStartTwi
}
if (softKeyboardEnabled_) {
if (!HasConnection()) {
AttachIme();
if (!HasConnection()) {
LOGE("Get TextInput connection error");
return false;
}
connection_->SetEditingState(GetEditingValue(), GetInstanceId());
}
connection_->Show(isFocusViewChanged, GetInstanceId());
if (!HasConnection()) {
MiscServices::InputMethodController::GetInstance()->Attach();
sleep(1);
listener_ = new OnTextChangedListenerImpl(WeakClaim(this));
MiscServices::InputMethodController::GetInstance()->ShowTextInput(listener_);
}
}
if (keyboard_ != TextInputType::MULTILINE) {
resetToStart_ = false;
@ -710,8 +766,7 @@ bool RenderTextField::CloseKeyboard(bool forceClose)
if (!isOverlayShowed_ || !isOverlayFocus_ || forceClose) {
StopTwinkling();
if (HasConnection()) {
connection_->Close(GetInstanceId());
connection_ = nullptr;
MiscServices::InputMethodController::GetInstance()->HideTextInput();
}
if (onKeyboardClose_) {
@ -733,26 +788,6 @@ bool RenderTextField::CloseKeyboard(bool forceClose)
return false;
}
void RenderTextField::AttachIme()
{
auto context = context_.Upgrade();
if (!context) {
LOGW("No context exists, failed to request keyboard.");
return;
}
TextInputConfiguration config;
config.type = keyboard_;
config.action = action_;
config.actionLabel = actionLabel_;
config.obscureText = obscure_;
LOGD("Request keyboard configuration: type=%{private}d action=%{private}d actionLabel=%{private}s "
"obscureText=%{private}d",
keyboard_, action_, actionLabel_.c_str(), obscure_);
connection_ =
TextInputProxy::GetInstance().Attach(WeakClaim(this), config, context->GetTaskExecutor(), GetInstanceId());
}
void RenderTextField::StartTwinkling()
{
// Ignore the result because all ops are called on this same thread (ACE UI).
@ -1340,7 +1375,6 @@ void RenderTextField::UpdateRemoteEditing(bool needFireChangeEvent)
if (!HasConnection()) {
return;
}
connection_->SetEditingState(GetEditingValue(), GetInstanceId(), needFireChangeEvent);
}
void RenderTextField::UpdateRemoteEditingIfNeeded(bool needFireChangeEvent)

View File

@ -23,10 +23,9 @@
#include "base/geometry/rect.h"
#include "base/geometry/size.h"
#include "base/utils/system_properties.h"
#include "input_method_controller.h"
#include "core/common/clipboard/clipboard.h"
#include "core/common/ime/text_edit_controller.h"
#include "core/common/ime/text_input_client.h"
#include "core/common/ime/text_input_connection.h"
#include "core/common/ime/text_input_formatter.h"
#include "core/common/ime/text_input_type.h"
#include "core/common/ime/text_selection.h"
@ -46,6 +45,7 @@ namespace OHOS::Ace {
class ClickRecognizer;
class ClickInfo;
class TextOverlayComponent;
class RenderTextField;
struct TextEditingValue;
enum class DirectionStatus : uint8_t {
@ -62,8 +62,19 @@ enum class CursorPositionType {
NORMAL,
};
class RenderTextField : public RenderNode, public TextInputClient, public ValueChangeObserver {
DECLARE_ACE_TYPE(RenderTextField, RenderNode, TextInputClient, ValueChangeObserver);
class OnTextChangedListenerImpl : public MiscServices::OnTextChangedListener {
public:
OnTextChangedListenerImpl(const WeakPtr<RenderTextField>& field ) : field_(field) {}
void InsertText(const std::u16string& text) override;
void DeleteBackward(int32_t length) override;
void SetKeyboardStatus(bool status) override;
private:
WeakPtr<RenderTextField> field_;
};
class RenderTextField : public RenderNode, public ValueChangeObserver {
DECLARE_ACE_TYPE(RenderTextField, RenderNode, ValueChangeObserver);
public:
~RenderTextField() override;
@ -75,8 +86,8 @@ public:
void Update(const RefPtr<Component>& component) override;
void PerformLayout() override;
// Override TextInputClient
void UpdateEditingValue(const std::shared_ptr<TextEditingValue>& value, bool needFireChangeEvent = true) override;
void PerformAction(TextInputAction action, bool forceCloseKeyboard = false) override;
void UpdateEditingValue(const std::shared_ptr<TextEditingValue>& value, bool needFireChangeEvent = true);
void PerformAction(TextInputAction action, bool forceCloseKeyboard = false);
void OnStatusChanged(RenderStatus renderStatus) override;
void OnValueChanged(bool needFireChangeEvent = true, bool needFireSelectChangeEvent = true) override;
void OnPaintFinish() override;
@ -208,6 +219,11 @@ public:
needNotifyChangeEvent_ = needNotifyChangeEvent;
}
void SetInputMethodStatus(bool imeAttached)
{
imeAttached_ = imeAttached;
}
protected:
// Describe where caret is and how tall visually.
struct CaretMetrics {
@ -262,7 +278,7 @@ protected:
bool HasConnection() const
{
return connection_;
return imeAttached_;
}
bool ShowCounter() const;
@ -436,8 +452,6 @@ private:
*/
void UpdateRemoteEditingIfNeeded(bool needFireChangeEvent = true);
void AttachIme();
int32_t initIndex_ = 0;
bool isOverlayFocus_ = false;
bool isShiftDown_ = false;
@ -446,6 +460,7 @@ private:
bool isSingleHandle_ = false;
bool hasTextOverlayPushed_ = false;
bool softKeyboardEnabled_ = true;
bool imeAttached_ = false;
Color pressColor_;
TextSelection selection_; // Selection from custom.
DeviceOrientation deviceOrientation_ = DeviceOrientation::PORTRAIT;
@ -487,6 +502,7 @@ private:
RefPtr<RawRecognizer> rawRecognizer_;
RefPtr<Animator> pressController_;
RefPtr<Animator> animator_;
sptr<MiscServices::OnTextChangedListener> listener_;
};
} // namespace OHOS::Ace

View File

@ -20,4 +20,9 @@ build_component("text_overlay") {
"text_overlay_component.cpp",
"text_overlay_element.cpp",
]
external_deps = [
"inputmethod_native:inputmethod_ability",
"inputmethod_native:inputmethod_client",
]
}

View File

@ -71,19 +71,12 @@ void FlutterRenderContext::PaintChild(const RefPtr<RenderNode>& child, const Off
if (child->NeedRender()) {
FlutterRenderContext context;
auto pipelineContext = child->GetContext().Upgrade();
LOGE("Hole: child canvas render");
if (clipHole_.IsValid() && !pipelineContext->GetHasMeetSubWindowNode()) {
auto transparentHole = pipelineContext->GetTransparentHole();
if (transparentHole.IsValid()) {
Offset childOffset = rect.GetOffset();
Rect hole = transparentHole - childOffset;
LOGE("Hole: FlutterRenderContext::PaintChild %{public}p: hole:%{public}s, offset:%{public}s", &context, hole.ToString().c_str(), childOffset.ToString().c_str());
context.SetClipHole(hole);
} else {
LOGE("Hole: FlutterRenderContext::PaintChild:hole is invalid");
}
} else {
LOGE("Hole: clipHole_ is not valid or has meed subwindownode");
LOGI("Hole: child canvas render");
auto transparentHole = pipelineContext->GetTransparentHole();
if (transparentHole.IsValid()) {
Offset childOffset = rect.GetOffset();
Rect hole = transparentHole - childOffset;
context.SetClipHole(hole);
}
context.Repaint(child);
} else {
@ -109,7 +102,8 @@ void FlutterRenderContext::StartRecording()
if (clipHole_.IsValid()) {
canvas_->save();
needRestoreHole_ = true;
canvas_->clipRect(clipHole_.Left(), clipHole_.Top(), clipHole_.Right(), clipHole_.Bottom(), SkClipOp::kDifference);
canvas_->clipRect(clipHole_.Left(), clipHole_.Top(),
clipHole_.Right(), clipHole_.Bottom(), SkClipOp::kDifference);
}
containerLayer_->AddChildren(currentLayer_);
}

View File

@ -246,7 +246,7 @@ void RenderNode::RenderWithContext(RenderContext& context, const Offset& offset)
}
pendingDispatchLayoutReady_ = false;
if (GetHasSubWindow()) {
LOGE("Hole: meet subwindow node");
LOGI("Hole: meet subwindow node");
auto& flutterRenderContext = static_cast<FlutterRenderContext&>(context);
if (flutterRenderContext.GetNeedRestoreHole()) {
auto canvas = flutterRenderContext.GetCanvas();
@ -292,6 +292,11 @@ void RenderNode::NotifyPaintFinish()
void RenderNode::Paint(RenderContext& context, const Offset& offset)
{
auto canvas = static_cast<FlutterRenderContext&>(context).GetCanvas();
if (!canvas || !canvas->canvas()) {
LOGI("Paint canvas is null");
return;
}
const auto& children = GetChildren();
for (const auto& item : SortChildrenByZIndex(children)) {
PaintChild(item, context, offset);

View File

@ -428,7 +428,7 @@ void PipelineContext::FlushRender(const RefPtr<RenderContext>& ctx)
RefPtr<RenderContext> context = isSub_ ? ctx : RenderContext::Create();
if (transparentHole_.IsValid()) {
LOGE("Hole: set transparentHole_ in FlushRender");
LOGI("Hole: set transparentHole_ in FlushRender");
context->SetClipHole(transparentHole_);
}
if (!dirtyRenderNodes_.empty()) {
@ -543,10 +543,6 @@ void PipelineContext::ProcessPreFlush()
CHECK_RUN_ON(UI);
ACE_FUNCTION_TRACE();
LOGI("Hole: set before flush.");
if (transparentHole_.IsValid()) {
hasMeetSubWindowNode_ = false;
}
if (preFlushListeners_.empty()) {
return;
}