diff --git a/core/shell/android/lynx_template_render_android.cc b/core/shell/android/lynx_template_render_android.cc index 919ff2df9b..55d286336d 100644 --- a/core/shell/android/lynx_template_render_android.cc +++ b/core/shell/android/lynx_template_render_android.cc @@ -62,6 +62,19 @@ using lynx::shell::LynxShell; namespace { +// A null lifecycle selects the optimized path. The LynxTemplateRender Java +// instance owns the native shell lifetime directly in this mode, so JNI calls +// intentionally skip the AtomicLifecycle synchronization. +bool TryLockLifecycle(AtomicLifecycle* lifecycle) { + return lifecycle == nullptr || AtomicLifecycle::TryLock(lifecycle); +} + +void FreeLifecycle(AtomicLifecycle* lifecycle) { + if (lifecycle != nullptr) { + AtomicLifecycle::TryFree(lifecycle); + } +} + Value ConvertJavaData(JNIEnv* env, jobject j_data, jint length) { if (j_data == nullptr || length <= 0) { return Value(); @@ -225,7 +238,7 @@ void InternalLoadTemplate(JNIEnv* env, jlong ptr, jlong lifecycle, AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } @@ -238,7 +251,7 @@ void InternalLoadTemplate(JNIEnv* env, jlong ptr, jlong lifecycle, reinterpret_cast(ptr)->LoadTemplate( JNIConvertHelper::ConvertToString(env, j_url), std::move(j_binary), pipeline_options, template_data); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void InternalLoadSSRData(JNIEnv* env, jlong ptr, jlong lifecycle, @@ -261,12 +274,12 @@ void InternalLoadSSRData(JNIEnv* env, jlong ptr, jlong lifecycle, AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->LoadSSRData( JNIConvertHelper::ConvertJavaBinary(env, j_binary), template_data); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } std::shared_ptr ConvertToTemplateData( @@ -423,7 +436,7 @@ void RebuildLynxEngine(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jobject module_factory) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } auto* ui_delegate = @@ -441,7 +454,7 @@ void RebuildLynxEngine(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, std::make_unique( env, tasm_platform_invoker, ui_delegate), std::move(native_module_manager)); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void Destroy(JNIEnv* env, jclass jcaller, jlong ptr) { @@ -465,12 +478,12 @@ jint GetInstanceId(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle) { jint id = -1; AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return id; } auto* shell = reinterpret_cast(ptr); id = shell->GetInstanceId(); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); return id; } @@ -478,11 +491,11 @@ void AttachRuntime(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jlong background_runtime) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->AttachRuntime(); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void InitRuntime(JNIEnv* env, jclass jcaller, jlong ptr, @@ -550,54 +563,54 @@ void OnLynxEngineCreated(JNIEnv* env, jclass jcaller, jlong ptr, void StartRuntime(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->StartJsRuntime(); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void ProcessRender(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->ForceFlush(); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void SetEnableUIFlush(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jboolean enable_ui_flush) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->SetEnableUIFlush(enable_ui_flush); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void OnEnterForeground(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->OnEnterForeground(); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void OnEnterBackground(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->OnEnterBackground(); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void LoadSSRDataByPreParsedData(JNIEnv* env, jclass jcaller, jlong ptr, @@ -691,7 +704,7 @@ void LoadTemplateBundleByPreParsedData(JNIEnv* env, jclass jcaller, jlong ptr, AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } auto pipeline_options = @@ -700,19 +713,19 @@ void LoadTemplateBundleByPreParsedData(JNIEnv* env, jclass jcaller, jlong ptr, reinterpret_cast(ptr)->LoadTemplateBundle( url, std::move(copied_bundle), pipeline_options, template_data); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void PreloadLazyBundles(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jobjectArray urls) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->PreloadLazyBundles( JNIConvertHelper::ConvertJavaStringArrayToStringVector(env, urls)); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } jboolean RegisterLazyBundle(JNIEnv* env, jclass jcaller, jlong ptr, @@ -721,12 +734,12 @@ jboolean RegisterLazyBundle(JNIEnv* env, jclass jcaller, jlong ptr, *reinterpret_cast(bundle_ptr); AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return false; } reinterpret_cast(ptr)->RegisterLazyBundle( JNIConvertHelper::ConvertToString(env, url), bundle); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); return true; } @@ -753,12 +766,12 @@ void UpdateDataByPreParsedData(JNIEnv* env, jclass jcaller, jlong ptr, AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->UpdateDataByParsedData(template_data, is_reuse_engine); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void UpdateMetaData(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, @@ -784,12 +797,12 @@ void UpdateMetaData(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!lynx::base::AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->UpdateMetaData(updated_data, updated_global_props); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void ResetDataByPreParsedData(JNIEnv* env, jclass jcaller, jlong ptr, @@ -815,11 +828,11 @@ void ResetDataByPreParsedData(JNIEnv* env, jclass jcaller, jlong ptr, AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->ResetDataByParsedData(template_data); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void ReloadTemplate(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, @@ -829,7 +842,7 @@ void ReloadTemplate(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jobject j_timing_option) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->ResetTimingBeforeReload(); @@ -853,7 +866,7 @@ void ReloadTemplate(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, pipeline_options, prop_value ? *prop_value : Value(lynx::lepus::Dictionary::Create())); } - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void UpdateConfig(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, @@ -862,11 +875,11 @@ void UpdateConfig(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, if (!config.IsNil()) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->UpdateConfig(config); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } } @@ -877,11 +890,11 @@ void UpdateGlobalProps(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, if (props != nullptr && !props->IsNil()) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->UpdateGlobalProps(*props); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } } @@ -890,7 +903,7 @@ void UpdateViewport(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jfloat scale, jlong ui_delegate_ptr, jboolean need_layout) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } auto* ui_delegate = @@ -902,7 +915,7 @@ void UpdateViewport(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, reinterpret_cast(ptr)->UpdateViewport(width, width_mode, height, height_mode, need_layout); } - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void SetSessionStorageItem(JNIEnv* env, jobject jcaller, jlong ptr, @@ -910,7 +923,7 @@ void SetSessionStorageItem(JNIEnv* env, jobject jcaller, jlong ptr, jboolean readonly) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } std::string shared_key = @@ -920,14 +933,14 @@ void SetSessionStorageItem(JNIEnv* env, jobject jcaller, jlong ptr, reinterpret_cast(ptr)->SetSessionStorageItem( std::move(shared_key), std::make_shared(shared_data, readonly)); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void GetSessionStorageItem(JNIEnv* env, jobject jcaller, jlong ptr, jlong lifecycle, jstring key, jobject callback) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } auto shared_key = @@ -936,7 +949,7 @@ void GetSessionStorageItem(JNIEnv* env, jobject jcaller, jlong ptr, std::make_unique(env, callback); reinterpret_cast(ptr)->GetSessionStorageItem( std::move(shared_key), std::move(platform_callback)); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } jdouble SubscribeSessionStorage(JNIEnv* env, jobject jcaller, jlong ptr, @@ -944,7 +957,7 @@ jdouble SubscribeSessionStorage(JNIEnv* env, jobject jcaller, jlong ptr, jobject callBack) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return -1; } std::string shared_key = @@ -954,7 +967,7 @@ jdouble SubscribeSessionStorage(JNIEnv* env, jobject jcaller, jlong ptr, auto id = reinterpret_cast(ptr)->SubscribeSessionStorage( std::move(shared_key), std::move(platform_callback)); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); return id; } @@ -962,14 +975,14 @@ void UnsubscribeSessionStorage(JNIEnv* env, jobject jcaller, jlong ptr, jlong lifecycle, jstring key, jdouble id) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } std::string shared_key = lynx::base::android::JNIConvertHelper::ConvertToString(env, key); reinterpret_cast(ptr)->UnSubscribeSessionStorage( std::move(shared_key), id); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void UpdateScreenMetrics(JNIEnv* env, jclass jcaller, jlong ptr, @@ -977,7 +990,7 @@ void UpdateScreenMetrics(JNIEnv* env, jclass jcaller, jlong ptr, jlong ui_delegate_ptr) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } auto* ui_delegate = @@ -989,64 +1002,64 @@ void UpdateScreenMetrics(JNIEnv* env, jclass jcaller, jlong ptr, reinterpret_cast(ptr)->UpdateScreenMetrics(width, height, scale); } - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void SetFontScale(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jfloat scale) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->SetFontScale(scale); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void SetPlatformConfig(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jstring platform_config) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->SetPlatformConfig( JNIConvertHelper::ConvertToString(env, platform_config)); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void UpdateFontScale(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jfloat scale) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->UpdateFontScale(scale); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void UpdateColorScheme(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jint scheme, jboolean use_act_lite) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->UpdateColorScheme( scheme, static_cast(use_act_lite)); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void SyncFetchLayoutResult(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->SyncFetchLayoutResult(); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void SendTouchEvent(JNIEnv* env, jclass jcaller, jlong ptr, jstring name, @@ -1080,11 +1093,11 @@ void SendSsrGlobalEvent(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, Value params = ConvertJavaData(env, buffer, length); AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->SendSsrGlobalEvent(event_name, params); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void SendGlobalEventToLepus(JNIEnv* env, jclass jcaller, jlong ptr, @@ -1094,11 +1107,11 @@ void SendGlobalEventToLepus(JNIEnv* env, jclass jcaller, jlong ptr, Value params = ConvertJavaData(env, buffer, length); AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->SendGlobalEventToLepus(event_name, params); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void TriggerEventBus(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, @@ -1107,23 +1120,23 @@ void TriggerEventBus(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, Value params = ConvertJavaData(env, buffer, length); AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->TriggerEventBus(event_name, params); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } jboolean ShouldSendEventToMainThread(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return false; } auto* shell = reinterpret_cast(ptr); bool result = shell->ShouldSendEventToMainThread(); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); return result; } @@ -1138,11 +1151,11 @@ void GetDataAsync(JNIEnv* env, jobject jcaller, jlong ptr, jlong lifecycle, jint tag) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } auto data = reinterpret_cast(ptr)->GetCurrentData(); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); if (data != nullptr) { lynx::tasm::LepusEncoder encoder; std::vector encoded_data = encoder.EncodeMessage(*data); @@ -1161,12 +1174,12 @@ jobject GetPageDataByKey(JNIEnv* env, jclass jcaller, jlong ptr, JNIConvertHelper::ConvertJavaStringArrayToStringVector(env, keys); AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return nullptr; } auto data = reinterpret_cast(ptr)->GetPageDataByKey(std::move(keys_vec)); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); lynx::tasm::LepusEncoder encoder; std::vector encoded_data = encoder.EncodeMessage(data); @@ -1185,20 +1198,20 @@ jobject GetAllJsSource(JNIEnv* env, jclass jcaller, jlong ptr, JavaOnlyMap jni_map; AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return env->NewLocalRef(jni_map.jni_object()); // NOLINT } for (const auto& item : reinterpret_cast(ptr)->GetAllJsSource()) { jni_map.PushString(item.first, item.second); } - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); return env->NewLocalRef(jni_map.jni_object()); // NOLINT } jboolean TakeBTSHeapSnapshotToFile(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jstring output_path, jobject callback) { - if (ptr == 0 || lifecycle == 0 || output_path == nullptr) { + if (ptr == 0 || output_path == nullptr) { return JNI_FALSE; } std::string native_output_path = @@ -1207,7 +1220,7 @@ jboolean TakeBTSHeapSnapshotToFile(JNIEnv* env, jclass jcaller, jlong ptr, AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return JNI_FALSE; } @@ -1217,7 +1230,7 @@ jboolean TakeBTSHeapSnapshotToFile(JNIEnv* env, jclass jcaller, jlong ptr, [callback = std::move(global_callback)](bool success) mutable { DispatchBTSHeapSnapshotResult(std::move(callback), success); }); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); return accepted ? JNI_TRUE : JNI_FALSE; } @@ -1227,7 +1240,7 @@ void QueryNativeMemoryUsageAsync(JNIEnv* env, jclass jcaller, jlong ptr, if (global_receiver.IsNull()) { return; } - if (ptr == 0 || lifecycle == 0) { + if (ptr == 0) { DispatchNativeMemoryUsageResult( std::move(global_receiver), lynx::tasm::performance::NativeMemoryUsageSnapshot()); @@ -1235,7 +1248,7 @@ void QueryNativeMemoryUsageAsync(JNIEnv* env, jclass jcaller, jlong ptr, } AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { DispatchNativeMemoryUsageResult( std::move(global_receiver), lynx::tasm::performance::NativeMemoryUsageSnapshot()); @@ -1247,44 +1260,44 @@ void QueryNativeMemoryUsageAsync(JNIEnv* env, jclass jcaller, jlong ptr, DispatchNativeMemoryUsageResult(std::move(receiver), std::move(snapshot)); }); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void RenderChild(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jint tag, jint index, jlong operation_id) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->RenderListChild( tag, static_cast(index), operation_id); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void UpdateChild(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jint tag, jint sign, jint index, jlong operation_id) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->UpdateListChild( tag, static_cast(sign), static_cast(index), operation_id); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void RemoveChild(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jint tag, jint sign) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->RemoveListChild( tag, static_cast(sign)); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } jint ObtainChild(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, @@ -1292,13 +1305,13 @@ jint ObtainChild(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jboolean enable_reuse_notification) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return -1; } jint ret = reinterpret_cast(ptr)->ObtainListChild( tag, static_cast(index), operation_id, enable_reuse_notification); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); return ret; } @@ -1306,37 +1319,37 @@ void ObtainChildAsync(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jint tag, jint index, jlong operation_id) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->LoadListNode(static_cast(tag), static_cast(index), operation_id, true); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void RecycleChild(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jint tag, jint sign) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->RecycleListChild( tag, static_cast(sign)); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void RecycleChildAsync(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jint tag, jint sign) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->EnqueueListNode( static_cast(tag), static_cast(sign)); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void ScrollByListContainer(JNIEnv* env, jobject jcaller, jlong ptr, @@ -1344,12 +1357,12 @@ void ScrollByListContainer(JNIEnv* env, jobject jcaller, jlong ptr, jfloat originalX, jfloat originalY) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->ScrollByListContainer( sign, dx, dy, originalX, originalY); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void ScrollToPosition(JNIEnv* env, jobject jcaller, jlong ptr, jlong lifecycle, @@ -1357,35 +1370,35 @@ void ScrollToPosition(JNIEnv* env, jobject jcaller, jlong ptr, jlong lifecycle, jboolean smooth) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->ScrollToPosition(sign, position, offset, align, smooth); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void ScrollStopped(JNIEnv* env, jobject jcaller, jlong ptr, jlong lifecycle, jint sign) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->ScrollStopped(sign); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } jlong GetListEngineProxy(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return 0; } auto shell = reinterpret_cast(ptr); auto engine_proxy = shell->GetListEngineProxy(); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); if (!engine_proxy) { return 0; } @@ -1418,12 +1431,12 @@ jobject GetListPlatformInfo(JNIEnv* env, jclass jcaller, jlong ptr, AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return nullptr; } reinterpret_cast(ptr)->AssembleListPlatformInfo( tag, std::move(assembler)); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); return env->NewLocalRef(jni_map.jni_object()); // NOLINT } @@ -1431,33 +1444,33 @@ void UpdateI18nResource(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jstring key, jstring data, jint) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->UpdateI18nResource( JNIConvertHelper::ConvertToString(env, key), JNIConvertHelper::ConvertToString(env, data)); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void MarkDirty(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->MarkDirty(); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void Flush(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } reinterpret_cast(ptr)->Flush(); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void GetLynxElementRoot(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, @@ -1465,7 +1478,7 @@ void GetLynxElementRoot(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, auto platform_callback = std::make_unique(env, callback); - if (ptr == 0 || lifecycle == 0) { + if (ptr == 0) { LOGW("GetLynxElementRoot failed since native render is null."); platform_callback->InvokeWithValue( lynx::lepus::Value(static_cast(lynx::tasm::kInvalidImplId))); @@ -1473,7 +1486,7 @@ void GetLynxElementRoot(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, } auto* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { LOGW("GetLynxElementRoot failed since native lifecycle is terminated."); platform_callback->InvokeWithValue( lynx::lepus::Value(static_cast(lynx::tasm::kInvalidImplId))); @@ -1482,7 +1495,7 @@ void GetLynxElementRoot(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, reinterpret_cast(ptr)->GetLynxElementRootSignAsync( std::move(platform_callback)); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void LynxElementToJSONString(JNIEnv* env, jclass jcaller, jlong ptr, @@ -1490,15 +1503,14 @@ void LynxElementToJSONString(JNIEnv* env, jclass jcaller, jlong ptr, auto platform_callback = std::make_unique(env, callback); - if (ptr == 0 || lifecycle == 0 || - sign == static_cast(lynx::tasm::kInvalidImplId)) { + if (ptr == 0 || sign == static_cast(lynx::tasm::kInvalidImplId)) { LOGW("LynxElementToJSONString failed since native render or sign is null."); platform_callback->InvokeWithValue(lynx::lepus::Value("")); return; } auto* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { LOGW( "LynxElementToJSONString failed since native lifecycle is terminated."); platform_callback->InvokeWithValue(lynx::lepus::Value("")); @@ -1507,7 +1519,7 @@ void LynxElementToJSONString(JNIEnv* env, jclass jcaller, jlong ptr, reinterpret_cast(ptr)->GetLynxElementTreeAsJSONStringAsync( sign, std::move(platform_callback)); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void SyncPackageExternalPath(JNIEnv* env, jclass jcaller, jlong ptr, @@ -1523,59 +1535,59 @@ void SetEnableBytecode(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jboolean enable, jstring url) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } auto* shell = reinterpret_cast(ptr); shell->SetEnableBytecode(enable, JNIConvertHelper::ConvertToString(env, url)); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void DispatchMessageEvent(JNIEnv* env, jclass jcaller, jlong ptr, jlong lifecycle, jobject event) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } auto* shell = reinterpret_cast(ptr); shell->DispatchMessageEvent(lynx::tasm::android::EventConverterAndroid:: ConvertJavaOnlyMapToMessageEvent(env, event)); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void SetTiming(JNIEnv* env, jobject jcaller, jlong ptr, jlong lifecycle, jlong usTimestamp, jstring timingKey, jstring updateFlag) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } auto* shell = reinterpret_cast(ptr); shell->SetTiming(usTimestamp, JNIConvertHelper::ConvertToString(env, timingKey), JNIConvertHelper::ConvertToString(env, updateFlag)); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void SetSSRTimingData(JNIEnv* env, jobject jcaller, jlong ptr, jlong lifecycle, jstring url, jlong dataSize) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } auto* shell = reinterpret_cast(ptr); shell->SetSSRTimingData(JNIConvertHelper::ConvertToString(env, url), dataSize); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } jobject GetAllTimingInfo(JNIEnv* env, jobject jcaller, jlong ptr, jlong lifecycle) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { JavaOnlyMap jni_map; return env->NewLocalRef(jni_map.jni_object()); // NOLINT } @@ -1583,7 +1595,7 @@ jobject GetAllTimingInfo(JNIEnv* env, jobject jcaller, jlong ptr, auto all_timing = lynx::tasm::android::ValueConverterAndroid::ConvertLepusToJavaOnlyMap( shell->GetAllTimingInfo()); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); return env->NewLocalRef(all_timing.jni_object()); // NOLINT } @@ -1591,19 +1603,19 @@ void ClearPipelineTimingInfo(JNIEnv* env, jobject jcaller, jlong ptr, jlong lifecycle) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } auto* shell = reinterpret_cast(ptr); shell->ClearPipelineTimingInfo(); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void SetLongTaskMonitorDisabled(JNIEnv* env, jobject jcaller, jlong ptr, jlong lifecycle, jboolean disabled) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } auto* shell = reinterpret_cast(ptr); @@ -1611,42 +1623,42 @@ void SetLongTaskMonitorDisabled(JNIEnv* env, jobject jcaller, jlong ptr, auto options = shell->GetPageOptions(); options.SetLongTaskMonitorDisabled(disabled); shell->SetPageOptions(options); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void AttachEngineToUIThread(JNIEnv* env, jobject jcaller, jlong ptr, jlong lifecycle) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } auto* shell = reinterpret_cast(ptr); shell->AttachEngineToUIThread(); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void DetachEngineFromUIThread(JNIEnv* env, jobject jcaller, jlong ptr, jlong lifecycle) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } auto* shell = reinterpret_cast(ptr); shell->DetachEngineFromUIThread(); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void SetExtensionDelegate(JNIEnv* env, jobject jcaller, jlong ptr, jlong lifecycle, jlong delegate_ptr) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } @@ -1654,20 +1666,20 @@ void SetExtensionDelegate(JNIEnv* env, jobject jcaller, jlong ptr, auto* extension_delegate = reinterpret_cast(delegate_ptr); extension_delegate->SetRuntimeActor(shell->GetRuntimeActor()); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void SetContextHasAttached(JNIEnv* env, jobject jcaller, jlong ptr, jlong lifecycle) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } auto* shell = reinterpret_cast(ptr); shell->SetContextHasAttached(); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void ReattachLynxEngineWrapper(JNIEnv* env, jobject jcaller, jlong ptr, @@ -1675,7 +1687,7 @@ void ReattachLynxEngineWrapper(JNIEnv* env, jobject jcaller, jlong ptr, jlong proxy_ptr) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } auto* shell = reinterpret_cast(ptr); @@ -1687,19 +1699,19 @@ void ReattachLynxEngineWrapper(JNIEnv* env, jobject jcaller, jlong ptr, reinterpret_cast(proxy_ptr); engine_proxy->ResetActor(shell->GetEngineActor()); } - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void DetachLynxEngineWrapper(JNIEnv* env, jobject jcaller, jlong ptr, jlong lifecycle) { AtomicLifecycle* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } auto* shell = reinterpret_cast(ptr); shell->PrepareEngineHandoff(); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } void EnforceRelayoutOnCurrentThreadWithUpdatedViewport( @@ -1707,7 +1719,7 @@ void EnforceRelayoutOnCurrentThreadWithUpdatedViewport( jint width_mode, jint height, jint height_mode) { auto* lifecycle_ptr = reinterpret_cast(lifecycle); - if (!AtomicLifecycle::TryLock(lifecycle_ptr)) { + if (!TryLockLifecycle(lifecycle_ptr)) { return; } @@ -1716,5 +1728,5 @@ void EnforceRelayoutOnCurrentThreadWithUpdatedViewport( static_cast(width), static_cast(width_mode), static_cast(height), static_cast(height_mode)); - AtomicLifecycle::TryFree(lifecycle_ptr); + FreeLifecycle(lifecycle_ptr); } diff --git a/platform/android/api/lynx_android.api b/platform/android/api/lynx_android.api index 4f011cd571..205b2f4499 100644 --- a/platform/android/api/lynx_android.api +++ b/platform/android/api/lynx_android.api @@ -5023,6 +5023,7 @@ public class abstract com::lynx::tasm::behavior::LynxContext : com.lynx.tasm.beh public Map com.lynx.tasm.behavior.LynxContext.getContextData(); public int com.lynx.tasm.behavior.LynxContext.getInstanceId(); public void com.lynx.tasm.behavior.LynxContext.setInstanceId(int instanceId); + public void com.lynx.tasm.behavior.LynxContext.setInstanceId(int instanceId, boolean syncFrameRecorderCallback); public void com.lynx.tasm.behavior.LynxContext.setInPreLoad(boolean preload); public void com.lynx.tasm.behavior.LynxContext.setEnableImageResourceHint(boolean enable); public boolean com.lynx.tasm.behavior.LynxContext.getEnableImageResourceHint(); @@ -7761,6 +7762,7 @@ public class com::lynx::tasm::LynxViewBuilder : LynxBaseConfigurator< LynxViewBu public LynxViewBuilder com.lynx.tasm.LynxViewBuilder.setUri(@Nullable Uri uri); public Uri com.lynx.tasm.LynxViewBuilder.getUri(); public LynxViewBuilder com.lynx.tasm.LynxViewBuilder.insertLynxViewConfig(String key, String value); + public LynxViewBuilder com.lynx.tasm.LynxViewBuilder.setEnableNativeLifecycleOptimization(boolean enable); public LynxViewBuilder com.lynx.tasm.LynxViewBuilder.setLynxViewGroup(ILynxViewGroup group); public LynxGroup com.lynx.tasm.LynxViewBuilder.getLynxGroup(); public LynxViewBuilder com.lynx.tasm.LynxViewBuilder.setLynxModuleExtraData(Object data); diff --git a/platform/android/lynx_android/src/android_test/java/com/lynx/tasm/behavior/LynxContextTest.java b/platform/android/lynx_android/src/android_test/java/com/lynx/tasm/behavior/LynxContextTest.java index 073a241e2a..663cb5e8a8 100644 --- a/platform/android/lynx_android/src/android_test/java/com/lynx/tasm/behavior/LynxContextTest.java +++ b/platform/android/lynx_android/src/android_test/java/com/lynx/tasm/behavior/LynxContextTest.java @@ -4,6 +4,7 @@ package com.lynx.tasm.behavior; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import android.content.Context; @@ -16,17 +17,19 @@ public class LynxContextTest { private LynxContext mContext; + private Context mAndroidContext; + private DisplayMetrics mDisplayMetrics; @Before public void setUp() throws Exception { - Context context = + mAndroidContext = InstrumentationRegistry.getInstrumentation().getTargetContext().getApplicationContext(); - DisplayMetricsHolder.updateOrInitDisplayMetrics(context, 3.0f); - DisplayMetrics displayMetrics = new DisplayMetrics(); - displayMetrics.widthPixels = 1080; - displayMetrics.heightPixels = 1920; - displayMetrics.density = 3.0f; - mContext = new LynxContext(context, displayMetrics) { + DisplayMetricsHolder.updateOrInitDisplayMetrics(mAndroidContext, 3.0f); + mDisplayMetrics = new DisplayMetrics(); + mDisplayMetrics.widthPixels = 1080; + mDisplayMetrics.heightPixels = 1920; + mDisplayMetrics.density = 3.0f; + mContext = new LynxContext(mAndroidContext, mDisplayMetrics) { @Override public void handleException(Exception e) {} }; @@ -48,4 +51,14 @@ public void markFallbackProcess() { mContext.markFallbackProcess(false); assertFalse(mContext.isFallbackProcess()); } + + @Test + public void takeScreenMetricsOwnership() { + LynxContext context = new LynxContext(mAndroidContext, mDisplayMetrics, true) { + @Override + public void handleException(Exception e) {} + }; + + assertSame(mDisplayMetrics, context.getScreenMetrics()); + } } diff --git a/platform/android/lynx_android/src/android_test/java/com/lynx/tasm/utils/DisplayMetricsHolderTest.java b/platform/android/lynx_android/src/android_test/java/com/lynx/tasm/utils/DisplayMetricsHolderTest.java new file mode 100644 index 0000000000..3d87467398 --- /dev/null +++ b/platform/android/lynx_android/src/android_test/java/com/lynx/tasm/utils/DisplayMetricsHolderTest.java @@ -0,0 +1,33 @@ +// Copyright 2026 The Lynx Authors. All rights reserved. +// Licensed under the Apache License Version 2.0 that can be found in the +// LICENSE file in the root directory of this source tree. +package com.lynx.tasm.utils; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import android.content.Context; +import android.util.DisplayMetrics; +import androidx.test.platform.app.InstrumentationRegistry; +import org.junit.Test; + +public class DisplayMetricsHolderTest { + @Test + public void getScreenDisplayMetricsReturnsIsolatedSnapshot() { + Context context = + InstrumentationRegistry.getInstrumentation().getTargetContext().getApplicationContext(); + float resourcesDensity = context.getResources().getDisplayMetrics().density; + DisplayMetricsHolder.updateOrInitDisplayMetrics(context, 3.0f); + DisplayMetrics snapshot = DisplayMetricsHolder.getScreenDisplayMetrics(); + + assertNotNull(snapshot); + assertEquals(3.0f, snapshot.density, 0); + assertEquals(resourcesDensity, context.getResources().getDisplayMetrics().density, 0); + int globalWidth = snapshot.widthPixels; + snapshot.widthPixels = globalWidth + 1; + + DisplayMetrics globalMetrics = DisplayMetricsHolder.getScreenDisplayMetrics(); + assertNotNull(globalMetrics); + assertEquals(globalWidth, globalMetrics.widthPixels); + } +} diff --git a/platform/android/lynx_android/src/main/java/com/lynx/tasm/LynxTemplateRender.java b/platform/android/lynx_android/src/main/java/com/lynx/tasm/LynxTemplateRender.java index 511a898a41..6b33f73291 100644 --- a/platform/android/lynx_android/src/main/java/com/lynx/tasm/LynxTemplateRender.java +++ b/platform/android/lynx_android/src/main/java/com/lynx/tasm/LynxTemplateRender.java @@ -119,7 +119,7 @@ private static final class RenderLynxContext extends LynxContext { private final WeakReference mRenderRef; RenderLynxContext(Context base, DisplayMetrics screenMetrics, LynxTemplateRender render) { - super(base, screenMetrics); + super(base, screenMetrics, true); mRenderRef = new WeakReference<>(render); } @@ -169,8 +169,6 @@ public void handleLynxError(LynxError error) { } } - private final TemplateAssembler mTemplateAssembler = new TemplateAssembler(); - private InnerPageLoadListener mPageLoadListener; private ViewLayoutTick mViewLayoutTick; private int mPreWidthMeasureSpec; @@ -270,7 +268,6 @@ public void handleLynxError(LynxError error) { private boolean mEnableSkipUpdateViewportOnInitWhenMeasureSpecEmpty; private boolean mEnableJSRuntime; - private boolean mEnableAirStrictMode; private JSProxy mJSProxy; @@ -282,6 +279,7 @@ public void handleLynxError(LynxError error) { private Map platformCallBackMap = new HashMap<>(); private AtomicBoolean mIsDestroyed = new AtomicBoolean(true); + private boolean mEnableNativeLifecycleOptimization; private long mNativeLifecycle; // Destory mNativeLifecycle when no reference to LynxTemplateRender. private CleanupReference mCleanupReference = null; @@ -311,9 +309,8 @@ public void handleLynxError(LynxError error) { @Nullable private LynxEngine mLynxEngineRef; private LynxModuleFactory mMainThreadModuleFactory; - @NonNull - private final LynxMemoryUsageFetcher mMemoryUsageFetcher = - new LynxTemplateRenderMemoryUsageFetcher(this); + @Nullable private LynxMemoryUsageFetcher mMemoryUsageFetcher; + private boolean mMemoryUsageFetcherRegistered; @Keep public LynxTemplateRender(Context context, UIBodyView bodyView, LynxViewBuilder builder) { @@ -415,6 +412,7 @@ private void init(@Nullable Context context, UIBodyView bodyView, LynxViewBuilde mTemplateProvider = builder.templateProvider; mEnableSyncFlush = mLynxViewConfigProvider.isEnableSyncFlush(); mEnableJSRuntime = mLynxViewConfigProvider.isEnableJSRuntime(); + mEnableNativeLifecycleOptimization = builder.isNativeLifecycleOptimizationEnabled(); mEnableGenericResourceFetcher = checkEnableGenericResourceFetcher(mLynxViewConfigProvider.isEnableGenericResourceFetcher()); mEnableAirStrictMode = mLynxViewConfigProvider.isEnableAirStrictMode(); @@ -423,8 +421,12 @@ private void init(@Nullable Context context, UIBodyView bodyView, LynxViewBuilde if (mBodyView != null) { mBodyView.setTimingCollector(mPerformanceController); } - mLynxRuntimeOptions = - new LynxBackgroundRuntimeOptions(mLynxViewConfigProvider.getLynxRuntimeOptions()); + // Static embedded pages do not initialize a JS runtime or native modules. Keep the + // runtime options lazy in this case; compatibility APIs can still initialize them later. + if (!isStaticEmbeddedMode()) { + mLynxRuntimeOptions = + new LynxBackgroundRuntimeOptions(mLynxViewConfigProvider.getLynxRuntimeOptions()); + } mAsyncRender = (mThreadStrategyForRendering == ThreadStrategyForRendering.MULTI_THREADS || mThreadStrategyForRendering == ThreadStrategyForRendering.MOST_ON_TASM); @@ -451,19 +453,18 @@ private void init(@Nullable Context context, UIBodyView bodyView, LynxViewBuilde // compatibility, some caller still using its related interface. DisplayMetricsHolder.updateOrInitDisplayMetrics(context, mLynxViewConfigProvider.getDensity()); DisplayMetrics screenMetrics = DisplayMetricsHolder.getScreenDisplayMetrics(); - if (mLynxViewConfigProvider.getScreenWidth() != DisplayMetricsHolder.UNDEFINE_SCREEN_SIZE_VALUE - && mLynxViewConfigProvider.getScreenHeight() - != DisplayMetricsHolder.UNDEFINE_SCREEN_SIZE_VALUE) { - screenMetrics.widthPixels = mLynxViewConfigProvider.getScreenWidth(); - screenMetrics.heightPixels = mLynxViewConfigProvider.getScreenHeight(); + int screenWidth = mLynxViewConfigProvider.getScreenWidth(); + int screenHeight = mLynxViewConfigProvider.getScreenHeight(); + if (screenWidth != DisplayMetricsHolder.UNDEFINE_SCREEN_SIZE_VALUE + && screenHeight != DisplayMetricsHolder.UNDEFINE_SCREEN_SIZE_VALUE) { + screenMetrics.widthPixels = screenWidth; + screenMetrics.heightPixels = screenHeight; } // Prepare for env mLynxContext = new RenderLynxContext( context != null ? context : LynxEnv.inst().getAppContext(), screenMetrics, this); mLynxContext.setRuntimeCacheManager(this.mCacheManager); - mTemplateAssembler.setLynxContext(mLynxContext); - mLynxContext.setEmbeddedMode(mEmbeddedMode); mLynxContext.setEnableReuseEngine(mEnableReuseEngine || mEnableCacheEngine); mLynxContext.setPerfController(mPerformanceController); @@ -587,6 +588,14 @@ private void setUserModules(LynxModuleFactory factory) { factory.addModuleParamWrapper(mLynxRuntimeOptions.getWrappers()); } + private boolean isStaticEmbeddedMode() { + return !mEnableJSRuntime && EmbeddedMode.isBaseModeEnable(mEmbeddedMode); + } + + private boolean isNativeLifecycleValid(long nativeLifecycle) { + return mEnableNativeLifecycleOptimization || nativeLifecycle != 0; + } + private void setUpMainThreadModuleFactory() { if (!mLynxViewBuilder.isEnableMTSModule()) { return; @@ -1049,24 +1058,22 @@ private void createLynxEngine(final int lastInstanceId) { lynxUIRenderer.attachNativeFacade(mNativeFacade); lynxUIRenderer.setLynxEngineForPlatformContextRef(mNativePtr); - mNativeLifecycle = nativeLifecycleCreate(); - mCleanupReference = new CleanupReference(this, new CleanupOnUiThread(mNativeLifecycle), true); + if (!mEnableNativeLifecycleOptimization) { + mNativeLifecycle = nativeLifecycleCreate(); + mCleanupReference = new CleanupReference(this, new CleanupOnUiThread(mNativeLifecycle), true); + } mLynxContext.setListNodeInfoFetcher(new ListNodeInfoFetcher(this)); mLynxContext.setEnableVSyncAligned(enableVSyncAligned); if (mDevTool != null) { mDevTool.onTemplateAssemblerCreated(mNativePtr); } - LynxProviderRegistry providerRegistry = new LynxProviderRegistry(); - for (Map.Entry global : - LynxEnv.inst().getResourceProvider().entrySet()) { - providerRegistry.addLynxResourceProvider(global.getKey(), global.getValue()); + LynxBackgroundRuntimeOptions providerRuntimeOptions = mLynxRuntimeOptions; + if (providerRuntimeOptions == null) { + providerRuntimeOptions = mLynxViewConfigProvider.getLynxRuntimeOptions(); } - for (Map.Entry local : - mLynxRuntimeOptions.getAllResourceProviders()) { - providerRegistry.addLynxResourceProvider(local.getKey(), local.getValue()); - } - mLynxContext.setProviderRegistry(providerRegistry); + mLynxContext.setProviderRegistry( + new LazyProviderRegistry(LynxEnv.inst().getResourceProvider(), providerRuntimeOptions)); mLynxContext.setFontLoader(mLynxViewBuilder.fontLoader); mLynxContext.setImageFetcher(mLynxViewBuilder.imageFetcher); @@ -1075,7 +1082,7 @@ private void createLynxEngine(final int lastInstanceId) { mNativeFacade.setLynxContext(mLynxContext); int instanceId = nativeGetInstanceId(mNativePtr, mNativeLifecycle); if (instanceId >= 0) { - mLynxContext.setInstanceId(instanceId); + mLynxContext.setInstanceId(instanceId, !isStaticEmbeddedMode()); mPerformanceController.setInstanceId(instanceId); } registerMemoryUsageFetcherIfNeeded(); @@ -1130,13 +1137,19 @@ private void createLynxEngine(final int lastInstanceId) { } } - mIntersectionObserverManager = new LynxIntersectionObserverManager(mLynxContext, mJSProxy); - mLynxContext.setIntersectionObserverManager(mIntersectionObserverManager); + if (!isStaticEmbeddedMode()) { + mIntersectionObserverManager = new LynxIntersectionObserverManager(mLynxContext, mJSProxy); + mLynxContext.setIntersectionObserverManager(mIntersectionObserverManager); + } - initEngineAndLayoutProxies(); + if (!isStaticEmbeddedMode()) { + initEngineAndLayoutProxies(); + } EventEmitter eventEmitter = new LynxEventEmitter(mEngineProxy); - eventEmitter.addObserver(mIntersectionObserverManager); + if (mIntersectionObserverManager != null) { + eventEmitter.addObserver(mIntersectionObserverManager); + } eventEmitter.registerEventReporter(mNativeFacade); eventEmitter.registerEventFallback(this); mLynxContext.setEventEmitter(eventEmitter); @@ -3255,10 +3268,14 @@ private synchronized void fallbackNewEngine(boolean enable_async) { mLynxUIRender.attachNativeFacade(mNativeFacade); mLynxUIRender.setLynxEngineForPlatformContextRef(mNativePtr); - initEngineAndLayoutProxies(); + if (!isStaticEmbeddedMode()) { + initEngineAndLayoutProxies(); + } EventEmitter eventEmitter = new LynxEventEmitter(mEngineProxy); - eventEmitter.addObserver(mIntersectionObserverManager); + if (mIntersectionObserverManager != null) { + eventEmitter.addObserver(mIntersectionObserverManager); + } eventEmitter.registerEventReporter(mNativeFacade); eventEmitter.registerEventFallback(this); mLynxContext.setEventEmitter(eventEmitter); @@ -3649,8 +3666,8 @@ public Map getAllJsSource() { boolean takeBTSHeapSnapshot( @NonNull String outputPath, @Nullable LynxConsumer callback) { - if (!checkIfEnvPrepared() || mNativePtr == 0 || mNativeLifecycle == 0 || mIsDestroyed.get() - || mHasDestroy || mDestroying) { + if (!checkIfEnvPrepared() || mNativePtr == 0 || !isNativeLifecycleValid(mNativeLifecycle) + || mIsDestroyed.get() || mHasDestroy || mDestroying) { return false; } return nativeTakeBTSHeapSnapshotToFile(mNativePtr, mNativeLifecycle, outputPath, callback); @@ -3694,6 +3711,10 @@ private void doSyncFlush() { } public void runOnTasmThread(Runnable runnable) { + // Static embedded pages defer LynxEngineProxy creation until a TASM task is actually needed. + if (mEngineProxy == null) { + initEngineAndLayoutProxies(); + } if (mEngineProxy == null) { LLog.i(TAG, "runOnTasmThread failed, engine proxy is null."); return; @@ -3748,12 +3769,13 @@ public void processRender() { } public void setEnableBytecode(boolean enableUserBytecode, String url) { - if (mLynxRuntimeOptions.isEnableUserBytecode() == enableUserBytecode - && Objects.equals(mLynxRuntimeOptions.getBytecodeSourceUrl(), url)) { + LynxBackgroundRuntimeOptions runtimeOptions = ensureLynxRuntimeOptions(); + if (runtimeOptions.isEnableUserBytecode() == enableUserBytecode + && Objects.equals(runtimeOptions.getBytecodeSourceUrl(), url)) { return; } - mLynxRuntimeOptions.setEnableUserBytecode(enableUserBytecode); - mLynxRuntimeOptions.setBytecodeSourceUrl(url); + runtimeOptions.setEnableUserBytecode(enableUserBytecode); + runtimeOptions.setBytecodeSourceUrl(url); if (mNativePtr != 0) { nativeSetEnableBytecode(mNativePtr, mNativeLifecycle, enableUserBytecode, url); } @@ -3915,7 +3937,7 @@ private void loadTemplateBundle(TemplateBundle bundle, String url, TemplateData NativeFacade facade = mNativeFacade; long nativePtr = mNativePtr; long nativeLifecycle = mNativeLifecycle; - if ((facade == null) || (nativePtr == 0) || (nativeLifecycle == 0)) { + if ((facade == null) || (nativePtr == 0) || !isNativeLifecycleValid(nativeLifecycle)) { LLog.e(TAG, "LoadTemplateBundle before inited"); return; } @@ -3960,7 +3982,7 @@ private void loadSSRData(byte[] ssr, TemplateData templateData, NativeFacade.Cal NativeFacade facade = mNativeFacade; long nativePtr = mNativePtr; long nativeLifecycle = mNativeLifecycle; - if ((facade == null) || (nativePtr == 0) || (nativeLifecycle == 0)) { + if ((facade == null) || (nativePtr == 0) || !isNativeLifecycleValid(nativeLifecycle)) { LLog.e(TAG, "Load ssr data before inited"); return; } @@ -3988,7 +4010,7 @@ private void nativeLoadTemplate(String url, byte[] template, ByteBuffer buffer, NativeFacade facade = mNativeFacade; long nativePtr = mNativePtr; long nativeLifecycle = mNativeLifecycle; - if (facade == null || nativePtr == 0 || nativeLifecycle == 0) { + if (facade == null || nativePtr == 0 || !isNativeLifecycleValid(nativeLifecycle)) { LLog.e(TAG, "Load Template before inited"); return; } @@ -4129,16 +4151,30 @@ private void initPiperInternal() { } } - private void initEngineAndLayoutProxies() { + private synchronized void initEngineAndLayoutProxies() { + if (mEngineProxy != null || mNativePtr == 0 || mNativeFacade == null) { + return; + } mEngineProxy = new LynxEngineProxy(mNativePtr); mNativeFacade.setEngineProxy(mEngineProxy); if (mLynxContext == null) { LLog.e(TAG, "mLynxContext is null, can not set LayoutProxy"); } else { mLynxContext.setEngineProxy(mEngineProxy); - mLayoutProxy = new LynxLayoutProxy(mNativePtr); - mLynxContext.setLayoutProxy(mLayoutProxy); + if ((mEmbeddedMode & EmbeddedMode.LAYOUT_IN_ELEMENT) == 0) { + mLayoutProxy = new LynxLayoutProxy(mNativePtr); + mLynxContext.setLayoutProxy(mLayoutProxy); + } + } + } + + private LynxBackgroundRuntimeOptions ensureLynxRuntimeOptions() { + if (mLynxRuntimeOptions == null) { + LynxBackgroundRuntimeOptions options = mLynxViewConfigProvider.getLynxRuntimeOptions(); + mLynxRuntimeOptions = options == null ? new LynxBackgroundRuntimeOptions() + : new LynxBackgroundRuntimeOptions(options); } + return mLynxRuntimeOptions; } // TODO(hexionghui): This interface will be deleted later. Since @@ -4222,11 +4258,70 @@ private String getJSGroupThreadNameIfNeed() { } private void registerMemoryUsageFetcherIfNeeded() { + if (mMemoryUsageFetcherRegistered || EmbeddedMode.isBaseModeEnable(mEmbeddedMode)) { + return; + } + if (mMemoryUsageFetcher == null) { + mMemoryUsageFetcher = new LynxTemplateRenderMemoryUsageFetcher(this); + } LynxGlobalMemoryUsageCollector.getInstance().registerMemoryUsageFetcher(mMemoryUsageFetcher); + mMemoryUsageFetcherRegistered = true; } private void unregisterMemoryUsageFetcherIfNeeded() { + if (!mMemoryUsageFetcherRegistered || mMemoryUsageFetcher == null) { + return; + } LynxGlobalMemoryUsageCollector.getInstance().unregisterMemoryUsageFetcher(mMemoryUsageFetcher); + mMemoryUsageFetcherRegistered = false; + } + + private static final class LazyProviderRegistry extends LynxProviderRegistry { + private final Map mGlobalProviders; + private final LynxBackgroundRuntimeOptions mRuntimeOptions; + private boolean mInitialized; + + LazyProviderRegistry( + Map globalProviders, LynxBackgroundRuntimeOptions options) { + mGlobalProviders = globalProviders; + mRuntimeOptions = options; + } + + private void ensureProviders() { + if (mInitialized) { + return; + } + mInitialized = true; + if (mGlobalProviders != null) { + for (Map.Entry global : mGlobalProviders.entrySet()) { + super.addLynxResourceProvider(global.getKey(), global.getValue()); + } + } + if (mRuntimeOptions != null) { + for (Map.Entry local : + mRuntimeOptions.getAllResourceProviders()) { + super.addLynxResourceProvider(local.getKey(), local.getValue()); + } + } + } + + @Override + public void addLynxResourceProvider(String key, LynxResourceProvider provider) { + ensureProviders(); + super.addLynxResourceProvider(key, provider); + } + + @Override + public LynxResourceProvider getProviderByKey(String key) { + ensureProviders(); + return super.getProviderByKey(key); + } + + @Override + public void clear() { + mInitialized = true; + super.clear(); + } } void queryNativeMemoryUsageForGlobalCollectorAsync( @@ -4236,8 +4331,8 @@ void queryNativeMemoryUsageForGlobalCollectorAsync( // but this class owns the private native bridge and reads these UI-thread-owned fields here. long nativePtr = mNativePtr; long nativeLifecycle = mNativeLifecycle; - if (nativePtr == 0 || nativeLifecycle == 0 || mIsDestroyed.get() || mHasDestroy - || mDestroying) { + if (nativePtr == 0 || !isNativeLifecycleValid(nativeLifecycle) || mIsDestroyed.get() + || mHasDestroy || mDestroying) { nativeQueryNativeMemoryUsageAsync(0L, 0L, receiver); return; } @@ -4261,8 +4356,8 @@ private void destroyLynxEngine() { } // need ensure destroy native on ui thread - UIThreadUtils.runOnUiThreadImmediately( - new DestroyTask(mNativePtr, mNativeLifecycle, this, mNativeFacade)); + UIThreadUtils.runOnUiThreadImmediately(new DestroyTask( + mNativePtr, mNativeLifecycle, mEnableNativeLifecycleOptimization, this, mNativeFacade)); if (shouldCacheLynxEngine) { LynxEngine lynxEngine = mLynxEngineRef; @@ -4308,21 +4403,26 @@ private boolean shouldCacheLynxEngine() { private static class DestroyTask implements Runnable { private long mNativePtr; private long mNativeLifecycle; + private final boolean mNativeLifecycleOptimizationEnabled; private volatile NativeFacade mNativeFacade; private LynxTemplateRender mRenderer; - public DestroyTask(long nativePtr, long nativeLifecycle, LynxTemplateRender renderer, + public DestroyTask(long nativePtr, long nativeLifecycle, + boolean nativeLifecycleOptimizationEnabled, LynxTemplateRender renderer, NativeFacade nativeFacade) { mNativePtr = nativePtr; mNativeLifecycle = nativeLifecycle; - mRenderer = ((nativeLifecycle != 0) && (nativePtr != 0)) ? renderer : null; + mNativeLifecycleOptimizationEnabled = nativeLifecycleOptimizationEnabled; + mRenderer = ((nativeLifecycleOptimizationEnabled || nativeLifecycle != 0) && nativePtr != 0) + ? renderer + : null; mNativeFacade = nativeFacade; } @Override public void run() { - if ((mNativeLifecycle != 0) && (mNativePtr != 0)) { - if (nativeLifecycleTryTerminate(mNativeLifecycle)) { + if (mNativePtr != 0) { + if (mNativeLifecycleOptimizationEnabled || nativeLifecycleTryTerminate(mNativeLifecycle)) { nativeDestroy(mNativePtr); mNativePtr = 0; mNativeLifecycle = 0; diff --git a/platform/android/lynx_android/src/main/java/com/lynx/tasm/LynxViewBuilder.java b/platform/android/lynx_android/src/main/java/com/lynx/tasm/LynxViewBuilder.java index 3864d5c274..4c0fe73f68 100644 --- a/platform/android/lynx_android/src/main/java/com/lynx/tasm/LynxViewBuilder.java +++ b/platform/android/lynx_android/src/main/java/com/lynx/tasm/LynxViewBuilder.java @@ -51,6 +51,7 @@ public class LynxViewBuilder Uri uri = null; ILynxViewGroup lynxViewGroup; boolean hasInheritedGroupRuntimeOptions = false; + private boolean enableNativeLifecycleOptimization = false; public LynxViewBuilder() { LynxEnv.inst().lazyInitIfNeeded(); @@ -113,6 +114,22 @@ public LynxViewBuilder insertLynxViewConfig(String key, String value) { return this; } + /** + * Enables the optimized native lifecycle path for this LynxView. When enabled, + * LynxTemplateRender skips the per-JNI-call AtomicLifecycle lock. + * + *

This API is experimental and disabled by default. + */ + @RestrictTo(RestrictTo.Scope.LIBRARY) + public LynxViewBuilder setEnableNativeLifecycleOptimization(boolean enable) { + enableNativeLifecycleOptimization = enable; + return this; + } + + boolean isNativeLifecycleOptimizationEnabled() { + return enableNativeLifecycleOptimization; + } + public LynxViewBuilder setLynxViewGroup(ILynxViewGroup group) { this.lynxViewGroup = group; this.hasInheritedGroupRuntimeOptions = false; diff --git a/platform/android/lynx_android/src/main/java/com/lynx/tasm/behavior/LynxContext.java b/platform/android/lynx_android/src/main/java/com/lynx/tasm/behavior/LynxContext.java index 467c7d8e65..94f07de35a 100644 --- a/platform/android/lynx_android/src/main/java/com/lynx/tasm/behavior/LynxContext.java +++ b/platform/android/lynx_android/src/main/java/com/lynx/tasm/behavior/LynxContext.java @@ -179,9 +179,19 @@ public abstract class LynxContext extends LynxBaseContext implements ExceptionHa private final LynxFrameRecorder.FrameCallback mFrameCallback = new ContextFrameCallback(this); public LynxContext(Context base, DisplayMetrics screenMetrics) { + this(base, screenMetrics, false); + } + + @RestrictTo(RestrictTo.Scope.LIBRARY) + protected LynxContext( + Context base, DisplayMetrics screenMetrics, boolean takeScreenMetricsOwnership) { super(base); - mVirtualScreenMetrics = new DisplayMetrics(); - mVirtualScreenMetrics.setTo(screenMetrics); + if (takeScreenMetricsOwnership) { + mVirtualScreenMetrics = screenMetrics; + } else { + mVirtualScreenMetrics = new DisplayMetrics(); + mVirtualScreenMetrics.setTo(screenMetrics); + } if (sLynxTextService == null) { sLynxTextService = LynxServiceCenter.inst().getService(ILynxTextService.class); } @@ -1576,12 +1586,19 @@ public int getInstanceId() { @RestrictTo(RestrictTo.Scope.LIBRARY) public void setInstanceId(int instanceId) { + setInstanceId(instanceId, true); + } + + @RestrictTo(RestrictTo.Scope.LIBRARY) + public void setInstanceId(int instanceId, boolean syncFrameRecorderCallback) { if (mInstanceId != INSTANCE_ID_DEFAULT && mInstanceId != instanceId) { LynxFrameRecorder.inst().stopRecording(mInstanceId); LynxFrameRecorder.inst().clearFrameCallback(mInstanceId); } this.mInstanceId = instanceId; - syncFrameRecorderCallback(); + if (syncFrameRecorderCallback) { + syncFrameRecorderCallback(); + } } private void syncFrameRecorderCallback() { @@ -1683,6 +1700,9 @@ public void runOnLayoutThread(Runnable runnable) { if (runnable == null) { return; } + if (mLayoutProxy == null) { + return; + } LynxLayoutProxy layoutProxy = mLayoutProxy.get(); if (layoutProxy == null) { return; diff --git a/platform/android/lynx_android/src/main/java/com/lynx/tasm/behavior/LynxUIRenderer.java b/platform/android/lynx_android/src/main/java/com/lynx/tasm/behavior/LynxUIRenderer.java index 406e2a45dc..3de126b6d2 100644 --- a/platform/android/lynx_android/src/main/java/com/lynx/tasm/behavior/LynxUIRenderer.java +++ b/platform/android/lynx_android/src/main/java/com/lynx/tasm/behavior/LynxUIRenderer.java @@ -121,6 +121,8 @@ public void onInitLynxTemplateRender(LynxContext lynxContext, BehaviorRegistry b mLynxUIOwner = new LynxUIOwner(lynxContext, behaviorRegistry, body); } else { mLynxUIOwner.attachLynxContext(lynxContext); + } + if (mHasInited) { mLynxUIOwner.attachUIBodyView(body); } if (body == null) { diff --git a/platform/android/lynx_android/src/main/java/com/lynx/tasm/behavior/ui/LynxBaseUI.java b/platform/android/lynx_android/src/main/java/com/lynx/tasm/behavior/ui/LynxBaseUI.java index 39aaa9397f..147702b2e8 100644 --- a/platform/android/lynx_android/src/main/java/com/lynx/tasm/behavior/ui/LynxBaseUI.java +++ b/platform/android/lynx_android/src/main/java/com/lynx/tasm/behavior/ui/LynxBaseUI.java @@ -2305,16 +2305,21 @@ public void setLynxDirection(int direction) { @LynxProp(name = PropsConstants.INTERSECTION_OBSERVERS) public void setIntersectionObservers(@Nullable ReadableArray observers) { - mContext.getIntersectionObserverManager().removeAttachedIntersectionObserver(this); + LynxIntersectionObserverManager intersectionObserverManager = + mContext.getIntersectionObserverManager(); + if (intersectionObserverManager == null) { + return; + } + intersectionObserverManager.removeAttachedIntersectionObserver(this); if (observers == null || !mEvents.containsKey("intersection")) { return; } for (int idx = 0; idx < observers.size(); idx++) { ReadableMap propsObject = observers.getMap(idx); if (propsObject != null) { - LynxIntersectionObserver observer = new LynxIntersectionObserver( - mContext.getIntersectionObserverManager(), propsObject, this); - mContext.getIntersectionObserverManager().addIntersectionObserver(observer); + LynxIntersectionObserver observer = + new LynxIntersectionObserver(intersectionObserverManager, propsObject, this); + intersectionObserverManager.addIntersectionObserver(observer); } } } diff --git a/platform/android/lynx_android/src/main/java/com/lynx/tasm/behavior/ui/UIBody.java b/platform/android/lynx_android/src/main/java/com/lynx/tasm/behavior/ui/UIBody.java index 67fc45a49c..714bfa5845 100644 --- a/platform/android/lynx_android/src/main/java/com/lynx/tasm/behavior/ui/UIBody.java +++ b/platform/android/lynx_android/src/main/java/com/lynx/tasm/behavior/ui/UIBody.java @@ -128,6 +128,9 @@ public List getMeaningfulPaintingAreas() { * @param view */ synchronized public void attachUIBodyView(UIBodyView view, LynxContext context) { + if (mContext.isEmbeddedModeOn() && !mContext.isEnginePoolEnabled() && mBodyView == view) { + return; + } mAttachTask = new OnceTask<>(new Callable() { @Override public Void call() throws Exception { diff --git a/platform/android/lynx_android/src/main/java/com/lynx/tasm/utils/DisplayMetricsHolder.java b/platform/android/lynx_android/src/main/java/com/lynx/tasm/utils/DisplayMetricsHolder.java index 0b9a18504d..3840e1924d 100644 --- a/platform/android/lynx_android/src/main/java/com/lynx/tasm/utils/DisplayMetricsHolder.java +++ b/platform/android/lynx_android/src/main/java/com/lynx/tasm/utils/DisplayMetricsHolder.java @@ -8,6 +8,7 @@ package com.lynx.tasm.utils; import android.content.Context; +import android.content.res.Resources; import android.os.Build; import android.util.DisplayMetrics; import android.view.Display; @@ -59,19 +60,6 @@ public class DisplayMetricsHolder { public final static int UNDEFINE_SCREEN_SIZE_VALUE = -1; public final static float DEFAULT_SCREEN_SCALE = 1; - /** - * @deprecated Use {@link #setScreenDisplayMetrics(DisplayMetrics)} instead. See comment above as - * to why this is not correct to use. - */ - private static void setWindowDisplayMetrics(DisplayMetrics displayMetrics) { - synchronized (DisplayMetricsHolder.class) { - if (sWindowDisplayMetrics == null) { - sWindowDisplayMetrics = new DisplayMetrics(); - } - sWindowDisplayMetrics.setTo(displayMetrics); - } - } - /** * @deprecated Use {@link com.lynx.tasm.LynxView#updateScreenMetrics(int, int)}instead. See * comment above as @@ -117,61 +105,41 @@ public static boolean updateOrInitDisplayMetrics(Context context, Float densityO "updateOrInitDisplayMetrics context parameter is null, fallback to updateOrInitDisplayMetrics by ApplicationContext"); context = LynxEnv.inst().getAppContext(); } - updateWindowDisplayMetrics(context, densityOverride); - - boolean needUpdateScreenMetrics = shouldUpdateScreenMetrics(context, densityOverride); + Resources resources = context.getResources(); + DisplayMetrics windowDisplayMetrics = resources.getDisplayMetrics(); + int orientation = resources.getConfiguration().orientation; + boolean needUpdateScreenMetrics; + boolean cacheInvalid; + synchronized (DisplayMetricsHolder.class) { + if (sWindowDisplayMetrics == null) { + sWindowDisplayMetrics = new DisplayMetrics(); + } + sWindowDisplayMetrics.setTo(windowDisplayMetrics); + if (densityOverride != null) { + sWindowDisplayMetrics.density = densityOverride; + } + needUpdateScreenMetrics = sScreenDisplayMetrics == null || sOrientation != orientation + || sScaleDensity != windowDisplayMetrics.scaledDensity || !hasNativeUpdateDeviceInfo + || (densityOverride != null && sScreenDisplayMetrics.density != densityOverride); + cacheInvalid = isCacheInvalid; + } // When other views call this method, the cache becomes invalid, so we must use the system's // interface to get real screen displayMetrics. - if (needUpdateScreenMetrics || isCacheInvalid) { - updateScreenDisplayMetrics(context, densityOverride); - // cache is valid again. - isCacheInvalid = false; + if (needUpdateScreenMetrics || cacheInvalid) { + updateScreenDisplayMetrics(context, windowDisplayMetrics, densityOverride, orientation); } - updateCurrentProps(context); - return needUpdateScreenMetrics; } - private static void updateWindowDisplayMetrics(Context context, Float densityOverride) { - DisplayMetrics windowDM = context.getResources().getDisplayMetrics(); - if (densityOverride != null) { - windowDM.density = densityOverride; - } - DisplayMetricsHolder.setWindowDisplayMetrics(windowDM); - } - - private static void updateScreenDisplayMetrics(Context context, Float densityOverride) { - DisplayMetrics displayMetrics = getRealScreenDisplayMetrics(context); + private static void updateScreenDisplayMetrics(Context context, + DisplayMetrics windowDisplayMetrics, Float densityOverride, int orientation) { + DisplayMetrics displayMetrics = getRealScreenDisplayMetrics(context, windowDisplayMetrics); if (densityOverride != null) { displayMetrics.density = densityOverride; } - DisplayMetricsHolder.setScreenDisplayMetrics(displayMetrics); - } - - private static boolean isScaleDensityChange(DisplayMetrics windowDisplayMetrics) { - return sScaleDensity != windowDisplayMetrics.scaledDensity; - } - - private static boolean isDensityChanged(Float densityOverride) { - return sScreenDisplayMetrics != null && densityOverride != null - && sScreenDisplayMetrics.density != densityOverride; - } - - private static boolean isOrientationChanged(Context context) { - return sOrientation != context.getResources().getConfiguration().orientation; - } - - private static void updateCurrentProps(Context context) { - sScaleDensity = context.getResources().getDisplayMetrics().scaledDensity; - sOrientation = context.getResources().getConfiguration().orientation; - } - - private static boolean shouldUpdateScreenMetrics(Context context, Float densityOverride) { - DisplayMetrics windowDM = context.getResources().getDisplayMetrics(); - return DisplayMetricsHolder.getScreenDisplayMetrics() == null || isOrientationChanged(context) - || isScaleDensityChange(windowDM) || !hasNativeUpdateDeviceInfo - || isDensityChanged(densityOverride); + DisplayMetricsHolder.setScreenDisplayMetrics( + displayMetrics, windowDisplayMetrics.scaledDensity, orientation); } /** @@ -180,10 +148,14 @@ private static boolean shouldUpdateScreenMetrics(Context context, Float densityO * @return metrics of real screen */ public static DisplayMetrics getRealScreenDisplayMetrics(Context context) { + return getRealScreenDisplayMetrics(context, getWindowDisplayMetrics()); + } + + private static DisplayMetrics getRealScreenDisplayMetrics( + Context context, @Nullable DisplayMetrics windowDisplayMetrics) { DisplayMetrics screenDisplayMetrics = new DisplayMetrics(); - DisplayMetrics windowDM = getWindowDisplayMetrics(); - if (windowDM != null) { - screenDisplayMetrics.setTo(getWindowDisplayMetrics()); + if (windowDisplayMetrics != null) { + screenDisplayMetrics.setTo(windowDisplayMetrics); } WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Assertions.assertNotNull(wm, "WindowManager is null!"); @@ -241,10 +213,14 @@ public static DisplayMetrics getWindowDisplayMetrics() { * comment above as * to why this is not correct to use. */ - private static void setScreenDisplayMetrics(DisplayMetrics dm) { + private static void setScreenDisplayMetrics( + DisplayMetrics dm, float scaleDensity, int orientation) { boolean isNativeLibraryLoaded = LynxEnv.inst().isNativeLibraryLoaded(); synchronized (DisplayMetricsHolder.class) { sScreenDisplayMetrics = dm; + sScaleDensity = scaleDensity; + sOrientation = orientation; + isCacheInvalid = false; if (isNativeLibraryLoaded) { hasNativeUpdateDeviceInfo = true; nativeUpdateDevice(dm.widthPixels, dm.heightPixels, dm.density);