diff --git a/framework/examples/ohos-demo/src/main/ets/pages/PageConfiguration.ets b/framework/examples/ohos-demo/src/main/ets/pages/PageConfiguration.ets index b52a8d45339..04c3b87e5a2 100755 --- a/framework/examples/ohos-demo/src/main/ets/pages/PageConfiguration.ets +++ b/framework/examples/ohos-demo/src/main/ets/pages/PageConfiguration.ets @@ -133,7 +133,7 @@ struct PageConfiguration { '', null, null, - null, + null ) loadParams.componentName = "Demo" loadParams.codeCacheTag = "Demo" @@ -389,6 +389,7 @@ struct PageConfiguration { .width('100%') .height('100%') .backgroundColor($r('app.color.home_background')) + .id("page_configuration") //.expandSafeArea() } } diff --git a/framework/examples/ohos-demo/src/main/resources/base/media/devtool.svg b/framework/examples/ohos-demo/src/main/resources/base/media/devtool.svg new file mode 100644 index 00000000000..b8d160dfa05 --- /dev/null +++ b/framework/examples/ohos-demo/src/main/resources/base/media/devtool.svg @@ -0,0 +1,4 @@ + + + + diff --git a/framework/ohos/src/main/cpp/impl/renderer/native/include/renderer/components/base_view.h b/framework/ohos/src/main/cpp/impl/renderer/native/include/renderer/components/base_view.h index 7bef902f21e..4b7e787320f 100644 --- a/framework/ohos/src/main/cpp/impl/renderer/native/include/renderer/components/base_view.h +++ b/framework/ohos/src/main/cpp/impl/renderer/native/include/renderer/components/base_view.h @@ -59,10 +59,8 @@ class BaseView : public ArkUINodeDelegate, public std::enable_shared_from_this params, std::function callback); - void AddSubRenderView(std::shared_ptr &subView, int32_t index); void RemoveSubView(std::shared_ptr &subView); void RemoveFromParentView(); @@ -168,6 +166,9 @@ class BaseView : public ArkUINodeDelegate, public std::enable_shared_from_this par result["width"] = HippyValue(viewSize.width); result["height"] = HippyValue(viewSize.height); callback(HippyValue(result)); + } else if (method == "getScreenShot") { + HippyValueObjectType snapshotResult = CallNativeRenderProviderMethod(ts_env_, ts_render_provider_ref_, ctx_->GetRootId(), "getComponentSnapshot"); + callback(HippyValue(snapshotResult)); + } else if (method == "addFrameCallback") { + // empty + } else if (method == "removeFrameCallback") { + auto resultMap = HippyValue(); + callback(resultMap); + } else if (method == "getLocationOnScreen") { + auto resultMap = CallNativeRenderProviderMethod(ts_env_, ts_render_provider_ref_, ctx_->GetRootId(), "getLocationOnScreen"); + callback(HippyValue(resultMap)); + } else { + FOOTSTONE_DLOG(INFO) << "Unsupported method called: " << method; } } @@ -833,6 +846,29 @@ void BaseView::OnViewComponentEvent(const std::string &event_name, const HippyVa arkTs.Call(callback, args); } +HippyValueObjectType BaseView::CallNativeRenderProviderMethod(napi_env env, napi_ref render_provider_ref, uint32_t component_id, const std::string &method) { + HippyValue futHippyValue; + ArkTS arkTs(env); + std::vector args = {arkTs.CreateUint32(component_id)}; + auto delegateObject = arkTs.GetObject(render_provider_ref); + auto napiValue = delegateObject.Call(method.c_str(), args); + + HippyValueObjectType map; + OhNapiObject napiObj = arkTs.GetObject(napiValue); + std::vector> pairs = napiObj.GetKeyValuePairs(); + for (auto it = pairs.begin(); it != pairs.end(); it++) { + auto &pair = *it; + auto &pairItem1 = pair.first; + auto objKey = arkTs.GetString(pairItem1); + if (objKey.length() > 0) { + auto &pairItem2 = pair.second; + auto objValue = OhNapiUtils::NapiValue2HippyValue(env, pairItem2); + map[objKey] = objValue; + } + } + return map; +} + } // namespace native } // namespace render } // namespace hippy diff --git a/framework/ohos/src/main/cpp/impl/renderer/native/src/native_render_provider_napi.cc b/framework/ohos/src/main/cpp/impl/renderer/native/src/native_render_provider_napi.cc index c9ae56fcd22..8b199e25fde 100644 --- a/framework/ohos/src/main/cpp/impl/renderer/native/src/native_render_provider_napi.cc +++ b/framework/ohos/src/main/cpp/impl/renderer/native/src/native_render_provider_napi.cc @@ -69,7 +69,7 @@ void CallRenderDelegateMethod(napi_env env, napi_ref render_provider_ref, delegateObject.Call(method.c_str(), args); }); } - + void CallRenderDelegateMethod(napi_env env, napi_ref render_provider_ref, const std::string& method, uint32_t root_id) { OhNapiTaskRunner *taskRunner = OhNapiTaskRunner::Instance(env); @@ -426,7 +426,7 @@ static napi_value DoMeasureText(napi_env env, napi_callback_info info) { int height = arkTs.GetInteger(args[4]); int heightMode = arkTs.GetInteger(args[5]); float density = render_manager->GetDensity(); - + uint32_t p = 0; OhMeasureText measureInst; OhMeasureResult result; diff --git a/framework/ohos/src/main/ets/hippy_framework/HippyEngineContextImpl.ets b/framework/ohos/src/main/ets/hippy_framework/HippyEngineContextImpl.ets index 42d3d57a62f..904ab9e2aaf 100644 --- a/framework/ohos/src/main/ets/hippy_framework/HippyEngineContextImpl.ets +++ b/framework/ohos/src/main/ets/hippy_framework/HippyEngineContextImpl.ets @@ -167,11 +167,11 @@ export class HippyEngineContextImpl implements HippyEngineContext { onBridgeDestroyed(isReload: boolean): void { // TODO devtools relaod - // if (isReload) { - // this.restartEngineInBackground(true); - // } else { - // this.destroy(false); - // } + if (isReload) { + // this.restartEngineInBackground(true); + } else { + this.destroy(false); + } } setLoadModuleCallback(loadModuleCallback: Function | null) { diff --git a/framework/ohos/src/main/ets/hippy_framework/devsupport/DevExceptionDialog.ets b/framework/ohos/src/main/ets/hippy_framework/devsupport/DevExceptionDialog.ets deleted file mode 100644 index 15c83994729..00000000000 --- a/framework/ohos/src/main/ets/hippy_framework/devsupport/DevExceptionDialog.ets +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making - * Hippy available. - * - * Copyright (C) 2022 THL A29 Limited, a Tencent company. - * All rights reserved. - * - * 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. - */ - -export class DevExceptionDialog { - -} - -export interface OnReloadListener { - onReload(): void -} diff --git a/framework/ohos/src/main/ets/hippy_framework/devsupport/DevFloatButton.ets b/framework/ohos/src/main/ets/hippy_framework/devsupport/DevFloatButton.ets index 1b726a6bc8a..51f7622879a 100644 --- a/framework/ohos/src/main/ets/hippy_framework/devsupport/DevFloatButton.ets +++ b/framework/ohos/src/main/ets/hippy_framework/devsupport/DevFloatButton.ets @@ -17,72 +17,164 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { display } from '@kit.ArkUI'; +import { ComponentContent, display, window } from '@kit.ArkUI'; -export class DevFloatButton{ - private mWidth: number; +class Params { + text: string = ""; + onClickHandle: (event: ClickEvent) => void; + radius: number; + btnPosition: Position | null = { x: 0, y: 0 }; + onTouchHandle: (event: TouchEvent) => void; + runColor = 0x317aff; + stopColor = 0xddd9d8; + btnColor = this.runColor; - constructor(context: Context) { - // super(); - this.mWidth = this.dip2px(context) as number; - this.buildBackground(); - // setFocusable(true); + constructor(text: string, btnPosition: Position | null, + radius: number, + onClickHandle: (event: ClickEvent) => void, + onTouchHandle: (event: TouchEvent) => void + ) { + this.text = text; + this.radius = radius; + this.onClickHandle = onClickHandle; + this.btnPosition = btnPosition; + this.onTouchHandle = onTouchHandle; } +} - private dip2px(context: Context): number { - let displayClass: display.Display = display.getDefaultDisplaySync(); - return displayClass.densityPixels - // DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); - // return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, SIZE, displayMetrics); +@Builder +function buildeFloatBtn(params: Params) { + Row() { + Image(null).width(params.radius).backgroundColor(params.btnColor).fillColor(params.btnColor) } + .width(params.radius * 2) + .height(params.radius * 2) + .justifyContent(FlexAlign.Center) + .borderRadius(params.radius) + .backgroundColor(params.btnColor) + .position(params.btnPosition) + .onClick(params.onClickHandle) + .onTouch(params.onTouchHandle) +} - private buildBackground() { - this.buildDrawableState(); +@Builder +function buildReload(params: Params) { + Flex() { + Text(params.text).fontSize(20).margin({ left: 20, top: 20 }) } + .width("88%") + .height("8%") + .align(Alignment.Center) + .backgroundColor(Color.White) + .onClick(params.onClickHandle) +} - /** - * 构建背景Drawble - */ - private buildDrawableState() { +export class DevFloatButton { + private mWidth: number; + private floatButtonArray: ComponentContent[] = []; + private uiContext?: UIContext; + private btnPosition: Position = { + x: 0, + y: 0, + }; + private statusHeight: number = 0 + private bottomAvoidAreaHeight: number = 0 + private startLeft: number = 0 + private startTop: number = 0 + private startX: number = 0 + private startY: number = 0 + private radius: number = 18 + private winWidth: number = 0 + private winHeight: number = 0 - // let mNormalState = new int[]; - // let mFocusedSate = new int[]{android.R.attr.state_focused, android.R.attr.state_enabled}; + constructor(context: Context, onClickHandle: (event: ClickEvent) => void) { + this.mWidth = this.getDensityPixels(context) as number; + this.getWindowInfo(onClickHandle); + } - //默认文字和背景颜色 - // let mBgNormalColor = Color.parseColor("#ddd9d9"); - // let mBgFocusedColor = Color.GREEN; - //创建状态管理器 - // StateListDrawable drawable = new StateListDrawable(); - // int radius = mWidth / 2; - // float[] outRect = new float[]{radius, radius, radius, radius, radius, radius, radius, - // radius}; - // RoundRectShape rectShape = new RoundRectShape(outRect, null, null); + getWindowInfo(onClickHandle: (event: ClickEvent) => void) { + window.getLastWindow(getContext(this), (err, windowClass) => { + if (!err.code) { + this.uiContext = windowClass.getUIContext(); + //状态栏高度 + this.statusHeight = + px2vp(windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM).topRect.height) + //获取手机底部规避区域高度 + this.bottomAvoidAreaHeight = + px2vp(windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) + .bottomRect + .height) + //获取窗口宽高 + let windowProperties = windowClass.getWindowProperties() + this.winWidth = px2vp(windowProperties.windowRect.width) + this.winHeight = px2vp(windowProperties.windowRect.height) + //设置初始位置 + this.btnPosition.x = this.winWidth * 0 + this.btnPosition.y = this.winHeight * 0.1 + // this.create(onClickHandle); + } + }); + } - //创建圆弧形状 - //创建drawable - // let pressedDrawable = new ShapeDrawable(rectShape); - //设置我们按钮背景的颜色 - // pressedDrawable.getPaint().setColor(mBgFocusedColor); - //添加到状态管理里面 - // drawable.addState(mFocusedSate, pressedDrawable); + private updateCurrentBtnPosition(params: Params, event: TouchEvent) { + let touch = event.touches[0]; + let curLeft = this.startLeft + (touch.windowX - this.startX); + curLeft = Math.max(0, curLeft) + this.btnPosition.x = Math.min(this.winWidth - 2 * this.radius, curLeft); - // ShapeDrawable normalDrawable = new ShapeDrawable(rectShape); - // normalDrawable.getPaint().setColor(mBgNormalColor); - // drawable.addState(mNormalState, normalDrawable); - //设置我们的背景,就是xml里面的selector - // this.setBackgroundDrawable(drawable); + let curTop = this.startTop + (touch.windowY - this.startY); + curTop = Math.max(0, curTop); + this.btnPosition.y = Math.min(this.winHeight - 2 * this.radius - this.bottomAvoidAreaHeight - + this.statusHeight, curTop); + this.floatButtonArray.forEach((btn: ComponentContent) => { + btn.update(params); + }); + } + + private create(onClickHandle: (event: ClickEvent) => void) { + let params = new Params("Test", this.btnPosition, this.radius, (event: ClickEvent) => { + const action = this.uiContext?.getPromptAction(); + if (this.uiContext != null) { + let contentNode = new ComponentContent(this.uiContext, wrapBuilder(buildReload), + new Params("Reload", null, this.radius, (reloaClickEvent: ClickEvent) => { + onClickHandle(reloaClickEvent); + action?.closeCustomDialog(contentNode); + }, (event: TouchEvent) => { + })); + action?.openCustomDialog(contentNode, { + autoCancel: true, + alignment: DialogAlignment.Center, + }); + } + }, + (event: TouchEvent) => { + if (event.type === TouchType.Down) { + this.startX = event.touches[0].windowX; + this.startY = event.touches[0].windowY; + this.startLeft = this.btnPosition.x as number; + this.startTop = this.btnPosition.y as number; + } else if (event.type === TouchType.Move) { + this.updateCurrentBtnPosition(params, event); + } + } + ); + if (this.uiContext != null) { + let componentContent = + new ComponentContent(this.uiContext, wrapBuilder<[Params]>(buildeFloatBtn), params); + this.floatButtonArray.push(componentContent); + this.uiContext?.getOverlayManager().addComponentContent(componentContent, 99); + } + } - // Looper.getMainLooper().myQueue().addIdleHandler(new MessageQueue.IdleHandler() { - // @Override - // public boolean queueIdle() { - // boolean result = requestFocusFromTouch(); - // LogUtils.d("requestFocus", "requestFocusFromTouch result:" + result); - // if (!result) { - // result = requestFocus(); - // LogUtils.d("requestFocus", "requestFocus result:" + result); - // } - // return false; - // } - // }); + public delete() { + if (this.floatButtonArray.length > 0) { + this.uiContext?.getOverlayManager().removeComponentContent(this.floatButtonArray.pop()); + } } + + private getDensityPixels(context: Context): number { + let displayClass: display.Display = display.getDefaultDisplaySync(); + return displayClass.densityPixels; + } + } diff --git a/framework/ohos/src/main/ets/hippy_framework/devsupport/DevServerCallBack.ets b/framework/ohos/src/main/ets/hippy_framework/devsupport/DevServerCallBack.ets index ca917dd5068..336b1cb519b 100644 --- a/framework/ohos/src/main/ets/hippy_framework/devsupport/DevServerCallBack.ets +++ b/framework/ohos/src/main/ets/hippy_framework/devsupport/DevServerCallBack.ets @@ -26,3 +26,7 @@ export interface DevServerCallBack { onDebugReLoad(): void } + +export interface OnReloadListener { + onReload(): void +} diff --git a/framework/ohos/src/main/ets/hippy_framework/devsupport/DevServerConfig.ets b/framework/ohos/src/main/ets/hippy_framework/devsupport/DevServerConfig.ets index 4d641e5c960..859a6f45de5 100644 --- a/framework/ohos/src/main/ets/hippy_framework/devsupport/DevServerConfig.ets +++ b/framework/ohos/src/main/ets/hippy_framework/devsupport/DevServerConfig.ets @@ -17,19 +17,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { HippyGlobalConfigs } from '../../hippy_framework/HippyGlobalConfigs'; export class DevServerConfig { - private static JS_REMOTE_DEBUG = "js_remote_debug"; - private static HIPPYDEBUGPREF = "hippydebugpref"; - private sharedPreferences = null; private mLiveDebug = false; private mServerHost: string private mBundleName: string constructor(serverHost: string, bundleName: string) { - // this.sharedPreferences = HippyGlobalConfigs.ContextHolder.getAppContext() - // .getSharedPreferences(HIPPYDEBUGPREF, Context.MODE_PRIVATE); this.mServerHost = serverHost; this.mBundleName = bundleName; } @@ -43,14 +37,6 @@ export class DevServerConfig { } public enableRemoteDebug(): boolean { - // kvStore.get(DevServerConfig.JS_REMOTE_DEBUG, (err, data) => { - // if (err != undefined) { - // console.error(`Failed to get data. Code:${err.code},message:${err.message}`); - // return; - // } - // console.info(`Succeeded in getting data. Data:${data}`); - // return data as boolean - // }); return false } diff --git a/framework/ohos/src/main/ets/hippy_framework/devsupport/DevServerImpl.ets b/framework/ohos/src/main/ets/hippy_framework/devsupport/DevServerImpl.ets index 64a540fdf68..7a9aa97de0c 100644 --- a/framework/ohos/src/main/ets/hippy_framework/devsupport/DevServerImpl.ets +++ b/framework/ohos/src/main/ets/hippy_framework/devsupport/DevServerImpl.ets @@ -19,14 +19,36 @@ */ // import { HippyJsException } from 'ets/hippy_framework/common/HippyJsException'; import { HippyGlobalConfigs } from '../../hippy_framework/HippyGlobalConfigs'; -import { OnReloadListener } from './DevExceptionDialog'; import { DevFloatButton } from './DevFloatButton'; -import { DevServerCallBack } from './DevServerCallBack'; +import { DevServerCallBack, OnReloadListener } from './DevServerCallBack'; import { DevServerConfig } from './DevServerConfig'; import { DevServerHelper } from './DevServerHelper'; import { DevServerInterface } from './DevServerInterface'; -import Stack from '@ohos.util.Stack'; import { HippyException } from '../../support/common/HippyException'; +import { ComponentContent, UIContext, window } from '@kit.ArkUI'; +import { LogUtils } from '../../support/utils/LogUtils'; + + +class Params { + text: string = ""; + onClickHandle: (event: ClickEvent) => void; + constructor(text: string, onClickHandle: (event: ClickEvent) => void) { + this.text = text; + this.onClickHandle = onClickHandle; + } +} + +@Builder +function buildErrorPrompt(params: Params) { + Flex() { + Text(params.text).fontSize(10).margin({ left: 20, top: 20 }) + } + .width("88%") + .height("50%") + .align(Alignment.Center) + .backgroundColor(Color.White) + .onClick(params.onClickHandle) +} export class DevServerImpl implements DevServerInterface, OnReloadListener { private static TAG = "DevServerImpl"; @@ -35,7 +57,7 @@ export class DevServerImpl implements DevServerInterface, OnReloadListener { private mDevButtonMaps: Map = new Map(); private mServerCallBack: DevServerCallBack | null = null private mFetchHelper: DevServerHelper - private mDevButtonStack: Stack = new Stack(); + private uiContext: UIContext | null = null constructor(configs: HippyGlobalConfigs, serverHost: string, bundleName: string, remoteServerUrl: string, debugMode: boolean) { @@ -99,14 +121,13 @@ export class DevServerImpl implements DevServerInterface, OnReloadListener { if (this.mDevButtonMaps.get(rootId) != null) { return; } - let devButton: DevFloatButton = new DevFloatButton(context); - // devButton.setOnClickListener(this); - // if (context instanceof Activity) { - // ViewGroup decorView = (ViewGroup) ((Activity) context).getWindow().getDecorView(); - // decorView.addView(devButton); - // } + const onClickHandle = (event: ClickEvent) => { + LogUtils.d(DevServerImpl.TAG, "onClickHandle::event" + JSON.stringify(event)); + this.onReload(); + } + let devButton: DevFloatButton = new DevFloatButton(context, onClickHandle); + this.mDevButtonMaps.set(rootId, devButton); - this.mDevButtonStack.push(devButton); } detachFromHost(context: Context, rootId: number): void { @@ -115,18 +136,34 @@ export class DevServerImpl implements DevServerInterface, OnReloadListener { } let button: DevFloatButton | undefined = this.mDevButtonMaps.get(rootId); if (button != undefined) { - if (this.mDevButtonStack != null) { - this.mDevButtonStack.pop(); - } - // ViewParent parent = button.getParent(); - // if (parent instanceof ViewGroup) { - // ((ViewGroup) parent).removeView(button); - // } + button.delete(); + this.mDevButtonMaps.delete(rootId); } } handleException(throwable: HippyException): void { + if (this.uiContext) { + this.popupErrorPrompt(this.uiContext, throwable); + } else { + window.getLastWindow(getContext(this), (err, windowClass) => { + if (!err.code) { + this.uiContext = windowClass.getUIContext(); + this.popupErrorPrompt(this.uiContext, throwable); + } + }); + } + } + popupErrorPrompt(uiContext: UIContext, throwable: HippyException) { + const action = uiContext.getPromptAction(); + let contentNode = new ComponentContent(uiContext, wrapBuilder(buildErrorPrompt), + new Params(throwable.message, (event: ClickEvent) => { + action.closeCustomDialog(contentNode); + })); + action.openCustomDialog(contentNode, { + autoCancel: true, + alignment: DialogAlignment.Center, + }); } getDevButton(rootId: number): Object | null { diff --git a/framework/ohos/src/main/ets/hippy_framework/devsupport/DevtoolsManager.ets b/framework/ohos/src/main/ets/hippy_framework/devsupport/DevtoolsManager.ets index 4ec2ebc1488..db0bb5cdedc 100644 --- a/framework/ohos/src/main/ets/hippy_framework/devsupport/DevtoolsManager.ets +++ b/framework/ohos/src/main/ets/hippy_framework/devsupport/DevtoolsManager.ets @@ -17,12 +17,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { HippyGlobalConfigs } from '../../hippy_framework/HippyGlobalConfigs'; -import { DevServerCallBack } from './DevServerCallBack'; -import { DevServerImpl } from './DevServerImpl'; -import { DevServerInterface } from './DevServerInterface'; + import { util } from '@kit.ArkTS'; -import { HippyJsException } from '../../hippy_framework/common/HippyJsException'; import { HippyLibrary } from '../../hippy_library/HippyLibrary'; import { JsDriver } from '../connector/JsDriver'; import { DomManager } from '../connector/DomManager'; diff --git a/framework/ohos/src/main/ets/hippy_framework/devsupport/LiveReloadController.ets b/framework/ohos/src/main/ets/hippy_framework/devsupport/LiveReloadController.ets deleted file mode 100644 index babae96a159..00000000000 --- a/framework/ohos/src/main/ets/hippy_framework/devsupport/LiveReloadController.ets +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making - * Hippy available. - * - * Copyright (C) 2022 THL A29 Limited, a Tencent company. - * All rights reserved. - * - * 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. - */ - -export class LiveReloadController { - -} diff --git a/framework/ohos/src/main/ets/hippy_framework/modules/HippyModuleManagerImpl.ets b/framework/ohos/src/main/ets/hippy_framework/modules/HippyModuleManagerImpl.ets index 72a17b7dded..0082deb83bc 100644 --- a/framework/ohos/src/main/ets/hippy_framework/modules/HippyModuleManagerImpl.ets +++ b/framework/ohos/src/main/ets/hippy_framework/modules/HippyModuleManagerImpl.ets @@ -125,7 +125,11 @@ export class HippyModuleManagerImpl implements HippyModuleManager { } public destroy(): void { - throw new Error('Method not implemented.') + this.cachedNativeModuleMap.forEach((module: HippyNativeModuleBase) => { + module.destroy(); + }) + this.cachedNativeModuleMap.clear(); + this.cachedJSModuleMap.clear(); } public addModules(customNativeModules: Map | null): void { diff --git a/framework/ohos/src/main/ets/hippy_framework/modules/native/HippyNativeModuleBase.ets b/framework/ohos/src/main/ets/hippy_framework/modules/native/HippyNativeModuleBase.ets index 60218d5154a..3f3f7324f96 100644 --- a/framework/ohos/src/main/ets/hippy_framework/modules/native/HippyNativeModuleBase.ets +++ b/framework/ohos/src/main/ets/hippy_framework/modules/native/HippyNativeModuleBase.ets @@ -21,8 +21,8 @@ import { HippyAny } from '../../../support/common/HippyTypes'; import { HippyEngineContext } from '../../HippyEngineContext'; import { HippyModulePromise } from '../HippyModulePromise'; -export class HippyNativeModuleBase { +export class HippyNativeModuleBase { public static readonly NAME: string protected ctx: HippyEngineContext diff --git a/framework/ohos/src/main/ets/renderer_native/NativeRenderProvider.ets b/framework/ohos/src/main/ets/renderer_native/NativeRenderProvider.ets index 6ed73087ff1..0dc7c4ca71f 100644 --- a/framework/ohos/src/main/ets/renderer_native/NativeRenderProvider.ets +++ b/framework/ohos/src/main/ets/renderer_native/NativeRenderProvider.ets @@ -26,7 +26,7 @@ import { NativeRenderProviderManager } from './NativeRenderProviderManager'; import { HREventType } from './utils/HREventUtils'; import { LogUtils } from '../support/utils/LogUtils'; import { HippyLibrary } from '../hippy_library/HippyLibrary'; -import { HippyAny, HippyMap } from '../support/common/HippyTypes'; +import { HippyAny, HippyMap, HippyResource, HippyValue } from '../support/common/HippyTypes'; import { HRRenderViewCreator } from './components/HippyRenderRegisterMap'; import { CallRenderViewMethodParamsForCApi, @@ -37,7 +37,16 @@ import { SetRenderViewFrameParamsForCApi, UpdateEventListenerParamsForCApi, UpdatePropsParamsForCApi} from './NativeRenderBuilderForCApi'; -import { FrameNode } from '@kit.ArkUI'; +import { componentSnapshot, componentUtils, display, FrameNode } from '@kit.ArkUI'; +import { image } from '@kit.ImageKit'; +import { util } from '@kit.ArkTS'; + +interface HippyResult { + screenShot?: string; + width?: bigint; + height?: bigint; + screenScale?: number; +} export class NativeRenderProvider { private readonly TAG = "NativeRenderProvider" @@ -46,6 +55,12 @@ export class NativeRenderProvider { private libHippy: HippyLibrary private renderImpl: NativeRenderImpl private instanceId: number = 0 + private hippyResult: HippyResult = { + screenShot: '', + width: BigInt(0), + height: BigInt(0), + screenScale: 0 + }; constructor(libHippy: HippyLibrary, enableArkCApi: boolean, customRenderViewCreatorMap: Map | null, @@ -222,6 +237,59 @@ export class NativeRenderProvider { this.libHippy?.NativeRenderProvider_DoCallBack(this.instanceId, result, functionName, rootId, nodeId, callbackId, buffer) } + setScreenShot(hippyResult: HippyResult) { + this.hippyResult = hippyResult; + } + + getScreenShot() { + return this.hippyResult; + } + + // for devtools + getComponentSnapshot(componentId: string, callback: Function): object { + const scale = 0.6; + componentSnapshot.get("HippyId" + componentId).then((pixmap: PixelMap) => { + pixmap.scaleSync(scale, scale); + const info = pixmap.getImageInfoSync(); + const imagePackageApi: image.ImagePacker = image.createImagePacker() + let packOpts: image.PackingOption = { + format: 'image/png', + quality: 100, + } + imagePackageApi.packing(pixmap, packOpts).then((readBuffer) => { + let base64Helper = new util.Base64Helper(); + let uint8Arr = new Uint8Array(readBuffer); + let pixelStr = base64Helper.encodeToStringSync(uint8Arr); + LogUtils.d(this.TAG, "pixelStr::" + pixelStr); + let hippyResult: HippyResult = {}; + hippyResult.screenShot = pixelStr; + hippyResult.width = BigInt(info.size.width); + hippyResult.height = BigInt(info.size.height); + hippyResult.screenScale = scale; + this.setScreenShot(hippyResult); + imagePackageApi.release(); + pixmap.release(); + }); + }); + return this.getScreenShot(); + } + + getLocationOnScreen(componentId: string): object { + interface HippyResult { + xOnScreen?: number; + yOnScreen?: number; + viewWidth?: number; + viewHeight?: number; + } + let info = componentUtils.getRectangleById("HippyId" + componentId); + let hippyResult: HippyResult = {}; + hippyResult.xOnScreen = info.screenOffset.x; + hippyResult.yOnScreen = info.screenOffset.y; + hippyResult.viewWidth = info.size.width; + hippyResult.viewHeight = info.size.height; + return hippyResult as object; + } + // for c-api onFirstPaint(): void { return this.renderImpl.onFirstPaint(); diff --git a/modules/ohos/oh_napi/src/ark_ts.cc b/modules/ohos/oh_napi/src/ark_ts.cc index b946e8f8cf1..e396dbb65ee 100644 --- a/modules/ohos/oh_napi/src/ark_ts.cc +++ b/modules/ohos/oh_napi/src/ark_ts.cc @@ -25,8 +25,10 @@ #include "oh_napi/oh_napi_object_builder.h" #include "footstone/logging.h" #include +#include #include #include +#include ArkTS::ArkTS(napi_env env) { env_ = env; diff --git a/modules/ohos/oh_napi/src/oh_napi_object.cc b/modules/ohos/oh_napi/src/oh_napi_object.cc index 202fafe0da5..d5288d5ea01 100644 --- a/modules/ohos/oh_napi/src/oh_napi_object.cc +++ b/modules/ohos/oh_napi/src/oh_napi_object.cc @@ -35,4 +35,4 @@ napi_value OhNapiObject::GetProperty(napi_value key) { std::vector> OhNapiObject::GetKeyValuePairs() { return arkTs_.GetObjectProperties(object_); -} +} \ No newline at end of file