diff --git a/dist/小妈厨房_Setup_1.5.1.exe b/dist/小妈厨房_Setup_1.5.1.exe new file mode 100644 index 0000000..2fd9b02 Binary files /dev/null and b/dist/小妈厨房_Setup_1.5.1.exe differ diff --git a/lib/src/controllers/tools/comparison_controller.dart b/lib/src/controllers/tools/comparison_controller.dart index 296a8fb..53aa348 100644 --- a/lib/src/controllers/tools/comparison_controller.dart +++ b/lib/src/controllers/tools/comparison_controller.dart @@ -223,7 +223,7 @@ class ComparisonController extends BaseController { 'ComparisonController: API返回: title=${apiRecipe.title}, ' 'nutrition=${apiRecipe.nutrition != null ? "有(${apiRecipe.nutrition!.calories}kcal)" : "NULL"}, ' 'meta=${apiRecipe.meta != null ? "有" : "NULL"}, ' - 'ingredients=${apiRecipe.ingredients?.length ?? 0}', + 'ingredients=${apiRecipe.ingredients.length}', ); } on TimeoutException { debugPrint('ComparisonController: fetchDetail超时5s,使用源数据'); @@ -255,7 +255,7 @@ class ComparisonController extends BaseController { RecipeModel _mergeRecipeData(RecipeModel original, RecipeModel api) { return RecipeModel( id: api.id > 0 ? api.id : original.id, - title: (api.title ?? '').isNotEmpty ? api.title : original.title, + title: api.title.isNotEmpty ? api.title : original.title, intro: (api.intro ?? '').isNotEmpty ? api.intro : original.intro, cover: (api.cover ?? '').isNotEmpty ? api.cover : original.cover, categoryName: (api.categoryName ?? '').isNotEmpty @@ -263,17 +263,15 @@ class ComparisonController extends BaseController { : original.categoryName, nutrition: api.nutrition ?? original.nutrition, meta: api.meta ?? original.meta, - ingredients: (api.ingredients != null && api.ingredients!.isNotEmpty) + ingredients: api.ingredients.isNotEmpty ? api.ingredients : original.ingredients, categorizedIngredients: api.categorizedIngredients ?? original.categorizedIngredients, statistics: api.statistics ?? original.statistics, rating: api.rating ?? original.rating, - tags: api.tags ?? original.tags, - allergens: (api.allergens != null && api.allergens!.isNotEmpty) - ? api.allergens - : original.allergens, + tags: api.tags, + allergens: api.allergens.isNotEmpty ? api.allergens : original.allergens, author: api.author ?? original.author, content: (api.content ?? '').isNotEmpty ? api.content : original.content, ); @@ -347,7 +345,9 @@ class ComparisonController extends BaseController { ); } on TimeoutException { debugPrint('ComparisonController: API超时5s,使用源数据'); - } catch (_) {} + } catch (_) { + // silently ignore - fall back to source data + } } } else { IngredientModel apiIng = ingredient; @@ -357,7 +357,9 @@ class ComparisonController extends BaseController { .timeout(const Duration(seconds: 5)); } on TimeoutException { debugPrint('ComparisonController: API超时5s,使用源数据'); - } catch (e) {} + } catch (e) { + // silently ignore - fall back to source data + } result = IngredientModel( id: apiIng.id > 0 ? apiIng.id : ingredient.id, name: apiIng.name.isNotEmpty ? apiIng.name : ingredient.name, @@ -751,7 +753,7 @@ class ComparisonSummary { emoji: '⚠️', title: '过敏原对比', description: aAllergens != bAllergens - ? '$fewer 过敏原更少 (${aAllergens} vs ${bAllergens})' + ? '$fewer 过敏原更少 ($aAllergens vs $bAllergens)' : '两者过敏原数量相同', type: aAllergens != bAllergens ? ComparisonType.green @@ -769,7 +771,7 @@ class ComparisonSummary { ComparisonPoint( emoji: '🥘', title: '用料数量', - description: '${a.title} ${aIngCount}种 vs ${b.title} ${bIngCount}种', + description: '${a.title} $aIngCount种 vs ${b.title} $bIngCount种', type: ComparisonType.purple, ), ); @@ -818,7 +820,7 @@ class ComparisonSummary { emoji: '⚠️', title: '过敏原对比', description: aAllergens != bAllergens - ? '$fewer 过敏原更少 (${aAllergens} vs ${bAllergens})' + ? '$fewer 过敏原更少 ($aAllergens vs $bAllergens)' : '两者过敏原数量相同', type: aAllergens != bAllergens ? ComparisonType.green diff --git a/lib/src/controllers/tools/what_to_eat_controller.dart b/lib/src/controllers/tools/what_to_eat_controller.dart index 7b03112..2235206 100644 --- a/lib/src/controllers/tools/what_to_eat_controller.dart +++ b/lib/src/controllers/tools/what_to_eat_controller.dart @@ -400,7 +400,7 @@ class WhatToEatController extends BaseController { 'title': recipe.title, 'categoryName': recipe.categoryName ?? '', 'time': DateTime.now().toIso8601String(), - 'displayIntro': recipe.displayIntro ?? '', + 'displayIntro': recipe.displayIntro, }; eatHistory.insert(0, entry); if (eatHistory.length > _maxHistorySize) { diff --git a/lib/src/pages/discover/components/browse_history_section.dart b/lib/src/pages/discover/components/browse_history_section.dart index 4d089d4..d6bc8de 100644 --- a/lib/src/pages/discover/components/browse_history_section.dart +++ b/lib/src/pages/discover/components/browse_history_section.dart @@ -117,7 +117,7 @@ class BrowseHistorySection extends StatelessWidget { return ListView.separated( scrollDirection: Axis.horizontal, padding: const EdgeInsets.symmetric(horizontal: DesignTokens.space1), - separatorBuilder: (_, __) => const SizedBox(width: DesignTokens.space2), + separatorBuilder: (_, _) => const SizedBox(width: DesignTokens.space2), itemCount: history.length, itemBuilder: (context, index) { final item = history[index]; diff --git a/lib/src/pages/discover/mini_card/mini_card_image_view.dart b/lib/src/pages/discover/mini_card/mini_card_image_view.dart index fbbde23..04826f9 100644 --- a/lib/src/pages/discover/mini_card/mini_card_image_view.dart +++ b/lib/src/pages/discover/mini_card/mini_card_image_view.dart @@ -1,4 +1,4 @@ -/* +/* * 文件: mini_card_image_view.dart * 名称: 迷你卡片图片组件 * 作用: 迷你卡片的图片展示组件,包含液态玻璃效果、分类标签、操作按钮 @@ -94,7 +94,7 @@ class MiniCardImageView extends StatelessWidget { maxHeightDiskCache: 800, fadeInDuration: const Duration(milliseconds: 300), fadeInCurve: Curves.easeOut, - errorWidget: (_, __, _) => Container( + errorWidget: (_, _, _) => Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, @@ -113,7 +113,7 @@ class MiniCardImageView extends StatelessWidget { ), ), ), - progressIndicatorBuilder: (_, __, progress) => Container( + progressIndicatorBuilder: (_, _, progress) => Container( color: DesignTokens.background, child: Center( child: CupertinoActivityIndicator( diff --git a/lib/src/pages/discover/mini_card/mini_card_page.dart b/lib/src/pages/discover/mini_card/mini_card_page.dart index d904c56..f3f6329 100644 --- a/lib/src/pages/discover/mini_card/mini_card_page.dart +++ b/lib/src/pages/discover/mini_card/mini_card_page.dart @@ -402,7 +402,9 @@ class _MiniCardPageState extends State { final boundary = _cardKey.currentContext?.findRenderObject() as RenderRepaintBoundary?; if (boundary == null) { - Share.share('🍳 ${recipe.name} — 来自 小妈厨房 迷你卡片'); + SharePlus.instance.share( + ShareParams(text: '🍳 ${recipe.name} — 来自 小妈厨房 迷你卡片'), + ); return; } @@ -411,7 +413,9 @@ class _MiniCardPageState extends State { image.dispose(); if (byteData == null || !mounted) { - Share.share('🍳 ${recipe.name} — 来自 小妈厨房 迷你卡片'); + SharePlus.instance.share( + ShareParams(text: '🍳 ${recipe.name} — 来自 小妈厨房 迷你卡片'), + ); return; } @@ -425,16 +429,21 @@ class _MiniCardPageState extends State { ); if (!mounted) return; - await Share.shareXFiles([ - XFile(filePath), - ], text: '🍳 ${recipe.name} — 来自 小妈厨房'); + await SharePlus.instance.share( + ShareParams( + text: '🍳 ${recipe.name} — 来自 小妈厨房', + files: [XFile(filePath)], + ), + ); Future.delayed(const Duration(seconds: 5), () { if (file.existsSync()) file.deleteSync(); }); } catch (e) { debugPrint('MiniCardPage: share failed: $e'); - Share.share('🍳 ${recipe.name} — 来自 小妈厨房 迷你卡片'); + SharePlus.instance.share( + ShareParams(text: '🍳 ${recipe.name} — 来自 小妈厨房 迷你卡片'), + ); } } diff --git a/lib/src/pages/discover/mini_card/mini_card_viewer.dart b/lib/src/pages/discover/mini_card/mini_card_viewer.dart index 7495c44..0a2335c 100644 --- a/lib/src/pages/discover/mini_card/mini_card_viewer.dart +++ b/lib/src/pages/discover/mini_card/mini_card_viewer.dart @@ -1,4 +1,4 @@ -/* +/* * 文件: mini_card_viewer.dart * 名称: 迷你卡片全屏查看器 * 作用: 迷你卡片的全屏图片查看,基于公共ImageViewerPage,增加液态玻璃信息层 @@ -48,7 +48,7 @@ class MiniCardViewer { fadeInCurve: Curves.easeOut, maxWidthDiskCache: 1200, maxHeightDiskCache: 1200, - errorWidget: (_, __, _) => Container( + errorWidget: (_, _, _) => Container( color: Colors.grey[900], child: const Center( child: Icon( @@ -58,7 +58,7 @@ class MiniCardViewer { ), ), ), - progressIndicatorBuilder: (_, __, _) => Container( + progressIndicatorBuilder: (_, _, _) => Container( color: Colors.grey[900], child: const Center( child: CupertinoActivityIndicator(radius: 16), diff --git a/lib/src/pages/home/search_page.dart b/lib/src/pages/home/search_page.dart index 83723be..604f2d0 100644 --- a/lib/src/pages/home/search_page.dart +++ b/lib/src/pages/home/search_page.dart @@ -1,4 +1,4 @@ -/* +/* * 文件: search_page.dart * 名称: 搜索页面 * 作用: iOS 26 风格的菜谱搜索页面,支持多维度搜索+高级筛选 @@ -633,7 +633,7 @@ class _SearchPageState extends State { child: ListView.separated( scrollDirection: Axis.horizontal, itemCount: tabs.length, - separatorBuilder: (_, __) => SizedBox(width: DesignTokens.space2), + separatorBuilder: (_, _) => SizedBox(width: DesignTokens.space2), itemBuilder: (context, index) { final tab = tabs[index]; final isSelected = @@ -744,7 +744,7 @@ class _SearchPageState extends State { vertical: DesignTokens.space2, ), itemCount: recipes.length, - separatorBuilder: (_, __) => const SizedBox(height: DesignTokens.space2), + separatorBuilder: (_, _) => const SizedBox(height: DesignTokens.space2), itemBuilder: (context, index) { final recipe = recipes[index]; return _buildRecipeCard(recipe, isDark); @@ -858,7 +858,7 @@ class _SearchPageState extends State { vertical: DesignTokens.space2, ), itemCount: ingredients.length, - separatorBuilder: (_, __) => const SizedBox(height: DesignTokens.space2), + separatorBuilder: (_, _) => const SizedBox(height: DesignTokens.space2), itemBuilder: (context, index) { final ingredient = ingredients[index]; return GestureDetector( diff --git a/lib/src/pages/profile/data/cache_manage_page.dart b/lib/src/pages/profile/data/cache_manage_page.dart index 9beed56..5ec1452 100644 --- a/lib/src/pages/profile/data/cache_manage_page.dart +++ b/lib/src/pages/profile/data/cache_manage_page.dart @@ -1,4 +1,4 @@ -/* +/* * 文件: cache_manage_page.dart * 说明: 缓存管理页面 * 作用: 管理首页Discover缓存、菜品详情缓存、食材缓存、API缓存与图片缓存 @@ -842,7 +842,7 @@ class _CacheManagePageState extends State { child: Image.network( item.cover!, fit: BoxFit.cover, - errorBuilder: (_, __, _) => Icon( + errorBuilder: (_, _, _) => Icon( CupertinoIcons.photo, color: DesignTokens.dynamicPrimary, ), diff --git a/lib/src/pages/profile/social/chat_page.dart b/lib/src/pages/profile/social/chat_page.dart index f56d90b..f533b40 100644 --- a/lib/src/pages/profile/social/chat_page.dart +++ b/lib/src/pages/profile/social/chat_page.dart @@ -579,7 +579,7 @@ class _FeedbackPageState extends State { ), trailing: CupertinoButton( padding: EdgeInsets.zero, - minSize: 36, + minimumSize: const Size(36, 36), onPressed: _showInfoDialog, child: Icon( CupertinoIcons.info_circle, diff --git a/lib/src/pages/profile/social/favorites_item_builders.dart b/lib/src/pages/profile/social/favorites_item_builders.dart index 87d9a15..e211f61 100644 --- a/lib/src/pages/profile/social/favorites_item_builders.dart +++ b/lib/src/pages/profile/social/favorites_item_builders.dart @@ -1,4 +1,4 @@ -/* +/* * 文件: favorites_item_builders.dart * 名称: 收藏项构建器 Mixin * 作用: 收藏页面中各类收藏项的构建方法,拆分自 favorites_page.dart @@ -204,7 +204,7 @@ mixin FavoritesItemBuilders on State { ? coverUrl : 'https://eat.wktyl.com/api/assets/$coverUrl', fit: BoxFit.cover, - errorBuilder: (_, __, _) => Container( + errorBuilder: (_, _, _) => Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, diff --git a/lib/src/pages/profile/social/footprints_page.dart b/lib/src/pages/profile/social/footprints_page.dart index 580e3e0..d88b82d 100644 --- a/lib/src/pages/profile/social/footprints_page.dart +++ b/lib/src/pages/profile/social/footprints_page.dart @@ -1,4 +1,4 @@ -/* +/* * 文件: footprints_page.dart * 说明: 浏览记录页面,展示用户浏览菜谱历史 * 作用: 展示用户足迹,支持管理、删除、清空 @@ -133,7 +133,7 @@ class FootprintsPage extends StatelessWidget { child: ListView.separated( padding: const EdgeInsets.all(DesignTokens.space4), itemCount: history.length, - separatorBuilder: (_, __) => + separatorBuilder: (_, _) => const SizedBox(height: DesignTokens.space3), itemBuilder: (context, index) => _buildHistoryCard(context, controller, history[index], isDark), diff --git a/lib/src/pages/tools/comparison/dish_comparison_page.dart b/lib/src/pages/tools/comparison/dish_comparison_page.dart index 363431f..0ff5f7e 100644 --- a/lib/src/pages/tools/comparison/dish_comparison_page.dart +++ b/lib/src/pages/tools/comparison/dish_comparison_page.dart @@ -320,7 +320,7 @@ class DishComparisonPage extends StatelessWidget { width: 48, height: 48, fit: BoxFit.cover, - errorBuilder: (_, __, ___) => Text( + errorBuilder: (_, _, _) => Text( _categoryEmoji( recipe.categoryName ?? '', ), @@ -832,7 +832,7 @@ class DishComparisonPage extends StatelessWidget { Widget _buildIndicesSection(List slots, bool isDark) { final allKeys = {}; for (final r in slots) { - allKeys.addAll(r.meta?.indices?.keys ?? []); + allKeys.addAll(r.meta?.indices.keys ?? []); } if (allKeys.isEmpty) return const SizedBox.shrink(); @@ -846,8 +846,8 @@ class DishComparisonPage extends StatelessWidget { child: Column( children: sortedKeys.map((key) { if (is1v1) { - final scoreA = slots[0].meta?.indices?[key] ?? 0; - final scoreB = slots[1].meta?.indices?[key] ?? 0; + final scoreA = slots[0].meta?.indices[key] ?? 0; + final scoreB = slots[1].meta?.indices[key] ?? 0; final colorA = ComparisonController.slotColors[0]; final colorB = ComparisonController.slotColors[1]; return Padding( @@ -901,7 +901,7 @@ class DishComparisonPage extends StatelessWidget { ...slots.asMap().entries.map((entry) { final i = entry.key; final recipe = entry.value; - final score = recipe.meta?.indices?[key] ?? 0; + final score = recipe.meta?.indices[key] ?? 0; final color = ComparisonController .slotColors[i % ComparisonController.slotColors.length]; return Padding( @@ -1105,7 +1105,6 @@ class DishComparisonPage extends StatelessWidget { final item = recipe.nutrition?.items ?.where((e) => e.name == name) .firstOrNull; - final hasValue = item != null; final value = item?.value ?? 0; final unit = item?.unit ?? ''; final slotColor = ComparisonController @@ -1390,8 +1389,9 @@ class DishComparisonPage extends StatelessWidget { Widget _buildSummarySection(ComparisonController ctrl, bool isDark) { final summary = ctrl.dishComparisonSummary; - if (summary == null || summary.points.isEmpty) + if (summary == null || summary.points.isEmpty) { return const SizedBox.shrink(); + } return _buildSectionCard( isDark, diff --git a/lib/src/pages/tools/comparison/ingredient_comparison_page.dart b/lib/src/pages/tools/comparison/ingredient_comparison_page.dart index d10c24e..67ffaae 100644 --- a/lib/src/pages/tools/comparison/ingredient_comparison_page.dart +++ b/lib/src/pages/tools/comparison/ingredient_comparison_page.dart @@ -181,7 +181,7 @@ class IngredientComparisonPage extends StatelessWidget { width: 48, height: 48, fit: BoxFit.cover, - errorBuilder: (_, __, ___) => Text( + errorBuilder: (_, _, _) => Text( ingredient.displayImage, style: const TextStyle(fontSize: 24), ), @@ -381,8 +381,9 @@ class IngredientComparisonPage extends StatelessWidget { final ing = entry.value; final color = ComparisonController .slotColors[i % ComparisonController.slotColors.length]; - if (ing.nutrition == null || ing.nutrition!.isEmpty) + if (ing.nutrition == null || ing.nutrition!.isEmpty) { return const SizedBox.shrink(); + } return Padding( padding: const EdgeInsets.only(bottom: DesignTokens.space3), child: _buildNutritionBlock( @@ -627,8 +628,9 @@ class IngredientComparisonPage extends StatelessWidget { final ing = entry.value; final color = ComparisonController .slotColors[i % ComparisonController.slotColors.length]; - if (ing.usageTip == null || ing.usageTip!.isEmpty) + if (ing.usageTip == null || ing.usageTip!.isEmpty) { return const SizedBox.shrink(); + } return Padding( padding: const EdgeInsets.only(bottom: DesignTokens.space3), child: _buildTipBlock( @@ -690,8 +692,9 @@ class IngredientComparisonPage extends StatelessWidget { Widget _buildSummarySection(ComparisonController ctrl, bool isDark) { final summary = ctrl.ingredientComparisonSummary; - if (summary == null || summary.points.isEmpty) + if (summary == null || summary.points.isEmpty) { return const SizedBox.shrink(); + } return _buildSectionCard( isDark, diff --git a/lib/src/pages/tools/cooking/calculator/order_assistant_page.dart b/lib/src/pages/tools/cooking/calculator/order_assistant_page.dart index 3af3fab..35ad0a3 100644 --- a/lib/src/pages/tools/cooking/calculator/order_assistant_page.dart +++ b/lib/src/pages/tools/cooking/calculator/order_assistant_page.dart @@ -1,4 +1,4 @@ -/* +/* * 文件: order_assistant_page.dart * 名称: 点餐助手主页面 * 作用: 点餐/推单主界面,支持菜品管理、账单生成、二维码分享、文本/图片分享 @@ -851,13 +851,11 @@ class _OrderAssistantPageState extends State { } final text = _generateOrderText(order); try { - final box = context.findRenderObject() as RenderBox?; - await Share.share( - text, - subject: '点餐助手 - ${order.orderNo}', - sharePositionOrigin: box != null - ? box.localToGlobal(Offset.zero) & box.size - : null, + await SharePlus.instance.share( + ShareParams( + text: text, + subject: '点餐助手 - ${order.orderNo}', + ), ); } catch (e) { debugPrint('[OrderPage] share text error: $e'); @@ -955,7 +953,7 @@ class _OrderAssistantPageState extends State { borderRadius: DesignTokens.borderRadiusMd, onPressed: () async { await _captureAndShare(previewKey, order); - if (context.mounted) Navigator.pop(context); + if (mounted) Navigator.pop(context); }, child: const Row( mainAxisSize: MainAxisSize.min, @@ -1310,14 +1308,12 @@ class _OrderAssistantPageState extends State { await File(filePath).writeAsBytes(buffer.asUint8List()); final xFile = XFile(filePath); if (!mounted) return; - final box = context.findRenderObject() as RenderBox?; - await Share.shareXFiles( - [xFile], - text: '点餐助手 - ${order.orderNo}', - subject: '点餐助手 - ${order.orderNo}', - sharePositionOrigin: box != null - ? box.localToGlobal(Offset.zero) & box.size - : null, + await SharePlus.instance.share( + ShareParams( + text: '点餐助手 - ${order.orderNo}', + subject: '点餐助手 - ${order.orderNo}', + files: [xFile], + ), ); } catch (e) { debugPrint('[OrderPage] capture and share error: $e'); diff --git a/lib/src/pages/tools/cooking/widgets/browse_history_picker.dart b/lib/src/pages/tools/cooking/widgets/browse_history_picker.dart index 6a9f28c..916a355 100644 --- a/lib/src/pages/tools/cooking/widgets/browse_history_picker.dart +++ b/lib/src/pages/tools/cooking/widgets/browse_history_picker.dart @@ -1,4 +1,4 @@ -/* +/* * 文件: browse_history_picker.dart * 名称: 浏览记录选择器 * 作用: 展示本地浏览记录供用户选择菜品 @@ -140,7 +140,7 @@ class BrowseHistoryPicker extends StatelessWidget { width: 44, height: 44, fit: BoxFit.cover, - errorBuilder: (_, __, ___) => _defaultFoodIcon(), + errorBuilder: (_, _, _) => _defaultFoodIcon(), ) : _defaultFoodIcon(), ), diff --git a/lib/src/pages/tools/ranking/dish_pick_sheet.dart b/lib/src/pages/tools/ranking/dish_pick_sheet.dart index 2e4f773..bfbeb97 100644 --- a/lib/src/pages/tools/ranking/dish_pick_sheet.dart +++ b/lib/src/pages/tools/ranking/dish_pick_sheet.dart @@ -1,4 +1,4 @@ -/* +/* * 文件: dish_pick_sheet.dart * 名称: 菜品选择面板 * 作用: 底部弹出面板,支持从浏览记录/收藏/手动输入三种方式选择菜品加入Tier List @@ -357,7 +357,7 @@ class _DishPickSheetState extends State { bottom: bottomPadding + DesignTokens.space3, ), itemCount: items.length, - separatorBuilder: (_, __) => material.Divider( + separatorBuilder: (_, _) => material.Divider( height: 1, color: isDark ? material.Colors.white10 : const Color(0x0F000000), ), @@ -390,7 +390,7 @@ class _DishPickSheetState extends State { bottom: bottomPadding + DesignTokens.space3, ), itemCount: items.length, - separatorBuilder: (_, __) => material.Divider( + separatorBuilder: (_, _) => material.Divider( height: 1, color: isDark ? material.Colors.white10 : const Color(0x0F000000), ), @@ -547,7 +547,7 @@ class _DishPickSheetState extends State { ? Image.network( coverUrl, fit: BoxFit.cover, - errorBuilder: (_, __, ___) => Center( + errorBuilder: (_, _, _) => Center( child: Text( emoji, style: const TextStyle(fontSize: 22), diff --git a/lib/src/pages/tools/ranking/dish_ranking_page.dart b/lib/src/pages/tools/ranking/dish_ranking_page.dart index 7ddd38f..c736c20 100644 --- a/lib/src/pages/tools/ranking/dish_ranking_page.dart +++ b/lib/src/pages/tools/ranking/dish_ranking_page.dart @@ -1,4 +1,4 @@ -/* +/* * 文件: dish_ranking_page.dart * 名称: 菜品排名页面 * 作用: Tier List主界面,展示5个层级的菜品排名,支持拖拽排序、跨层级移动、添加/删除 @@ -325,7 +325,7 @@ class _DishRankingPageState extends State scrollDirection: Axis.horizontal, physics: const BouncingScrollPhysics(), itemCount: items.length, - separatorBuilder: (_, __) => const SizedBox(width: 8), + separatorBuilder: (_, _) => const SizedBox(width: 8), itemBuilder: (context, index) { return _DishCard( item: items[index], @@ -549,7 +549,7 @@ class _DishCard extends StatelessWidget { item.coverImage!, fit: BoxFit.cover, width: double.infinity, - errorBuilder: (_, __, ___) => Center( + errorBuilder: (_, _, _) => Center( child: Text( item.emoji, style: const TextStyle(fontSize: 32), diff --git a/lib/src/services/api/api_service.dart b/lib/src/services/api/api_service.dart index 591916a..c99b092 100644 --- a/lib/src/services/api/api_service.dart +++ b/lib/src/services/api/api_service.dart @@ -235,7 +235,7 @@ class ApiService { final result = await Connectivity().checkConnectivity().timeout( const Duration(seconds: 3), ); - return result == ConnectivityResult.none; + return result.contains(ConnectivityResult.none); } catch (_) { return true; } diff --git a/lib/src/services/data/business/data_export_service.dart b/lib/src/services/data/business/data_export_service.dart index a87b9be..431dd5c 100644 --- a/lib/src/services/data/business/data_export_service.dart +++ b/lib/src/services/data/business/data_export_service.dart @@ -278,10 +278,12 @@ class DataExportService extends GetxService { Future shareExportedData(String filePath) async { if (kIsWeb) return; - await Share.shareXFiles( - [XFile(filePath)], - subject: '小妈厨房 - 数据导出', - text: '从小妈厨房导出的数据', + await SharePlus.instance.share( + ShareParams( + text: '从小妈厨房导出的数据', + subject: '小妈厨房 - 数据导出', + files: [XFile(filePath)], + ), ); } diff --git a/lib/src/services/system/connectivity_service.dart b/lib/src/services/system/connectivity_service.dart index 0efba0f..8a26c4e 100644 --- a/lib/src/services/system/connectivity_service.dart +++ b/lib/src/services/system/connectivity_service.dart @@ -13,7 +13,7 @@ typedef OnNetworkRestoredCallback = Future Function(); class ConnectivityService extends GetxService with WidgetsBindingObserver { final Connectivity _connectivity = Connectivity(); - StreamSubscription? _subscription; + StreamSubscription>? _subscription; final Rx status = Rx( ConnectivityStatus.unknown, @@ -91,8 +91,8 @@ class ConnectivityService extends GetxService with WidgetsBindingObserver { _onChanged(result); } - void _onChanged(ConnectivityResult result) { - final hasConnection = result != ConnectivityResult.none; + void _onChanged(List results) { + final hasConnection = !results.contains(ConnectivityResult.none); final newStatus = hasConnection ? ConnectivityStatus.online : ConnectivityStatus.offline; @@ -122,8 +122,8 @@ class ConnectivityService extends GetxService with WidgetsBindingObserver { Future checkConnection() async { if (kIsWeb) return true; - final result = await _connectivity.checkConnectivity(); - return result != ConnectivityResult.none; + final results = await _connectivity.checkConnectivity(); + return !results.contains(ConnectivityResult.none); } @override diff --git a/lib/src/services/ui/theme_service.dart b/lib/src/services/ui/theme_service.dart index 5a2c325..dca4525 100644 --- a/lib/src/services/ui/theme_service.dart +++ b/lib/src/services/ui/theme_service.dart @@ -366,7 +366,7 @@ class ThemeService extends GetxController { } ThemeData getThemeData() { - final _font = fontFamilyStyle.value == FontFamilyStyle.notoSansSC + final font = fontFamilyStyle.value == FontFamilyStyle.notoSansSC ? 'NotoSansSC' : null; return ThemeData( @@ -379,42 +379,42 @@ class ThemeService extends GetxController { bodyLarge: TextStyle( fontSize: fontSize.value, color: textColor.value, - fontFamily: _font, + fontFamily: font, ), bodyMedium: TextStyle( fontSize: fontSize.value - 2, color: textColor.value, - fontFamily: _font, + fontFamily: font, ), bodySmall: TextStyle( fontSize: fontSize.value - 4, color: textColor.value, - fontFamily: _font, + fontFamily: font, ), titleLarge: TextStyle( fontSize: fontSize.value + 4, fontWeight: FontWeight.w700, color: textColor.value, - fontFamily: _font, + fontFamily: font, ), titleMedium: TextStyle( fontSize: fontSize.value + 2, fontWeight: FontWeight.w600, color: textColor.value, - fontFamily: _font, + fontFamily: font, ), titleSmall: TextStyle( fontSize: fontSize.value, fontWeight: FontWeight.w500, color: textColor.value, - fontFamily: _font, + fontFamily: font, ), ), ); } CupertinoThemeData get cupertinoThemeData { - final _font = fontFamilyStyle.value == FontFamilyStyle.notoSansSC + final font = fontFamilyStyle.value == FontFamilyStyle.notoSansSC ? 'NotoSansSC' : null; return CupertinoThemeData( @@ -428,14 +428,14 @@ class ThemeService extends GetxController { inherit: false, fontSize: fontSize.value, color: textColor.value, - fontFamily: _font, + fontFamily: font, ), navTitleTextStyle: TextStyle( inherit: false, fontSize: fontSize.value + 2, fontWeight: FontWeight.w600, color: textColor.value, - fontFamily: _font, + fontFamily: font, ), ), ); diff --git a/lib/src/utils/app_utils.dart b/lib/src/utils/app_utils.dart index fec85c5..877794b 100644 --- a/lib/src/utils/app_utils.dart +++ b/lib/src/utils/app_utils.dart @@ -33,7 +33,7 @@ class AppUtils { } static Future shareContent(String text, {String? subject}) async { - await Share.share(text, subject: subject); + await SharePlus.instance.share(ShareParams(text: text, subject: subject)); } static void copyToClipboard(BuildContext context, String text) { @@ -153,14 +153,14 @@ class StringUtils { class NetworkUtils { static Future isConnected() async { final connectivityResult = await Connectivity().checkConnectivity(); - return connectivityResult != ConnectivityResult.none; + return !connectivityResult.contains(ConnectivityResult.none); } static Future getConnectionType() async { final connectivityResult = await Connectivity().checkConnectivity(); - if (connectivityResult == ConnectivityResult.wifi) { + if (connectivityResult.contains(ConnectivityResult.wifi)) { return 'WiFi'; - } else if (connectivityResult == ConnectivityResult.mobile) { + } else if (connectivityResult.contains(ConnectivityResult.mobile)) { return 'Mobile'; } else { return 'No Connection'; diff --git a/lib/src/utils/farm_share_util.dart b/lib/src/utils/farm_share_util.dart index 57ba251..2636df3 100644 --- a/lib/src/utils/farm_share_util.dart +++ b/lib/src/utils/farm_share_util.dart @@ -63,10 +63,11 @@ class FarmShareUtil { await file.writeAsBytes(bytes); // 分享 - await Share.shareXFiles( - [XFile(file.path)], - text: - '🌾 我在小妈菜园的收获!\n等级: Lv.$level | 收获: $totalHarvest 次 | 金币: $gold 💰', + await SharePlus.instance.share( + ShareParams( + text: '🌾 我在小妈菜园的收获!\n等级: Lv.$level | 收获: $totalHarvest 次 | 金币: $gold 💰', + files: [XFile(file.path)], + ), ); // 清理临时文件 diff --git a/lib/src/widgets/base/app_page_scaffold.dart b/lib/src/widgets/base/app_page_scaffold.dart index 6b3838b..9e3e338 100644 --- a/lib/src/widgets/base/app_page_scaffold.dart +++ b/lib/src/widgets/base/app_page_scaffold.dart @@ -1,4 +1,4 @@ -// 2026-04-09 | AppPageScaffold | 全局可复用页面骨架组件 | 统一iOS26风格页面结构 +// 2026-04-09 | AppPageScaffold | 全局可复用页面骨架组件 | 统一iOS26风格页面结构 // 2026-04-09 | 初始创建,提供导航栏/加载/空态/错误/内容五种状态 import 'package:flutter/cupertino.dart'; import 'package:get/get.dart'; @@ -200,7 +200,7 @@ class AppSectionHeader extends StatelessWidget { ), ), ), - if (trailing != null) trailing!, + ?trailing, ], ), ); diff --git a/lib/src/widgets/comparison/comparison_layout.dart b/lib/src/widgets/comparison/comparison_layout.dart index 5ff9856..c49bf7f 100644 --- a/lib/src/widgets/comparison/comparison_layout.dart +++ b/lib/src/widgets/comparison/comparison_layout.dart @@ -225,7 +225,7 @@ class ComparisonLayout extends StatelessWidget { ), const SizedBox(width: DesignTokens.space2), Text( - '添加对比项 (${itemCount}/${ComparisonController.maxSlots})', + '添加对比项 ($itemCount/${ComparisonController.maxSlots})', style: TextStyle( fontSize: DesignTokens.fontSm, fontWeight: FontWeight.w500, diff --git a/lib/src/widgets/discover/content/mini_card_discover_card.dart b/lib/src/widgets/discover/content/mini_card_discover_card.dart index 21fd48d..2e46432 100644 --- a/lib/src/widgets/discover/content/mini_card_discover_card.dart +++ b/lib/src/widgets/discover/content/mini_card_discover_card.dart @@ -93,13 +93,13 @@ class MiniCardDiscoverCard extends StatelessWidget { : CachedNetworkImage( imageUrl: recipe.fullImageUrl, fit: BoxFit.cover, - placeholder: (_, __) => Container( + placeholder: (_, _) => Container( color: DesignTokens.background, child: const Center( child: CupertinoActivityIndicator(), ), ), - errorWidget: (_, __, _) => Container( + errorWidget: (_, _, _) => Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, diff --git a/lib/src/widgets/glass/glass_animations.dart b/lib/src/widgets/glass/glass_animations.dart index 85a6a07..9974986 100644 --- a/lib/src/widgets/glass/glass_animations.dart +++ b/lib/src/widgets/glass/glass_animations.dart @@ -215,7 +215,7 @@ class GlassFadeSwitch extends StatelessWidget { alignment: alignment, children: [ ...previousChildren, - if (currentChild != null) currentChild, + ?currentChild, ], ); }, diff --git a/lib/src/widgets/recipe_detail/header/recipe_cover_image.dart b/lib/src/widgets/recipe_detail/header/recipe_cover_image.dart index a8caa61..5d850b9 100644 --- a/lib/src/widgets/recipe_detail/header/recipe_cover_image.dart +++ b/lib/src/widgets/recipe_detail/header/recipe_cover_image.dart @@ -182,8 +182,9 @@ class _RecipeCoverImageState extends State { Color _getBadgeBgColor(RecipeRating ratingData) { if (ratingData.isExcellent) return DesignTokens.gold.withValues(alpha: 0.9); - if (ratingData.isRecommended) + if (ratingData.isRecommended) { return DesignTokens.dynamicPrimary.withValues(alpha: 0.9); + } return DesignTokens.orange.withValues(alpha: 0.9); } diff --git a/lib/src/widgets/recipe_detail/interaction/recipe_export_button.dart b/lib/src/widgets/recipe_detail/interaction/recipe_export_button.dart index 39994f9..919ddd7 100644 --- a/lib/src/widgets/recipe_detail/interaction/recipe_export_button.dart +++ b/lib/src/widgets/recipe_detail/interaction/recipe_export_button.dart @@ -87,8 +87,9 @@ class RecipeExportButton extends StatelessWidget { } if (codeUnit == 0x7F) return true; if (codeUnit >= 0x80 && codeUnit <= 0x9F) return true; - if ((codeUnit & 0xFFFE) == 0xFFFE || (codeUnit & 0xFFFE) == 0xFFFF) + if ((codeUnit & 0xFFFE) == 0xFFFE || (codeUnit & 0xFFFE) == 0xFFFF) { return true; + } if (codeUnit == 0xFFFD) return true; if (codeUnit >= 0xFDD0 && codeUnit <= 0xFDEF) return true; if (codeUnit >= 0xE000 && codeUnit <= 0xF8FF) return true; @@ -591,17 +592,21 @@ class RecipeExportButton extends StatelessWidget { return; } final fileSize = await file.length(); - debugPrint('开始分享文件: $filePath (${fileSize} bytes)'); + debugPrint('开始分享文件: $filePath ($fileSize bytes)'); final xFile = XFile(filePath); - await Share.shareXFiles([xFile], text: subject ?? '来自小妈厨房的菜谱'); + await SharePlus.instance.share( + ShareParams(text: subject ?? '来自小妈厨房的菜谱', files: [xFile]), + ); } on PlatformException catch (e) { debugPrint( '分享PlatformException: code=${e.code} msg=${e.message} details=${e.details}', ); try { debugPrint('尝试 fallback 纯文本分享...'); - await Share.share(subject ?? '来自小妈厨房的菜谱', sharePositionOrigin: null); + await SharePlus.instance.share( + ShareParams(text: subject ?? '来自小妈厨房的菜谱'), + ); } catch (e2) { debugPrint('fallback 分享也失败: $e2'); ToastService.show( @@ -1502,7 +1507,7 @@ class RecipeExportButton extends StatelessWidget { const Spacer(), CupertinoButton( padding: EdgeInsets.zero, - minSize: 30, + minimumSize: const Size(30, 30), onPressed: () => Navigator.pop(ctx), child: Text( '取消', diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index db4e6ab..df275dd 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -18,7 +18,7 @@ import sqflite_darwin import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { - ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin")) + ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/BuildProfile.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/BuildProfile.ets deleted file mode 100644 index e599d28..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/BuildProfile.ets +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Use these variables when you tailor your ArkTS code. They must be of the const type. - */ -export const HAR_VERSION = '1.0.0-e34a685f4b'; -export const BUILD_MODE_NAME = 'release'; -export const DEBUG = false; -export const TARGET_NAME = 'default'; - -/** - * BuildProfile Class is used only for compatibility purposes. - */ -export default class BuildProfile { - static readonly HAR_VERSION = HAR_VERSION; - static readonly BUILD_MODE_NAME = BUILD_MODE_NAME; - static readonly DEBUG = DEBUG; - static readonly TARGET_NAME = TARGET_NAME; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/build-profile.json5 b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/build-profile.json5 deleted file mode 100644 index e395590..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/build-profile.json5 +++ /dev/null @@ -1,40 +0,0 @@ - - -{ - "apiType": "stageMode", - "buildOption": { - "sourceOption": { - "workers": [ - "./src/main/ets/embedding/engine/workers/PlatformChannelWorker.ets" - ] - }, - "nativeLib": { - "debugSymbol": { - "strip": false, - "exclude": [] - } - } - }, - "buildOptionSet": [ - { - "name": "release", - "arkOptions": { - "obfuscation": { - "ruleOptions": { - "enable": false, - "files": [ - "./obfuscation-rules.txt" - ] - }, - "consumerFiles": ["./consumer-rules.txt"] - } - } - }, - ], - "targets": [ - { - "name": "default", - "runtimeOS": "HarmonyOS" - } - ] -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/consumer-rules.txt b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/consumer-rules.txt deleted file mode 100644 index 33b1039..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/consumer-rules.txt +++ /dev/null @@ -1,4 +0,0 @@ -# flutter_ohos 在混淆时需要保留的代码 --keep-property-name -flutter -native* diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/hvigorfile.ts b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/hvigorfile.ts deleted file mode 100644 index f2c2731..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/hvigorfile.ts +++ /dev/null @@ -1,3 +0,0 @@ - -// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. -export { harTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/index.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/index.ets deleted file mode 100644 index 2ac7c12..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/index.ets +++ /dev/null @@ -1,108 +0,0 @@ - - -export { default as FlutterInjector } from './src/main/ets/FlutterInjector'; -export { default as FlutterPluginRegistry } from './src/main/ets/app/FlutterPluginRegistry'; -export { default as FlutterComponent } from './src/main/ets/component/FlutterComponent'; -export { default as FlutterEngine } from './src/main/ets/embedding/engine/FlutterEngine'; -export { default as FlutterEngineCache } from './src/main/ets/embedding/engine/FlutterEngineCache'; -export { default as FlutterEngineConnectionRegistry } from './src/main/ets/embedding/engine/FlutterEngineConnectionRegistry'; -export { default as FlutterEngineGroup } from './src/main/ets/embedding/engine/FlutterEngineGroup'; -export { default as FlutterEnginePreload } from './src/main/ets/embedding/engine/FlutterEnginePreload'; -export { default as FlutterEngineGroupCache } from './src/main/ets/embedding/engine/FlutterEngineGroupCache'; -export { default as FlutterNapi } from './src/main/ets/embedding/engine/FlutterNapi'; -export * from './src/main/ets/embedding/engine/FlutterOverlaySurface'; -export { default as FlutterShellArgs } from './src/main/ets/embedding/engine/FlutterShellArgs'; -export { default as DartExecutor } from './src/main/ets/embedding/engine/dart/DartExecutor'; -export * from './src/main/ets/embedding/engine/dart/DartMessenger'; -export * from './src/main/ets/embedding/engine/dart/PlatformMessageHandler'; -export { default as ApplicationInfoLoader } from './src/main/ets/embedding/engine/loader/ApplicationInfoLoader'; -export { default as FlutterApplicationInfo } from './src/main/ets/embedding/engine/loader/FlutterApplicationInfo'; -export { default as FlutterLoader } from './src/main/ets/embedding/engine/loader/FlutterLoader'; -export * from './src/main/ets/embedding/engine/mutatorsstack/FlutterMutatorView'; -export * from './src/main/ets/embedding/engine/mutatorsstack/FlutterMutatorsStack'; -export * from './src/main/ets/embedding/engine/plugins/FlutterPlugin'; -export { default as PluginRegistry } from './src/main/ets/embedding/engine/plugins/PluginRegistry'; -export { default as AbilityAware } from './src/main/ets/embedding/engine/plugins/ability/AbilityAware'; -export { default as AbilityControlSurface } from './src/main/ets/embedding/engine/plugins/ability/AbilityControlSurface'; -export * from './src/main/ets/embedding/engine/plugins/ability/AbilityPluginBinding'; -export * from './src/main/ets/embedding/engine/renderer/FlutterRenderer'; -export * from './src/main/ets/embedding/engine/renderer/FlutterUiDisplayListener'; -export { default as AccessibilityChannel } from './src/main/ets/embedding/engine/systemchannels/AccessibilityChannel'; -export { default as KeyEventChannel } from './src/main/ets/embedding/engine/systemchannels/KeyEventChannel'; -export { default as LifecycleChannel } from './src/main/ets/embedding/engine/systemchannels/LifecycleChannel'; -export { default as LocalizationChannel } from './src/main/ets/embedding/engine/systemchannels/LocalizationChannel'; -export { default as MouseCursorChannel } from './src/main/ets/embedding/engine/systemchannels/MouseCursorChannel'; -export { default as DisplayMetricsChannel } from './src/main/ets/embedding/engine/systemchannels/DisplayMetricsChannel'; -export { default as NavigationChannel } from './src/main/ets/embedding/engine/systemchannels/NavigationChannel'; -export { default as PlatformChannel } from './src/main/ets/embedding/engine/systemchannels/PlatformChannel'; -export { default as PlatformViewsChannel } from './src/main/ets/embedding/engine/systemchannels/PlatformViewsChannel'; -export { default as RestorationChannel } from './src/main/ets/embedding/engine/systemchannels/RestorationChannel'; -export { default as SettingsChannel } from './src/main/ets/embedding/engine/systemchannels/SettingsChannel'; -export { default as SystemChannel } from './src/main/ets/embedding/engine/systemchannels/SystemChannel'; -export { default as TestChannel } from './src/main/ets/embedding/engine/systemchannels/TestChannel'; -export { default as TextInputChannel } from './src/main/ets/embedding/engine/systemchannels/TextInputChannel'; -export { default as NativeVsyncChannel } from './src/main/ets/embedding/engine/systemchannels/NativeVsyncChannel'; -export { default as ExclusiveAppComponent } from './src/main/ets/embedding/ohos/ExclusiveAppComponent'; -export * from './src/main/ets/embedding/ohos/FlutterAbility'; -export * from './src/main/ets/embedding/ohos/FlutterAbilityAndEntryDelegate'; -export { default as FlutterAbilityLaunchConfigs } from './src/main/ets/embedding/ohos/FlutterAbilityLaunchConfigs'; -export { default as FlutterEngineConfigurator } from './src/main/ets/embedding/ohos/FlutterEngineConfigurator'; -export { default as FlutterEngineProvider } from './src/main/ets/embedding/ohos/FlutterEngineProvider'; -export { default as FlutterEntry } from './src/main/ets/embedding/ohos/FlutterEntry'; -export { default as FlutterManager, DragDropCallback as DragDropCallback } from './src/main/ets/embedding/ohos/FlutterManager'; -export * from './src/main/ets/embedding/ohos/FlutterPage'; -export { default as KeyboardManager } from './src/main/ets/embedding/ohos/KeyboardManager'; -export { default as OhosTouchProcessor } from './src/main/ets/embedding/ohos/OhosTouchProcessor'; -export { default as Settings } from './src/main/ets/embedding/ohos/Settings'; -export * from './src/main/ets/embedding/ohos/TouchEventTracker'; -export { default as WindowInfoRepositoryCallbackAdapterWrapper } from './src/main/ets/embedding/ohos/WindowInfoRepositoryCallbackAdapterWrapper'; -export { default as PlatformPlugin } from './src/main/ets/plugin/PlatformPlugin'; -export { default as BasicMessageChannel, Reply } from './src/main/ets/plugin/common/BasicMessageChannel'; -export { default as BinaryCodec } from './src/main/ets/plugin/common/BinaryCodec'; -export * from './src/main/ets/plugin/common/BinaryMessenger'; -export { default as EventChannel, StreamHandler, EventSink } from './src/main/ets/plugin/common/EventChannel'; -export { default as FlutterException } from './src/main/ets/plugin/common/FlutterException'; -export { default as JSONMessageCodec } from './src/main/ets/plugin/common/JSONMessageCodec'; -export { default as JSONMethodCodec } from './src/main/ets/plugin/common/JSONMethodCodec'; -export { default as MessageCodec } from './src/main/ets/plugin/common/MessageCodec'; -export { default as MethodCall } from './src/main/ets/plugin/common/MethodCall'; -export * from './src/main/ets/plugin/common/MethodChannel'; -export { default as MethodChannel } from './src/main/ets/plugin/common/MethodChannel'; -export { default as MethodCodec } from './src/main/ets/plugin/common/MethodCodec'; -export { default as BackgroundBasicMessageChannel } from './src/main/ets/plugin/common/BackgroundBasicMessageChannel'; -export { default as BackgroundMethodChannel} from './src/main/ets/plugin/common/BackgroundMethodChannel' -export { default as SendableBinaryCodec} from './src/main/ets/plugin/common/SendableBinaryCodec' -export { default as SendableJSONMessageCodec} from './src/main/ets/plugin/common/SendableJSONMessageCodec' -export { default as SendableJSONMethodCodec} from './src/main/ets/plugin/common/SendableJSONMethodCodec' -export { default as SendableMessageHandler} from './src/main/ets/plugin/common/SendableMessageHandler' -export { default as SendableMethodCallHandler} from './src/main/ets/plugin/common/SendableMethodCallHandler' -export { default as SendableMethodCodec} from './src/main/ets/plugin/common/SendableMethodCodec' -export { default as SendableStandardMessageCodec } from './src/main/ets/plugin/common/SendableStandardMessageCodec'; -export { default as SendableStandardMethodCodec } from './src/main/ets/plugin/common/SendableStandardMethodCodec'; -export { default as SendableStringCodec} from './src/main/ets/plugin/common/SendableStringCodec' -export { default as StandardMessageCodec } from './src/main/ets/plugin/common/StandardMessageCodec'; -export { default as StandardMethodCodec } from './src/main/ets/plugin/common/StandardMethodCodec'; -export { default as StringCodec } from './src/main/ets/plugin/common/StringCodec'; -export * from './src/main/ets/plugin/editing/ListenableEditingState'; -export * from './src/main/ets/plugin/editing/TextEditingDelta'; -export { default as TextInputPlugin } from './src/main/ets/plugin/editing/TextInputPlugin'; -export { default as LocalizationPlugin } from './src/main/ets/plugin/localization/LocalizationPlugin'; -export { default as MouseCursorPlugin } from './src/main/ets/plugin/mouse/MouseCursorPlugin'; -export { default as PlatformView } from './src/main/ets/plugin/platform/PlatformView'; -export { default as PlatformViewFactory } from './src/main/ets/plugin/platform/PlatformViewFactory'; -export { default as PlatformViewRegistry } from './src/main/ets/plugin/platform/PlatformViewRegistry'; -export { default as PlatformViewRegistryImpl } from './src/main/ets/plugin/platform/PlatformViewRegistryImpl'; -export * from './src/main/ets/plugin/platform/PlatformViewWrapper'; -export { default as PlatformViewsController } from './src/main/ets/plugin/platform/PlatformViewsController'; -export * from './src/main/ets/view/FlutterCallbackInformation'; -export { default as FlutterRunArguments } from './src/main/ets/view/FlutterRunArguments'; -export * from './src/main/ets/view/FlutterView'; -export * from './src/main/ets/view/TextureRegistry'; -export * from './src/main/ets/util/ByteBuffer'; -export { default as Log } from './src/main/ets/util/Log'; -export { default as MessageChannelUtils } from './src/main/ets/util/MessageChannelUtils'; -export { default as PathUtils } from './src/main/ets/util/PathUtils'; -export { default as StringUtils } from './src/main/ets/util/StringUtils'; -export { default as ToolUtils } from './src/main/ets/util/ToolUtils'; -export * from './src/main/ets/util/TraceSection'; -export { default as Any } from './src/main/ets/plugin/common/Any'; diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/obfuscation-rules.txt b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/obfuscation-rules.txt deleted file mode 100644 index eb5c766..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/obfuscation-rules.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Define project specific obfuscation rules here. -# You can include the obfuscation configuration files in the current module's build-profile.json5. -# -# For more details, see -# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 - -# Obfuscation options: -# -disable-obfuscation: disable all obfuscations -# -enable-property-obfuscation: obfuscate the property names -# -enable-toplevel-obfuscation: obfuscate the names in the global scope -# -compact: remove unnecessary blank spaces and all line feeds -# -remove-log: remove all console.* statements -# -print-namecache: print the name cache that contains the mapping from the old names to new names -# -apply-namecache: reuse the given cache file - -# Keep options: -# -keep-property-name: specifies property names that you want to keep -# -keep-global-name: specifies names that you want to keep in the global scope diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/obfuscation.txt b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/obfuscation.txt deleted file mode 100644 index 08f59e3..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/obfuscation.txt +++ /dev/null @@ -1,3 +0,0 @@ --keep-property-name -flutter -native* diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/oh-package.json5 b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/oh-package.json5 deleted file mode 100644 index bf91be6..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/oh-package.json5 +++ /dev/null @@ -1 +0,0 @@ -{"license":"Apache-2.0","author":"","name":"@ohos/flutter_ohos","description":"The embedder of flutter in ohos.","main":"index.ets","version":"1.0.0-e34a685f4b","dependencies":{},"devDependencies":{"@types/libflutter.so":"file:./src/main/cpp/types/libflutter"},"metadata":{"workers":["./src/main/ets/embedding/engine/workers/PlatformChannelWorker.ets"],"sourceRoots":["./src/main"],"debug":false},"compatibleSdkVersionStage":"beta1","compatibleSdkVersion":12,"compatibleSdkType":"HarmonyOS","obfuscated":false} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index.d.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index.d.ets deleted file mode 100644 index 20dec02..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index.d.ets +++ /dev/null @@ -1,532 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -import common from '@ohos.app.ability.common'; -import resourceManager from '@ohos.resourceManager'; -import image from '@ohos.multimedia.image'; -import FlutterNapi from '../../../ets/embedding/engine/FlutterNapi'; -import { ByteBuffer } from '../../../ets/util/ByteBuffer'; -import { FlutterCallbackInformation } from '../../../ets/view/FlutterCallbackInformation'; - -/** - * Updates the refresh rate for the Flutter engine. - * @param rate - The refresh rate value to set - */ -export const nativeUpdateRefreshRate: ( - rate: number -) => void; - -/** - * Initializes SkFontMgr::RefDefault() to prefetch the default font manager. - * This should be called before using fonts in the Flutter engine. - */ -export const nativePrefetchDefaultFontManager: () => void; - -/** - * Checks and reloads fonts for the specified shell holder. - * @param nativeShellHolderId - The ID of the native shell holder - */ -export const nativeCheckAndReloadFont: (nativeShellHolderId: number) => void; - -/** - * Updates the size of the Flutter view. - * @param width - The new width in pixels - * @param height - The new height in pixels - */ -export const nativeUpdateSize: ( - width: number, - height: number -) => void; - -/** - * Updates the pixel density of the display. - * @param densityPixels - The pixel density value (dots per inch) - */ -export const nativeUpdateDensity: ( - densityPixels: number -) => void; - -/** - * Initializes the Dart VM and Flutter engine. - * @param context - The application context - * @param args - Command line arguments for the Flutter engine - * @param bundlePath - Path to the Flutter bundle - * @param appStoragePath - Path to the application storage directory - * @param engineCachesPath - Path to the engine caches directory - * @param initTimeMillis - Initialization time in milliseconds - * @param productModel - Product model identifier - * @returns The native shell holder ID, or null if initialization fails - */ -export const nativeInit: ( - context: common.Context, - args: Array, - bundlePath: string, - appStoragePath: string, - engineCachesPath: string, - initTimeMillis: number, - productModel: string -) => number | null; - -/** - * Attaches a FlutterNapi instance to the engine. - * @param napi - The FlutterNapi instance to attach - * @returns The native shell holder ID - */ -export const nativeAttach: (napi: FlutterNapi) => number; - -/** - * Spawns a new Flutter shell instance. - * @param nativeSpawningShellId - The ID of the spawning shell, or null for a new shell - * @param entrypointFunctionName - Name of the entrypoint function - * @param pathToEntrypointFunction - Path to the entrypoint function - * @param initialRoute - Initial route for navigation - * @param entrypointArgs - Arguments to pass to the entrypoint function - * @param napi - The FlutterNapi instance - * @returns The native shell holder ID of the spawned shell - */ -export const nativeSpawn: ( - nativeSpawningShellId: number | null, - entrypointFunctionName: string, - pathToEntrypointFunction: string, - initialRoute: string, - entrypointArgs: Array, - napi: FlutterNapi -) => number; - -/** - * Runs a Flutter bundle and snapshot from a library. - * @param nativeShellHolderId - The ID of the native shell holder - * @param bundlePath - Path to the Flutter bundle - * @param entrypointFunctionName - Name of the entrypoint function - * @param pathToEntrypointFunction - Path to the entrypoint function - * @param assetManager - Resource manager for accessing assets - * @param entrypointArgs - Arguments to pass to the entrypoint function - */ -export const nativeRunBundleAndSnapshotFromLibrary: ( - nativeShellHolderId: number, - bundlePath: string, - entrypointFunctionName: string, - pathToEntrypointFunction: string, - assetManager: resourceManager.ResourceManager, - entrypointArgs: Array -) => void; - -/** - * Sends a data-carrying response to a platform message received from Dart. - * @param nativeShellHolderId - The ID of the native shell holder - * @param responseId - The response ID for the platform message - * @param message - The message data as an ArrayBuffer - * @param position - The position in the message buffer - */ -export const nativeInvokePlatformMessageResponseCallback: (nativeShellHolderId: number, responseId: number, message: ArrayBuffer, position: number) => void; - -/** - * Sends an empty response to a platform message received from Dart. - * @param nativeShellHolderId - The ID of the native shell holder - * @param responseId - The response ID for the platform message - */ -export const nativeInvokePlatformMessageEmptyResponseCallback: (nativeShellHolderId: number, responseId: number) => void; - -/** - * Sends a data-carrying platform message to Dart. - * @param nativeShellHolderId - The ID of the native shell holder - * @param channel - The channel name for the platform message - * @param message - The message data as an ArrayBuffer - * @param position - The position in the message buffer - * @param responseId - The response ID for the platform message - */ -export const nativeDispatchPlatformMessage: (nativeShellHolderId: number, channel: String, message: ArrayBuffer, position: number, responseId: number) => void; - -/** - * Sends an empty platform message to Dart. - * @param nativeShellHolderId - The ID of the native shell holder - * @param channel - The channel name for the platform message - * @param responseId - The response ID for the platform message - */ -export const nativeDispatchEmptyPlatformMessage: (nativeShellHolderId: number, channel: String, responseId: number) => void; - -/** - * Sets the viewport metrics for the Flutter view. - * @param nativeShellHolderId - The ID of the native shell holder - * @param devicePixelRatio - The device pixel ratio - * @param physicalWidth - Physical width in pixels - * @param physicalHeight - Physical height in pixels - * @param physicalPaddingTop - Top padding in physical pixels - * @param physicalPaddingRight - Right padding in physical pixels - * @param physicalPaddingBottom - Bottom padding in physical pixels - * @param physicalPaddingLeft - Left padding in physical pixels - * @param physicalViewInsetTop - Top view inset in physical pixels - * @param physicalViewInsetRight - Right view inset in physical pixels - * @param physicalViewInsetBottom - Bottom view inset in physical pixels - * @param physicalViewInsetLeft - Left view inset in physical pixels - * @param systemGestureInsetTop - Top system gesture inset - * @param systemGestureInsetRight - Right system gesture inset - * @param systemGestureInsetBottom - Bottom system gesture inset - * @param systemGestureInsetLeft - Left system gesture inset - * @param physicalTouchSlop - Physical touch slop value - * @param displayFeaturesBounds - Array of display feature bounds - * @param displayFeaturesType - Array of display feature types - * @param displayFeaturesState - Array of display feature states - */ -export const nativeSetViewportMetrics: (nativeShellHolderId: number, devicePixelRatio: number, physicalWidth: number - , physicalHeight: number, physicalPaddingTop: number, physicalPaddingRight: number - , physicalPaddingBottom: number, physicalPaddingLeft: number, physicalViewInsetTop: number - , physicalViewInsetRight: number, physicalViewInsetBottom: number, physicalViewInsetLeft: number - , systemGestureInsetTop: number, systemGestureInsetRight: number, systemGestureInsetBottom: number - , systemGestureInsetLeft: number, physicalTouchSlop: number, displayFeaturesBounds: Array - , displayFeaturesType: Array, displayFeaturesState: Array) => void; - -/** - * Gets the system languages and populates the provided array. - * @param nativeShellHolderId - The ID of the native shell holder - * @param languages - Array to be populated with system language codes - */ -export const nativeGetSystemLanguages: (nativeShellHolderId: number, languages: Array) => void; - -/** - * Attaches a Flutter engine to an XComponent. - * @param xcomponentId - The ID of the XComponent - * @param nativeShellHolderId - The ID of the native shell holder - */ -export const nativeXComponentAttachFlutterEngine: (xcomponentId: string, nativeShellHolderId: number) => void; - -/** - * Called before drawing the XComponent. - * @param xcomponentId - The ID of the XComponent - * @param nativeShellHolderId - The ID of the native shell holder - * @param width - The width of the component - * @param height - The height of the component - */ -export const nativeXComponentPreDraw: (xcomponentId: string, nativeShellHolderId: number, width: number, height: number) => void; - -/** - * Detaches a Flutter engine from an XComponent. - * @param xcomponentId - The ID of the XComponent - * @param nativeShellHolderId - The ID of the native shell holder - */ -export const nativeXComponentDetachFlutterEngine: (xcomponentId: string, nativeShellHolderId: number) => void; - -/** - * Dispatches a mouse wheel event to the Flutter engine. - * @param nativeShellHolderId - The ID of the native shell holder - * @param xcomponentId - The ID of the XComponent - * @param eventType - The type of the mouse wheel event - * @param fingerId - The finger ID for the event - * @param globalX - Global X coordinate - * @param globalY - Global Y coordinate - * @param offsetY - Vertical scroll offset - * @param timestamp - Event timestamp - */ -export const nativeXComponentDispatchMouseWheel: (nativeShellHolderId: number, - xcomponentId: string, - eventType: string, - fingerId: number, - globalX: number, - globalY: number, - offsetY: number, - timestamp: number - ) => void; - - -/** - * Detaches the association between FlutterNapi and the engine. - * This method should only be called when FlutterNapi is already associated with the engine. - * @param nativeShellHolderId - The ID of the native shell holder to destroy - */ -export const nativeDestroy: ( - nativeShellHolderId: number -) => void; - - -/** - * Unregisters a texture from the Flutter engine. - * @param nativeShellHolderId - The ID of the native shell holder - * @param textureId - The ID of the texture to unregister - */ -export const nativeUnregisterTexture: (nativeShellHolderId: number, textureId: number) => void; - -/** - * Registers a PixelMap as a texture in the Flutter engine. - * @param nativeShellHolderId - The ID of the native shell holder - * @param textureId - The ID of the texture - * @param pixelMap - The PixelMap to register - */ -export const nativeRegisterPixelMap: (nativeShellHolderId: number, textureId: number, pixelMap: PixelMap) => void; - -/** - * Sets the background PixelMap for a texture. - * @param nativeShellHolderId - The ID of the native shell holder - * @param textureId - The ID of the texture - * @param pixelMap - The PixelMap to use as background - */ -export const nativeSetTextureBackGroundPixelMap: (nativeShellHolderId: number, textureId: number, pixelMap: PixelMap) => void; - -/** - * Sets the background color for a texture. - * @deprecated since 3.7 - * @param nativeShellHolderId - The ID of the native shell holder - * @param textureId - The ID of the texture - * @param color - The color value as a number - */ -export const nativeSetTextureBackGroundColor: (nativeShellHolderId: number, textureId: number, color: number) => void; - -/** - * Registers a texture with the Flutter engine. - * @param nativeShellHolderId - The ID of the native shell holder - * @param textureId - The ID of the texture to register - * @returns The registered texture ID - */ -export const nativeRegisterTexture: (nativeShellHolderId: number, textureId: number) => number; - -/** - * Gets the window ID for a texture. - * @deprecated since 3.22 - * @useinstead nativeGetTextureWindowPtr - * @param nativeShellHolderId - The ID of the native shell holder - * @param textureId - The ID of the texture - * @returns The window ID - */ -export const nativeGetTextureWindowId: (nativeShellHolderId: number, textureId: number) => number; - -/** - * Gets the window pointer for a texture. - * @param nativeShellHolderId - The ID of the native shell holder - * @param textureId - The ID of the texture - * @returns The window pointer as a bigint - */ -export const nativeGetTextureWindowPtr: (nativeShellHolderId: number, textureId: number) => bigint; - -/** - * Sets an external native image for a texture. - * @deprecated since 3.22 - * @useinstead nativeSetExternalNativeImagePtr - * @param nativeShellHolderId - The ID of the native shell holder - * @param textureId - The ID of the texture - * @param native_image - The native image ID - * @returns The result code - */ -export const nativeSetExternalNativeImage: (nativeShellHolderId: number, textureId: number, native_image: number) => number; - -/** - * Sets an external native image pointer for a texture. - * @param nativeShellHolderId - The ID of the native shell holder - * @param textureId - The ID of the texture - * @param native_image_ptr - The native image pointer as a bigint - * @returns The result code - */ -export const nativeSetExternalNativeImagePtr: (nativeShellHolderId: number, textureId: number, native_image_ptr: bigint) => number; - -/** - * Resets an external texture. - * @param nativeShellHolderId - The ID of the native shell holder - * @param textureId - The ID of the texture - * @param need_surfaceId - Whether a surface ID is needed - * @returns The result code - */ -export const nativeResetExternalTexture: (nativeShellHolderId: number, textureId: number, need_surfaceId: boolean) => number; - -/** - * Encodes a string to UTF-8 bytes. - * @param str - The string to encode - * @returns The UTF-8 encoded bytes as a Uint8Array - */ -export const nativeEncodeUtf8: (str: string) => Uint8Array; - -/** - * Decodes UTF-8 bytes to a string. - * @param array - The UTF-8 encoded bytes as a Uint8Array - * @returns The decoded string - */ -export const nativeDecodeUtf8: (array: Uint8Array) => string; - -/** - * Sets the buffer size for a texture. - * @param nativeShellHolderId - The ID of the native shell holder - * @param textureId - The ID of the texture - * @param width - The buffer width - * @param height - The buffer height - */ -export const nativeSetTextureBufferSize: (nativeShellHolderId: number, textureId: number, width: number, height: number) => void; - -/** - * Notifies the Flutter engine that a texture is being resized. - * @param nativeShellHolderId - The ID of the native shell holder - * @param textureId - The ID of the texture - * @param width - The new width - * @param height - The new height - */ -export const nativeNotifyTextureResizing: (nativeShellHolderId: number, textureId: number, width: number, height: number) => void; - -/** - * Enables or disables frame caching for the Flutter engine. - * @param nativeShellHolderId - The ID of the native shell holder - * @param enable - Whether to enable frame caching - */ -export const nativeEnableFrameCache: (nativeShellHolderId: number, enable: boolean) => void; - -/** - * Looks up callback information for a given handler. - * @param callback - The FlutterCallbackInformation object to populate - * @param handler - The handler number - * @returns The result code - */ -export const nativeLookupCallbackInformation: (callback: FlutterCallbackInformation, handler: number) => number; - -/** - * Checks if a Unicode code point is an emoji. - * @param code - The Unicode code point - * @returns 1 if it is an emoji, 0 otherwise - */ -export const nativeUnicodeIsEmoji: (code: number) => number; - -/** - * Checks if a Unicode code point is an emoji modifier. - * @param code - The Unicode code point - * @returns 1 if it is an emoji modifier, 0 otherwise - */ -export const nativeUnicodeIsEmojiModifier: (code: number) => number; - -/** - * Checks if a Unicode code point is an emoji modifier base. - * @param code - The Unicode code point - * @returns 1 if it is an emoji modifier base, 0 otherwise - */ -export const nativeUnicodeIsEmojiModifierBase: (code: number) => number; - -/** - * Checks if a Unicode code point is a variation selector. - * @param code - The Unicode code point - * @returns 1 if it is a variation selector, 0 otherwise - */ -export const nativeUnicodeIsVariationSelector: (code: number) => number; - -/** - * Checks if a Unicode code point is a regional indicator symbol. - * @param code - The Unicode code point - * @returns 1 if it is a regional indicator symbol, 0 otherwise - */ -export const nativeUnicodeIsRegionalIndicatorSymbol: (code: number) => number; - -/** - * Sets accessibility features in the accessibility channel. - * @param accessibilityFeatureFlags - The accessibility feature flags - * @param responseId - The response ID for the platform message - */ -export const nativeSetAccessibilityFeatures: (accessibilityFeatureFlags: number, responseId: number) => void; - -/** - * Notifies the Flutter engine of an accessibility state change. - * @param nativeShellHolderId - The ID of the native shell holder - * @param state - The new accessibility state - */ -export const nativeAccessibilityStateChange: (nativeShellHolderId: number, state: Boolean) => void; - -/** - * Announces an accessibility message to the Flutter engine. - * @param nativeShellHolderId - The ID of the native shell holder - * @param message - The message to announce - */ -export const nativeAccessibilityAnnounce: (nativeShellHolderId: number, message: string) => void; - -/** - * Handles an accessibility tap event. - * @param nativeShellHolderId - The ID of the native shell holder - * @param nodeId - The ID of the accessibility node that was tapped - */ -export const nativeAccessibilityOnTap: (nativeShellHolderId: number, nodeId: number) => void; - -/** - * Handles an accessibility long press event. - * @param nativeShellHolderId - The ID of the native shell holder - * @param nodeId - The ID of the accessibility node that was long pressed - */ -export const nativeAccessibilityOnLongPress: (nativeShellHolderId: number, nodeId: number) => void; - -/** - * Handles an accessibility tooltip event. - * @param nativeShellHolderId - The ID of the native shell holder - * @param message - The tooltip message - */ -export const nativeAccessibilityOnTooltip: (nativeShellHolderId: number, message: string) => void; - -/** - * Enables or disables semantics for the Flutter engine. - * @param nativeShellHolderId - The ID of the native shell holder - * @param enabled - Whether to enable semantics - */ -export const nativeSetSemanticsEnabled: (nativeShellHolderId: number, enabled: boolean) => void; - -/** - * Sets the font weight scale for the Flutter engine. - * @param nativeShellHolderId - The ID of the native shell holder - * @param fontWeightScale - The font weight scale value - */ -export const nativeSetFontWeightScale: (nativeShellHolderId: number, fontWeightScale: number) => void; - -/** - * Sets the Flutter navigation action state. - * @param nativeShellHolderId - The ID of the native shell holder - * @param isNavigate - Whether navigation is active - */ -export const nativeSetFlutterNavigationAction: (nativeShellHolderId: number, isNavigate: boolean) => void; - -/** - * Enables or disables VSync for the Flutter engine. - * @param nativeShellHolderId - The ID of the native shell holder - * @param isEnable - Whether to enable VSync - */ -export const nativeSetDVsyncSwitch: (nativeShellHolderId: number, isEnable: boolean) => void; - -/** - * Updates the current XComponent ID. - * @param xcomponent_id - The ID of the XComponent - */ -export const nativeUpdateCurrentXComponentId: (xcomponent_id: string) => void; - -/** - * Performs animation voting based on type and velocity. - * @param type - The animation type - * @param velocity - The animation velocity - */ -export const nativeAnimationVoting: (type: number, velocity: number) => void; - -/** - * Performs video voting based on duration and frame count. - * @param seconds - The video duration in seconds - * @param frameCount - The number of frames - */ -export const nativeVideoVoting: (seconds: number, frameCount: number) => void; - -/** - * Prefetches frame configuration. - */ -export const nativePrefetchFramesCfg: () => void; - -/** - * Checks the LTPO (Low Temperature Polycrystalline Oxide) switch state. - * @returns The LTPO switch state value - */ -export const nativeCheckLTPOSwitchState: () => number; - -/** - * Sets QoS (Quality of Service) settings when low memory is detected. - * @param nativeShellHolderId - The ID of the native shell holder - * @param lowMemoryLevel - The low memory level - */ -export const nativeSetQosOnLowMemory: (nativeShellHolderId: number, lowMemoryLevel: number) => void; - -export const nativeSetAnimationStatus: (nativeShellHolderId: number, animationStatus: number) => void; - -export const nativeNotifyPageChanged: (pageName: string, pageNameLen: number, windowID: number) => number; diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/oh-package.json5 b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/oh-package.json5 deleted file mode 100644 index 68c9ab9..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/oh-package.json5 +++ /dev/null @@ -1,8 +0,0 @@ - - -{ - "name": "libflutter.so", - "types": "./index.d.ets", - "version": "", - "description": "Please describe the basic information." -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/FlutterInjector.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/FlutterInjector.ets deleted file mode 100644 index 3b2ea50..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/FlutterInjector.ets +++ /dev/null @@ -1,70 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import FlutterNapi from './embedding/engine/FlutterNapi'; -import FlutterLoader from './embedding/engine/loader/FlutterLoader'; - -/** - * Singleton holder for Flutter-related main classes. - * Manages instances of FlutterLoader and FlutterNapi, providing centralized access to these core Flutter components. - */ -export default class FlutterInjector { - private static instance: FlutterInjector; - private flutterLoader: FlutterLoader; - private preloadFlutterNapi: FlutterNapi | null = null; - - /** - * Gets the singleton instance of FlutterInjector. - * @returns The FlutterInjector singleton instance - */ - static getInstance(): FlutterInjector { - if (FlutterInjector.instance == null) { - FlutterInjector.instance = new FlutterInjector(); - } - return FlutterInjector.instance; - } - - /** - * 初始化 - */ - private constructor() { - this.flutterLoader = new FlutterLoader(new FlutterNapi()); - } - - /** - * Gets the FlutterLoader instance. - * @returns The FlutterLoader instance - */ - getFlutterLoader(): FlutterLoader { - return this.flutterLoader; - } - - /** - * Gets a FlutterNapi instance. - * If a preloaded FlutterNapi exists, it is returned and cleared. - * Otherwise, a new FlutterNapi instance is created. - * @returns A FlutterNapi instance - */ - getFlutterNapi(): FlutterNapi { - if (this.preloadFlutterNapi) { - let retFlutterNapi = this.preloadFlutterNapi; - this.preloadFlutterNapi = null; - return retFlutterNapi; - } - return new FlutterNapi(); - } - - /** - * Creates a preloaded FlutterNapi instance. - * This instance will be returned by the next call to getFlutterNapi(). - * If a preloaded instance already exists, it will be replaced with a new one. - * @returns The newly created preloaded FlutterNapi instance - */ - getPreloadFlutterNapi(): FlutterNapi { - this.preloadFlutterNapi = new FlutterNapi(); - return this.preloadFlutterNapi; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/app/FlutterPluginRegistry.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/app/FlutterPluginRegistry.ets deleted file mode 100644 index 38c2873..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/app/FlutterPluginRegistry.ets +++ /dev/null @@ -1,67 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -*/ -import { FlutterView } from '../view/FlutterView'; -import common from '@ohos.app.ability.common'; -import PlatformViewController from '../plugin/platform/PlatformViewsController' - -/** - * Registry for managing Flutter plugins and platform views. - * This class handles the lifecycle of FlutterView, Context, and PlatformViewController, - * providing methods to attach, detach, and manage resources during engine restarts. - */ -export default class FlutterPluginRegistry { - private mPlatformViewsController: PlatformViewController; - private mFlutterView: FlutterView | null = null; - private mContext: common.Context | null = null; - - /** - * Constructs a new FlutterPluginRegistry instance. - * Initializes the platform views controller and sets FlutterView and Context to null. - */ - constructor() { - this.mPlatformViewsController = new PlatformViewController(); - this.mFlutterView = null; - this.mContext = null; - } - - /** - * Attaches a FlutterView and Context to this registry. - * @param flutterView - The FlutterView instance to attach - * @param context - The application context to attach - */ - attach(flutterView: FlutterView, context: common.Context): void { - this.mFlutterView = flutterView; - this.mContext = context; - } - - /** - * Detaches the FlutterView and Context from this registry. - * Cleans up the platform views controller and resets all references. - */ - detach(): void { - this.mPlatformViewsController.detach(); - this.mPlatformViewsController.onDetachedFromNapi(); - this.mFlutterView = null; - this.mContext = null; - } - - /** - * Destroys this registry instance. - * Notifies the platform views controller that it has been detached from NAPI. - */ - destroy(): void { - this.mPlatformViewsController.onDetachedFromNapi(); - } - - /** - * Called before the Flutter engine restarts. - * Notifies the platform views controller to prepare for engine restart. - */ - onPreEngineRestart(): void { - this.mPlatformViewsController.onPreEngineRestart(); - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/component/FlutterComponent.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/component/FlutterComponent.ets deleted file mode 100644 index 931486e..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/component/FlutterComponent.ets +++ /dev/null @@ -1,28 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -/** - * Basic Flutter component, not yet fully encapsulated. - * This is a placeholder component that may be used as needed. - */ -@Component -export default struct FlutterComponent { - /** - * Builds the component UI. - * @returns The component tree - */ - build() { - Row() { - Column() { - Text("xxx") - .fontSize(50) - .fontWeight(FontWeight.Bold) - } - .width('100%') - } - .height('100%') - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/component/XComponentStruct.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/component/XComponentStruct.ets deleted file mode 100644 index efe073f..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/component/XComponentStruct.ets +++ /dev/null @@ -1,65 +0,0 @@ -/* -* Copyright (c) 2025 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ -import Any from '../plugin/common/Any'; -import ApplicationInfoLoader from '../embedding/engine/loader/ApplicationInfoLoader'; - -import { BuilderParams, DVModelParameters } from '../view/DynamicView/dynamicView'; - -/** - * XComponent structure for rendering Flutter content. - * This component creates an XComponent with TEXTURE type to display Flutter views. - * It handles both debug and release modes with different background color configurations. - */ -@Component -struct XComponentStruct { - private context: Any; - private applicationInfo = ApplicationInfoLoader.load(getContext()); - /** Parameters for the DynamicView model, including XComponent ID and other attributes. */ - dvModelParams: DVModelParameters = new DVModelParameters(); - - /** - * Builds the XComponent structure for Flutter rendering. - * Creates an XComponent with TEXTURE type, handling both debug and release modes. - * @returns The XComponent tree - */ - build() { - // todo OS解决默认背景色后可以移除冗余重复代码,仅保留差异的backgroundColor属性条件配置 - if (this.applicationInfo.isDebugMode) { - XComponent({ - id: (this.dvModelParams as Record)["xComponentId"], - type: XComponentType.TEXTURE, - libraryname: 'flutter' - }) - .onLoad((context) => { - this.context = context; - }) - .onDestroy(() => { - }) - .backgroundColor(Color.White) - } else { - XComponent({ - id: (this.dvModelParams as Record)["xComponentId"], - type: XComponentType.TEXTURE, - libraryname: 'flutter' - }) - .onLoad((context) => { - this.context = context; - }) - .onDestroy(() => { - }) - } - } -} - -/** - * Builder function for creating an XComponentStruct component. - * This function is used in DynamicView to build XComponent instances for Flutter rendering. - * @param buildParams - The BuilderParams containing the DVModelParameters for the XComponent - */ -@Builder -export function BuildXComponentStruct(buildParams: BuilderParams) { - XComponentStruct({ dvModelParams: buildParams.params }); -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine.ets deleted file mode 100644 index cfd34fe..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine.ets +++ /dev/null @@ -1,468 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on FlutterEngine.java originally written by -* Copyright (C) Copyright 2013 The Flutter Authors. -* -*/ - -import LifecycleChannel from './systemchannels/LifecycleChannel'; -import DartExecutor, { DartEntrypoint } from './dart/DartExecutor'; -import FlutterShellArgs from './FlutterShellArgs'; -import FlutterInjector from '../../FlutterInjector'; -import FlutterLoader from './loader/FlutterLoader'; -import common from '@ohos.app.ability.common'; -import resourceManager from '@ohos.resourceManager'; -import FlutterNapi from './FlutterNapi'; -import NavigationChannel from './systemchannels/NavigationChannel'; -import Log from '../../util/Log'; -import TestChannel from './systemchannels/TestChannel' -import FlutterEngineConnectionRegistry from './FlutterEngineConnectionRegistry'; -import PluginRegistry from './plugins/PluginRegistry'; -import AbilityControlSurface from './plugins/ability/AbilityControlSurface'; -import TextInputChannel from './systemchannels/TextInputChannel'; -import TextInputPlugin from '../../plugin/editing/TextInputPlugin'; -import PlatformChannel from './systemchannels/PlatformChannel'; -import SystemChannel from './systemchannels/SystemChannel'; -import MouseCursorChannel from './systemchannels/MouseCursorChannel'; -import DisplayMetricsChannel from './systemchannels/DisplayMetricsChannel'; -import RestorationChannel from './systemchannels/RestorationChannel'; -import LocalizationChannel from './systemchannels/LocalizationChannel'; -import AccessibilityChannel from './systemchannels/AccessibilityChannel'; -import LocalizationPlugin from '../../plugin/localization/LocalizationPlugin' -import SettingsChannel from './systemchannels/SettingsChannel'; -import SensitiveContentChannel from './systemchannels/SensitiveContentChannel'; -import PlatformViewsController from '../../plugin/platform/PlatformViewsController'; -import { FlutterRenderer } from './renderer/FlutterRenderer'; -import NativeVsyncChannel from './systemchannels/NativeVsyncChannel'; - -const TAG = "FlutterEngine"; - -/** - * A single Flutter execution environment. - * - * The FlutterEngine is the container through which Dart code can be run in an OpenHarmony application. - * - * Dart code in a FlutterEngine can execute in the background, or it can be rendered to the screen by - * using the accompanying FlutterRenderer and Dart code using the Flutter framework on the Dart side. - * Rendering can be started and stopped, thus allowing a FlutterEngine to move from UI interaction - * to data-only processing and then back to UI interaction. - * - * Multiple FlutterEngines may exist, execute Dart code, and render UIs within a single OpenHarmony app. - * For better memory performance characteristics, construct multiple FlutterEngines via FlutterEngineGroup - * rather than via FlutterEngine's constructor directly. - * - * To start running Dart and/or Flutter within this FlutterEngine, get a reference to this engine's - * DartExecutor and then use DartExecutor.executeDartEntrypoint(DartEntrypoint). The - * DartExecutor.executeDartEntrypoint(DartEntrypoint) method must not be invoked twice on the same FlutterEngine. - * - * To start rendering Flutter content to the screen, use getFlutterRenderer() to obtain a FlutterRenderer - * and then attach a RenderSurface. Consider using a FlutterView as a RenderSurface. - * - * Instantiating the first FlutterEngine per process will also load the Flutter engine's native library - * and start the Dart VM. Subsequent FlutterEngines will run on the same VM instance but will have - * their own Dart Isolate when the DartExecutor is run. Each Isolate is a self-contained Dart environment - * and cannot communicate with each other except via Isolate ports. - */ -export default class FlutterEngine implements EngineLifecycleListener { - private engineLifecycleListeners = new Set(); - dartExecutor: DartExecutor; - private flutterLoader: FlutterLoader; - private assetManager: resourceManager.ResourceManager; - //channel定义 - private lifecycleChannel: LifecycleChannel | null = null; - private navigationChannel: NavigationChannel | null = null; - private textInputChannel: TextInputChannel | null = null; - private testChannel: TestChannel | null = null; - private platformChannel: PlatformChannel | null = null; - private sensitiveContentChannel: SensitiveContentChannel | null = null; - private systemChannel: SystemChannel | null = null; - private mouseCursorChannel: MouseCursorChannel | null = null; - private displayMetricsChannel: DisplayMetricsChannel | null = null; - private restorationChannel: RestorationChannel | null = null; - private accessibilityChannel: AccessibilityChannel | null = null; - private localeChannel: LocalizationChannel | null = null; - private flutterNapi: FlutterNapi; - private renderer: FlutterRenderer; - private pluginRegistry: FlutterEngineConnectionRegistry | null = null; - private textInputPlugin: TextInputPlugin | null = null; - private localizationPlugin: LocalizationPlugin | null = null; - private settingsChannel: SettingsChannel | null = null; - private platformViewsController: PlatformViewsController; - private nativeVsyncChannel: NativeVsyncChannel | null = null; - - /** - * Constructs a new FlutterEngine instance. - * Initializes DartExecutor, channels, plugins, FlutterLoader, FlutterNapi, and lifecycle listeners. - * @param context - The application context - * @param flutterLoader - Optional FlutterLoader instance, will be created if null - * @param flutterNapi - Optional FlutterNapi instance, will be created if null - * @param platformViewsController - Optional PlatformViewsController, will be created if null - */ - constructor(context: common.Context, flutterLoader: FlutterLoader | null, flutterNapi: FlutterNapi | null, - platformViewsController: PlatformViewsController | null) { - const injector: FlutterInjector = FlutterInjector.getInstance(); - if (flutterNapi == null) { - flutterNapi = FlutterInjector.getInstance().getFlutterNapi(); - } - this.flutterNapi = flutterNapi; - this.assetManager = context.resourceManager; - - this.dartExecutor = new DartExecutor(this.flutterNapi, this.assetManager); - this.dartExecutor.onAttachedToNAPI(); - - if (flutterLoader == null) { - flutterLoader = injector.getFlutterLoader(); - } - this.flutterLoader = flutterLoader; - - this.renderer = new FlutterRenderer(this.flutterNapi); - - if (platformViewsController == null) { - platformViewsController = new PlatformViewsController(); - } - this.platformViewsController = platformViewsController; - this.platformViewsController.attach(context, this.renderer, this.dartExecutor); - } - - /** - * Initializes the Flutter engine. - * Sets up all channels, plugins, and attaches to the native engine. - * @param context - The application context - * @param dartVmArgs - Optional Dart VM arguments - * @param waitForRestorationData - Whether to wait for restoration data - */ - init(context: common.Context, dartVmArgs: Array | null, waitForRestorationData: boolean) { - if (!this.flutterNapi.isAttached()) { - this.flutterLoader.startInitialization(context) - this.flutterLoader.ensureInitializationComplete(dartVmArgs); - } - //channel初始化 - this.lifecycleChannel = new LifecycleChannel(this.dartExecutor); - this.navigationChannel = new NavigationChannel(this.dartExecutor, context); - this.textInputChannel = new TextInputChannel(this.dartExecutor); - this.testChannel = new TestChannel(this.dartExecutor); - this.platformChannel = new PlatformChannel(this.dartExecutor, this.flutterNapi); - this.sensitiveContentChannel = new SensitiveContentChannel(this.dartExecutor); - this.systemChannel = new SystemChannel(this.dartExecutor); - this.mouseCursorChannel = new MouseCursorChannel(this.dartExecutor); - this.displayMetricsChannel = new DisplayMetricsChannel(this.dartExecutor, context); - this.restorationChannel = new RestorationChannel(this.dartExecutor, waitForRestorationData); - this.settingsChannel = new SettingsChannel(this.dartExecutor); - this.localeChannel = new LocalizationChannel(this.dartExecutor); - this.accessibilityChannel = new AccessibilityChannel(this.dartExecutor, this.flutterNapi); - this.flutterNapi.addEngineLifecycleListener(this); - this.localizationPlugin = new LocalizationPlugin(context, this.localeChannel); - this.nativeVsyncChannel = new NativeVsyncChannel(this.dartExecutor, this.flutterNapi); - - // It should typically be a fresh, unattached NAPI. But on a spawned engine, the NAPI instance - // is already attached to a native shell. In that case, the Java FlutterEngine is created around - // an existing shell. - if (!this.flutterNapi.isAttached()) { - this.attachToNapi(); - } - this.flutterNapi.setLocalizationPlugin(this.localizationPlugin); - - this.pluginRegistry = - new FlutterEngineConnectionRegistry(context.getApplicationContext(), this, this.flutterLoader); - this.localizationPlugin.sendLocaleToFlutter(); - Log.d(TAG, "Call init finished.") - } - - private attachToNapi(): void { - Log.d(TAG, "Attaching to NAPI."); - this.flutterNapi.attachToNative(); - if (!this.isAttachedToNapi()) { - throw new Error("FlutterEngine failed to attach to its native Object reference."); - } - } - - /** - * Spawns a new Flutter engine from this engine. - * The spawned engine shares resources with the parent engine. - * @param context - The application context - * @param dartEntrypoint - The Dart entrypoint configuration - * @param initialRoute - The initial route for navigation - * @param dartEntrypointArgs - Arguments for the Dart entrypoint - * @param platformViewsController - The platform views controller - * @param waitForRestorationData - Whether to wait for restoration data - * @returns The spawned FlutterEngine instance - * @throws Error if this engine is not fully constructed - */ - spawn(context: common.Context, - dartEntrypoint: DartEntrypoint, - initialRoute: string, - dartEntrypointArgs: Array, - platformViewsController: PlatformViewsController, - waitForRestorationData: boolean) { - if (!this.isAttachedToNapi()) { - throw new Error( - "Spawn can only be called on a fully constructed FlutterEngine"); - } - - const newFlutterNapi = - this.flutterNapi.spawn( - dartEntrypoint.dartEntrypointFunctionName, - dartEntrypoint.dartEntrypointLibrary, - initialRoute, - dartEntrypointArgs); - const flutterEngine = new FlutterEngine( - context, - null, - newFlutterNapi, - platformViewsController - ); - flutterEngine.init(context, null, waitForRestorationData) - return flutterEngine - } - - private isAttachedToNapi(): boolean { - return this.flutterNapi.isAttached(); - } - - /** - * Processes any pending messages from the native side. - */ - processPendingMessages() { - if (this.flutterNapi.isAttached()) { - this.flutterNapi.processPendingMessages(); - } - } - - /** - * Gets the lifecycle channel for managing application lifecycle events. - * @returns The LifecycleChannel instance, or null if not initialized - */ - getLifecycleChannel(): LifecycleChannel | null { - return this.lifecycleChannel; - } - - /** - * Gets the navigation channel for managing navigation events. - * @returns The NavigationChannel instance, or null if not initialized - */ - getNavigationChannel(): NavigationChannel | null { - return this.navigationChannel; - } - - /** - * Gets the text input channel for managing text input events. - * @returns The TextInputChannel instance, or null if not initialized - */ - getTextInputChannel(): TextInputChannel | null { - return this.textInputChannel; - } - - /** - * Gets the platform channel for platform-specific communication. - * @returns The PlatformChannel instance, or null if not initialized - */ - getPlatformChannel(): PlatformChannel | null { - return this.platformChannel; - } - - /** - * Gets the system channel for system-level communication. - * @returns The SystemChannel instance, or null if not initialized - */ - getSystemChannel(): SystemChannel | null { - return this.systemChannel; - } - - /** - * Gets the localization channel for managing locale information. - * @returns The LocalizationChannel instance, or null if not initialized - */ - getLocaleChannel(): LocalizationChannel | null { - return this.localeChannel; - } - - /** - * Gets the mouse cursor channel for managing cursor changes. - * @returns The MouseCursorChannel instance, or null if not initialized - */ - getMouseCursorChannel(): MouseCursorChannel | null { - return this.mouseCursorChannel; - } - - getDisplayMetricsChannel(): DisplayMetricsChannel | null { - return this.displayMetricsChannel; - } - - /** - * Gets the FlutterNapi instance for native communication. - * @returns The FlutterNapi instance - */ - getFlutterNapi(): FlutterNapi { - return this.flutterNapi; - } - - /** - * Gets the FlutterRenderer instance for rendering operations. - * @returns The FlutterRenderer instance - */ - getFlutterRenderer(): FlutterRenderer { - return this.renderer; - } - - /** - * Gets the DartExecutor instance for executing Dart code. - * @returns The DartExecutor instance - */ - getDartExecutor(): DartExecutor { - return this.dartExecutor - } - - getSensitiveContentChannel():SensitiveContentChannel |null { - return this.sensitiveContentChannel - } - - /** - * Gets the plugin registry for managing Flutter plugins. - * @returns The PluginRegistry instance, or null if not initialized - */ - getPlugins(): PluginRegistry | null { - return this.pluginRegistry; - } - - /** - * Gets the ability control surface for managing ability-related operations. - * @returns The AbilityControlSurface instance, or null if not initialized - */ - getAbilityControlSurface(): AbilityControlSurface | null { - return this.pluginRegistry; - } - - /** - * Gets the settings channel for managing application settings. - * @returns The SettingsChannel instance, or null if not initialized - */ - getSettingsChannel() { - return this.settingsChannel; - } - - /** - * Gets the FlutterLoader instance for loading Flutter assets. - * @returns The FlutterLoader instance - */ - getFlutterLoader() { - return this.flutterLoader; - } - - /** - * Called before the engine restarts. - * Notifies all registered lifecycle listeners. - */ - onPreEngineRestart(): void { - this.engineLifecycleListeners.forEach(listener => listener.onPreEngineRestart()) - } - - /** - * Called when the engine is about to be destroyed. - */ - onEngineWillDestroy(): void { - - } - - /** - * Adds a lifecycle listener to be notified of engine lifecycle events. - * @param listener - The EngineLifecycleListener to add - */ - addEngineLifecycleListener(listener: EngineLifecycleListener): void { - this.engineLifecycleListeners.add(listener); - } - - /** - * Removes a lifecycle listener from the list of registered listeners. - * @param listener - The EngineLifecycleListener to remove - */ - removeEngineLifecycleListener(listener: EngineLifecycleListener): void { - this.engineLifecycleListeners.delete(listener); - } - - /** - * Destroys the Flutter engine and releases all resources. - * Notifies listeners, detaches from ability, and cleans up all components. - */ - destroy(): void { - Log.d(TAG, "Destroying."); - this.engineLifecycleListeners.forEach(listener => listener.onEngineWillDestroy()) - this.flutterNapi.removeEngineLifecycleListener(this); - this.pluginRegistry?.detachFromAbility(); - this.platformViewsController?.onDetachedFromNapi(); - this.pluginRegistry?.destroy(); - this.dartExecutor.onDetachedFromNAPI(); - this.flutterNapi.detachFromNativeAndReleaseResources(); - } - - /** - * Gets the restoration channel for managing state restoration. - * @returns The RestorationChannel instance, or null if not initialized - */ - getRestorationChannel(): RestorationChannel | null { - return this.restorationChannel; - } - - /** - * Gets the accessibility channel for managing accessibility features. - * @returns The AccessibilityChannel instance, or null if not initialized - */ - getAccessibilityChannel(): AccessibilityChannel | null { - return this.accessibilityChannel; - } - - /** - * Gets the localization plugin for managing locale information. - * @returns The LocalizationPlugin instance, or null if not initialized - */ - getLocalizationPlugin(): LocalizationPlugin | null { - return this.localizationPlugin; - } - - /** - * Gets the system languages from the native side. - */ - getSystemLanguages(): void { - return this.flutterNapi.getSystemLanguages(); - } - - /** - * Gets the platform views controller for managing platform views. - * @returns The PlatformViewsController instance, or null if not initialized - */ - getPlatformViewsController(): PlatformViewsController | null { - return this.platformViewsController; - } - - /** - * Gets the native VSync channel for managing vertical synchronization. - * @returns The NativeVsyncChannel instance, or null if not initialized - */ - getNativeVsyncChannel(): NativeVsyncChannel | null { - return this.nativeVsyncChannel; - } - - /** - * Prefetches frame configuration for improved performance. - */ - async prefetchFramesCfg(): Promise { - FlutterNapi.prefetchFramesCfg(); - } -} - -/** - * Interface for listening to Flutter engine lifecycle events. - */ -export interface EngineLifecycleListener { - /** - * Called before the engine restarts. - */ - onPreEngineRestart(): void; - - /** - * Called when the engine is about to be destroyed. - */ - onEngineWillDestroy(): void; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineCache.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineCache.ets deleted file mode 100644 index f530204..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineCache.ets +++ /dev/null @@ -1,84 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on FlutterEngineCache.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import FlutterEngine from "./FlutterEngine" - -/** - * Static singleton cache that holds FlutterEngine instances identified by Strings. - * - * The ID of a given FlutterEngine can be whatever String is desired. - * - * FlutterEngineCache is useful for storing pre-warmed FlutterEngine instances. FlutterAbility - * and FlutterEntry can use cached FlutterEngine instances by implementing getCachedEngineId() - * to return a cached engine ID. The FlutterAbilityAndEntryDelegate will then retrieve the - * engine from this cache. See FlutterAbility.getCachedEngineId() and FlutterEntry.getCachedEngineId() - * for related APIs. - */ -export default class FlutterEngineCache { - private static instance: FlutterEngineCache; - private cachedEngines: Map = new Map(); - - /** - * Gets the singleton instance of FlutterEngineCache. - * @returns The FlutterEngineCache instance - */ - static getInstance(): FlutterEngineCache { - if (FlutterEngineCache.instance == null) { - FlutterEngineCache.instance = new FlutterEngineCache(); - } - return FlutterEngineCache.instance; - } - - /** - * Checks if an engine with the given ID exists in the cache. - * @param engineId - The ID of the engine to check - * @returns true if the engine exists, false otherwise - */ - contains(engineId: String): boolean { - return this.cachedEngines.has(engineId); - } - - /** - * Gets an engine from the cache by ID. - * @param engineId - The ID of the engine to retrieve - * @returns The FlutterEngine instance, or null if not found - */ - get(engineId: String): FlutterEngine | null { - return this.cachedEngines.get(engineId) || null; - } - - /** - * Puts an engine into the cache or removes it if null is provided. - * @param engineId - The ID of the engine - * @param engine - The FlutterEngine instance to cache, or null to remove - */ - put(engineId: String, engine: FlutterEngine | null): void { - if (engine != null) { - this.cachedEngines.set(engineId, engine); - } else { - this.cachedEngines.delete(engineId); - } - } - - /** - * Removes an engine from the cache by ID. - * @param engineId - The ID of the engine to remove - */ - remove(engineId: String): void { - this.put(engineId, null); - } - - /** - * Clears all engines from the cache. - */ - clear(): void { - this.cachedEngines.clear(); - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineConnectionRegistry.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineConnectionRegistry.ets deleted file mode 100644 index 74b5f20..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineConnectionRegistry.ets +++ /dev/null @@ -1,426 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on FlutterEngineConnectionRegistry.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import PluginRegistry from './plugins/PluginRegistry'; -import { FlutterAssets, FlutterPlugin, FlutterPluginBinding } from './plugins/FlutterPlugin'; -import FlutterEngine from './FlutterEngine'; -import AbilityAware from './plugins/ability/AbilityAware'; -import UIAbility from '@ohos.app.ability.UIAbility'; -import { - AbilityPluginBinding, - WindowFocusChangedListener, - OnSaveStateListener, - NewWantListener -} from './plugins/ability/AbilityPluginBinding'; -import HashSet from '@ohos.util.HashSet'; -import Want from '@ohos.app.ability.Want'; -import AbilityConstant from '@ohos.app.ability.AbilityConstant'; -import common from '@ohos.app.ability.common'; -import FlutterLoader from './loader/FlutterLoader'; -import Log from '../../util/Log'; -import ToolUtils from '../../util/ToolUtils'; -import AbilityControlSurface from './plugins/ability/AbilityControlSurface'; -import ExclusiveAppComponent from '../ohos/ExclusiveAppComponent'; -import FlutterEngineGroup from './FlutterEngineGroup'; -import Any from '../../plugin/common/Any'; - -const TAG = "FlutterEngineCxnRegistry"; - -/** - * Registry for managing Flutter plugins and their connections to the engine and ability. - * This class implements both PluginRegistry and AbilityControlSurface interfaces, - * providing a unified way to manage plugin lifecycle and ability-related operations. - */ -export default class FlutterEngineConnectionRegistry implements PluginRegistry, AbilityControlSurface { - private plugins = new Map(); - private defaultPlugin: FlutterPlugin = new EmptyPlugin(); - private flutterEngine: FlutterEngine; - private pluginBinding: FlutterPluginBinding; - private abilityAwarePlugins = new Map(); - private exclusiveAbility: ExclusiveAppComponent | null = null; - private abilityPluginBinding: FlutterEngineAbilityPluginBinding | null = null; - - /** - * Constructs a new FlutterEngineConnectionRegistry instance. - * @param appContext - The application context - * @param flutterEngine - The FlutterEngine instance this registry is associated with - * @param flutterLoader - The FlutterLoader instance for asset management - */ - constructor(appContext: common.Context, flutterEngine: FlutterEngine, flutterLoader: FlutterLoader) { - this.flutterEngine = flutterEngine; - this.pluginBinding = new FlutterPluginBinding(appContext, flutterEngine, flutterEngine.getDartExecutor(), - new DefaultFlutterAssets(flutterLoader), flutterEngine.getFlutterRenderer(), - flutterEngine.getPlatformViewsController()?.getRegistry()); - } - - /** - * Adds a plugin to this registry. - * @param plugin - The FlutterPlugin instance to add - */ - add(plugin: FlutterPlugin): void { - try { - if (this.has(plugin.getUniqueClassName())) { - Log.w( - TAG, - "Attempted to register plugin (" - + plugin - + ") but it was " - + "already registered with this FlutterEngine (" - + this.flutterEngine - + ")."); - return; - } - - Log.w(TAG, "Adding plugin: " + plugin.getUniqueClassName()); - // Add the plugin to our generic set of plugins and notify the plugin - // that is has been attached to an engine. - this.plugins.set(plugin.getUniqueClassName(), plugin); - plugin.onAttachedToEngine(this.pluginBinding); - - // For AbilityAware plugins, add the plugin to our set of AbilityAware - // plugins, and if this engine is currently attached to an Ability, - // notify the AbilityAware plugin that it is now attached to an Ability. - if (ToolUtils.implementsInterface(plugin, "onAttachedToAbility")) { - const abilityAware: Any = plugin; - this.abilityAwarePlugins.set(plugin.getUniqueClassName(), abilityAware); - if (this.isAttachedToAbility()) { - abilityAware.onAttachedToAbility(this.abilityPluginBinding); - } - } - } finally { - - } - } - - /** - * Adds multiple plugins to this registry. - * @param plugins - Set of FlutterPlugin instances to add - */ - addList(plugins: Set): void { - plugins.forEach(plugin => this.add(plugin)) - } - - /** - * Checks if a plugin with the given class name is registered. - * @param pluginClassName - The class name of the plugin to check - * @returns true if the plugin is registered, false otherwise - */ - has(pluginClassName: string): boolean { - return this.plugins.has(pluginClassName); - } - - /** - * Gets a plugin by its class name. - * @param pluginClassName - The class name of the plugin to retrieve - * @returns The FlutterPlugin instance, or a default empty plugin if not found - */ - get(pluginClassName: string): FlutterPlugin { - return this.plugins.get(pluginClassName) ?? this.defaultPlugin; - } - - /** - * Removes a plugin from this registry. - * @param pluginClassName - The class name of the plugin to remove - */ - remove(pluginClassName: string): void { - const plugin = this.plugins.get(pluginClassName); - if (plugin == null) { - return; - } - if (ToolUtils.implementsInterface(plugin, "onAttachedToAbility")) { - if (this.isAttachedToAbility()) { - const abilityAware: Any = plugin; - abilityAware.onDetachedFromAbility(); - } - this.abilityAwarePlugins.delete(pluginClassName); - } - // Notify the plugin that is now detached from this engine. Then remove - // it from our set of generic plugins. - plugin.onDetachedFromEngine(this.pluginBinding); - this.plugins.delete(pluginClassName) - } - - /** - * Removes multiple plugins from this registry. - * @param pluginClassNames - Set of plugin class names to remove - */ - removeList(pluginClassNames: Set): void { - pluginClassNames.forEach(plugin => this.remove(plugin)) - } - - /** - * Removes all plugins from this registry. - */ - removeAll(): void { - this.removeList(new Set(this.plugins.keys())); - this.plugins.clear(); - } - - private isAttachedToAbility(): boolean { - return this.exclusiveAbility != null; - } - - /** - * Attaches this registry to an ability. - * @param exclusiveAbility - The exclusive app component (UIAbility) to attach to - */ - attachToAbility(exclusiveAbility: ExclusiveAppComponent): void { - if (this.exclusiveAbility != null) { - this.exclusiveAbility.detachFromFlutterEngine(); - } - // If we were already attached to an app component, detach from it. - this.detachFromAppComponent(); - this.exclusiveAbility = exclusiveAbility; - this.attachToAbilityInternal(exclusiveAbility.getAppComponent(),); - } - - /** - * Detaches this registry from the current ability. - */ - detachFromAbility(): void { - if (this.isAttachedToAbility()) { - try { - this.abilityAwarePlugins.forEach(abilityAware => abilityAware.onDetachedFromAbility()) - } catch (e) { - Log.e(TAG, "abilityAwarePlugins DetachedFromAbility failed, msg:" + e); - } - this.detachFromAbilityInternal(); - } else { - Log.e(TAG, "Attempted to detach plugins from an Ability when no Ability was attached."); - } - } - - /** - * Handles a new Want event from the ability. - * @param want - The Want object containing the intent - * @param launchParams - The launch parameters - */ - onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void { - this.abilityPluginBinding?.onNewWant(want, launchParams); - } - - /** - * Handles window focus change events from the ability. - * @param hasFocus - Whether the window has focus - */ - onWindowFocusChanged(hasFocus: boolean): void { - this.abilityPluginBinding?.onWindowFocusChanged(hasFocus); - } - - /** - * Handles save state requests from the ability. - * @param reason - The reason for saving state - * @param wantParam - Parameters to save - * @returns The result of the save state operation - */ - onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult { - return this.abilityPluginBinding?.onSaveState(reason, wantParam) ?? AbilityConstant.OnSaveResult.ALL_REJECT; - } - - private detachFromAppComponent(): void { - if (this.isAttachedToAbility()) { - this.detachFromAbility(); - } - } - - private attachToAbilityInternal(ability: UIAbility): void { - this.abilityPluginBinding = new FlutterEngineAbilityPluginBinding(ability); - // Notify all AbilityAware plugins that they are now attached to a new Ability. - this.abilityAwarePlugins.forEach(abilityAware => abilityAware.onAttachedToAbility(this.abilityPluginBinding!)); - } - - private detachFromAbilityInternal(): void { - this.exclusiveAbility = null; - this.abilityPluginBinding = null; - } - - /** - * Destroys this registry and removes all plugins. - */ - destroy(): void { - this.detachFromAppComponent(); - // Remove all registered plugins. - this.removeAll(); - } -} - -/** - * Implementation of AbilityPluginBinding for FlutterEngine. - * Manages ability-related listeners and events for plugins. - */ -class FlutterEngineAbilityPluginBinding implements AbilityPluginBinding { - private ability: UIAbility; - private onNewWantListeners = new HashSet(); - private onWindowFocusChangedListeners = new HashSet(); - private onSaveStateListeners = new HashSet(); - - /** - * Constructs a new FlutterEngineAbilityPluginBinding instance. - * @param ability - The UIAbility instance this binding is associated with - */ - constructor(ability: UIAbility) { - this.ability = ability; - - } - - /** - * Gets the UIAbility instance. - * @returns The UIAbility instance - */ - getAbility(): UIAbility { - return this.ability; - } - - /** - * Adds a listener for new Want events. - * @param listener - The NewWantListener to add - */ - addOnNewWantListener(listener: NewWantListener): void { - this.onNewWantListeners.add(listener) - } - - /** - * Removes a listener for new Want events. - * @param listener - The NewWantListener to remove - */ - removeOnNewWantListener(listener: NewWantListener): void { - this.onNewWantListeners.remove(listener) - } - - /** - * Adds a listener for window focus change events. - * @param listener - The WindowFocusChangedListener to add - */ - addOnWindowFocusChangedListener(listener: WindowFocusChangedListener): void { - this.onWindowFocusChangedListeners.add(listener) - } - - /** - * Removes a listener for window focus change events. - * @param listener - The WindowFocusChangedListener to remove - */ - removeOnWindowFocusChangedListener(listener: WindowFocusChangedListener): void { - this.onWindowFocusChangedListeners.remove(listener) - } - - /** - * Adds a listener for save state events. - * @param listener - The OnSaveStateListener to add - */ - addOnSaveStateListener(listener: OnSaveStateListener) { - this.onSaveStateListeners.add(listener) - } - - /** - * Removes a listener for save state events. - * @param listener - The OnSaveStateListener to remove - */ - removeOnSaveStateListener(listener: OnSaveStateListener) { - this.onSaveStateListeners.remove(listener) - } - - /** - * Notifies all registered listeners of a new Want event. - * @param want - The Want object - * @param launchParams - The launch parameters - */ - onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void { - this.onNewWantListeners.forEach((listener, key) => { - listener?.onNewWant(want, launchParams) - }); - } - - /** - * Notifies all registered listeners of a window focus change. - * @param hasFocus - Whether the window has focus - */ - onWindowFocusChanged(hasFocus: boolean): void { - this.onWindowFocusChangedListeners.forEach((listener, key) => { - listener?.onWindowFocusChanged(hasFocus) - }); - } - - /** - * Notifies all registered listeners of a save state request. - * @param reason - The reason for saving state - * @param wantParam - Parameters to save - * @returns The result of the save state operation - */ - onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult { - this.onSaveStateListeners.forEach((listener, key) => { - listener?.onSaveState(reason, wantParam) - }); - return AbilityConstant.OnSaveResult.ALL_AGREE; - } -} - -/** - * Default implementation of FlutterAssets using FlutterLoader. - */ -class DefaultFlutterAssets implements FlutterAssets { - private flutterLoader: FlutterLoader; - - /** - * Constructs a new DefaultFlutterAssets instance. - * @param flutterLoader - The FlutterLoader instance for asset lookup - */ - constructor(flutterLoader: FlutterLoader) { - this.flutterLoader = flutterLoader; - } - - /** - * Gets the file path for an asset by name. - * @param assetFileName - The name of the asset file - * @param packageName - Optional package name - * @returns The file path for the asset - */ - getAssetFilePathByName(assetFileName: string, packageName?: string): string { - return this.flutterLoader.getLookupKeyForAsset(assetFileName, packageName); - } - - /** - * Gets the file path for an asset by subpath. - * @param assetSubpath - The subpath of the asset - * @param packageName - Optional package name - * @returns The file path for the asset - */ - getAssetFilePathBySubpath(assetSubpath: string, packageName?: string) { - return this.flutterLoader.getLookupKeyForAsset(assetSubpath, packageName); - } -} - -/** - * Empty plugin implementation used as a default when a plugin is not found. - */ -class EmptyPlugin implements FlutterPlugin { - /** - * Gets the unique class name of this plugin. - * @returns An empty string - */ - getUniqueClassName(): string { - return ''; - } - - /** - * Called when this plugin is attached to an engine. - * @param binding - The FlutterPluginBinding instance - */ - onAttachedToEngine(binding: FlutterPluginBinding) { - - } - - /** - * Called when this plugin is detached from an engine. - * @param binding - The FlutterPluginBinding instance - */ - onDetachedFromEngine(binding: FlutterPluginBinding) { - - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroup.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroup.ets deleted file mode 100644 index 6db5011..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroup.ets +++ /dev/null @@ -1,292 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on FlutterEngineGroup.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import FlutterEngine, { EngineLifecycleListener } from "./FlutterEngine" -import common from '@ohos.app.ability.common' -import display from '@ohos.display'; -import FlutterLoader from './loader/FlutterLoader' -import FlutterInjector from '../../FlutterInjector' -import { DartEntrypoint } from './dart/DartExecutor' -import PlatformViewsController from '../../plugin/platform/PlatformViewsController' -import ArrayList from '@ohos.util.ArrayList' -import Log from '../../util/Log'; -import FlutterManager from '../ohos/FlutterManager'; - -const TAG = "FlutterEngineGroup" - -/** - * Represents a collection of FlutterEngines who share resources to allow them to be created - * faster and with less memory than calling the FlutterEngine's constructor multiple times. - * - * When creating or recreating the first FlutterEngine in the FlutterEngineGroup, the behavior - * is the same as creating a FlutterEngine via its constructor. When subsequent FlutterEngines - * are created, resources from an existing living FlutterEngine is re-used. - * - * The shared resources are kept until the last surviving FlutterEngine is destroyed. - * - * Deleting a FlutterEngineGroup doesn't invalidate its existing FlutterEngines, but it eliminates - * the possibility to create more FlutterEngines in that group. - */ -export default class FlutterEngineGroup { - private activeEngines: ArrayList = new ArrayList(); - - /** - * Constructs a new FlutterEngineGroup instance. - */ - constructor() { - - } - - /** - * Checks and initializes the FlutterLoader if not already initialized. - * @param context - The application context - * @param args - Command-line arguments for Dart VM initialization - */ - checkLoader(context: common.Context, args: Array) { - let loader: FlutterLoader = FlutterInjector.getInstance().getFlutterLoader(); - if (!loader.initialized) { - loader.startInitialization(context); - loader.ensureInitializationComplete(args); - } - } - - /** - * Creates and runs a Flutter engine based on the provided options. - * If no engines exist, creates a new engine. Otherwise, spawns from the first engine. - * @param options - Configuration options for engine creation - * @returns The created or spawned FlutterEngine instance - */ - createAndRunEngineByOptions(options: Options) { - let engine: FlutterEngine | null = null; - let context: common.Context = options.getContext(); - let dartEntrypoint: DartEntrypoint | null = options.getDartEntrypoint(); - let initialRoute: string = options.getInitialRoute(); - let dartEntrypointArgs: Array = options.getDartEntrypointArgs(); - let platformViewsController: PlatformViewsController | null = options.getPlatformViewsController(); - let waitForRestorationData: boolean = options.getWaitForRestorationData(); - - if (dartEntrypoint == null) { - dartEntrypoint = DartEntrypoint.createDefault(); - } - - if (platformViewsController == null) { - platformViewsController = new PlatformViewsController(); - } - - Log.i(TAG, "shellHolder, this.activeEngines.length=" + this.activeEngines.length) - if (this.activeEngines.length == 0) { - engine = this.createEngine(context, platformViewsController); - engine.init(context, null, // String[]. The Dart VM has already started, this arguments will have no effect. - waitForRestorationData) - if (initialRoute != null) { - engine.getNavigationChannel()?.setInitialRoute(initialRoute); - } - engine.getDartExecutor().executeDartEntrypoint(dartEntrypoint, dartEntrypointArgs); - engine.prefetchFramesCfg(); - } else { - engine = this.activeEngines[0] - .spawn( - context, - dartEntrypoint, - initialRoute, - dartEntrypointArgs, - platformViewsController, - waitForRestorationData); - } - this.activeEngines.add(engine); - - const engineToCleanUpOnDestroy = engine; - let listener: EngineLifecycleListener = new EngineLifecycleListenerImpl( - platformViewsController, - this.activeEngines, - engineToCleanUpOnDestroy); - engine?.addEngineLifecycleListener(listener); - return engine; - } - - /** - * Creates a new FlutterEngine instance. - * @param context - The application context - * @param platformViewsController - The platform views controller for the engine - * @returns A new FlutterEngine instance - */ - createEngine(context: common.Context, platformViewsController: PlatformViewsController): FlutterEngine { - return new FlutterEngine(context, null, null, platformViewsController); - } - - /** - * Gets the default (first) engine in this group. - * @returns The default FlutterEngine, or null if no engines exist - */ - getDefaultEngine(): FlutterEngine | null { - let engine: FlutterEngine | null = null; - if (this.activeEngines.length != 0) { - engine = this.activeEngines[0]; - } - return engine; - } -} - -/** - * Implementation of EngineLifecycleListener for managing engine lifecycle in a group. - */ -class EngineLifecycleListenerImpl implements EngineLifecycleListener { - private platformViewsController: PlatformViewsController; - private activeEngines: ArrayList = new ArrayList(); - private engine: FlutterEngine | null; - - /** - * Constructs a new EngineLifecycleListenerImpl instance. - * @param platformViewsController - The platform views controller - * @param activeEngines - List of active engines in the group - * @param engine - The engine this listener is associated with - */ - constructor( - platformViewsController: PlatformViewsController, - activeEngines: ArrayList, - engine: FlutterEngine | null) { - this.platformViewsController = platformViewsController; - this.activeEngines = activeEngines; - this.engine = engine; - } - - /** - * Called before the engine restarts. - */ - onPreEngineRestart(): void { - this.platformViewsController.onPreEngineRestart(); - } - - /** - * Called when the engine is about to be destroyed. - * Removes the engine from the active engines list. - */ - onEngineWillDestroy(): void { - this.activeEngines.remove(this.engine); - } -} - -/** - * Options that control how a FlutterEngine should be created.. - */ -export class Options { - private context: common.Context; - private dartEntrypoint: DartEntrypoint | null = null; - private initialRoute: string = ''; - private dartEntrypointArgs: Array = []; - private platformViewsController: PlatformViewsController | null = null; - private waitForRestorationData: boolean = false; - - /** - * Constructs a new Options instance. - * @param context - The application context - */ - constructor(context: common.Context) { - this.context = context; - } - - /** - * Gets the application context. - * @returns The context - */ - getContext(): common.Context { - return this.context; - } - - /** - * Gets the Dart entrypoint configuration. - * @returns The DartEntrypoint, or null if not set - */ - getDartEntrypoint(): DartEntrypoint | null { - return this.dartEntrypoint; - } - - /** - * Gets the initial route for navigation. - * @returns The initial route string - */ - getInitialRoute(): string { - return this.initialRoute; - } - - /** - * Gets the Dart entrypoint arguments. - * @returns Array of entrypoint arguments - */ - getDartEntrypointArgs(): Array { - return this.dartEntrypointArgs; - } - - /** - * Gets whether to wait for restoration data. - * @returns true if waiting for restoration data, false otherwise - */ - getWaitForRestorationData(): boolean { - return this.waitForRestorationData; - } - - /** - * Gets the platform views controller. - * @returns The PlatformViewsController, or null if not set - */ - getPlatformViewsController(): PlatformViewsController | null { - return this.platformViewsController; - } - - /** - * Sets the Dart entrypoint configuration. - * @param dartEntrypoint - The DartEntrypoint to set - * @returns This Options instance for method chaining - */ - setDartEntrypoint(dartEntrypoint: DartEntrypoint): Options { - this.dartEntrypoint = dartEntrypoint; - return this; - } - - /** - * Sets the initial route for navigation. - * @param initialRoute - The initial route string - * @returns This Options instance for method chaining - */ - setInitialRoute(initialRoute: string): Options { - this.initialRoute = initialRoute; - return this; - } - - /** - * Sets the Dart entrypoint arguments. - * @param dartEntrypointArgs - Array of entrypoint arguments - * @returns This Options instance for method chaining - */ - setDartEntrypointArgs(dartEntrypointArgs: Array): Options { - this.dartEntrypointArgs = dartEntrypointArgs; - return this; - } - - /** - * Sets whether to wait for restoration data. - * @param waitForRestorationData - Whether to wait for restoration data - * @returns This Options instance for method chaining - */ - setWaitForRestorationData(waitForRestorationData: boolean): Options { - this.waitForRestorationData = waitForRestorationData; - return this; - } - - /** - * Sets the platform views controller. - * @param platformViewsController - The PlatformViewsController to set - * @returns This Options instance for method chaining - */ - setPlatformViewsController(platformViewsController: PlatformViewsController): Options { - this.platformViewsController = platformViewsController; - return this; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroupCache.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroupCache.ets deleted file mode 100644 index 8d1d7d3..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroupCache.ets +++ /dev/null @@ -1,61 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import FlutterEngineGroup from './FlutterEngineGroup'; - -/** - * Static singleton cache that holds FlutterEngineGroup instances identified by Strings. - * - * The ID of a given FlutterEngineGroup can be whatever String is desired. - * - * FlutterEngineGroupCache is useful for storing pre-warmed FlutterEngineGroup instances. FlutterAbility - * and FlutterEntry can use cached FlutterEngineGroup instances by implementing getCachedEngineGroupId() - * to return a cached engine group ID. The FlutterAbilityAndEntryDelegate will then retrieve the - * engine group from this cache and create new engines within that group. See FlutterAbility.getCachedEngineGroupId() - * and FlutterEntry.getCachedEngineGroupId() for related APIs. - */ -export default class FlutterEngineGroupCache { - static readonly instance = new FlutterEngineGroupCache(); - private cachedEngineGroups = new Map(); - - /** - * Checks if an engine group with the given ID exists in the cache. - * @param engineGroupId - The ID of the engine group to check - * @returns true if the engine group exists, false otherwise - */ - contains(engineGroupId: string): boolean { - return this.cachedEngineGroups.has(engineGroupId); - } - - /** - * Gets an engine group from the cache by ID. - * @param engineGroupId - The ID of the engine group to retrieve - * @returns The FlutterEngineGroup instance, or null if not found - */ - get(engineGroupId: string): FlutterEngineGroup | null { - return this.cachedEngineGroups.get(engineGroupId) ?? null; - } - - /** - * Puts an engine group into the cache or removes it if null is provided. - * @param engineGroupId - The ID of the engine group - * @param engineGroup - The FlutterEngineGroup instance to cache, or undefined to remove - */ - put(engineGroupId: string, engineGroup?: FlutterEngineGroup) { - if (engineGroup != null) { - this.cachedEngineGroups.set(engineGroupId, engineGroup); - } else { - this.cachedEngineGroups.delete(engineGroupId); - } - } - - /** - * Clears all engine groups from the cache. - */ - clear(): void { - this.cachedEngineGroups.clear(); - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEnginePreload.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEnginePreload.ets deleted file mode 100644 index 40da2a1..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEnginePreload.ets +++ /dev/null @@ -1,213 +0,0 @@ -/* -* Copyright (c) 2025 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import FlutterEngine, { EngineLifecycleListener } from "./FlutterEngine" -import common from '@ohos.app.ability.common' -import display from '@ohos.display'; -import FlutterLoader from './loader/FlutterLoader' -import Log from '../../util/Log'; -import FlutterManager from '../ohos/FlutterManager'; -import FlutterInjector from '../../FlutterInjector' -import FlutterEngineCache from './FlutterEngineCache'; -import FlutterEngineGroupCache from './FlutterEngineGroupCache'; -import FlutterAbilityLaunchConfigs from '../ohos/FlutterAbilityLaunchConfigs'; -import JSONMethodCodec from '../../plugin/common/JSONMethodCodec'; -import MethodCall from '../../plugin/common/MethodCall'; -import FlutterNapi from './FlutterNapi'; -import { ViewportMetrics } from '../../view/FlutterView'; - -const TAG = "FlutterEnginePreload" - -/** - * Utility class for preloading Flutter engines. - * This class provides static methods to preload and prepare Flutter engines - * before they are actually displayed, improving startup performance. - */ -export default class FlutterEnginePreload { - /** - * Preloads a Flutter engine with the specified parameters. - * @param context - The application context - * @param params - Parameters for engine preloading, including entrypoint, route, etc. - * @param nextViewId - Optional view ID for the next Flutter view - */ - static async preloadEngine(context: common.Context, params: Record = {}, - nextViewId: string | null = null) { - let loader: FlutterLoader = FlutterInjector.getInstance().getFlutterLoader(); - let dartArgs = new Array(); - if (params[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT_ARGS]) { - dartArgs = params[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT_ARGS] as Array; - } - - if (!loader.initialized) { - loader.startInitialization(context); - loader.ensureInitializationComplete(dartArgs); - } - - let flutterNapi: FlutterNapi | null = - FlutterEnginePreload.preLoadFlutterNapi(context, loader.findAppBundlePath(), params) - let viewportMetrics: ViewportMetrics = new ViewportMetrics(); - if (params[FlutterAbilityLaunchConfigs.PRELOAD_VIEWPORT_METRICS_KEY]) { - viewportMetrics = params[FlutterAbilityLaunchConfigs.PRELOAD_VIEWPORT_METRICS_KEY] as ViewportMetrics; - } else { - let display_info: display.Display = display.getDefaultDisplaySync(); - viewportMetrics.physicalWidth = display_info.width; - viewportMetrics.physicalHeight = display_info.height; - viewportMetrics.devicePixelRatio = display_info.densityPixels; - viewportMetrics.physicalTouchSlop = 1.0 * display_info.densityPixels; - } - if (flutterNapi) { - if (!nextViewId) { - nextViewId = FlutterManager.getInstance().getNextFlutterViewId(); - } - flutterNapi.setPreloading(); - flutterNapi.xComponentPreDraw(nextViewId, viewportMetrics.physicalWidth, viewportMetrics.physicalHeight); - flutterNapi.setViewportMetrics(viewportMetrics.devicePixelRatio, - viewportMetrics.physicalWidth, - viewportMetrics.physicalHeight, - viewportMetrics.physicalViewPaddingTop, - viewportMetrics.physicalViewPaddingRight, - viewportMetrics.physicalViewPaddingBottom, - viewportMetrics.physicalViewPaddingLeft, - viewportMetrics.physicalViewInsetTop, - viewportMetrics.physicalViewInsetRight, - viewportMetrics.physicalViewInsetBottom, - viewportMetrics.physicalViewInsetLeft, - viewportMetrics.systemGestureInsetTop, - viewportMetrics.systemGestureInsetRight, - viewportMetrics.systemGestureInsetBottom, - viewportMetrics.systemGestureInsetLeft, - viewportMetrics.physicalTouchSlop, - new Array(0), - new Array(0), - new Array(0) - ); - } - } - - /** - * Prepares an existing engine for drawing by setting up viewport metrics and pre-drawing. - * @param engine - The FlutterEngine instance to prepare - * @param params - Parameters for engine preparation, including viewport metrics - * @param nextViewId - Optional view ID for the next Flutter view - */ - static predrawEngine(engine: FlutterEngine, params: Record = {}, nextViewId: string | null = null) { - if (!engine) { - return; - } - let flutterNapi = engine.getFlutterNapi(); - if (!flutterNapi.isAttached()) { - flutterNapi.attachToNative(); - } - if (!nextViewId) { - nextViewId = FlutterManager.getInstance().getNextFlutterViewId(); - } - let viewportMetrics: ViewportMetrics = new ViewportMetrics(); - if (params[FlutterAbilityLaunchConfigs.PRELOAD_VIEWPORT_METRICS_KEY]) { - viewportMetrics = params[FlutterAbilityLaunchConfigs.PRELOAD_VIEWPORT_METRICS_KEY] as ViewportMetrics; - } else { - let display_info: display.Display = display.getDefaultDisplaySync(); - viewportMetrics.physicalWidth = display_info.width; - viewportMetrics.physicalHeight = display_info.height; - viewportMetrics.devicePixelRatio = display_info.densityPixels; - viewportMetrics.physicalTouchSlop = 1.0 * display_info.densityPixels; - } - flutterNapi.setPreloading(); - flutterNapi.xComponentPreDraw(nextViewId, viewportMetrics.physicalWidth, viewportMetrics.physicalHeight); - flutterNapi.setViewportMetrics(viewportMetrics.devicePixelRatio, - viewportMetrics.physicalWidth, - viewportMetrics.physicalHeight, - viewportMetrics.physicalViewPaddingTop, - viewportMetrics.physicalViewPaddingRight, - viewportMetrics.physicalViewPaddingBottom, - viewportMetrics.physicalViewPaddingLeft, - viewportMetrics.physicalViewInsetTop, - viewportMetrics.physicalViewInsetRight, - viewportMetrics.physicalViewInsetBottom, - viewportMetrics.physicalViewInsetLeft, - viewportMetrics.systemGestureInsetTop, - viewportMetrics.systemGestureInsetRight, - viewportMetrics.systemGestureInsetBottom, - viewportMetrics.systemGestureInsetLeft, - viewportMetrics.physicalTouchSlop, - new Array(0), - new Array(0), - new Array(0) - ); - } - - /** - * Preloads a FlutterNapi instance with the specified configuration. - * @param context - The application context - * @param bundlePath - Path to the Flutter bundle - * @param params - Parameters for NAPI preloading, including cached engine ID, entrypoint, etc. - * @returns The preloaded FlutterNapi instance, or null if preloading fails - */ - static preLoadFlutterNapi(context: common.Context, bundlePath: string, - params: Record = {}): FlutterNapi | null { - - let cachedEngineId = params[FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] as string; - let cachedEngineGroupId = params[FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_GROUP_ID] as string; - - let dartEntrypoint = FlutterAbilityLaunchConfigs.DEFAULT_DART_ENTRYPOINT; - if (params[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT]) { - dartEntrypoint = params[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT] as string; - } - - let dartEntrypointLibraryUri = ""; - if (params[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT_LIBRARY_URI]) { - dartEntrypointLibraryUri = params[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT_LIBRARY_URI] as string; - } - - let initialRoute = ""; - if (params[FlutterAbilityLaunchConfigs.EXTRA_INITIAL_ROUTE]) { - initialRoute = params[FlutterAbilityLaunchConfigs.EXTRA_INITIAL_ROUTE] as string - } - - let dartArgs = new Array(); - if (params[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT_ARGS]) { - dartArgs = params[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT_ARGS] as Array; - } - - Log.d(TAG, "cachedEngineId=" + cachedEngineId); - let flutterNapi: FlutterNapi | null = null; - if (cachedEngineId && cachedEngineId.length > 0) { - let engine = FlutterEngineCache.getInstance().get(cachedEngineId); - if (engine) { - flutterNapi = engine.getFlutterNapi(); - } - } - if (cachedEngineGroupId && cachedEngineGroupId.length > 0) { - let flutterEngineGroup = FlutterEngineGroupCache.instance.get(cachedEngineGroupId); - if (flutterEngineGroup) { - let defaultEngine = flutterEngineGroup.getDefaultEngine(); - if (defaultEngine) { - let oldFlutterNapi = defaultEngine.getFlutterNapi(); - return oldFlutterNapi.preSpawn(dartEntrypoint, dartEntrypointLibraryUri, initialRoute, dartArgs); - } - } - } - - if (!flutterNapi) { - flutterNapi = FlutterInjector.getInstance().getPreloadFlutterNapi(); - } - if (flutterNapi) { - if (!flutterNapi.isAttached()) { - flutterNapi.attachToNative(); - } - Log.d(TAG, "setInitialRoute: " + initialRoute); - let message = JSONMethodCodec.INSTANCE.encodeMethodCall(new MethodCall("setInitialRoute", initialRoute)); - flutterNapi.dispatchPlatformMessage("flutter/navigation", message, message.byteLength, 0); - - flutterNapi.runBundleAndSnapshotFromLibrary( - bundlePath, - dartEntrypoint, - dartEntrypointLibraryUri, - context.resourceManager, - dartArgs); - } - return flutterNapi; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterNapi.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterNapi.ets deleted file mode 100644 index 50c6282..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterNapi.ets +++ /dev/null @@ -1,1162 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import flutter from 'libflutter.so'; -import common from '@ohos.app.ability.common'; -import Log from '../../util/Log'; -import resourceManager from '@ohos.resourceManager'; -import { PlatformMessageHandler } from './dart/PlatformMessageHandler'; -import { FlutterCallbackInformation } from '../../view/FlutterCallbackInformation'; -import image from '@ohos.multimedia.image'; -import { EngineLifecycleListener } from './FlutterEngine'; -import { ByteBuffer } from '../../util/ByteBuffer'; -import LocalizationPlugin from '../../plugin/localization/LocalizationPlugin'; -import i18n from '@ohos.i18n'; -import Any from '../../plugin/common/Any'; -import FlutterManager from '../ohos/FlutterManager'; -import deviceInfo from '@ohos.deviceInfo'; -import TouchEventProcessor from '../ohos/TouchEventProcessor'; -import BuildProfile from '../../../../../BuildProfile'; -import { Action } from '../engine/systemchannels/AccessibilityChannel'; - -const TAG = "FlutterNapi"; - -enum ContextType { - APP_LIFECYCLE = 0, - JS_PAGE_LIFECYCLE, -} - -/** - * Represents a pending platform message that is queued during preloading. - * These messages are processed once the Flutter engine is ready to handle them. - */ -interface PendingMessage { - /** The channel name for the message. */ - channel: string; - /** The message data as an ArrayBuffer. */ - message: ArrayBuffer; - /** The reply ID for responding to the message. */ - replyId: number; - /** Additional message data. */ - messageData: number; -} - -/** - * Provides Flutter NAPI interface for ArkTS. - * This class serves as the bridge between the ArkTS layer and the native Flutter engine, - * handling initialization, message passing, viewport management, and lifecycle events. - */ -export default class FlutterNapi { - private static hasInit: boolean = false; - /** Whether the native methods have been implemented. */ - hasImplemented: boolean = false; - /** The native shell holder ID, or null if not attached. */ - nativeShellHolderId: number | null = null; - /** The platform message handler for receiving messages from Dart, or null if not set. */ - platformMessageHandler: PlatformMessageHandler | null = null; - private engineLifecycleListeners = new Set(); - /** The accessibility delegate for handling accessibility events, or null if not set. */ - accessibilityDelegate: AccessibilityDelegate | null = null; - /** The localization plugin for handling locale information, or null if not set. */ - localizationPlugin: LocalizationPlugin | null = null; - /** Whether Flutter UI is currently being displayed. */ - isDisplayingFlutterUi: boolean = false; - /** Whether Flutter UI has been preloaded. */ - isPreloadedFlutterUi: boolean = false; - /** Whether Dart code is currently running. */ - isRunningDart: boolean = false; - private nextSpawnNapi: FlutterNapi | null = null; - private pendingMessages: PendingMessage[] = []; - private readyForHandleMessage: boolean = true; - private firstPreloading: boolean = true; - - /** - * Updates the refresh rate for the Flutter engine. - * @param refreshRateFPS - The refresh rate in frames per second - */ - updateRefreshRate(refreshRateFPS: number) { - flutter.nativeUpdateRefreshRate(refreshRateFPS); - } - - /** - * Updates the size of the Flutter view. - * @param width - The new width in pixels - * @param height - The new height in pixels - */ - updateSize(width: number, height: number) { - flutter.nativeUpdateSize(width, height); - } - - /** - * Updates the pixel density of the display. - * @param densityPixels - The pixel density value (dots per inch) - */ - updateDensity(densityPixels: number) { - flutter.nativeUpdateDensity(densityPixels); - } - - /** - * Initializes the Flutter engine with the specified parameters. - * @param context - The application context - * @param args - Command-line arguments for the Flutter engine - * @param bundlePath - Path to the Flutter bundle - * @param appStoragePath - Path to the application storage directory - * @param engineCachesPath - Path to the engine caches directory - * @param initTimeMillis - Initialization time in milliseconds - */ - init(context: common.Context, - args: Array, - bundlePath: string, - appStoragePath: string, - engineCachesPath: string, - initTimeMillis: number) { - if (FlutterNapi.hasInit) { - Log.e(TAG, "the engine has init"); - return; - } - Log.w(TAG, "HAR_VERSION=" + BuildProfile.HAR_VERSION); - Log.d(TAG, JSON.stringify({ - "name": "init, initTimeMillis=" + initTimeMillis, - "bundlePath": bundlePath, - "appStoragePath": appStoragePath, - "engineCachesPath": engineCachesPath, - "args": args, - })); - let code: number | null = flutter.nativeInit(context, args, bundlePath, appStoragePath, - engineCachesPath, initTimeMillis, deviceInfo.productModel); - FlutterNapi.hasInit = code == 0; - Log.d(TAG, "init code=" + code + ", FlutterNapi.hasInit" + FlutterNapi.hasInit); - } - - /** - * Prefetches the default font manager. - * This should be called before using fonts in the Flutter engine. - */ - static prefetchDefaultFontManager(): void { - flutter.nativePrefetchDefaultFontManager(); - } - - /** - * Checks and reloads fonts for this engine instance. - */ - checkAndReloadFont(): void { - flutter.nativeCheckAndReloadFont(this.nativeShellHolderId!); - } - - /** - * Attaches this FlutterNapi instance to the native engine. - * This must be called before using most FlutterNapi methods. - */ - attachToNative(): void { - if (!FlutterNapi.hasInit) { - Log.e(TAG, "attachToNative fail, FlutterNapi.hasInit=" + FlutterNapi.hasInit); - return; - } - if (this.nativeShellHolderId == null) { - this.nativeShellHolderId = flutter.nativeAttach(this); - } - Log.d(TAG, "nativeShellHolderId=" + this.nativeShellHolderId); - } - - /** - * Runs a Flutter bundle and snapshot from a library. - * @param bundlePath - Path to the Flutter bundle - * @param entrypointFunctionName - Name of the entrypoint function - * @param pathToEntrypointFunction - Path to the entrypoint function - * @param assetManager - Resource manager for accessing assets - * @param entrypointArgs - Arguments to pass to the entrypoint function - */ - runBundleAndSnapshotFromLibrary( - bundlePath: string, - entrypointFunctionName: string | undefined, - pathToEntrypointFunction: string | undefined, - assetManager: resourceManager.ResourceManager, - entrypointArgs: Array) { - if (!FlutterNapi.hasInit) { - Log.e(TAG, "runBundleAndSnapshotFromLibrary fail, FlutterNapi.hasInit=" + FlutterNapi.hasInit); - return; - } - Log.d(TAG, "init: bundlePath=" + bundlePath + " entrypointFunctionName=" + entrypointFunctionName + - " pathToEntrypointFunction=" + pathToEntrypointFunction + " entrypointArgs=" + JSON.stringify(entrypointArgs)) - if (!this.nativeShellHolderId) { - Log.e(TAG, "runBundleAndSnapshotFromLibrary this.nativeShellHolderId = " + this.nativeShellHolderId) - return; - } - flutter.nativeRunBundleAndSnapshotFromLibrary(this.nativeShellHolderId!, bundlePath, entrypointFunctionName, - pathToEntrypointFunction, assetManager, entrypointArgs); - this.isRunningDart = true; - this.isDisplayingFlutterUi = false; - this.isPreloadedFlutterUi = false; - }; - - /** - * Checks if the native methods are implemented. - * @param methodName - Optional method name for logging - * @returns true if methods are implemented, false otherwise - */ - checkImplemented(methodName: string = ""): boolean { - if (!this.hasImplemented) { - Log.e(TAG, "this method has not implemented -> " + methodName) - } - return this.hasImplemented; - } - - /** - * Sets the platform message handler for receiving messages from Dart. - * @param platformMessageHandler - The PlatformMessageHandler instance, or null to remove - */ - setPlatformMessageHandler(platformMessageHandler: PlatformMessageHandler | null): void { - this.ensureRunningOnMainThread(); - this.platformMessageHandler = platformMessageHandler; - } - - private nativeNotifyLowMemoryWarning(nativeShellHolderId: number): void { - - } - - /** - * Looks up callback information for a given handler. - * @param handle - The handler number - * @returns The FlutterCallbackInformation, or null if not found - */ - static nativeLookupCallbackInformation(handle: number): FlutterCallbackInformation | null { - let callbackInformation = new FlutterCallbackInformation(); - let ret: number = flutter.nativeLookupCallbackInformation(callbackInformation, handle); - if (ret == 0) { - return callbackInformation; - } - return null; - } - - /** - * Notifies the Flutter engine of a low memory warning. - */ - notifyLowMemoryWarning(): void { - this.ensureRunningOnMainThread(); - if (!this.nativeShellHolderId) { - Log.e(TAG, "notifyLowMemoryWarning this.nativeShellHolderId = " + this.nativeShellHolderId) - return; - } - this.nativeNotifyLowMemoryWarning(this.nativeShellHolderId!); - } - - /** - * Checks if this FlutterNapi instance is attached to the native engine. - * @returns true if attached, false otherwise - */ - isAttached(): boolean { - return this.nativeShellHolderId != null; - } - - /** - * Ensures that the current code is running on the main thread. - */ - private ensureRunningOnMainThread(): void { - - } - - /** - * Dispatches an empty platform message to Dart. - * @param channel - The channel name for the message - * @param responseId - The response ID for receiving a reply - */ - dispatchEmptyPlatformMessage(channel: String, responseId: number): void { - this.ensureRunningOnMainThread(); - if (this.isAttached()) { - if (!this.nativeShellHolderId) { - Log.e(TAG, "dispatchEmptyPlatformMessage this.nativeShellHolderId = " + this.nativeShellHolderId) - return; - } - flutter.nativeDispatchEmptyPlatformMessage(this.nativeShellHolderId!, channel, responseId); - } else { - Log.w( - TAG, - "Tried to send a platform message to Flutter, but FlutterNapi was detached from native C++. Could not send. Channel: " - + channel - + ". Response ID: " - + responseId); - } - } - - /** - * Sends a platform message with data from OpenHarmony to Flutter over the given channel. - * @param channel - The channel name for the message - * @param message - The message data as an ArrayBuffer - * @param position - The position in the message buffer - * @param responseId - The response ID for receiving a reply - */ - dispatchPlatformMessage(channel: String, message: ArrayBuffer, position: number, responseId: number): void { - this.ensureRunningOnMainThread(); - if (this.isAttached()) { - if (!this.nativeShellHolderId) { - Log.e(TAG, "dispatchPlatformMessage this.nativeShellHolderId = " + this.nativeShellHolderId) - return; - } - flutter.nativeDispatchPlatformMessage(this.nativeShellHolderId!, channel, message, position, responseId); - } else { - Log.w( - TAG, - "Tried to send a platform message to Flutter, but FlutterNapi was detached from native C++. Could not send. Channel: " - + channel - + ". Response ID: " - + responseId); - } - } - - /** - * Invokes an empty response callback for a platform message. - * @param responseId - The response ID that was sent with the original message - */ - invokePlatformMessageEmptyResponseCallback(responseId: number): void { - if (this.isAttached()) { - if (!this.nativeShellHolderId) { - Log.e(TAG, "invokePlatformMessageEmptyResponseCallback this.nativeShellHolderId = " + this.nativeShellHolderId) - return; - } - flutter.nativeInvokePlatformMessageEmptyResponseCallback(this.nativeShellHolderId!, responseId); - } else { - Log.w( - TAG, - "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " - + responseId); - } - } - - /** - * Invokes a response callback with data for a platform message. - * @param responseId - The response ID that was sent with the original message - * @param message - The reply data as an ArrayBuffer - * @param position - The position in the message buffer - */ - invokePlatformMessageResponseCallback(responseId: number, message: ArrayBuffer, position: number) { - if (this.isAttached()) { - if (!this.nativeShellHolderId) { - Log.e(TAG, "this.nativeShellHolderId = " + this.nativeShellHolderId) - return; - } - flutter.nativeInvokePlatformMessageResponseCallback( - this.nativeShellHolderId!, responseId, message, position); - } else { - Log.w( - TAG, - "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " - + responseId); - } - } - - /** - * Sets the viewport metrics for the Flutter view. - * @param devicePixelRatio - The device pixel ratio - * @param physicalWidth - Physical width in pixels - * @param physicalHeight - Physical height in pixels - * @param physicalPaddingTop - Top padding in physical pixels - * @param physicalPaddingRight - Right padding in physical pixels - * @param physicalPaddingBottom - Bottom padding in physical pixels - * @param physicalPaddingLeft - Left padding in physical pixels - * @param physicalViewInsetTop - Top view inset in physical pixels - * @param physicalViewInsetRight - Right view inset in physical pixels - * @param physicalViewInsetBottom - Bottom view inset in physical pixels - * @param physicalViewInsetLeft - Left view inset in physical pixels - * @param systemGestureInsetTop - Top system gesture inset - * @param systemGestureInsetRight - Right system gesture inset - * @param systemGestureInsetBottom - Bottom system gesture inset - * @param systemGestureInsetLeft - Left system gesture inset - * @param physicalTouchSlop - Physical touch slop value - * @param displayFeaturesBounds - Array of display feature bounds - * @param displayFeaturesType - Array of display feature types - * @param displayFeaturesState - Array of display feature states - */ - setViewportMetrics(devicePixelRatio: number, physicalWidth: number - , physicalHeight: number, physicalPaddingTop: number, physicalPaddingRight: number - , physicalPaddingBottom: number, physicalPaddingLeft: number, physicalViewInsetTop: number - , physicalViewInsetRight: number, physicalViewInsetBottom: number, physicalViewInsetLeft: number - , systemGestureInsetTop: number, systemGestureInsetRight: number, systemGestureInsetBottom: number - , systemGestureInsetLeft: number, physicalTouchSlop: number, displayFeaturesBounds: Array - , displayFeaturesType: Array, displayFeaturesState: Array): void { - if (this.isAttached()) { - if (!this.nativeShellHolderId) { - Log.e(TAG, "setViewportMetrics this.nativeShellHolderId = " + this.nativeShellHolderId) - return; - } - flutter.nativeSetViewportMetrics(this.nativeShellHolderId!, devicePixelRatio, - physicalWidth, - physicalHeight, - physicalPaddingTop, - physicalPaddingRight, - physicalPaddingBottom, - physicalPaddingLeft, - physicalViewInsetTop, - physicalViewInsetRight, - physicalViewInsetBottom, - physicalViewInsetLeft, - systemGestureInsetTop, - systemGestureInsetRight, - systemGestureInsetBottom, - systemGestureInsetLeft, - physicalTouchSlop, - displayFeaturesBounds, - displayFeaturesType, - displayFeaturesState); - } - } - - /** - * Spawns a new FlutterNapi instance from this instance. - * @param entrypointFunctionName - Name of the entrypoint function - * @param pathToEntrypointFunction - Path to the entrypoint function - * @param initialRoute - Initial route for navigation - * @param entrypointArgs - Arguments to pass to the entrypoint function - * @returns A new FlutterNapi instance - */ - spawn(entrypointFunctionName: string, pathToEntrypointFunction: string, initialRoute: string, - entrypointArgs: Array): FlutterNapi { - if (this.nextSpawnNapi) { - let ret = this.nextSpawnNapi; - this.nextSpawnNapi = null; - return ret; - } - let flutterNapi = new FlutterNapi(); - let shellHolderId: number = - flutter.nativeSpawn(this.nativeShellHolderId, entrypointFunctionName, pathToEntrypointFunction, initialRoute, - entrypointArgs, flutterNapi); - flutterNapi.nativeShellHolderId = shellHolderId; - flutterNapi.isRunningDart = this.isRunningDart; - flutterNapi.isDisplayingFlutterUi = false; - flutterNapi.isPreloadedFlutterUi = false; - return flutterNapi; - } - - /** - * Pre-spawns a new FlutterNapi instance for later use. - * @param entrypointFunctionName - Name of the entrypoint function - * @param pathToEntrypointFunction - Path to the entrypoint function - * @param initialRoute - Initial route for navigation - * @param entrypointArgs - Arguments to pass to the entrypoint function - * @returns A new FlutterNapi instance that will be used on the next spawn call - */ - preSpawn(entrypointFunctionName: string, pathToEntrypointFunction: string, initialRoute: string, - entrypointArgs: Array): FlutterNapi { - if (this.nextSpawnNapi) { - this.nextSpawnNapi.detachFromNativeAndReleaseResources(); - } - let flutterNapi = new FlutterNapi(); - let shellHolderId: number = - flutter.nativeSpawn(this.nativeShellHolderId, entrypointFunctionName, pathToEntrypointFunction, initialRoute, - entrypointArgs, flutterNapi); - flutterNapi.nativeShellHolderId = shellHolderId; - flutterNapi.isRunningDart = this.isRunningDart; - flutterNapi.isDisplayingFlutterUi = false; - flutterNapi.isPreloadedFlutterUi = false; - this.nextSpawnNapi = flutterNapi; - return flutterNapi; - } - - /** - * Adds an engine lifecycle listener. - * @param engineLifecycleListener - The EngineLifecycleListener to add - */ - addEngineLifecycleListener(engineLifecycleListener: EngineLifecycleListener): void { - this.engineLifecycleListeners.add(engineLifecycleListener); - } - - /** - * Removes an engine lifecycle listener. - * @param engineLifecycleListener - The EngineLifecycleListener to remove - */ - removeEngineLifecycleListener(engineLifecycleListener: EngineLifecycleListener) { - this.engineLifecycleListeners.delete(engineLifecycleListener); - } - - /** - * Called by native to respond to a platform message that we sent. - * @param replyId - The response ID that was sent with the original message - * @param reply - The reply data as an ArrayBuffer - */ - handlePlatformMessageResponse(replyId: number, reply: ArrayBuffer): void { - Log.d(TAG, "called handlePlatformMessageResponse Response ID: " + replyId); - if (this.platformMessageHandler != null) { - this.platformMessageHandler.handlePlatformMessageResponse(replyId, reply); - } - } - - /** - * Called by native on any thread to handle a platform message from Dart. - * @param channel - The channel name for the message - * @param message - The message data as an ArrayBuffer - * @param replyId - The reply ID for responding to the message - * @param messageData - Additional message data - */ - handlePlatformMessage(channel: string, message: ArrayBuffer, replyId: number, messageData: number): void { - Log.d(TAG, "called handlePlatformMessage Channel: " + channel + ". Response ID: " + replyId); - if (this.platformMessageHandler != null && this.readyForHandleMessage) { - this.platformMessageHandler.handleMessageFromDart(channel, message, replyId, messageData); - } else { - const pendingMessage: PendingMessage = { - channel, - message, - replyId, - messageData - }; - this.pendingMessages.push(pendingMessage); - } - } - - /** - * Sets the preloading state, preventing message handling until ready. - */ - setPreloading(): void { - if (this.firstPreloading) { - this.readyForHandleMessage = false; - this.firstPreloading = false; - } - } - - /** - * Processes all pending messages that were queued during preloading. - */ - processPendingMessages(): void { - Log.d(TAG, "processPendingMessages len:" + this.pendingMessages.length); - this.readyForHandleMessage = true; - while (this.pendingMessages.length > 0 && this.platformMessageHandler) { - const pendingMessage = this.pendingMessages.shift(); - if (pendingMessage) { - this.platformMessageHandler.handleMessageFromDart( - pendingMessage.channel, - pendingMessage.message, - pendingMessage.replyId, - pendingMessage.messageData - ); - } - } - } - - /** - * Called by native to notify that the first Flutter frame has been rendered. - * @param isPreload - Whether this is a preload frame (1) or a regular frame (0) - */ - onFirstFrame(isPreload: number): void { - Log.d(TAG, "called onFirstFrame isPreload:" + isPreload); - if (isPreload) { - this.isPreloadedFlutterUi = true; - } else { - this.processPendingMessages(); - if (this.isDisplayingFlutterUi) { - return; - } - this.isDisplayingFlutterUi = true; - } - FlutterManager.getInstance().getFlutterViewList().forEach((value) => { - if (this.nativeShellHolderId != null && value.isSameEngineShellHolderId(this.nativeShellHolderId)) { - value.onFirstFrame(isPreload); - } - }); - } - - /** - * Called by native when the engine is about to restart. - * Notifies all registered lifecycle listeners. - */ - onPreEngineRestart(): void { - Log.d(TAG, "called onPreEngineRestart") - this.engineLifecycleListeners.forEach(listener => listener.onPreEngineRestart()); - } - - /** - * Computes the platform-resolved locale from the given locale strings. - * Invoked by native to obtain the results of OpenHarmony's locale resolution algorithm. - * @param strings - Array of locale strings - * @returns Array of resolved locale strings - */ - computePlatformResolvedLocale(strings: Array): Array { - Log.d(TAG, "called computePlatformResolvedLocale " + JSON.stringify(strings)) - return [] - } - - /** - * Sets whether semantics are enabled and sends a response. - * @param enabled - Whether to enable semantics - * @param responseId - The response ID for the reply - */ - setSemanticsEnabledWithRespId(enabled: boolean, responseId: number): void { - this.ensureRunningOnMainThread(); - if (this.isAttached()) { - flutter.nativeSetSemanticsEnabled(this.nativeShellHolderId!, enabled); - } else { - Log.w( - TAG, - "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " - + responseId); - } - } - - /** - * Sets whether semantics are enabled. - * @param enabled - Whether to enable semantics - */ - setSemanticsEnabled(enabled: boolean): void { - this.ensureRunningOnMainThread(); - if (this.isAttached()) { - flutter.nativeSetSemanticsEnabled(this.nativeShellHolderId!, enabled); - } else { - Log.e( - TAG, - "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send."); - } - } - - /** - * Sets accessibility features and sends a response. - * @param accessibilityFeatureFlags - The accessibility feature flags - * @param responseId - The response ID for the reply - */ - setAccessibilityFeatures(accessibilityFeatureFlags: number, responseId: number): void { - if (this.isAttached()) { - flutter.nativeSetAccessibilityFeatures(accessibilityFeatureFlags, responseId); - } else { - Log.w( - TAG, - "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " - + responseId); - } - } - - /** - * Native method for setting accessibility features. - * @param accessibilityFeatureFlags - The accessibility feature flags - * @param responseId - The response ID for the reply - */ - nativeSetAccessibilityFeatures(accessibilityFeatureFlags: number, responseId: number): void { - } - - /** - * Dispatches a semantics action to the native engine. - * @param virtualViewId - The virtual view ID - * @param action - The semantics action to dispatch - * @param responseId - The response ID for the reply - */ - dispatchSemanticsAction(virtualViewId: number, action: Action, responseId: number): void { - if (this.isAttached()) { - this.nativeDispatchSemanticsAction(virtualViewId, action, responseId); - } else { - Log.w( - TAG, - "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " - + responseId); - } - } - - /** - * Native method for dispatching a semantics action. - * @param virtualViewId - The virtual view ID - * @param action - The semantics action to dispatch - * @param responseId - The response ID for the reply - */ - nativeDispatchSemanticsAction(virtualViewId: number, action: Action, responseId: number): void { - } - - /** - * Sets the accessibility delegate for handling accessibility events. - * @param delegate - The AccessibilityDelegate instance - * @param responseId - The response ID for the reply - */ - setAccessibilityDelegate(delegate: AccessibilityDelegate, responseId: number): void { - if (this.isAttached()) { - this.accessibilityDelegate = delegate; - } else { - Log.w( - TAG, - "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " - + responseId); - } - } - - /** - * Called when the accessibility state changes. - * @param state - Whether accessibility is enabled - */ - accessibilityStateChange(state: Boolean): void { - this.ensureRunningOnMainThread(); - if (this.accessibilityDelegate != null) { - this.accessibilityDelegate.accessibilityStateChange(state); - } - Log.d(TAG, "accessibilityStateChange: state is " + state ? "on" : "off"); - if (this.nativeShellHolderId != null) { - flutter.nativeAccessibilityStateChange(this.nativeShellHolderId!, state); - } else { - Log.w(TAG, "accessibilityStateChange, nativeShellHolderId is null") - } - } - - /** - * Sets the localization plugin for handling locale information. - * @param localizationPlugin - The LocalizationPlugin instance, or null to remove - */ - setLocalizationPlugin(localizationPlugin: LocalizationPlugin | null): void { - this.localizationPlugin = localizationPlugin; - } - - /** - * Gets the system language list from the platform. - */ - getSystemLanguages() { - Log.d(TAG, "called getSystemLanguages ") - let index: number; - let systemLanguages = i18n.System.getPreferredLanguageList(); - for (index = 0; index < systemLanguages.length; index++) { - Log.d(TAG, "systemlanguages " + index + ":" + systemLanguages[index]); - } - if (!this.nativeShellHolderId) { - Log.e(TAG, "getSystemLanguages this.nativeShellHolderId = " + this.nativeShellHolderId) - return; - } - flutter.nativeGetSystemLanguages(this.nativeShellHolderId!, systemLanguages); - } - - /** - * Attaches a FlutterEngine to an XComponent. - * @param xcomponentId - The XComponent ID - */ - xComponentAttachFlutterEngine(xcomponentId: string) { - flutter.nativeXComponentAttachFlutterEngine(xcomponentId, this.nativeShellHolderId!); - } - - /** - * Pre-renders an XComponent. - * @param xcomponentId - The XComponent ID - * @param width - The width of the component - * @param height - The height of the component - */ - xComponentPreDraw(xcomponentId: string, width: number, height: number) { - flutter.nativeXComponentPreDraw(xcomponentId, this.nativeShellHolderId!, width, height); - } - - /** - * Detaches a FlutterEngine from an XComponent. - * @param xcomponentId - The XComponent ID - */ - xComponentDetachFlutterEngine(xcomponentId: string) { - flutter.nativeXComponentDetachFlutterEngine(xcomponentId, this.nativeShellHolderId!); - } - - /** - * Dispatches a mouse wheel event from an XComponent to the Flutter engine. - * @param xcomponentId - The XComponent ID - * @param eventType - The type of the mouse wheel event - * @param event - The pan gesture event containing mouse wheel data - */ - xComponentDisPatchMouseWheel(xcomponentId: string, eventType: string, event: PanGestureEvent) { - // only mouse - if (event.source !== SourceType.Mouse) { - return; - } - const vaildFinger = event.fingerList?.find(item => item.globalX && item.globalY); - if (!vaildFinger) { - return; - } - flutter.nativeXComponentDispatchMouseWheel( - this.nativeShellHolderId!!, - xcomponentId, - eventType, - vaildFinger?.id, - vaildFinger?.localX, - vaildFinger?.localY, - event.offsetY, - event.timestamp - ); - } - - /** - * Detaches this FlutterNapi instance from the native engine and releases all resources. - */ - detachFromNativeAndReleaseResources() { - if (!this.nativeShellHolderId) { - Log.e(TAG, "detachFromNativeAndReleaseResources this.nativeShellHolderId = " + this.nativeShellHolderId) - return; - } - flutter.nativeDestroy(this.nativeShellHolderId!!); - this.nativeShellHolderId = null; - this.isRunningDart = false; - this.isDisplayingFlutterUi = false; - this.isPreloadedFlutterUi = false; - this.readyForHandleMessage = false; - } - - /** - * Unregisters a texture from the Flutter engine. - * @param textureId - The texture ID to unregister - */ - unregisterTexture(textureId: number): void { - Log.d(TAG, "called unregisterTexture "); - if (!this.nativeShellHolderId) { - Log.e(TAG, "unregisterTexture this.nativeShellHolderId = " + this.nativeShellHolderId) - return; - } - flutter.nativeUnregisterTexture(this.nativeShellHolderId!, textureId); - } - - /** - * Registers a PixelMap as a texture in the Flutter engine. - * @param textureId - The texture ID - * @param pixelMap - The PixelMap to register - */ - registerPixelMap(textureId: number, pixelMap: PixelMap): void { - Log.d(TAG, "called registerPixelMap "); - if (!this.nativeShellHolderId) { - Log.e(TAG, "registerPixelMap this.nativeShellHolderId = " + this.nativeShellHolderId) - return; - } - flutter.nativeRegisterPixelMap(this.nativeShellHolderId!, textureId, pixelMap); - } - - /** - * Sets the background PixelMap for a texture. - * @param textureId - The texture ID - * @param pixelMap - The PixelMap to use as background - */ - setTextureBackGroundPixelMap(textureId: number, pixelMap: PixelMap): void { - if (this.isAttached()) { - if (!this.nativeShellHolderId) { - Log.e(TAG, "this.nativeShellHolderId = " + this.nativeShellHolderId) - return; - } - flutter.nativeSetTextureBackGroundPixelMap(this.nativeShellHolderId!, textureId, pixelMap); - } else { - return; - } - } - - /** - * Sets the background color for a texture. - * @param textureId - The texture ID - * @param color - The color value in ARGB format - */ - setTextureBackGroundColor(textureId: number, color: number): void { - Log.d(TAG, "called setTextureBackGroundColor"); - if (!this.isAttached()) { - Log.e(TAG, "setTextureBackGroundColor when napi is not attached"); - return; - } - flutter.nativeSetTextureBackGroundColor(this.nativeShellHolderId!, textureId, color); - } - - /** - * Registers a texture in the Flutter engine. - * @param textureId - The texture ID to register - * @returns The registered texture ID, or 0 if registration fails - */ - registerTexture(textureId: number): number { - Log.d(TAG, "called registerTexture "); - if (!this.nativeShellHolderId) { - Log.e(TAG, "registerTexture this.nativeShellHolderId = " + this.nativeShellHolderId) - return 0; - } - return flutter.nativeRegisterTexture(this.nativeShellHolderId!, textureId); - } - - /** - * @deprecated since 3.22 - * @useinstead FlutterNapi#getTextureNativeWindowPtr - */ - getTextureNativeWindowId(textureId: number): number { - Log.d(TAG, "called getTextureNativeWindowId "); - if (this.isAttached()) { - if (!this.nativeShellHolderId) { - Log.e(TAG, "this.nativeShellHolderId = " + this.nativeShellHolderId) - return 0; - } - return flutter.nativeGetTextureWindowId(this.nativeShellHolderId!, textureId); - } else { - return 0; - } - } - - /** - * Gets the native window pointer for a texture. - * @param textureId - The texture ID - * @returns The native window pointer as a bigint, or BigInt("0") if not available - */ - getTextureNativeWindowPtr(textureId: number): bigint { - Log.d(TAG, "called getTextureNativeWindowPtr"); - if (this.isAttached()) { - if (!this.nativeShellHolderId) { - Log.e(TAG, "this.nativeShellHolderId = " + this.nativeShellHolderId) - return BigInt("0"); - } - return flutter.nativeGetTextureWindowPtr(this.nativeShellHolderId!, textureId); - } else { - return BigInt("0"); - } - } - - /** - * @deprecated since 3.22 - * @useinstead FlutterNapi#setExternalNativeImagePtr - */ - setExternalNativeImage(textureId: number, native_image: number): boolean { - Log.d(TAG, "called setExternalNativeImage "); - if (this.isAttached()) { - if (!this.nativeShellHolderId) { - Log.e(TAG, "this.nativeShellHolderId = " + this.nativeShellHolderId) - return false; - } - return Boolean(flutter.nativeSetExternalNativeImage(this.nativeShellHolderId!, textureId, native_image)); - } else { - return false; - } - } - - /** - * Sets an external native image pointer for a texture. - * @param textureId - The texture ID - * @param native_image_ptr - The native image pointer as a bigint - * @returns true if successful, false otherwise - */ - setExternalNativeImagePtr(textureId: number, native_image_ptr: bigint): boolean { - Log.d(TAG, "called setExternalNativeImagePtr"); - if (this.isAttached()) { - if (!this.nativeShellHolderId) { - Log.e(TAG, "this.nativeShellHolderId = " + this.nativeShellHolderId) - return false; - } - return Boolean(flutter.nativeSetExternalNativeImagePtr(this.nativeShellHolderId!, textureId, native_image_ptr)); - } else { - return false; - } - } - - /** - * Resets an external texture. - * @param textureId - The texture ID - * @param need_surfaceId - Whether a surface ID is needed - * @returns The surface ID if needed, or 0 otherwise - */ - resetExternalTexture(textureId: number, need_surfaceId: boolean): number { - Log.d(TAG, "called resetExternalTexture "); - if (this.isAttached()) { - if (!this.nativeShellHolderId) { - Log.e(TAG, "this.nativeShellHolderId = " + this.nativeShellHolderId) - return 0; - } - return flutter.nativeResetExternalTexture(this.nativeShellHolderId!, textureId, need_surfaceId); - } else { - return 0; - } - } - - /** - * Sets the buffer size for a texture. - * @param textureId - The texture ID - * @param width - The width of the buffer - * @param height - The height of the buffer - */ - setTextureBufferSize(textureId: number, width: number, height: number): void { - Log.d(TAG, "called setTextureBufferSize "); - if (!this.isAttached()) { - Log.e(TAG, "setTextureBufferSize this.nativeShellHolderId:" + this.nativeShellHolderId) - return; - } - flutter.nativeSetTextureBufferSize(this.nativeShellHolderId!, textureId, width, height); - } - - /** - * Notifies the Flutter engine that a texture is being resized. - * @param textureId - The texture ID - * @param width - The new width - * @param height - The new height - */ - notifyTextureResizing(textureId: number, width: number, height: number): void { - Log.d(TAG, "called notifyTextureResizing "); - if (!this.isAttached()) { - Log.e(TAG, "notifyTextureResizing this.nativeShellHolderId:" + this.nativeShellHolderId) - return; - } - flutter.nativeNotifyTextureResizing(this.nativeShellHolderId!, textureId, width, height); - } - - /** - * Enables or disables frame caching for improved performance. - * @param enable - Whether to enable frame caching - */ - enableFrameCache(enable: boolean): void { - if (!this.nativeShellHolderId) { - return; - } - flutter.nativeEnableFrameCache(this.nativeShellHolderId!, enable); - } - - /** - * Handles touch events from the platform. - * @param strings - Array of strings containing touch event data - */ - onTouchEvent(strings: Array): void { - if (this.isAttached()) { - TouchEventProcessor.getInstance().postTouchEvent(strings); - } - } - - /** - * Handles mouse events from the platform. - * @param strings - Array of strings containing mouse event data - */ - onMouseEvent(strings: Array): void { - if (this.isAttached()) { - TouchEventProcessor.getInstance().postMouseEvent(strings); - } - } - - /** - * Handles axis events (scroll wheel, etc.) from the platform. - * @param strings - Array of strings containing axis event data - */ - onAxisEvent(strings: Array): void { - if (this.isAttached()) { - TouchEventProcessor.getInstance().postAxisEvent(strings); - } - } - - /** - * Checks if a Unicode code point is an emoji. - * @param code - The Unicode code point - * @returns true if the code point is an emoji, false otherwise - */ - static unicodeIsEmoji(code: number): boolean { - return Boolean(flutter.nativeUnicodeIsEmoji(code)); - } - - /** - * Checks if a Unicode code point is an emoji modifier. - * @param code - The Unicode code point - * @returns true if the code point is an emoji modifier, false otherwise - */ - static unicodeIsEmojiModifier(code: number): boolean { - return Boolean(flutter.nativeUnicodeIsEmojiModifier(code)); - } - - /** - * Checks if a Unicode code point is an emoji modifier base. - * @param code - The Unicode code point - * @returns true if the code point is an emoji modifier base, false otherwise - */ - static unicodeIsEmojiModifierBase(code: number): boolean { - return Boolean(flutter.nativeUnicodeIsEmojiModifierBase(code)); - } - - /** - * Checks if a Unicode code point is a variation selector. - * @param code - The Unicode code point - * @returns true if the code point is a variation selector, false otherwise - */ - static unicodeIsVariationSelector(code: number): boolean { - return Boolean(flutter.nativeUnicodeIsVariationSelector(code)); - } - - /** - * Checks if a Unicode code point is a regional indicator symbol. - * @param code - The Unicode code point - * @returns true if the code point is a regional indicator symbol, false otherwise - */ - static unicodeIsRegionalIndicatorSymbol(code: number): boolean { - return Boolean(flutter.nativeUnicodeIsRegionalIndicatorSymbol(code)); - } - - /** - * Sets the font weight scale for text rendering. - * @param fontWeightScale - The font weight scale factor - */ - setFontWeightScale(fontWeightScale: number): void { - this.ensureRunningOnMainThread(); - if (this.isAttached()) { - Log.i(TAG, "setFontWeightScale: " + fontWeightScale); - flutter.nativeSetFontWeightScale(this.nativeShellHolderId!, fontWeightScale); - } else { - Log.w(TAG, "setFontWeightScale is detached !"); - } - } - - /** - * Sets the Flutter navigation action state. - * @param shellHolderId - The shell holder ID - * @param isNavigate - Whether navigation is active - */ - setFlutterNavigationAction(shellHolderId: number, isNavigate: boolean): void { - this.ensureRunningOnMainThread(); - if (this.isAttached()) { - Log.i(TAG, "setFlutterNavigationAction: " + isNavigate); - flutter.nativeSetFlutterNavigationAction(shellHolderId, isNavigate); - } else { - Log.w(TAG, "setFlutterNavigationAction is detached !"); - } - } - - /** - * Sets the D-VSync switch state. - * @param isEnable - Whether to enable D-VSync - */ - SetDVsyncSwitch(isEnable: boolean): void { - flutter.nativeSetDVsyncSwitch(this.nativeShellHolderId!, isEnable); - } - - /** - * Sends screen scrolling velocity to the native engine. - * @param type - The animation type - * @param velocity - The current screen scrolling velocity - */ - static animationVoting(type: number, velocity: number): void { - flutter.nativeAnimationVoting(type, velocity); - } - - /** - * Sends video frame count to the native engine. - * @param seconds - The time duration in seconds - * @param frameCount - The number of frames within the specified time duration - */ - static videoVoting(seconds: number, frameCount: number): void { - flutter.nativeVideoVoting(seconds, frameCount); - } - - /** - * Prefetches the frame rate configuration file. - */ - static prefetchFramesCfg(): void { - flutter.nativePrefetchFramesCfg(); - } - - /** - * Checks the LTPO (Low Temperature Polycrystalline Oxide) switch state. - * @returns The LTPO switch state value - */ - static checkLTPOSwitchState(): number { - return flutter.nativeCheckLTPOSwitchState(); - } - - /** - * Sets the QoS (Quality of Service) level when low memory is detected. - * @param lowMemoryLevel - The low memory level - */ - SetQosOnLowMemory(lowMemoryLevel: number): void { - flutter.nativeSetQosOnLowMemory(this.nativeShellHolderId!, lowMemoryLevel); - } - - SetAnimationStatus(animationStatus: number): void { - flutter.nativeSetAnimationStatus(this.nativeShellHolderId!, animationStatus); - } - - NotifyPageChanged(pageName: string, pageNameLen: number, windowID: number): number { - return flutter.nativeNotifyPageChanged(pageName, pageNameLen, windowID); - } -} - -/** - * Interface for handling accessibility state changes. - * Implementations of this interface will be notified when the accessibility state changes. - */ -export interface AccessibilityDelegate { - /** - * Called when the accessibility state changes. - * @param state - Whether accessibility is enabled - */ - accessibilityStateChange(state: Boolean): void; -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterOverlaySurface.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterOverlaySurface.ets deleted file mode 100644 index 5ca47e3..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterOverlaySurface.ets +++ /dev/null @@ -1,33 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on FlutterOverlaySurface.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -/** - * Represents an overlay surface in the Flutter rendering system. - * Overlay surfaces are used for displaying content above the main Flutter view. - */ -export class FlutterOverlaySurface { - private id: number; - - /** - * Constructs a new FlutterOverlaySurface instance. - * @param id - The unique identifier for this overlay surface - */ - constructor(id: number) { - this.id = id - } - - /** - * Gets the unique identifier of this overlay surface. - * @returns The overlay surface ID - */ - getId(): number { - return this.id; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterShellArgs.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterShellArgs.ets deleted file mode 100644 index 9cf6b65..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterShellArgs.ets +++ /dev/null @@ -1,163 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on FlutterShellArgs.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import Want from '@ohos.app.ability.Want'; - -/** - * Encapsulates arguments for the Flutter shell. - * This class provides methods to parse and manage command-line arguments - * that are passed to the Flutter engine during initialization. - */ -export default class FlutterShellArgs { - static ARG_KEY_TRACE_STARTUP = "trace-startup"; - static ARG_TRACE_STARTUP = "--trace-startup"; - static ARG_KEY_START_PAUSED = "start-paused"; - static ARG_START_PAUSED = "--start-paused"; - static ARG_KEY_DISABLE_SERVICE_AUTH_CODES = "disable-service-auth-codes"; - static ARG_DISABLE_SERVICE_AUTH_CODES = "--disable-service-auth-codes"; - static ARG_KEY_ENDLESS_TRACE_BUFFER = "endless-trace-buffer"; - static ARG_ENDLESS_TRACE_BUFFER = "--endless-trace-buffer"; - static ARG_KEY_USE_TEST_FONTS = "use-test-fonts"; - static ARG_USE_TEST_FONTS = "--use-test-fonts"; - static ARG_KEY_ENABLE_DART_PROFILING = "enable-dart-profiling"; - static ARG_ENABLE_DART_PROFILING = "--enable-dart-profiling"; - static ARG_KEY_ENABLE_SOFTWARE_RENDERING = "enable-software-rendering"; - static ARG_ENABLE_SOFTWARE_RENDERING = "--enable-software-rendering"; - static ARG_KEY_SKIA_DETERMINISTIC_RENDERING = "skia-deterministic-rendering"; - static ARG_SKIA_DETERMINISTIC_RENDERING = "--skia-deterministic-rendering"; - static ARG_KEY_TRACE_SKIA = "trace-skia"; - static ARG_TRACE_SKIA = "--trace-skia"; - static ARG_KEY_TRACE_SKIA_ALLOWLIST = "trace-skia-allowlist"; - static ARG_TRACE_SKIA_ALLOWLIST = "--trace-skia-allowlist="; - static ARG_KEY_TRACE_SYSTRACE = "trace-systrace"; - static ARG_TRACE_SYSTRACE = "--trace-systrace"; - static ARG_KEY_ENABLE_IMPELLER = "enable-impeller"; - static ARG_ENABLE_IMPELLER = "--enable-impeller"; - static ARG_KEY_DUMP_SHADER_SKP_ON_SHADER_COMPILATION = - "dump-skp-on-shader-compilation"; - static ARG_DUMP_SHADER_SKP_ON_SHADER_COMPILATION = - "--dump-skp-on-shader-compilation"; - static ARG_KEY_CACHE_SKSL = "cache-sksl"; - static ARG_CACHE_SKSL = "--cache-sksl"; - static ARG_KEY_PURGE_PERSISTENT_CACHE = "purge-persistent-cache"; - static ARG_PURGE_PERSISTENT_CACHE = "--purge-persistent-cache"; - static ARG_KEY_VERBOSE_LOGGING = "verbose-logging"; - static ARG_VERBOSE_LOGGING = "--verbose-logging"; - static ARG_KEY_OBSERVATORY_PORT = "observatory-port"; - static ARG_OBSERVATORY_PORT = "--observatory-port="; - static ARG_KEY_DART_FLAGS = "dart-flags"; - static ARG_DART_FLAGS = "--dart-flags="; - static ARG_KEY_MSAA_SAMPLES = "msaa-samples"; - static ARG_MSAA_SAMPLES = "--msaa-samples="; - - /** - * Parses arguments from a Want object and creates a FlutterShellArgs instance. - * @param want - The Want object containing the parameters - * @returns A FlutterShellArgs instance with parsed arguments - */ - static fromWant(want: Want): FlutterShellArgs { - let flutterShellArgs: FlutterShellArgs = new FlutterShellArgs(); - FlutterShellArgs.checkArg(FlutterShellArgs.ARG_KEY_TRACE_STARTUP, FlutterShellArgs.ARG_TRACE_STARTUP, want, - flutterShellArgs); - FlutterShellArgs.checkArg(FlutterShellArgs.ARG_KEY_START_PAUSED, FlutterShellArgs.ARG_START_PAUSED, want, - flutterShellArgs); - FlutterShellArgs.checkArg(FlutterShellArgs.ARG_KEY_DISABLE_SERVICE_AUTH_CODES, - FlutterShellArgs.ARG_DISABLE_SERVICE_AUTH_CODES, want, flutterShellArgs); - FlutterShellArgs.checkArg(FlutterShellArgs.ARG_KEY_ENDLESS_TRACE_BUFFER, FlutterShellArgs.ARG_ENDLESS_TRACE_BUFFER, - want, flutterShellArgs); - FlutterShellArgs.checkArg(FlutterShellArgs.ARG_KEY_USE_TEST_FONTS, FlutterShellArgs.ARG_USE_TEST_FONTS, want, - flutterShellArgs); - FlutterShellArgs.checkArg(FlutterShellArgs.ARG_KEY_ENABLE_DART_PROFILING, - FlutterShellArgs.ARG_ENABLE_DART_PROFILING, want, flutterShellArgs); - FlutterShellArgs.checkArg(FlutterShellArgs.ARG_KEY_ENABLE_SOFTWARE_RENDERING, - FlutterShellArgs.ARG_ENABLE_SOFTWARE_RENDERING, want, flutterShellArgs); - FlutterShellArgs.checkArg(FlutterShellArgs.ARG_KEY_SKIA_DETERMINISTIC_RENDERING, - FlutterShellArgs.ARG_SKIA_DETERMINISTIC_RENDERING, want, flutterShellArgs); - FlutterShellArgs.checkArg(FlutterShellArgs.ARG_KEY_TRACE_SKIA, FlutterShellArgs.ARG_TRACE_SKIA, want, - flutterShellArgs); - FlutterShellArgs.checkArg(FlutterShellArgs.ARG_KEY_TRACE_SYSTRACE, FlutterShellArgs.ARG_TRACE_SYSTRACE, want, - flutterShellArgs); - FlutterShellArgs.checkArg(FlutterShellArgs.ARG_KEY_ENABLE_IMPELLER, FlutterShellArgs.ARG_ENABLE_IMPELLER, want, - flutterShellArgs); - FlutterShellArgs.checkArg(FlutterShellArgs.ARG_KEY_DUMP_SHADER_SKP_ON_SHADER_COMPILATION, - FlutterShellArgs.ARG_DUMP_SHADER_SKP_ON_SHADER_COMPILATION, want, flutterShellArgs); - FlutterShellArgs.checkArg(FlutterShellArgs.ARG_KEY_CACHE_SKSL, FlutterShellArgs.ARG_CACHE_SKSL, want, - flutterShellArgs); - FlutterShellArgs.checkArg(FlutterShellArgs.ARG_KEY_PURGE_PERSISTENT_CACHE, - FlutterShellArgs.ARG_PURGE_PERSISTENT_CACHE, want, flutterShellArgs); - FlutterShellArgs.checkArg(FlutterShellArgs.ARG_KEY_VERBOSE_LOGGING, FlutterShellArgs.ARG_VERBOSE_LOGGING, want, - flutterShellArgs); - - let skia_allow_list: Object = want.parameters![FlutterShellArgs.ARG_KEY_TRACE_SKIA_ALLOWLIST]; - if (skia_allow_list != undefined) { - flutterShellArgs.add(FlutterShellArgs.ARG_TRACE_SKIA_ALLOWLIST + (skia_allow_list as string)); - } - - let observatory_port: Object = want.parameters![FlutterShellArgs.ARG_KEY_OBSERVATORY_PORT]; - if (observatory_port != undefined && (observatory_port as number > 0)) { - flutterShellArgs.add(FlutterShellArgs.ARG_OBSERVATORY_PORT + (observatory_port as number)); - } - - let msaa: Object = want.parameters![FlutterShellArgs.ARG_KEY_MSAA_SAMPLES]; - if (msaa != undefined && (msaa as number > 1)) { - flutterShellArgs.add(FlutterShellArgs.ARG_MSAA_SAMPLES + (msaa as number)); - } - - let dart_flags: Object = want.parameters![FlutterShellArgs.ARG_KEY_DART_FLAGS]; - if (dart_flags != undefined) { - flutterShellArgs.add(FlutterShellArgs.ARG_DART_FLAGS + (msaa as string)); - } - return flutterShellArgs; - } - - /** - * Checks if an argument exists in the Want parameters and adds it to FlutterShellArgs if present. - * @param argKey - The key to look for in the Want parameters - * @param argFlag - The command-line flag to add if the argument is present - * @param want - The Want object containing the parameters - * @param flutterShellArgs - The FlutterShellArgs instance to add the flag to - */ - static checkArg(argKey: string, argFlag: string, want: Want, flutterShellArgs: FlutterShellArgs) { - if (want.parameters == undefined) { - return; - } - let value: Object = want.parameters![argKey]; - if (value != undefined && value as Boolean) { - flutterShellArgs.add(argFlag); - } - } - - /** Command-line arguments for the Flutter shell. */ - args: Set = new Set(); - - /** - * Adds an argument to the set of shell arguments. - * @param arg - The argument string to add - */ - add(arg: string) { - this.args.add(arg); - } - - /** - * Removes an argument from the set of shell arguments. - * @param arg - The argument string to remove - */ - remove(arg: string) { - this.args.delete(arg); - } - - /** - * Converts the set of arguments to an array. - * @returns An array containing all shell arguments - */ - toArray(): Array { - return Array.from(this.args); - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/DartExecutor.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/DartExecutor.ets deleted file mode 100644 index 89824a2..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/DartExecutor.ets +++ /dev/null @@ -1,426 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on DartExecutor.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ -import resourceManager from '@ohos.resourceManager'; -import FlutterInjector from '../../../FlutterInjector'; -import { BinaryMessageHandler, BinaryReply, TaskQueue, TaskQueueOptions } from '../../../plugin/common/BinaryMessenger'; -import { BinaryMessenger } from '../../../plugin/common/BinaryMessenger'; -import StringCodec from '../../../plugin/common/StringCodec'; -import Log from '../../../util/Log'; -import { TraceSection } from '../../../util/TraceSection'; -import { FlutterCallbackInformation } from '../../../view/FlutterCallbackInformation'; -import FlutterNapi from '../FlutterNapi'; -import { DartMessenger } from './DartMessenger'; -import SendableBinaryMessageHandler from '../../../plugin/common/SendableBinaryMessageHandler' - - -const TAG = "DartExecutor"; - -/** - * Configures, bootstraps, and starts executing Dart code. - * - * To specify a top-level Dart function to execute, use a {@link DartEntrypoint} to tell - * DartExecutor where to find the Dart code to execute, and which Dart function to use as the - * entrypoint. To execute the entrypoint, pass the {@link DartEntrypoint} to - * {@link executeDartEntrypoint}. - * - * To specify a Dart callback to execute, use a {@link DartCallback}. A given Dart callback must - * be registered with the Dart VM to be invoked by a DartExecutor. To execute the callback, - * pass the {@link DartCallback} to {@link executeDartCallback}. - * - * Once started, a DartExecutor cannot be stopped. The associated Dart code will execute - * until it completes, or until the {@link FlutterEngine} that owns this - * DartExecutor is destroyed. - */ -export default class DartExecutor implements BinaryMessenger { - /** The FlutterNapi instance for native communication. */ - flutterNapi: FlutterNapi; - /** The resource manager for accessing application assets. */ - assetManager: resourceManager.ResourceManager; - private dartMessenger: DartMessenger; - private binaryMessenger: BinaryMessenger; - private isApplicationRunning: boolean = false; - private isolateServiceId: String = ""; - private isolateServiceIdListener: IsolateServiceIdListener | null = null; - private isolateChannelMessageHandler: BinaryMessageHandler = - new IsolateChannelMessageHandler(this.isolateServiceId, this.isolateServiceIdListener); - - /** - * Constructs a new DartExecutor instance. - * @param flutterNapi - The FlutterNapi instance for native communication - * @param assetManager - The resource manager for accessing assets - */ - constructor(flutterNapi: FlutterNapi, assetManager: resourceManager.ResourceManager) { - this.flutterNapi = flutterNapi; - this.assetManager = assetManager; - this.dartMessenger = new DartMessenger(flutterNapi); - this.dartMessenger.setMessageHandler("flutter/isolate", this.isolateChannelMessageHandler); - this.binaryMessenger = new DefaultBinaryMessenger(this.dartMessenger); - // The NAPI might already be attached if coming from a spawned engine. If so, correctly report - // that this DartExecutor is already running. - if (flutterNapi.isRunningDart) { - this.isApplicationRunning = true; - } - } - - /** - * Invoked when the FlutterEngine that owns this DartExecutor attaches to NAPI. - * - * When attached to NAPI, this DartExecutor begins handling 2-way communication to/from - * the Dart execution context. This communication is facilitated via 2 APIs: - * BinaryMessenger, which sends messages to Dart - * PlatformMessageHandler, which receives messages from Dart - */ - onAttachedToNAPI(): void { - Log.d(TAG, "Attached to NAPI. Registering the platform message handler for this Dart execution context."); - this.flutterNapi.setPlatformMessageHandler(this.dartMessenger); - } - - /** - * Invoked when the FlutterEngine that owns this DartExecutor detaches from NAPI. - * - * When detached from NAPI, this DartExecutor stops handling 2-way communication to/from - * the Dart execution context. - */ - onDetachedFromNAPI(): void { - Log.d(TAG, "Detached from NAPI. De-registering the platform message handler for this Dart execution context."); - this.flutterNapi.setPlatformMessageHandler(null); - } - - /** - * Checks if this DartExecutor is currently executing Dart code. - * - * @returns True if Dart code is being executed, false otherwise - */ - isExecutingDart(): boolean { - return this.isApplicationRunning; - } - - /** - * Starts executing Dart code based on the given dartEntrypoint and the dartEntrypointArgs. - * - * See DartEntrypoint for configuration options. - * - * @param dartEntrypoint - Specifies which Dart function to run, and where to find it - * @param dartEntrypointArgs - Arguments passed as a list of strings to Dart's entrypoint function - */ - executeDartEntrypoint(dartEntrypoint: DartEntrypoint, dartEntrypointArgs?: string[]): void { - if (this.isApplicationRunning) { - Log.w(TAG, "Attempted to run a DartExecutor that is already running."); - return; - } - - let traceId: number = TraceSection.begin("DartExecutor#executeDartEntrypoint"); - try { - Log.d(TAG, "Executing Dart entrypoint: " + dartEntrypoint); - this.flutterNapi.runBundleAndSnapshotFromLibrary( - dartEntrypoint.pathToBundle, - dartEntrypoint.dartEntrypointFunctionName, - dartEntrypoint.dartEntrypointLibrary, - this.assetManager, - dartEntrypointArgs ?? []); - - this.isApplicationRunning = true; - } finally { - TraceSection.endWithId("DartExecutor#executeDartEntrypoint", traceId); - } - } - - /** - * Starts executing Dart code based on the given dartCallback. - * - * See DartCallback for configuration options. - * - * @param dartCallback - Specifies which Dart callback to run, and where to find it - */ - executeDartCallback(dartCallback: DartCallback): void { - if (this.isApplicationRunning) { - Log.w(TAG, "Attempted to run a DartExecutor that is already running."); - return; - } - - let traceId: number = TraceSection.begin("DartExecutor#executeDartCallback"); - try { - Log.d(TAG, "Executing Dart callback: " + dartCallback); - this.flutterNapi.runBundleAndSnapshotFromLibrary( - dartCallback.pathToBundle, - dartCallback.callbackHandle.callbackName, - dartCallback.callbackHandle.callbackLibraryPath, - dartCallback.resourceManager, - []); - - this.isApplicationRunning = true; - } finally { - TraceSection.endWithId("DartExecutor#executeDartCallback", traceId); - } - } - - /** - * Gets a BinaryMessenger that can be used to send messages to, and receive messages - * from, Dart code that this DartExecutor is executing. - * @returns The BinaryMessenger instance - */ - getBinaryMessenger(): BinaryMessenger { - return this.binaryMessenger; - } - - /** - * Creates a background task queue for handling messages asynchronously. - * @param options - Optional task queue configuration options - * @returns A TaskQueue instance for background message processing - */ - makeBackgroundTaskQueue(options?: TaskQueueOptions): TaskQueue { - return this.getBinaryMessenger().makeBackgroundTaskQueue(options); - } - - - /** - * Sends a binary message to Dart over the specified channel. - * @param channel - The channel name for the message - * @param message - The message data as an ArrayBuffer - * @param callback - Optional callback to receive the reply from Dart - */ - send(channel: String, message: ArrayBuffer, callback?: BinaryReply): void { - this.getBinaryMessenger().send(channel, message, callback); - } - - /** - * Sets a message handler for incoming messages from Dart on the specified channel. - * @param channel - The channel name to listen on - * @param handler - The message handler, or null to remove the handler - * @param taskQueue - Optional task queue for processing messages - * @param args - Additional arguments to pass to the handler - */ - setMessageHandler(channel: String, handler: BinaryMessageHandler | SendableBinaryMessageHandler | null, - taskQueue?: TaskQueue, ...args: Object[]): void { - this.getBinaryMessenger().setMessageHandler(channel, handler, taskQueue, ...args); - } - - /** - * Gets the number of pending channel callback replies. - * When sending messages with reply callbacks, this tracks how many are still waiting for responses. - * Must be called from the main thread. - * Mainly useful for testing frameworks to determine if the app is idle. - * @returns The number of pending channel callback replies - */ - getPendingChannelResponseCount(): number { - return this.dartMessenger.getPendingChannelResponseCount(); - } - - /** - * Gets an identifier for this executor's primary isolate. This identifier can be used in - * queries to the Dart service protocol. - * @returns The isolate service ID - */ - getIsolateServiceId(): String { - return this.isolateServiceId; - } - - - /** - * Sets a listener that will be notified when an isolate identifier is available for this - * executor's primary isolate. - * @param listener - The listener to be notified when the isolate service ID is available - */ - setIsolateServiceIdListener(listener: IsolateServiceIdListener): void { - this.isolateServiceIdListener = listener; - if (this.isolateServiceIdListener != null && this.isolateServiceId != null) { - this.isolateServiceIdListener.onIsolateServiceIdAvailable(this.isolateServiceId); - } - } - - /** - * Notifies the Dart VM of a low memory event. - * This allows the Dart VM to free resources, but does not notify the Flutter application. - * To notify the Flutter application, use SystemChannel.sendMemoryPressureWarning(). - * - * Note: Calling this method may cause performance issues. Avoid calling during startup or animations. - */ - notifyLowMemoryWarning(): void { - if (this.flutterNapi.isAttached()) { - this.flutterNapi.notifyLowMemoryWarning(); - } - } -} - - -/** - * Configuration options that specify which Dart entrypoint function is executed and where to find - * that entrypoint and other assets required for Dart execution. - */ -export class DartEntrypoint { - /** The path within the ResourceManager where the app will look for assets. */ - pathToBundle: string; - /** The library or file location that contains the Dart entrypoint function. */ - dartEntrypointLibrary: string; - /** The name of a Dart function to execute. */ - dartEntrypointFunctionName: string; - - /** - * Constructs a new DartEntrypoint instance. - * @param pathToBundle - The path within the AssetManager where the app will look for assets - * @param dartEntrypointLibrary - The library or file location that contains the Dart entrypoint function - * @param dartEntrypointFunctionName - The name of a Dart function to execute - */ - constructor(pathToBundle: string, - dartEntrypointLibrary: string, - dartEntrypointFunctionName: string) { - this.pathToBundle = pathToBundle; - this.dartEntrypointLibrary = dartEntrypointLibrary; - this.dartEntrypointFunctionName = dartEntrypointFunctionName; - } - - /** - * Creates a default DartEntrypoint using the main function. - * @returns A DartEntrypoint configured with the default main entrypoint - * @throws Error if FlutterLoader is not initialized - */ - static createDefault() { - const flutterLoader = FlutterInjector.getInstance().getFlutterLoader(); - if (!flutterLoader.initialized) { - throw new Error( - "DartEntrypoints can only be created once a FlutterEngine is created."); - } - return new DartEntrypoint(flutterLoader.findAppBundlePath(), "", "main"); - } -} - - -/** - * Callback interface invoked when the isolate identifier becomes available. - */ -interface IsolateServiceIdListener { - /** - * Called when the isolate service ID becomes available. - * @param isolateServiceId - The isolate service ID - */ - onIsolateServiceIdAvailable(isolateServiceId: String): void; -} - - -/** - * Configuration options that specify which Dart callback function is executed and where to find - * that callback and other assets required for Dart execution. - */ -export class DartCallback { - /** Standard OpenHarmony ResourceManager for accessing assets. */ - public resourceManager: resourceManager.ResourceManager; - /** The path within the ResourceManager where the app will look for assets. */ - public pathToBundle: string; - /** A Dart callback that was previously registered with the Dart VM. */ - public callbackHandle: FlutterCallbackInformation; - - /** - * Constructs a new DartCallback instance. - * @param resourceManager - Standard OpenHarmony ResourceManager - * @param pathToBundle - The path within the ResourceManager where the app will look for assets - * @param callbackHandle - A Dart callback that was previously registered with the Dart VM - */ - constructor(resourceManager: resourceManager.ResourceManager, - pathToBundle: string, - callbackHandle: FlutterCallbackInformation) { - this.resourceManager = resourceManager; - this.pathToBundle = pathToBundle; - this.callbackHandle = callbackHandle; - } - - /** - * Returns a string representation of this DartCallback. - * @returns A string describing the callback's bundle path, library path, and function name - */ - toString(): String { - return "DartCallback( bundle path: " - + this.pathToBundle - + ", library path: " - + this.callbackHandle.callbackLibraryPath - + ", function: " - + this.callbackHandle.callbackName - + " )"; - } -} - -/** - * Default implementation of BinaryMessenger that delegates to DartMessenger. - */ -export class DefaultBinaryMessenger implements BinaryMessenger { - private messenger: DartMessenger; - - /** - * Constructs a new DefaultBinaryMessenger instance. - * @param messenger - The DartMessenger instance to delegate to - */ - constructor(messenger: DartMessenger) { - this.messenger = messenger; - } - - /** - * Creates a background task queue for handling messages asynchronously. - * @param options - Optional task queue configuration options - * @returns A TaskQueue instance for background message processing - */ - makeBackgroundTaskQueue(options?: TaskQueueOptions): TaskQueue { - return this.messenger.makeBackgroundTaskQueue(options); - } - - /** - * Sends a message from OpenHarmony to Dart over the given channel and then - * has the provided callback invoked when the Dart side responds. - * - * @param channel - The name of the logical channel used for the message - * @param message - The message payload as an ArrayBuffer, or null for an empty message - * @param callback - A callback invoked when the Dart application responds to the message - */ - send(channel: String, message: ArrayBuffer, callback?: BinaryReply): void { - this.messenger.send(channel, message, callback); - } - - /** - * Sets the given BinaryMessageHandler as the singular handler for all incoming messages - * received from the Dart side of this Dart execution context. - * - * @param channel - The name of the channel - * @param handler - A BinaryMessageHandler to be invoked on incoming messages, or null - * @param taskQueue - Optional task queue for processing messages - * @param args - Additional arguments to pass to the handler - */ - setMessageHandler(channel: String, handler: BinaryMessageHandler | SendableBinaryMessageHandler | null, - taskQueue?: TaskQueue, ...args: Object[]): void { - this.messenger.setMessageHandler(channel, handler, taskQueue, ...args); - } -} - -/** - * Message handler for the isolate channel that receives isolate service IDs. - */ -class IsolateChannelMessageHandler implements BinaryMessageHandler { - private isolateServiceId: String; - private isolateServiceIdListener: IsolateServiceIdListener | null = null; - - /** - * Constructs a new IsolateChannelMessageHandler instance. - * @param isolateServiceId - The isolate service ID - * @param isolateServiceIdListener - Optional listener to be notified when the ID is available - */ - constructor(isolateServiceId: String, isolateServiceIdListener: IsolateServiceIdListener | null) { - this.isolateServiceId = isolateServiceId; - this.isolateServiceIdListener = isolateServiceIdListener; - } - - /** - * Handles a message received on the isolate channel. - * @param message - The message containing the isolate service ID - * @param callback - The reply callback - */ - onMessage(message: ArrayBuffer, callback: BinaryReply): void { - this.isolateServiceId = StringCodec.INSTANCE.decodeMessage(message); - if (this.isolateServiceIdListener != null) { - this.isolateServiceIdListener.onIsolateServiceIdAvailable(this.isolateServiceId); - } - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/DartMessenger.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/DartMessenger.ets deleted file mode 100644 index e85ef1c..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/DartMessenger.ets +++ /dev/null @@ -1,516 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on DartMessenger.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ -import { ErrorEvent, Queue, taskpool, worker, MessageEvents, JSON } from '@kit.ArkTS'; - -import Log from '../../../util/Log'; -import { - BinaryMessageHandler, - BinaryMessenger, - BinaryReply, - TaskPriority, - TaskQueue, - TaskQueueOptions -} from '../../../plugin/common/BinaryMessenger'; -import FlutterNapi from '../FlutterNapi'; -import { PlatformMessageHandler } from './PlatformMessageHandler'; -import { TraceSection } from '../../../util/TraceSection'; -import SendableBinaryMessageHandler from '../../../plugin/common/SendableBinaryMessageHandler' - -/** - * Message conduit for 2-way communication between OpenHarmony and Dart. - * - * See {@link BinaryMessenger}, which sends messages from OpenHarmony to Dart - * - * See {@link PlatformMessageHandler}, which handles messages to OpenHarmony from Dart - */ - -const TAG = "DartMessenger"; - -export class DartMessenger implements BinaryMessenger, PlatformMessageHandler { - /** The FlutterNapi instance for native communication. */ - flutterNapi: FlutterNapi; - /** Map of channel names to their message handlers. */ - messageHandlers: Map = new Map(); - /** Map of reply IDs to their callback functions waiting for responses. */ - pendingReplies: Map = new Map(); - /** The next reply ID to use for message callbacks. */ - nextReplyId: number = 1; - /** Factory for creating task queues for background message processing. */ - taskQueueFactory: TaskQueueFactory; - /** Map of TaskQueue tokens to their actual task queue implementations. */ - createdTaskQueues: Map = new Map(); - - /** - * Constructs a new DartMessenger instance. - * @param flutterNapi - The FlutterNapi instance for native communication - */ - constructor(flutterNapi: FlutterNapi) { - this.flutterNapi = flutterNapi; - this.taskQueueFactory = new DefaultTaskQueueFactory(); - } - - /** - * Creates a background task queue for handling messages asynchronously. - * @param options - Optional task queue configuration options - * @returns A TaskQueue instance for background message processing - */ - makeBackgroundTaskQueue(options?: TaskQueueOptions): TaskQueue { - let taskQueue: DartMessengerTaskQueue = - this.taskQueueFactory.makeBackgroundTaskQueue(options ?? new TaskQueueOptions()); - let token: TaskQueueToken = new TaskQueueToken(); - this.createdTaskQueues.set(token, taskQueue); - return token; - } - - /** - * Sets a message handler for incoming messages from Dart on the specified channel. - * @param channel - The channel name to listen on - * @param handler - The message handler, or null to remove the handler - * @param taskQueue - Optional task queue for processing messages - * @param args - Additional arguments to pass to the handler - */ - setMessageHandler(channel: String, handler: BinaryMessageHandler | SendableBinaryMessageHandler | null, - taskQueue?: TaskQueue, ...args: Object[]): void { - if (handler == null) { - Log.d(TAG, "Removing handler for channel '" + channel + "'"); - this.messageHandlers.delete(channel); - return; - } - let dartMessengerTaskQueue: DartMessengerTaskQueue | null = null; - if (taskQueue !== null && taskQueue !== undefined) { - dartMessengerTaskQueue = this.createdTaskQueues.get(taskQueue) ?? null; - if (dartMessengerTaskQueue == null) { - throw new Error( - "Unrecognized TaskQueue, use BinaryMessenger to create your TaskQueue (ex makeBackgroundTaskQueue)." - ); - } - } - Log.d(TAG, "Setting handler for channel '" + channel + "'"); - - this.messageHandlers.set(channel, new HandlerInfo(handler, dartMessengerTaskQueue, ...args)); - } - - /** - * Sends a binary message to Dart over the specified channel. - * @param channel - The channel name for the message - * @param message - The message data as an ArrayBuffer, or null for an empty message - * @param callback - Optional callback to receive the reply from Dart - */ - send(channel: String, message: ArrayBuffer, callback?: BinaryReply): void { - Log.d(TAG, "Sending message over channel '" + channel + "'"); - let traceId: number = TraceSection.begin("DartMessenger#send on " + channel); - try { - Log.d(TAG, "Sending message with callback over channel '" + channel + "'"); - let replyId: number = this.nextReplyId++; - if (callback != null) { - this.pendingReplies.set(replyId, callback); - } - if (message == null) { - this.flutterNapi.dispatchEmptyPlatformMessage(channel, replyId); - } else { - this.flutterNapi.dispatchPlatformMessage(channel, message, message.byteLength, replyId); - } - } finally { - TraceSection.endWithId("DartMessenger#send on " + channel, traceId); - } - this.IsFlutterNavigationExecuted(channel); - } - - /** - * Dispatches a message to a task queue for asynchronous processing. - * @param handlerInfo - The handler information containing the handler and task queue - * @param message - The message data as an ArrayBuffer - * @param replyId - The reply ID for responding to the message - */ - dispatchMessageToQueue(handlerInfo: HandlerInfo, message: ArrayBuffer, replyId: number): void { - let taskState: TaskState = new TaskState(handlerInfo.handler as ESObject, message, ...handlerInfo.args); - handlerInfo.taskQueue?.dispatch(taskState, new Reply(this.flutterNapi, replyId)); - } - - /** - * Invokes a message handler synchronously. - * @param handler - The message handler to invoke, or null if no handler is registered - * @param message - The message data as an ArrayBuffer - * @param replyId - The reply ID for responding to the message - */ - invokeHandler(handler: BinaryMessageHandler | null, message: ArrayBuffer, replyId: number): void { - if (handler != null) { - try { - Log.d(TAG, "Deferring to registered handler to process message."); - handler.onMessage(message, new Reply(this.flutterNapi, replyId)); - } catch (ex) { - Log.e(TAG, "Uncaught exception in binary message listener", ex); - this.flutterNapi.invokePlatformMessageEmptyResponseCallback(replyId); - } - } else { - Log.d(TAG, "No registered handler for message. Responding to Dart with empty reply message."); - this.flutterNapi.invokePlatformMessageEmptyResponseCallback(replyId); - } - } - - /** - * Handles a message received from Dart over a specific channel. - * @param channel - The channel name for the message - * @param message - The message data as an ArrayBuffer - * @param replyId - The reply ID for responding to the message - * @param messageData - Additional message data - */ - handleMessageFromDart(channel: String, message: ArrayBuffer, replyId: number, messageData: number): void { - Log.d(TAG, "Received message from Dart over channel '" + channel + "'"); - let handlerInfo: HandlerInfo | null = this.messageHandlers.get(channel) ?? null; - if (handlerInfo?.taskQueue != null) { - this.dispatchMessageToQueue(handlerInfo, message, replyId); - } else { - this.invokeHandler(handlerInfo?.handler as BinaryMessageHandler, message, replyId); - } - this.IsFlutterNavigationExecuted(channel); - } - - /** - * Handles a platform message response from Dart. - * @param replyId - The reply ID that was sent with the original message - * @param reply - The reply data as an ArrayBuffer - */ - handlePlatformMessageResponse(replyId: number, reply: ArrayBuffer): void { - Log.d(TAG, "Received message reply from Dart."); - let callback: BinaryReply | null = this.pendingReplies.get(replyId) ?? null; - this.pendingReplies.delete(replyId); - if (callback != null) { - try { - Log.d(TAG, "Invoking registered callback for reply from Dart."); - callback.reply(reply); - } catch (e) { - Log.e(TAG, "Uncaught exception in binary message reply handler", e); - } - } - } - - /** - * Returns the number of pending channel callback replies. - * - * When sending messages to the Flutter application using BinaryMessenger.send, - * developers can optionally specify a reply callback if they expect a reply from the Flutter application. - * - * This method tracks all the pending callbacks that are waiting for response, and is supposed - * to be called from the main thread (as other methods). Calling from a different thread could - * possibly capture an indeterministic internal state, so don't do it. - * @returns The number of pending channel callback replies - */ - getPendingChannelResponseCount(): number { - return this.pendingReplies.size; - } - - /** - * Checks if the current Flutter page is performing navigation and notifies the native side. - * @param channel - The channel name to check - */ - IsFlutterNavigationExecuted(channel: String): void { - if (channel == "flutter/navigation") { - this.flutterNapi.setFlutterNavigationAction(this.flutterNapi.nativeShellHolderId!, true); - Log.d(TAG, "setFlutterNavigationAction -> '" + channel + "'"); - } - } -} - -/** - * Holds information about a platform handler, such as the task queue that processes messages from - * Dart. - */ -class HandlerInfo { - handler: BinaryMessageHandler | SendableBinaryMessageHandler; - taskQueue: DartMessengerTaskQueue | null; - args: Object[]; - - /** - * Constructs a new HandlerInfo instance. - * @param handler - The message handler - * @param taskQueue - The task queue for processing messages, or null for synchronous processing - * @param args - Additional arguments to pass to the handler - */ - constructor(handler: BinaryMessageHandler | SendableBinaryMessageHandler, - taskQueue: DartMessengerTaskQueue | null, - ...args: Object[]) { - this.handler = handler; - this.taskQueue = taskQueue; - this.args = args; - } -} - -/** - * Implementation of BinaryReply that sends replies back to Dart. - */ -class Reply implements BinaryReply { - flutterNapi: FlutterNapi; - replyId: number; - done: boolean = false; - - /** - * Constructs a new Reply instance. - * @param flutterNapi - The FlutterNapi instance for sending replies - * @param replyId - The reply ID for this reply - */ - constructor(flutterNapi: FlutterNapi, replyId: number) { - this.flutterNapi = flutterNapi; - this.replyId = replyId; - } - - /** - * Sends a reply back to Dart. - * @param reply - The reply data as an ArrayBuffer, or null for an empty reply - * @throws Error if reply has already been submitted - */ - reply(reply: ArrayBuffer | null) { - if (this.done) { - throw new Error("Reply already submitted"); - } - - if (reply == null) { - this.flutterNapi.invokePlatformMessageEmptyResponseCallback(this.replyId); - } else { - this.flutterNapi.invokePlatformMessageResponseCallback(this.replyId, reply, reply.byteLength); - } - } -} - -/** - * Represents the state of a task to be executed in a background task queue. - */ -export class TaskState { - /** The message handler to execute. */ - handler: SendableBinaryMessageHandler; - /** The message data as an ArrayBuffer. */ - message: ArrayBuffer; - /** Additional arguments to pass to the handler. */ - args: Object[]; - - /** - * Constructs a new TaskState instance. - * @param handler - The message handler to execute - * @param message - The message data as an ArrayBuffer - * @param args - Additional arguments to pass to the handler - */ - constructor(handler: SendableBinaryMessageHandler, message: ArrayBuffer, ...args: Object[]) { - this.handler = handler; - this.message = message; - this.args = args; - } -} - -/** - * Interface for task queues that process messages asynchronously. - */ -interface DartMessengerTaskQueue { - /** - * Dispatches a task to be executed in the task queue. - * @param taskState - The task state containing the handler and message - * @param callback - The reply callback for sending responses - */ - dispatch(taskState: TaskState, callback: Reply): void; -} - -/** - * Interface for serial task queues that process messages sequentially. - */ -interface SerialTaskQueue extends DartMessengerTaskQueue { -} - -/** - * Factory interface for creating task queues. - */ -interface TaskQueueFactory { - /** - * Creates a background task queue with the specified options. - * @param options - Task queue configuration options - * @returns A DartMessengerTaskQueue instance - */ - makeBackgroundTaskQueue(options: TaskQueueOptions): DartMessengerTaskQueue; -} - -/** - * Task queue that processes messages concurrently. - */ -class ConcurrentTaskQueue implements DartMessengerTaskQueue { - private priority: TaskPriority; - - /** - * Constructs a new ConcurrentTaskQueue instance. - * @param priority - The priority level for task execution - */ - constructor(priority: TaskPriority) { - this.priority = priority; - } - - /** - * Dispatches a task to be executed concurrently. - * @param taskState - The task state containing the handler and message - * @param callback - The reply callback for sending responses - */ - dispatch(taskState: TaskState, callback: Reply): void { - let task: taskpool.Task = new taskpool.Task(handleMessageInBackground, - taskState.handler, - taskState.message, - ...taskState.args); - taskpool.execute(task, this.priority as number).then((result: Object) => { - callback.reply(result as ArrayBuffer); - }).catch((err: string) => { - callback.reply(null); - Log.e(TAG, "Oops! Failed to execute task: ", err); - }); - } -} - -const scriptURL: string = '../workers/PlatformChannelWorker.ets'; -/** - * Task queue that processes messages serially using a worker thread. - */ -class SerialTaskQueueWithWorker implements SerialTaskQueue { - private static workerInstance: worker.ThreadWorker | null = null; - - /** - * Constructs a new SerialTaskQueueWithWorker instance. - * Creates a singleton worker instance if one doesn't exist. - */ - constructor () { - if (!SerialTaskQueueWithWorker.workerInstance) { - SerialTaskQueueWithWorker.workerInstance = - new worker.ThreadWorker(scriptURL, {name: 'PlatformChannelWorker'}); - } - } - - /** - * Dispatches a task to be executed serially in the worker thread. - * @param taskState - The task state containing the handler and message - * @param callback - The reply callback for sending responses - */ - dispatch(taskState: TaskState, callback: Reply): void { - SerialTaskQueueWithWorker.workerInstance!.onmessage = (e: MessageEvents): void => { - callback.reply(e.data as ArrayBuffer); - } - - SerialTaskQueueWithWorker.workerInstance!.onerror = (err: ErrorEvent) => { - callback.reply(null); - Log.e(TAG, "Oops! Failed to execute task in worker thread: ", err.message); - } - - SerialTaskQueueWithWorker.workerInstance!.postMessageWithSharedSendable(taskState, [taskState.message]); - } -} - -type Runnable = () => Promise; -/** - * Task queue that processes messages serially using a task pool. - */ -class SerialTaskQueueWithTaskPool implements SerialTaskQueue { - private priority: TaskPriority; - private queue: Queue = new Queue(); - private isRunning: boolean = false; - - /** - * Constructs a new SerialTaskQueueWithTaskPool instance. - * @param priority - The priority level for task execution - */ - constructor(priority: TaskPriority) { - this.priority = priority; - } - - /** - * Dispatches a task to be executed serially in the task pool. - * @param taskState - The task state containing the handler and message - * @param callback - The reply callback for sending responses - */ - dispatch(taskState: TaskState, callback: Reply): void { - let task: taskpool.Task = new taskpool.Task(handleMessageInBackground, - taskState.handler, - taskState.message, - ...taskState.args); - const runnable: Runnable = async () => { - try { - const result = await taskpool.execute(task, this.priority as number); - callback.reply(result as ArrayBuffer); - } catch (err) { - callback.reply(null); - Log.e(TAG, "Oops! Failed to execute task: ", err); - } - }; - - this.queue.add(runnable); - - if (!this.isRunning) { - this.runNext(); - } - } - - private async runNext(): Promise { - if (this.queue.length > 0) { - this.isRunning = true; - const task = this.queue.pop(); - try { - await task(); - } finally { - this.isRunning = false; - this.runNext(); // 执行下一个任务 - } - } - } -} - -/** - * Default implementation of TaskQueueFactory. - */ -class DefaultTaskQueueFactory implements TaskQueueFactory { - /** - * Creates a background task queue based on the provided options. - * @param options - Task queue configuration options - * @returns A DartMessengerTaskQueue instance (serial or concurrent) - */ - makeBackgroundTaskQueue(options: TaskQueueOptions): DartMessengerTaskQueue { - if (options.isSingleThreadMode()) { - return new SerialTaskQueueWithWorker(); - } else { - if (options.getIsSerial()) { - return new SerialTaskQueueWithTaskPool(options.getPriority()); - } - return new ConcurrentTaskQueue(options.getPriority()); - } - } -} - -/** - * Token implementation of TaskQueue used to identify task queues. - */ -class TaskQueueToken implements TaskQueue { -} - -/** - * Handles a message in the background thread. - * This function is executed concurrently and processes messages asynchronously. - * @param handler - The message handler to execute - * @param message - The message data as an ArrayBuffer - * @param args - Additional arguments to pass to the handler - * @returns A promise that resolves to the reply ArrayBuffer, or null if no reply - */ -@Concurrent -async function handleMessageInBackground(handler: SendableBinaryMessageHandler, - message: ArrayBuffer, - ...args: Object[]): Promise { - const result = await new Promise((resolve, reject) => { - try { - handler.onMessage(message, { - reply: (reply: ArrayBuffer | null): void => { - resolve(reply); - } - }, ...args); - } catch (e) { - reject(null); - Log.e('WARNING', "Oops! Failed to handle message in the background: ", e); - } - }); - return result; -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/PlatformMessageHandler.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/PlatformMessageHandler.ets deleted file mode 100644 index 8d3cf70..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/PlatformMessageHandler.ets +++ /dev/null @@ -1,33 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on PlatformMessageHandler.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -/** - * Interface for handling platform messages from Dart. - * This interface provides methods to receive messages from the Dart side of the Flutter application. - */ -export interface PlatformMessageHandler { - - /** - * Handles a message received from Dart over a specific channel. - * @param channel - The channel name for the message - * @param message - The message data as an ArrayBuffer - * @param replyId - The reply ID for responding to the message - * @param messageData - Additional message data - */ - handleMessageFromDart(channel: String, message: ArrayBuffer, replyId: number, messageData: number): void; - - /** - * Handles a platform message response from Dart. - * @param replyId - The reply ID that was sent with the original message - * @param reply - The reply data as an ArrayBuffer - */ - handlePlatformMessageResponse(replyId: number, reply: ArrayBuffer): void; - -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/ApplicationInfoLoader.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/ApplicationInfoLoader.ets deleted file mode 100644 index 54e1d44..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/ApplicationInfoLoader.ets +++ /dev/null @@ -1,25 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import FlutterApplicationInfo from './FlutterApplicationInfo'; -import common from '@ohos.app.ability.common'; - -/** - * Loader for Flutter application information. - * This class provides a static method to load FlutterApplicationInfo from the application context. - */ -export default class ApplicationInfoLoader { - /** - * Loads FlutterApplicationInfo from the application context. - * @param context - The application context - * @returns A FlutterApplicationInfo instance with default or context-based values - */ - static load(context: common.Context) { - let applicationInfo = - new FlutterApplicationInfo(null, null, null, null, null, context.bundleCodeDir + '/libs/arm64', true); - return applicationInfo - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/FlutterApplicationInfo.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/FlutterApplicationInfo.ets deleted file mode 100644 index 1a3f9af..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/FlutterApplicationInfo.ets +++ /dev/null @@ -1,71 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on FlutterApplicationInfo.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import BuildProfile from "../../../../../../BuildProfile"; - -const DEFAULT_AOT_SHARED_LIBRARY_NAME = "libapp.so"; -const DEFAULT_VM_SNAPSHOT_DATA = "vm_snapshot_data"; -const DEFAULT_ISOLATE_SNAPSHOT_DATA = "isolate_snapshot_data"; -const DEFAULT_FLUTTER_ASSETS_DIR = "flutter_assets"; - - -/** - * Contains application information for Flutter initialization. - * This class holds configuration data such as AOT library names, snapshot data paths, - * asset directories, and build mode information. - */ -export default class FlutterApplicationInfo { - /** Name of the AOT shared library. */ - aotSharedLibraryName: string; - /** Name of the VM snapshot data file. */ - vmSnapshotData: string; - /** Name of the isolate snapshot data file. */ - isolateSnapshotData: string; - /** Directory containing Flutter assets. */ - flutterAssetsDir: string; - /** Domain network policy configuration. */ - domainNetworkPolicy: string; - /** Directory containing native libraries. */ - nativeLibraryDir: string; - /** Whether to automatically register plugins. */ - automaticallyRegisterPlugins: boolean; - /** Whether the application is running in debug mode. */ - isDebugMode: boolean; - /** Whether the application is running in profile mode. */ - isProfile: boolean; - - /** - * Constructs a new FlutterApplicationInfo instance. - * @param aotSharedLibraryName - Name of the AOT shared library, or null to use default - * @param vmSnapshotData - Name of the VM snapshot data file, or null to use default - * @param isolateSnapshotData - Name of the isolate snapshot data file, or null to use default - * @param flutterAssetsDir - Directory containing Flutter assets, or null to use default - * @param domainNetworkPolicy - Domain network policy, or null for empty string - * @param nativeLibraryDir - Directory containing native libraries - * @param automaticallyRegisterPlugins - Whether to automatically register plugins - */ - constructor(aotSharedLibraryName: string | null, - vmSnapshotData: string | null, - isolateSnapshotData: string | null, - flutterAssetsDir: string | null, - domainNetworkPolicy: string | null, - nativeLibraryDir: string, - automaticallyRegisterPlugins: boolean) { - this.aotSharedLibraryName = aotSharedLibraryName == null ? DEFAULT_AOT_SHARED_LIBRARY_NAME : aotSharedLibraryName; - this.vmSnapshotData = vmSnapshotData == null ? DEFAULT_VM_SNAPSHOT_DATA : vmSnapshotData; - this.isolateSnapshotData = isolateSnapshotData == null ? DEFAULT_ISOLATE_SNAPSHOT_DATA : isolateSnapshotData; - this.flutterAssetsDir = flutterAssetsDir == null ? DEFAULT_FLUTTER_ASSETS_DIR : flutterAssetsDir; - this.domainNetworkPolicy = domainNetworkPolicy == null ? "" : domainNetworkPolicy; - this.nativeLibraryDir = nativeLibraryDir; - this.automaticallyRegisterPlugins = automaticallyRegisterPlugins; - this.isDebugMode = "debug" == String(BuildProfile.BUILD_MODE_NAME); - this.isProfile = "profile" == String(BuildProfile.BUILD_MODE_NAME); - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/FlutterLoader.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/FlutterLoader.ets deleted file mode 100644 index a0f37c7..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/FlutterLoader.ets +++ /dev/null @@ -1,400 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on FlutterLoader.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -/** - * FlutterLoader is responsible for starting the Dart VM and loading Dart code. - * This class locates Flutter resources in the HAP package and loads the Flutter native library. - * It handles initialization, resource copying, and Dart VM configuration. - */ -import FlutterShellArgs from '../FlutterShellArgs'; -import FlutterNapi from '../FlutterNapi'; -import Log from '../../../util/Log'; -import FlutterApplicationInfo from './FlutterApplicationInfo'; -import common from '@ohos.app.ability.common'; -import StringUtils from '../../../util/StringUtils'; -import ApplicationInfoLoader from './ApplicationInfoLoader'; -import bundleManager from '@ohos.bundle.bundleManager'; -import fs from '@ohos.file.fs'; -import { BusinessError } from '@ohos.base'; -import data_preferences from '@ohos.data.preferences'; -import { util } from '@kit.ArkTS'; -import deviceInfo from '@ohos.deviceInfo'; -import { json5Tojson } from '../../../util/Json5ToJson'; - -const TAG = "FlutterLoader"; - -// Flutter engine shared library -const DEFAULT_LIBRARY = "libflutter.so"; -// Default kernel file for JIT builds -const DEFAULT_KERNEL_BLOB = "kernel_blob.bin"; -// Default snapshot library for JIT builds -const VMSERVICE_SNAPSHOT_LIBRARY = "libvmservice_snapshot.so"; -// Key for snapshot asset path -const SNAPSHOT_ASSET_PATH_KEY = "snapshot-asset-path"; -// Key for VM snapshot data -const VM_SNAPSHOT_DATA_KEY = "vm-snapshot-data"; -// Key for isolate snapshot data -const ISOLATE_SNAPSHOT_DATA_KEY = "isolate-snapshot-data"; - - -const AOT_SHARED_LIBRARY_NAME = "aot-shared-library-name"; - -const AOT_VMSERVICE_SHARED_LIBRARY_NAME = "aot-vmservice-shared-library-name"; - -// File path separator -const FILE_SEPARATOR = "/"; - -const TIMESTAMP_PREFIX = "res_timestamp-"; - -const ENABLE_IMPELLER_TAG = "enable_impeller"; - -const TRUE_STRING = "true"; - -const BUILD_INFO_FILE_NAME = "buildinfo.json5"; - -/** - * Represents a string item with name and value. - */ -interface StringItem { - name: string; - value: string; -} - -/** - * Represents build information data containing an array of string items. - */ -interface InfoData { - string: StringItem[]; -} - -/** - * Prefetches the default font manager asynchronously. - * This should be called before using fonts in the Flutter engine. - */ -async function prefetchDefaultFontManager(): Promise { - await new Promise((resolve: Function) => { - FlutterNapi.prefetchDefaultFontManager() - resolve() - }) -} - -/** - * FlutterLoader is responsible for starting the Dart VM and loading Dart code. - * This class locates Flutter resources in the HAP package and loads the Flutter native library. - * It handles initialization, resource copying, and Dart VM configuration. - */ -export default class FlutterLoader { - /** The FlutterNapi instance for native communication. */ - flutterNapi: FlutterNapi; - /** Initialization result containing paths for app storage, engine caches, and data directory. */ - initResult: InitResult | null = null; - /** Flutter application information including asset paths and build mode. */ - flutterApplicationInfo: FlutterApplicationInfo | null = null; - /** The application context for accessing resources. */ - context: common.Context | null = null; - /** Whether the FlutterLoader has been initialized. */ - initialized: boolean = false; - /** Timestamp when initialization started. */ - initStartTimestampMillis: number = 0; - /** Whether Impeller rendering backend is enabled. */ - isEnableImpeller: boolean = false; - - /** - * Constructs a new FlutterLoader instance. - * @param flutterNapi - The FlutterNapi instance for native communication - */ - constructor(flutterNapi: FlutterNapi) { - this.flutterNapi = flutterNapi; - } - - /** - * Gets build information from the buildinfo.json5 file. - * @param context - The application context - * @returns A map containing build information key-value pairs - */ - private getBuildInfo(context: common.Context): Map { - let buildInfoMap: Map = new Map(); - try { - let rawFile = context.resourceManager.getRawFileContentSync(BUILD_INFO_FILE_NAME); - let textDecoder = util.TextDecoder.create('utf-8', { - ignoreBOM: true - }); - let record = textDecoder.decodeWithStream(rawFile, { - stream: false - }); - let jsonRecord: InfoData = JSON.parse(json5Tojson(record)); - jsonRecord.string.forEach((item: StringItem) => { - buildInfoMap.set(item.name, item.value); - }); - return buildInfoMap; - } catch (error) { - Log.e(TAG, "can not find buildinfo.json5 file.") - return buildInfoMap; - } - - } - - /** - * Starts initialization of the native system. - * - * This loads the Flutter engine's native library to enable subsequent NAPI calls. This also - * starts locating and unpacking Dart resources packaged in the app's HAP. - * - * Calling this method multiple times has no effect. - * - * @param context - The OpenHarmony application context - */ - startInitialization(context: common.Context) { - Log.d(TAG, "flutterLoader start init") - this.initStartTimestampMillis = Date.now(); - this.context = context; - this.flutterApplicationInfo = ApplicationInfoLoader.load(context); - prefetchDefaultFontManager(); - if (this.flutterApplicationInfo!.isDebugMode) { - this.copyResource(context) - } - let buildInfoMap = this.getBuildInfo(this.context!); - if (!buildInfoMap.has(ENABLE_IMPELLER_TAG) || buildInfoMap.get(ENABLE_IMPELLER_TAG) == TRUE_STRING) { - this.isEnableImpeller = true; - } else { - this.isEnableImpeller = false; - } - this.initResult = new InitResult( - `${context.filesDir}/`, - `${context.cacheDir}/`, - `${context.filesDir}` - ) - Log.d(TAG, "flutterLoader end init") - } - - private copyResource(context: common.Context) { - let filePath = context.filesDir + FILE_SEPARATOR + this.flutterApplicationInfo!.flutterAssetsDir - const timestamp = this.checkTimestamp(filePath); - if (timestamp == null) { - Log.d(TAG, "no need copyResource") - return; - } - if (this.context != null) { - Log.d(TAG, "start copyResource") - if (fs.accessSync(filePath + FILE_SEPARATOR + DEFAULT_KERNEL_BLOB)) { - Log.d(TAG, "hap has changed, start delete previous file") - fs.rmdirSync(filePath); - } - - if (!fs.accessSync(filePath)) { - fs.mkdirSync(filePath) - } - - let kernelBuffer = - this.context.resourceManager.getRawFileContentSync(this.flutterApplicationInfo!.flutterAssetsDir + - FILE_SEPARATOR + DEFAULT_KERNEL_BLOB) - let kernelFile = - fs.openSync(filePath + FILE_SEPARATOR + DEFAULT_KERNEL_BLOB, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE) - fs.writeSync(kernelFile.fd, kernelBuffer.buffer) - - let vmBuffer = - this.context.resourceManager.getRawFileContentSync(this.flutterApplicationInfo!.flutterAssetsDir + - FILE_SEPARATOR + this.flutterApplicationInfo!.vmSnapshotData) - let vmFile = fs.openSync(filePath + FILE_SEPARATOR + this.flutterApplicationInfo!.vmSnapshotData, - fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE) - fs.writeSync(vmFile.fd, vmBuffer.buffer) - - let isolateBuffer = - this.context.resourceManager.getRawFileContentSync(this.flutterApplicationInfo!.flutterAssetsDir + - FILE_SEPARATOR + this.flutterApplicationInfo!.isolateSnapshotData) - let isolateFile = fs.openSync(filePath + FILE_SEPARATOR + this.flutterApplicationInfo!.isolateSnapshotData, - fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE) - fs.writeSync(isolateFile.fd, isolateBuffer.buffer) - - if (timestamp != null) { - fs.closeSync(fs.openSync(filePath + FILE_SEPARATOR + timestamp, fs.OpenMode.READ_ONLY | fs.OpenMode.CREATE)) - } - fs.closeSync(kernelFile) - fs.closeSync(vmFile) - fs.closeSync(isolateFile) - Log.d(TAG, "copyResource end") - } else { - Log.d(TAG, "no copyResource") - } - } - - /** - * Ensures that Dart VM initialization is complete. - * This method initializes the Dart VM with the appropriate shell arguments - * based on the build mode (debug, profile, or release). - * @param shellArgs - Optional array of shell arguments, will be created if null - */ - ensureInitializationComplete(shellArgs: Array | null) { - if (this.initialized) { - return; - } - if (shellArgs == null) { - shellArgs = new Array(); - } - shellArgs.push("--icu-symbol-prefix=_binary_icudtl_dat"); - shellArgs.push( - "--icu-native-lib-path=" - + this.flutterApplicationInfo!.nativeLibraryDir - + FILE_SEPARATOR + DEFAULT_LIBRARY - ); - - let kernelPath: string = ""; - if (this.flutterApplicationInfo!.isDebugMode) { - Log.d(TAG, "this.initResult!.dataDirPath=" + this.initResult!.dataDirPath) - const snapshotAssetPath = - this.initResult!.dataDirPath + FILE_SEPARATOR + this.flutterApplicationInfo!.flutterAssetsDir; - kernelPath = snapshotAssetPath + FILE_SEPARATOR + DEFAULT_KERNEL_BLOB; - shellArgs.push("--" + SNAPSHOT_ASSET_PATH_KEY + "=" + snapshotAssetPath); - shellArgs.push("--" + VM_SNAPSHOT_DATA_KEY + "=" + this.flutterApplicationInfo!.vmSnapshotData); - shellArgs.push( - "--" + ISOLATE_SNAPSHOT_DATA_KEY + "=" + this.flutterApplicationInfo!.isolateSnapshotData); - shellArgs.push('--enable-checked-mode') - shellArgs.push('--verbose-logging') - } else { - shellArgs.push( - "--" + AOT_SHARED_LIBRARY_NAME + "=" + this.flutterApplicationInfo!.aotSharedLibraryName); - shellArgs.push( - "--" - + AOT_SHARED_LIBRARY_NAME - + "=" - + this.flutterApplicationInfo!.nativeLibraryDir - + FILE_SEPARATOR - + this.flutterApplicationInfo!.aotSharedLibraryName); - - const snapshotAssetPath = - this.initResult!.dataDirPath + FILE_SEPARATOR + this.flutterApplicationInfo!.flutterAssetsDir; - - if (this.flutterApplicationInfo!.isProfile) { - shellArgs.push("--" + AOT_VMSERVICE_SHARED_LIBRARY_NAME + "=" + VMSERVICE_SNAPSHOT_LIBRARY); - } - } - shellArgs.push("--cache-dir-path=" + this.initResult!.engineCachesPath); - if (StringUtils.isNotEmpty(this.flutterApplicationInfo!.domainNetworkPolicy)) { - shellArgs.push("--domain-network-policy=" + this.flutterApplicationInfo!.domainNetworkPolicy); - } - - const resourceCacheMaxBytesThreshold = 1080 * 1920 * 12 * 4; - shellArgs.push("--resource-cache-max-bytes-threshold=" + resourceCacheMaxBytesThreshold); - - shellArgs.push("--prefetched-default-font-manager"); - - shellArgs.push("--leak-vm=" + true); - - if (this.isEnableImpeller == true && deviceInfo.productModel != "emulator") { - shellArgs.push("--enable-impeller"); - Log.d(TAG, "Enable Impeller in Ohos."); - } else { - Log.d(TAG, "Do not find enableImpeller tag or enableImpeller tag set to false, enable Skia in Ohos."); - } - - // Final initialization operation - const costTime = Date.now() - this.initStartTimestampMillis; - this.flutterNapi.init( - this.context!, - shellArgs, - kernelPath, - this.initResult!.appStoragePath, - this.initResult!.engineCachesPath!, - costTime - ); - this.initialized = true; - Log.d(TAG, "ensureInitializationComplete") - } - - /** - * Finds the path to the Flutter app bundle. - * @returns The path to the Flutter assets directory, or empty string if not initialized - */ - findAppBundlePath(): string { - return this.flutterApplicationInfo == null ? "" : this.flutterApplicationInfo!.flutterAssetsDir; - } - - /** - * Gets the lookup key for an asset file. - * @param asset - The asset file path - * @param packageName - Optional package name for package-specific assets - * @returns The full asset path lookup key - */ - getLookupKeyForAsset(asset: string, packageName?: string): string { - if (typeof packageName === 'string' && packageName.trim().length > 0) { - return this.fullAssetPathFrom('packages' + FILE_SEPARATOR + packageName + FILE_SEPARATOR + asset); - } - return this.fullAssetPathFrom(asset); - } - - /** - * Gets the full asset path from a relative file path. - * @param filePath - The relative file path - * @returns The full asset path, or empty string if not initialized - */ - fullAssetPathFrom(filePath: string): string { - return this.flutterApplicationInfo == null ? "" : this.flutterApplicationInfo!.flutterAssetsDir + "/" + filePath; - } - - private checkTimestamp(dataDir: string): string | null { - let bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_DEFAULT); - const expectedTimestamp = TIMESTAMP_PREFIX + bundleInfo.versionCode + "-" + bundleInfo.updateTime; - const existingTimestamps = this.getExistingTimestamps(dataDir); - if (existingTimestamps == null) { - Log.i(TAG, "No extracted resources found"); - return expectedTimestamp; - } - - if (existingTimestamps.length == 1) { - Log.i(TAG, "Found extracted resources " + existingTimestamps[0]); - } - - if (existingTimestamps.length != 1 || !(expectedTimestamp == existingTimestamps[0])) { - Log.i(TAG, "Resource version mismatch " + expectedTimestamp); - return expectedTimestamp; - } - - return null; - } - - private getExistingTimestamps(dataDir: string): string[] { - return fs.accessSync(dataDir) ? fs.listFileSync(dataDir, { - filter: { - displayName: [`${TIMESTAMP_PREFIX}*`] - } - }) : new Array(); - } - - /** - * Checks if the FlutterLoader has been initialized. - * @returns true if initialized, false otherwise - */ - isInitialized(): boolean { - return this.initialized; - } -} - -/** - * Contains initialization result paths for the Flutter engine. - */ -class InitResult { - appStoragePath: string; - engineCachesPath: string; - dataDirPath: string; - - /** - * Constructs a new InitResult instance. - * @param appStoragePath - Path to the application storage directory - * @param engineCachesPath - Path to the engine caches directory - * @param dataDirPath - Path to the data directory - */ - constructor(appStoragePath: string, - engineCachesPath: string, - dataDirPath: string) { - this.appStoragePath = appStoragePath; - this.engineCachesPath = engineCachesPath; - this.dataDirPath = dataDirPath; - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/mutatorsstack/FlutterMutatorView.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/mutatorsstack/FlutterMutatorView.ets deleted file mode 100644 index 8db1a16..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/mutatorsstack/FlutterMutatorView.ets +++ /dev/null @@ -1,170 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on FlutterMutatorView.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ -import ArrayList from '@ohos.util.ArrayList'; -import matrix4 from '@ohos.matrix4'; -import { DVModel, DVModelEvents, DVModelParameters } from '../../../view/DynamicView/dynamicView'; -import { createDVModelFromJson } from '../../../view/DynamicView/dynamicViewJson'; -import OhosTouchProcessor from '../../ohos/OhosTouchProcessor'; -import { FlutterMutator, FlutterMutatorsStack } from './FlutterMutatorsStack' -import Any from '../../../plugin/common/Any'; - -/** - * View that applies Flutter mutators (transforms, clips) to a dynamic view model. - * This class manages the layout and mutator application for platform views. - */ -export class FlutterMutatorView { - private mutatorsStack: FlutterMutatorsStack | null = null; - private screenDensity: number = 0; - private left: number = 0; - private top: number = 0; - private prevLeft: number = 0; - private prevTop: number = 0; - private onTouch = (touchEvent: Any) => { - let params = this.model.params as Record; - switch (touchEvent.type) { - case TouchType.Down: - this.prevLeft = this.left; - this.prevTop = this.top; - params.translateX = this.left; - params.translateY = this.top; - break; - case TouchType.Move: - params.translateX = this.prevLeft; - params.translateY = this.prevTop; - this.prevLeft = this.left; - this.prevTop = this.top; - break; - case TouchType.Up: - case TouchType.Cancel: - default: - break; - } - } - private model: DVModel = createDVModelFromJson( - new DVModelParam("Column", [], { backgroundColor: Color.Red }, { onTouch: this.onTouch }) - ); - - /** - * Sets listeners for descendant focus change events. - * @param onFocus - Callback invoked when a descendant gains focus - * @param onBlur - Callback invoked when a descendant loses focus - */ - setOnDescendantFocusChangeListener(onFocus: () => void, onBlur: () => void) { - // this.model.events["onFocus"] = onFocus; - // this.model.events["onBlur"] = onBlur; - let events2 = this.model.events as Record; - events2.onFocus = onFocus; - events2.onBlur = onBlur; - } - - /** - * Sets the layout parameters for this view. - * @param parameters - The layout parameters including margin, width, and height - */ - public setLayoutParams(parameters: DVModelParameters): void { - if (this.model.params == null) { - this.model.params = new DVModelParameters(); - } - let params = this.model.params as Record | matrix4.Matrix4Transit>; - let parametersRecord = - parameters as Record | matrix4.Matrix4Transit>; - params.marginLeft = parametersRecord['marginLeft']; - params.marginTop = parametersRecord['marginTop']; - params.width = parametersRecord['width']; - params.height = parametersRecord['height']; - this.left = parametersRecord.marginLeft as number; - this.top = parametersRecord.marginTop as number; - } - - /** - * Adds a child dynamic view model to this view. - * @param model - The DVModel to add as a child - */ - public addDvModel(model: DVModel): void { - this.model?.children.push(model); - } - - /** - * Prepares this view for display by applying mutators and setting layout parameters. - * @param mutatorsStack - The stack of mutators to apply - * @param left - The left position of the view - * @param top - The top position of the view - * @param width - The width of the view - * @param height - The height of the view - */ - public readyToDisplay(mutatorsStack: FlutterMutatorsStack, left: number, top: number, width: number, height: number) { - this.mutatorsStack = mutatorsStack; - this.left = left; - this.top = top; - let parameters = - new DVModelParameters() as Record | matrix4.Matrix4Transit>; - parameters['marginLeft'] = left; - parameters['marginTop'] = top; - parameters['width'] = width; - parameters['height'] = height; - this.setLayoutParams(parameters); - this.dealMutators(); - } - - private dealMutators() { - if (this.mutatorsStack == null) { - return; - } - let paths = this.mutatorsStack.getFinalClippingPaths(); - let rects = this.mutatorsStack.getFinalClippingRects(); - let matrix = this.mutatorsStack.getFinalMatrix(); - let params = this.model.params as Record | matrix4.Matrix4Transit>; - if (!paths.isEmpty()) { - let path = paths.getLast(); - params.pathWidth = path.width; - params.pathHeight = path.height; - params.pathCommands = path.commands; - } - if (!rects.isEmpty()) { - let rect = rects.getLast(); - params.rectWidth = rect.width; - params.rectHeight = rect.height; - params.rectRadius = rect.radius; - } - params.matrix = matrix; - } - - /** - * Gets the dynamic view model for this view. - * @returns The DVModel instance, or undefined if not set - */ - public getDvModel(): DVModel | undefined { - return this.model; - } -} - -/** - * Parameters for creating a dynamic view model. - */ -class DVModelParam { - compType: string - children: [] - attributes: Any - events: Any - - /** - * Constructs a new DVModelParam instance. - * @param compType - The component type - * @param children - Array of child components - * @param attributes - Component attributes - * @param events - Component event handlers - */ - constructor(compType: string, children: [], attributes: Any, events: Any) { - this.compType = compType; - this.children = children; - this.attributes = attributes; - this.events = events; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/mutatorsstack/FlutterMutatorsStack.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/mutatorsstack/FlutterMutatorsStack.ets deleted file mode 100644 index 09f71ec..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/mutatorsstack/FlutterMutatorsStack.ets +++ /dev/null @@ -1,210 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on FlutterMutatorsStack.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import matrix4 from '@ohos.matrix4' -import List from '@ohos.util.List'; - -/** - * Types of mutators that can be applied to Flutter views. - */ -export enum FlutterMutatorType { - CLIP_RECT, - CLIP_PATH, - TRANSFORM, - OPACITY -} - -/** - * Represents a rectangular clipping region. - */ -class Rect { - width: number; - height: number; - radius: string | number | Array; - - /** - * Constructs a new Rect instance. - * @param width - The width of the rectangle - * @param height - The height of the rectangle - * @param radius - Optional corner radius for rounded rectangles - */ - constructor(width: number, height: number, radius?: string | number | Array) { - this.width = width; - this.height = height; - this.radius = radius ?? 0; - } -} - -/** - * Represents a path-based clipping region. - */ -class Path { - width: number | string; - height: number | string; - commands: string; - - /** - * Constructs a new Path instance. - * @param width - The width of the path - * @param height - The height of the path - * @param commands - Optional SVG path commands - */ - constructor(width: number | string, height: number | string, commands?: string) { - this.width = width; - this.height = height; - this.commands = commands ?? ''; - } -} - -/** - * Represents a single mutator operation (transform, clip rect, or clip path). - */ -export class FlutterMutator { - private matrix: matrix4.Matrix4Transit | null = null; - private rect: Rect = new Rect(0, 0); - private path: Path = new Path(0, 0); - - /** - * Constructs a new FlutterMutator instance. - * @param args - Either a transformation matrix, a clipping rectangle, or a clipping path - */ - constructor(args: matrix4.Matrix4Transit | Rect | Path) { - if (args instanceof Rect) { - this.rect = args; - } else if (args instanceof Path) { - this.path = args; - } else { - this.matrix = args; - } - } - - /** - * Gets the transformation matrix, if this mutator is a transform. - * @returns The transformation matrix, or null if not a transform - */ - public getMatrix(): matrix4.Matrix4Transit | null { - return this.matrix; - } - - /** - * Gets the clipping rectangle, if this mutator is a clip rect. - * @returns The clipping rectangle - */ - public getRect() { - return this.rect; - } - - /** - * Gets the clipping path, if this mutator is a clip path. - * @returns The clipping path - */ - public getPath() { - return this.path; - } -} - -/** - * Stack of mutators that can be applied to Flutter views. - * This class manages transformations, clipping rectangles, and clipping paths - * that are applied in sequence to create the final view appearance. - */ -export class FlutterMutatorsStack { - private mutators: List; - private finalClippingPaths: List; - private finalClippingRects: List; - private finalMatrix: matrix4.Matrix4Transit; - - /** - * Constructs a new FlutterMutatorsStack instance. - */ - constructor() { - this.mutators = new List(); - this.finalClippingPaths = new List(); - this.finalClippingRects = new List(); - this.finalMatrix = matrix4.identity(); - } - - /** - * Pushes a transformation matrix onto the mutators stack. - * @param values - Array of 16 numbers representing a 4x4 transformation matrix - */ - public pushTransform(values: Array): void { - if (values.length != 16) { - return; - } - let index = 0; - let matrix = matrix4.init( - [values[index++], values[index++], values[index++], values[index++], - values[index++], values[index++], values[index++], values[index++], - values[index++], values[index++], values[index++], values[index++], - values[index++], values[index++], values[index++], values[index++]]); - let mutator = new FlutterMutator(matrix); - this.mutators.add(mutator); - this.finalMatrix.combine(matrix); - } - - /** - * Pushes a rectangular clipping region onto the mutators stack. - * @param width - The width of the clipping rectangle - * @param height - The height of the clipping rectangle - * @param radius - Optional corner radius for rounded rectangles - */ - public pushClipRect(width: number, height: number, radius?: number) { - let rect = new Rect(width, height, radius); - let mutator = new FlutterMutator(rect); - this.mutators.add(mutator); - this.finalClippingRects.add(rect); - } - - /** - * Pushes a path-based clipping region onto the mutators stack. - * @param width - The width of the clipping path - * @param height - The height of the clipping path - * @param command - Optional SVG path commands - */ - public pushClipPath(width: number, height: number, command?: string) { - let path = new Path(width, height, command); - let mutator = new FlutterMutator(path); - this.mutators.add(mutator); - this.finalClippingPaths.add(path); - } - - /** - * Gets all mutators in the stack. - * @returns List of all mutators - */ - public getMutators() { - return this.mutators; - } - - /** - * Gets all final clipping paths. - * @returns List of all clipping paths - */ - public getFinalClippingPaths() { - return this.finalClippingPaths; - } - - /** - * Gets all final clipping rectangles. - * @returns List of all clipping rectangles - */ - public getFinalClippingRects() { - return this.finalClippingRects; - } - - /** - * Gets the final combined transformation matrix. - * @returns The combined transformation matrix from all transforms - */ - public getFinalMatrix() { - return this.finalMatrix; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin.ets deleted file mode 100644 index 990ded7..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin.ets +++ /dev/null @@ -1,225 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on FlutterPlugin.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import common from '@ohos.app.ability.common'; -import { BinaryMessenger } from '../../../plugin/common/BinaryMessenger'; -import PlatformViewFactory from '../../../plugin/platform/PlatformViewFactory'; -import PlatformViewRegistry from '../../../plugin/platform/PlatformViewRegistry'; -import { TextureRegistry } from '../../../view/TextureRegistry'; -import FlutterEngine from '../FlutterEngine'; - -/** - * Interface to be implemented by all Flutter plugins. - * - * A Flutter plugin allows Flutter developers to interact with a host platform, e.g., OpenHarmony, - * via Dart code. It includes platform code, as well as Dart code. A plugin author is responsible - * for setting up an appropriate MethodChannel to communicate between platform code and Dart code. - * - * A Flutter plugin has a lifecycle. First, a developer must add a FlutterPlugin to an instance - * of FlutterEngine. To do this, obtain a PluginRegistry with FlutterEngine.getPlugins(), then call - * PluginRegistry.add(FlutterPlugin), passing the instance of the Flutter plugin. During the call - * to PluginRegistry.add(FlutterPlugin), the FlutterEngine will invoke onAttachedToEngine(FlutterPluginBinding) - * on the given FlutterPlugin. If the FlutterPlugin is removed from the FlutterEngine via - * PluginRegistry.remove(pluginClassName), or if the FlutterEngine is destroyed, the FlutterEngine will invoke - * onDetachedFromEngine(FlutterPluginBinding) on the given FlutterPlugin. - * - * Once a FlutterPlugin is attached to a FlutterEngine, the plugin's code is permitted to access - * and invoke methods on resources within the FlutterPlugin.FlutterPluginBinding that the FlutterEngine - * gave to the FlutterPlugin in onAttachedToEngine(FlutterPluginBinding). This includes, for example, - * the application Context for the running app. - * - * The FlutterPlugin.FlutterPluginBinding provided in onAttachedToEngine(FlutterPluginBinding) is - * no longer valid after the execution of onDetachedFromEngine(FlutterPluginBinding). Do not access - * any properties of the FlutterPlugin.FlutterPluginBinding after the completion of - * onDetachedFromEngine(FlutterPluginBinding). - * - * To register a MethodChannel, obtain a BinaryMessenger via the FlutterPlugin.FlutterPluginBinding. - * - * An OpenHarmony Flutter plugin may require access to app resources or other artifacts that can only - * be retrieved through a Context. Developers can access the application context via - * FlutterPlugin.FlutterPluginBinding.getApplicationContext(). - * - * Some plugins may require access to the UIAbility that is displaying a Flutter experience, or - * may need to react to UIAbility lifecycle events, e.g., onCreate(), onWindowStageCreate(), onForeground(), - * onBackground(), onWindowStageDestroy(), onDestroy(). Any such plugin should implement AbilityAware - * in addition to implementing FlutterPlugin. AbilityAware provides callback hooks that expose access - * to an associated UIAbility and its Lifecycle. All plugins must respect the possibility that a Flutter - * experience may never be associated with a UIAbility, e.g., when Flutter is used for background - * behavior. Additionally, all plugins must respect that UIAbilities may come and go over time, thus - * requiring plugins to cleanup resources and recreate those resources as the UIAbility comes and goes. - */ -export interface FlutterPlugin { - /** - * Gets the unique class name of this plugin. - * Similar to Android's Class, but in TypeScript this must be user-defined. - * @returns The unique class name of this plugin - */ - getUniqueClassName(): string - - /** - * This FlutterPlugin has been associated with a FlutterEngine instance. - * - * Relevant resources that this FlutterPlugin may need are provided via the binding. - * The binding may be cached and referenced until onDetachedFromEngine is invoked and returns. - * @param binding - The FlutterPluginBinding providing access to engine resources - */ - onAttachedToEngine(binding: FlutterPluginBinding): void; - - /** - * This FlutterPlugin has been removed from a FlutterEngine instance. - * - * The binding passed to this method is the same instance that was passed in - * onAttachedToEngine. It is provided again in this method as a convenience. - * The binding may be referenced during the execution of this method, but it - * must not be cached or referenced after this method returns. - * - * FlutterPlugins should release all resources in this method. - * @param binding - The FlutterPluginBinding that was provided in onAttachedToEngine - */ - onDetachedFromEngine(binding: FlutterPluginBinding): void; -} - -/** - * Binding that provides Flutter plugins with access to Flutter engine resources. - * This class holds references to the engine, messenger, assets, and registries that plugins may need. - */ -export class FlutterPluginBinding { - private applicationContext: common.Context; - private flutterEngine: FlutterEngine; - private binaryMessenger: BinaryMessenger; - private flutterAssets: FlutterAssets; - private textureRegistry: TextureRegistry; - private platformViewRegistry: PlatformViewRegistry; - - /** - * Constructs a new FlutterPluginBinding instance. - * @param applicationContext - The application context - * @param flutterEngine - The FlutterEngine instance - * @param binaryMessenger - The BinaryMessenger for platform communication - * @param flutterAssets - The FlutterAssets for accessing Flutter assets - * @param textureRegistry - The TextureRegistry for managing textures - * @param platformViewRegistry - Optional PlatformViewRegistry, will be created if not provided - */ - constructor(applicationContext: common.Context, flutterEngine: FlutterEngine, binaryMessenger: BinaryMessenger, - flutterAssets: FlutterAssets, textureRegistry: TextureRegistry, platformViewRegistry?: PlatformViewRegistry) { - this.applicationContext = applicationContext; - this.flutterEngine = flutterEngine; - this.binaryMessenger = binaryMessenger; - this.flutterAssets = flutterAssets; - this.textureRegistry = textureRegistry; - this.platformViewRegistry = platformViewRegistry ?? new EmptyPlatformViewRegistry(); - } - - /** - * Gets the application context. - * @returns The application context - */ - getApplicationContext(): common.Context { - return this.applicationContext; - } - - /** - * Gets the FlutterEngine instance. - * @returns The FlutterEngine instance - */ - getFlutterEngine(): FlutterEngine { - return this.flutterEngine; - } - - /** - * Gets the BinaryMessenger for platform communication. - * @returns The BinaryMessenger instance - */ - getBinaryMessenger(): BinaryMessenger { - return this.binaryMessenger; - } - - /** - * Gets the FlutterAssets for accessing Flutter assets. - * @returns The FlutterAssets instance - */ - getFlutterAssets(): FlutterAssets { - return this.flutterAssets; - } - - /** - * Gets the TextureRegistry for managing textures. - * @returns The TextureRegistry instance - */ - getTextureRegistry(): TextureRegistry { - return this.textureRegistry; - } - - /** - * Gets the PlatformViewRegistry for managing platform views. - * @returns The PlatformViewRegistry instance - */ - public getPlatformViewRegistry(): PlatformViewRegistry { - return this.platformViewRegistry; - } -} - -/** Provides Flutter plugins with access to Flutter asset information. */ -export interface FlutterAssets { - /** - * Returns the relative file path to the Flutter asset with the given name, including the file's - * extension, e.g., "myImage.jpg". - * - * The returned file path is relative to the OpenHarmony app's standard assets directory. - * Therefore, the returned path is appropriate to pass to OpenHarmony's ResourceManager, but - * the path is not appropriate to load as an absolute path. - * @param assetFileName - The name of the asset file - * @returns The relative file path to the asset - */ - getAssetFilePathByName(assetFileName: string): string; - - /** - * Same as getAssetFilePathByName but with added support for an explicit bundleName. - * @param assetFileName - The name of the asset file - * @param bundleName - The bundle name - * @returns The relative file path to the asset - */ - getAssetFilePathByName(assetFileName: string, bundleName: string): string; - - /** - * Returns the relative file path to the Flutter asset with the given subpath, including the - * file's extension, e.g., "/dir1/dir2/myImage.jpg". - * - * The returned file path is relative to the OpenHarmony app's standard assets directory. - * Therefore, the returned path is appropriate to pass to OpenHarmony's ResourceManager, but - * the path is not appropriate to load as an absolute path. - * @param assetSubpath - The subpath of the asset - * @returns The relative file path to the asset - */ - getAssetFilePathBySubpath(assetSubpath: string): string; - - /** - * Same as getAssetFilePathBySubpath but with added support for an explicit bundleName. - * @param assetSubpath - The subpath of the asset - * @param bundleName - The bundle name - * @returns The relative file path to the asset - */ - getAssetFilePathBySubpath(assetSubpath: string, bundleName: string): string; -} - -/** - * Empty implementation of PlatformViewRegistry that does nothing. - */ -class EmptyPlatformViewRegistry implements PlatformViewRegistry { - /** - * Attempts to register a view factory, but always returns false. - * @param viewTypeId - The view type identifier - * @param factory - The PlatformViewFactory to register - * @returns Always returns false - */ - registerViewFactory(viewTypeId: string, factory: PlatformViewFactory): boolean { - return false; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/PluginRegistry.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/PluginRegistry.ets deleted file mode 100644 index aa81268..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/PluginRegistry.ets +++ /dev/null @@ -1,73 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on PluginRegistry.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import { FlutterPlugin } from './FlutterPlugin'; - -/** - * Registry for managing Flutter plugins. - * This interface provides methods to add, remove, and query plugins attached to a FlutterEngine. - */ -export default interface PluginRegistry { - /** - * Attaches the given plugin to the FlutterEngine associated with this PluginRegistry. - * @param plugin - The FlutterPlugin to attach - */ - add(plugin: FlutterPlugin): void; - - /** - * Attaches the given plugins to the FlutterEngine associated with this PluginRegistry. - * @param plugins - The set of FlutterPlugins to attach - */ - addList(plugins: Set): void; - - /** - * Checks if a plugin of the given type is currently attached to the FlutterEngine - * associated with this PluginRegistry. - * @param pluginClassName - The class name of the plugin to check - * @returns True if the plugin is attached, false otherwise - */ - has(pluginClassName: string): boolean; - - /** - * Gets the instance of a plugin that is currently attached to the FlutterEngine - * associated with this PluginRegistry, which matches the given pluginClassName. - * - * If no matching plugin is found, null is returned. - * @param pluginClassName - The class name of the plugin to get - * @returns The FlutterPlugin instance, or null if not found - */ - get(pluginClassName: string): FlutterPlugin; - - /** - * Detaches the plugin of the given type from the FlutterEngine - * associated with this PluginRegistry. - * - * If no such plugin exists, this method does nothing. - * @param pluginClassName - The class name of the plugin to remove - */ - remove(pluginClassName: string): void; - - /** - * Detaches the plugins of the given types from the FlutterEngine - * associated with this PluginRegistry. - * - * If no such plugins exist, this method does nothing. - * @param pluginClassNames - The set of plugin class names to remove - */ - removeList(pluginClassNames: Set): void; - - /** - * Detaches all plugins that are currently attached to the FlutterEngine - * associated with this PluginRegistry. - * - * If no plugins are currently attached, this method does nothing. - */ - removeAll(): void; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityAware.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityAware.ets deleted file mode 100644 index 43151f9..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityAware.ets +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2013 The Flutter Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. -*/ - -import { AbilityPluginBinding } from './AbilityPluginBinding'; - -/** - * FlutterPlugin that is interested in UIAbility lifecycle events related to a FlutterEngine - * running within the given UIAbility. - */ -export default interface AbilityAware { - /** - * This AbilityAware FlutterPlugin is now associated with a UIAbility. - * - * This method can be invoked in 1 of 2 situations: - * - * This AbilityAware FlutterPlugin was just added to a FlutterEngine that was already - * connected to a running UIAbility. - * This AbilityAware FlutterPlugin was already added to a FlutterEngine and that - * FlutterEngine was just connected to a UIAbility. - * - * The given AbilityPluginBinding contains UIAbility-related references that an AbilityAware - * FlutterPlugin may require, such as a reference to the actual UIAbility in question. - * The AbilityPluginBinding may be referenced until either onDetachedFromAbilityForConfigChanges - * or onDetachedFromAbility is invoked. At the conclusion of either of those methods, the - * binding is no longer valid. Clear any references to the binding or its resources, and do not - * invoke any further methods on the binding or its resources. - * @param binding - The AbilityPluginBinding providing access to UIAbility resources - */ - onAttachedToAbility(binding: AbilityPluginBinding): void; - - /** - * This plugin has been detached from a UIAbility. - * - * Detachment can occur for a number of reasons: - * - * The app is no longer visible and the UIAbility instance has been destroyed. - * The FlutterEngine that this plugin is connected to has been detached from its FlutterView. - * This AbilityAware plugin has been removed from its FlutterEngine. - * - * By the end of this method, the UIAbility that was made available in - * onAttachedToAbility is no longer valid. Any references to the - * associated UIAbility or AbilityPluginBinding should be cleared. - * - * Any Lifecycle listeners that were registered in onAttachedToAbility or - * onReattachedToAbilityForConfigChanges should be deregistered here to - * avoid a possible memory leak and other side effects. - */ - onDetachedFromAbility(): void; -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityControlSurface.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityControlSurface.ets deleted file mode 100644 index 61490f8..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityControlSurface.ets +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2013 The Flutter Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. -*/ - -import AbilityConstant from '@ohos.app.ability.AbilityConstant'; -import Want from '@ohos.app.ability.Want'; -import UIAbility from '@ohos.app.ability.UIAbility'; -import ExclusiveAppComponent from '../../../ohos/ExclusiveAppComponent'; - -/** - * Interface for controlling ability-related operations in Flutter engines. - * This interface provides methods to attach/detach from abilities and handle ability lifecycle events. - */ -export default interface ActivityControlSurface { - /** - * Attaches this surface to an exclusive app component (UIAbility). - * @param exclusiveActivity - The exclusive app component to attach to - */ - attachToAbility(exclusiveActivity: ExclusiveAppComponent): void; - - /** - * Detaches this surface from the current ability. - */ - detachFromAbility(): void; - - /** - * Handles a new Want event from the ability. - * @param want - The Want object containing the intent - * @param launchParams - The launch parameters - */ - onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void; - - /** - * Handles window focus change events from the ability. - * @param hasFocus - Whether the window has focus - */ - onWindowFocusChanged(hasFocus: boolean): void; - - /** - * Handles save state requests from the ability. - * @param reason - The reason for saving state - * @param wantParam - Parameters to save - * @returns The result of the save state operation - */ - onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityPluginBinding.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityPluginBinding.ets deleted file mode 100644 index 4fc1e24..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityPluginBinding.ets +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2013 The Flutter Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. -*/ - -import UIAbility from '@ohos.app.ability.UIAbility' -import Want from '@ohos.app.ability.Want'; -import AbilityConstant from '@ohos.app.ability.AbilityConstant'; - -/** - * Binding that provides plugins with access to UIAbility-related resources. - * This interface allows plugins to access the ability and register for ability lifecycle events. - */ -export interface AbilityPluginBinding { - /** - * Gets the UIAbility instance. - * @returns The UIAbility instance - */ - getAbility(): UIAbility; - - /** - * Adds a listener that is invoked whenever the associated UIAbility's onNewWant method is invoked. - * @param listener - The NewWantListener to add - */ - addOnNewWantListener(listener: NewWantListener): void; - - /** - * Removes a listener that was added in addOnNewWantListener. - * @param listener - The NewWantListener to remove - */ - removeOnNewWantListener(listener: NewWantListener): void; - - /** - * Adds a listener that is invoked whenever the associated UIAbility's windowStageEvent method is invoked. - * @param listener - The WindowFocusChangedListener to add - */ - addOnWindowFocusChangedListener(listener: WindowFocusChangedListener): void; - - /** - * Removes a listener that was added in addOnWindowFocusChangedListener. - * @param listener - The WindowFocusChangedListener to remove - */ - removeOnWindowFocusChangedListener(listener: WindowFocusChangedListener): void; - - /** - * Adds a listener that is invoked when the associated UIAbility saves and restores instance state. - * @param listener - The OnSaveStateListener to add - */ - addOnSaveStateListener(listener: OnSaveStateListener): void; - - /** - * Removes a listener that was added in addOnSaveStateListener. - * @param listener - The OnSaveStateListener to remove - */ - removeOnSaveStateListener(listener: OnSaveStateListener): void; -} - -/** - * Delegate interface for handling new wants on behalf of the main UIAbility. - */ -export interface NewWantListener { - /** - * Called when a new want is started for the UIAbility. - * @param want - The new want that was started for the UIAbility - * @param launchParams - The launch parameters - */ - onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void; -} - -/** - * Delegate interface for handling window focus changes on behalf of the main UIAbility. - */ -export interface WindowFocusChangedListener { - /** - * Called when the window focus changes. - * @param hasFocus - Whether the window has focus - */ - onWindowFocusChanged(hasFocus: boolean): void; -} - -/** - * Delegate interface for handling save state events. - */ -export interface OnSaveStateListener { - /** - * Invoked when the associated UIAbility saves and restores instance state. - * @param reason - The reason for saving state - * @param wantParam - Parameters to save - * @returns The result of the save state operation - */ - onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/renderer/FlutterRenderer.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/renderer/FlutterRenderer.ets deleted file mode 100644 index 1cb48a0..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/renderer/FlutterRenderer.ets +++ /dev/null @@ -1,269 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import image from '@ohos.multimedia.image'; -import { BusinessError } from '@ohos.base'; -import { SurfaceTextureEntry, TextureRegistry } from '../../../view/TextureRegistry'; -import { FlutterAbility } from '../../ohos/FlutterAbility'; -import FlutterNapi from '../FlutterNapi'; -import Log from '../../../util/Log'; - -const TAG = "FlutterRenderer" - -/** - * Renderer for Flutter content that manages textures and rendering operations. - * This class implements TextureRegistry and provides methods to register and manage textures - * for use in Flutter applications. - */ -export class FlutterRenderer implements TextureRegistry { - private flutterNapi: FlutterNapi; - private static globalTextureId: number = 0; - - /** - * Constructs a new FlutterRenderer instance. - * @param flutterNapi - The FlutterNapi instance for native communication - */ - constructor(flutterNapi: FlutterNapi) { - this.flutterNapi = flutterNapi; - } - - /** - * @deprecated since 3.7 - */ - createSurfaceTexture(): SurfaceTextureEntry { - let receiver: image.ImageReceiver = this.getImageReceiver(); - return this.registerSurfaceTexture(receiver); - } - - /** - * Gets the next available texture ID. - * @returns A unique texture ID - */ - getTextureId(): number { - let nextTextureId: number = FlutterRenderer.globalTextureId + 1; - FlutterRenderer.globalTextureId = FlutterRenderer.globalTextureId + 1; - Log.i(TAG, "getTextureId: " + nextTextureId) - return nextTextureId; - } - - /** - * Registers a texture with the Flutter engine. - * @param textureId - The texture ID to register - * @returns A SurfaceTextureEntry containing the registered texture information - */ - registerTexture(textureId: number): SurfaceTextureEntry { - let surfaceTextureRegistryEntry = new SurfaceTextureRegistryEntry(textureId); - let surfaceId = this.flutterNapi.registerTexture(textureId); - Log.i(TAG, "registerTexture, surfaceId=" + surfaceId); - surfaceTextureRegistryEntry.setSurfaceId(surfaceId); - let nativeWindowId = this.flutterNapi.getTextureNativeWindowId(textureId); - surfaceTextureRegistryEntry.setNativeWindowId(nativeWindowId); - let nativeWindowPtr = this.flutterNapi.getTextureNativeWindowPtr(textureId); - surfaceTextureRegistryEntry.setNativeWindowPtr(nativeWindowPtr); - return surfaceTextureRegistryEntry; - } - - /** - * @deprecated since 3.7 - */ - registerSurfaceTexture(receiver: image.ImageReceiver): SurfaceTextureEntry { - let nextTextureId: number = FlutterRenderer.globalTextureId + 1; - FlutterRenderer.globalTextureId = FlutterRenderer.globalTextureId + 1; - let surfaceTextureRegistryEntry = new SurfaceTextureRegistryEntry(nextTextureId); - return surfaceTextureRegistryEntry; - } - - /** - * Registers a PixelMap as a texture. - * @param pixelMap - The PixelMap to register - * @returns The texture ID assigned to the PixelMap - */ - registerPixelMap(pixelMap: PixelMap): number { - let nextTextureId: number = this.getTextureId(); - this.flutterNapi.registerPixelMap(nextTextureId, pixelMap); - return nextTextureId; - } - - /** - * Sets the background PixelMap for a texture. - * @param textureId - The texture ID - * @param pixelMap - The PixelMap to use as background - */ - setTextureBackGroundPixelMap(textureId: number, pixelMap: PixelMap): void { - this.flutterNapi.setTextureBackGroundPixelMap(textureId, pixelMap); - } - - /** - * @deprecated since 3.7 - */ - setTextureBackGroundColor(textureId: number, color: number): void { - this.flutterNapi.setTextureBackGroundColor(textureId, color); - } - - /** - * Sets the buffer size for a texture. - * @param textureId - The texture ID - * @param width - The buffer width - * @param height - The buffer height - */ - setTextureBufferSize(textureId: number, width: number, height: number): void { - this.flutterNapi.setTextureBufferSize(textureId, width, height); - } - - /** - * Notifies the Flutter engine that a texture is being resized. - * @param textureId - The texture ID - * @param width - The new width - * @param height - The new height - */ - notifyTextureResizing(textureId: number, width: number, height: number): void { - this.flutterNapi.notifyTextureResizing(textureId, width, height); - } - - /** - * @deprecated since 3.22 - * @useinstead FlutterRenderer#setExternalNativeImagePtr - */ - setExternalNativeImage(textureId: number, native_image: number): boolean { - return this.flutterNapi.setExternalNativeImage(textureId, native_image); - } - - /** - * Sets an external native image pointer for a texture. - * @param textureId - The texture ID - * @param native_image_ptr - The native image pointer as a bigint - * @returns true if successful, false otherwise - */ - setExternalNativeImagePtr(textureId: number, native_image_ptr: bigint): boolean { - return this.flutterNapi.setExternalNativeImagePtr(textureId, native_image_ptr); - } - - /** - * Resets an external texture. - * @param textureId - The texture ID - * @param need_surfaceId - Whether a surface ID is needed - * @returns The result code - */ - resetExternalTexture(textureId: number, need_surfaceId: boolean): number { - return this.flutterNapi.resetExternalTexture(textureId, need_surfaceId); - } - - /** - * Unregisters a texture from the Flutter engine. - * @param textureId - The texture ID to unregister - */ - unregisterTexture(textureId: number): void { - this.flutterNapi.unregisterTexture(textureId); - } - - /** - * Called when the system needs to trim memory. - * @param level - The memory trim level - */ - onTrimMemory(level: number) { - throw new Error('Method not implemented.'); - } - - /** - * @deprecated since 3.7 - */ - private getImageReceiver(): image.ImageReceiver { - let receiver: image.ImageReceiver = image.createImageReceiver(640, 480, 4, 8); - if (receiver !== undefined) { - Log.i(TAG, '[camera test] ImageReceiver is ok'); - } else { - Log.i(TAG, '[camera test] ImageReceiver is not ok'); - } - receiver?.on('imageArrival', () => { - receiver.readNextImage().then(() => { receiver.release() }) - }) - return receiver; - } - -} - -/** - * Entry in the surface texture registry representing a registered texture. - * This class holds information about a texture including its ID, surface ID, and native window information. - */ -export class SurfaceTextureRegistryEntry implements SurfaceTextureEntry { - private textureId: number = 0; - private surfaceId: number = 0; - private nativeWindowId: number = 0; - private nativeWindowPtr: bigint = BigInt("0"); - private released: boolean = false; - - /** - * Constructs a new SurfaceTextureRegistryEntry instance. - * @param id - The texture ID - */ - constructor(id: number) { - this.textureId = id; - } - - /** - * Gets the texture ID. - * @returns The texture ID - */ - getTextureId(): number { - return this.textureId; - } - - /** - * Gets the surface ID. - * @returns The surface ID - */ - getSurfaceId(): number { - return this.surfaceId; - } - - /** - * @deprecated since 3.22 - * @useinstead SurfaceTextureRegistryEntry#getNativeWindowPtr - */ - getNativeWindowId(): number { - return this.nativeWindowId; - } - - /** - * Gets the native window pointer. - * @returns The native window pointer as a bigint - */ - getNativeWindowPtr(): bigint { - return this.nativeWindowPtr; - } - - /** - * Sets the surface ID. - * @param surfaceId - The surface ID to set - */ - setSurfaceId(surfaceId: number): void { - this.surfaceId = surfaceId; - } - - /** - * @deprecated since 3.22 - * @useinstead SurfaceTextureRegistryEntry#setNativeWindowPtr - */ - setNativeWindowId(nativeWindowId: number): void { - this.nativeWindowId = nativeWindowId; - } - - /** - * Sets the native window pointer. - * @param nativeWindowPtr - The native window pointer as a bigint - */ - setNativeWindowPtr(nativeWindowPtr: bigint): void { - this.nativeWindowPtr = nativeWindowPtr; - } - - /** - * Releases this texture entry and frees associated resources. - */ - release() { - throw new Error('Method not implemented.'); - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/renderer/FlutterUiDisplayListener.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/renderer/FlutterUiDisplayListener.ets deleted file mode 100644 index 733215c..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/renderer/FlutterUiDisplayListener.ets +++ /dev/null @@ -1,25 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on FlutterUiDisplayListener.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -/** - * Listener interface for Flutter UI display state changes. - * Implementations of this interface are notified when Flutter UI is displayed or hidden. - */ -export interface FlutterUiDisplayListener { - /** - * Called when Flutter UI is displayed for the first time. - */ - onFlutterUiDisplayed(): void; - - /** - * Called when Flutter UI is no longer displayed. - */ - onFlutterUiNoLongerDisplayed(): void; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/AccessibilityChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/AccessibilityChannel.ets deleted file mode 100644 index d141f8f..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/AccessibilityChannel.ets +++ /dev/null @@ -1,259 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on AccessibilityChannel.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import Log from '../../../util/Log'; -import DartExecutor from '../dart/DartExecutor'; -import BasicMessageChannel, { MessageHandler, Reply } from '../../../plugin/common/BasicMessageChannel'; -import HashMap from '@ohos.util.HashMap'; -import FlutterNapi, { AccessibilityDelegate } from '../FlutterNapi'; -import StandardMessageCodec from '../../../plugin/common/StandardMessageCodec'; -import StringUtils from '../../../util/StringUtils'; -import Any from '../../../plugin/common/Any'; -import flutter from 'libflutter.so'; -import { ByteBuffer } from '../../../util/ByteBuffer'; - -/** - * Channel for handling accessibility-related communication between Flutter and OpenHarmony. - * This channel manages accessibility features, semantics, and accessibility events. - */ -export default class AccessibilityChannel implements MessageHandler { - private static TAG = "AccessibilityChannel"; - private static CHANNEL_NAME = "flutter/accessibility"; - private channel: BasicMessageChannel; - private flutterNapi: FlutterNapi; - private handler: AccessibilityMessageHandler; - private nextReplyId: number = 1; - - /** - * Handles messages from Dart. - * @param message - The message object from Dart - * @param reply - The reply callback to send a response - */ - onMessage(message: object, reply: Reply): void { - if (this.handler == null) { - Log.i(AccessibilityChannel.TAG, "handler == NULL"); - reply.reply(StringUtils.stringToArrayBuffer("")); - return; - } - let annotatedEvent: HashMap = message as HashMap; - let type: string = annotatedEvent.get("type") as string; - let data: HashMap = annotatedEvent.get("data") as HashMap; - - Log.i(AccessibilityChannel.TAG, "Received " + type + " message."); - switch (type) { - case "announce": { - Log.i(AccessibilityChannel.TAG, "Announce"); - let announceMessage: string = data.get("message"); - if (announceMessage != null) { - Log.i(AccessibilityChannel.TAG, "message is " + announceMessage); - this.handler.announce(announceMessage); - } - break; - } - case "tap": { - Log.i(AccessibilityChannel.TAG, "Tag"); - let nodeId: number = annotatedEvent.get("nodeId"); - if (nodeId != null) { - this.handler.onTap(nodeId); - } - break; - } - case "longPress": { - Log.i(AccessibilityChannel.TAG, "LongPress"); - let nodeId: number = annotatedEvent.get("nodeId"); - if (nodeId != null) { - this.handler.onLongPress(nodeId); - } - break; - } - case "tooltip": { - Log.i(AccessibilityChannel.TAG, "ToolTip"); - let tooltipMessage: string = data.get("message"); - if (tooltipMessage != null) { - this.handler.onTooltip(tooltipMessage); - } - break; - } - } - reply.reply(StringUtils.stringToArrayBuffer("")); - } - - /** - * Constructs a new AccessibilityChannel instance. - * @param dartExecutor - The DartExecutor for sending messages to Dart - * @param flutterNapi - The FlutterNapi instance for native communication - */ - constructor(dartExecutor: DartExecutor, flutterNapi: FlutterNapi) { - Log.i(AccessibilityChannel.TAG, "Channel entered"); - this.channel = - new BasicMessageChannel(dartExecutor, AccessibilityChannel.CHANNEL_NAME, StandardMessageCodec.INSTANCE); - this.channel.setMessageHandler(this); - this.flutterNapi = flutterNapi; - this.handler = new DefaultHandler(this.flutterNapi); - } - - /** - * Called when OpenHarmony accessibility is enabled. - */ - onOhosAccessibilityEnabled(): void { - let replyId: number = this.nextReplyId++; - this.flutterNapi.setSemanticsEnabledWithRespId(true, replyId); - Log.i(AccessibilityChannel.TAG, "onOhosAccessibilityEnabled = true"); - } - - /** - * Called when OpenHarmony accessibility features change. - * @param accessibilityFeatureFlags - The accessibility feature flags - */ - onOhosAccessibilityFeatures(accessibilityFeatureFlags: number): void { - let replyId: number = this.nextReplyId++; - this.flutterNapi.setAccessibilityFeatures(accessibilityFeatureFlags, replyId); - Log.i(AccessibilityChannel.TAG, "onOhosAccessibilityFeatures"); - } - - /** - * Dispatches a semantics action to Flutter. - * @param virtualViewId - The virtual view ID - * @param action - The accessibility action to dispatch - */ - dispatchSemanticsAction(virtualViewId: number, action: Action): void { - let replyId: number = this.nextReplyId++; - this.flutterNapi.dispatchSemanticsAction(virtualViewId, action, replyId); - Log.i(AccessibilityChannel.TAG, "dispatchSemanticsAction"); - } - - /** - * Sets the accessibility message handler. - * @param handler - The AccessibilityMessageHandler instance - */ - setAccessibilityMessageHandler(handler: AccessibilityMessageHandler): void { - this.handler = handler; - let replyId: number = this.nextReplyId++; - this.flutterNapi.setAccessibilityDelegate(handler, replyId); - } -} - -/** - * Interface for handling accessibility messages. - */ -export interface AccessibilityMessageHandler extends AccessibilityDelegate { - /** - * Announces a message to the user. - * @param message - The message to announce - */ - announce(message: string): void; - - /** - * Handles a tap event on an accessibility node. - * @param nodeId - The ID of the accessibility node - */ - onTap(nodeId: number): void; - - /** - * Handles a long press event on an accessibility node. - * @param nodeId - The ID of the accessibility node - */ - onLongPress(nodeId: number): void; - - /** - * Handles a tooltip event. - * @param nodeId - The tooltip node ID - */ - onTooltip(nodeId: string): void; -} - -/** - * Default implementation of AccessibilityMessageHandler. - * Handles accessibility events and forwards them to the native Flutter engine. - */ -export class DefaultHandler implements AccessibilityMessageHandler { - private static TAG = "AccessibilityMessageHandler"; - private flutterNapi: FlutterNapi; - - /** - * Constructs a new DefaultHandler instance. - * @param flutterNapi - The FlutterNapi instance for native communication - */ - constructor(flutterNapi: FlutterNapi) { - this.flutterNapi = flutterNapi; - } - - /** - * Announces a message to the user. - * @param message - The message to announce - */ - announce(message: string): void { - Log.i(DefaultHandler.TAG, "handler announce."); - flutter.nativeAccessibilityAnnounce(this.flutterNapi.nativeShellHolderId!, message); - } - - /** - * Handles a tap event on an accessibility node. - * @param nodeId - The ID of the accessibility node - */ - onTap(nodeId: number): void { - Log.i(DefaultHandler.TAG, "handler onTap."); - flutter.nativeAccessibilityOnTap(this.flutterNapi.nativeShellHolderId!, nodeId); - } - - /** - * Handles a long press event on an accessibility node. - * @param nodeId - The ID of the accessibility node - */ - onLongPress(nodeId: number): void { - Log.i(DefaultHandler.TAG, "handler onLongPress."); - flutter.nativeAccessibilityOnLongPress(this.flutterNapi.nativeShellHolderId!, nodeId); - } - - /** - * Handles a tooltip event. - * @param message - The tooltip message - */ - onTooltip(message: string): void { - Log.i(DefaultHandler.TAG, "handler onTooltip."); - flutter.nativeAccessibilityOnTooltip(this.flutterNapi.nativeShellHolderId!, message); - } - - /** - * Called when accessibility state changes. - * @param state - The new accessibility state - */ - accessibilityStateChange(state: Boolean): void { - Log.i(DefaultHandler.TAG, "handler accessibilityStateChange"); - } -} - -/** - * Accessibility actions that can be performed on semantic nodes. - */ -export enum Action { - TAP = 1 << 0, - LONG_PRESS = 1 << 1, - SCROLL_LEFT = 1 << 2, - SCROLL_RIGHT = 1 << 3, - SCROLL_UP = 1 << 4, - SCROLL_DOWN = 1 << 5, - INCREASE = 1 << 6, - DECREASE = 1 << 7, - SHOW_ON_SCREEN = 1 << 8, - MOVE_CURSOR_FORWARD_BY_CHARACTER = 1 << 9, - MOVE_CURSOR_BACKWARD_BY_CHARACTER = 1 << 10, - SET_SELECTION = 1 << 11, - COPY = 1 << 12, - CUT = 1 << 13, - PASTE = 1 << 14, - DID_GAIN_ACCESSIBILITY_FOCUS = 1 << 15, - DID_LOSE_ACCESSIBILITY_FOCUS = 1 << 16, - CUSTOM_ACTION = 1 << 17, - DISMISS = 1 << 18, - MOVE_CURSOR_FORWARD_BY_WORD = 1 << 19, - MOVE_CURSOR_BACKWARD_BY_WORD = 1 << 20, - SET_NEXT = 1 << 21, -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/DisplayMetricsChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/DisplayMetricsChannel.ets deleted file mode 100644 index fd44a8a..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/DisplayMetricsChannel.ets +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2026 Huawei Device Co., Ltd. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE_HW file. - */ - -import MethodCall from '../../../plugin/common/MethodCall'; -import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; -import StandardMethodCodec from '../../../plugin/common/StandardMethodCodec'; -import Log from '../../../util/Log'; -import DartExecutor from '../dart/DartExecutor'; -import { common } from '@kit.AbilityKit'; - -const TAG: string = 'DisplayMetricsChannel'; - -export default class DisplayMetricsChannel implements MethodCallHandler { - public channel: MethodChannel; - public context: common.Context; - - onMethodCall(call: MethodCall, result: MethodResult): void { - let method: string = call.method; - Log.i(TAG, "Received '" + method + "' message."); - try { - // More methods are expected to be added here, hence the switch. - switch (method) { - case "updateDpiScale": - let dpiScaleFactor: number = call.argument('dpiScale'); - Log.i(TAG, "Received dpiScaleFactor '" + dpiScaleFactor + "' message."); - this.context.eventHub.emit('changeDevicePixelRatio', dpiScaleFactor) - result.success(true); - break; - default: - result.notImplemented(); - break; - } - } catch (error) { - result.error("error", "UnHandled error: " + JSON.stringify(error), null) - } - } - - constructor(dartExecutor: DartExecutor, context: common.Context) { - this.channel = new MethodChannel(dartExecutor, "flutter/displaymetrics", StandardMethodCodec.INSTANCE); - this.channel.setMethodCallHandler(this); - this.context = context; - } -} - diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/KeyEventChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/KeyEventChannel.ets deleted file mode 100644 index de5ff4f..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/KeyEventChannel.ets +++ /dev/null @@ -1,259 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on KeyEventChannel.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import BasicMessageChannel from '../../../plugin/common/BasicMessageChannel'; -import { BinaryMessenger } from '../../../plugin/common/BinaryMessenger'; -import Log from '../../../util/Log'; -import JSONMessageCodec from '../../../plugin/common/JSONMessageCodec'; -import { KeyCode } from '@kit.InputKit'; -import { ModifierKeyMetaInfo } from '../../ohos/KeyboardMap' -import Any from '../../../plugin/common/Any'; - -/** - * Channel for handling keyboard key events between OpenHarmony and Flutter. - * This channel manages communication of key events, including both hardware keyboard events - * and simulated key events for soft-keyboard text-editing. It uses a BasicMessageChannel - * with JSON encoding to send key event data to the Flutter framework. - */ -export default class KeyEventChannel { - private static TAG = "KeyEventChannel"; - private static CHANNEL_NAME = "flutter/keyevent"; - private channel: BasicMessageChannel; - - /** - * Constructs a new KeyEventChannel instance. - * @param binaryMessenger - The BinaryMessenger for sending messages to Dart - */ - constructor(binaryMessenger: BinaryMessenger) { - this.channel = new BasicMessageChannel(binaryMessenger, KeyEventChannel.CHANNEL_NAME, - JSONMessageCodec.INSTANCE); - } - - /** - * Sends a hardware key event to the Flutter framework. - * The event is encoded and sent asynchronously. The response handler will be called - * when Flutter responds, indicating whether the event was handled. - * @param keyEvent - The FlutterKeyEvent containing the OpenHarmony key event data - * @param isKeyUp - Whether this is a key up event (true) or key down event (false) - * @param responseHandler - Handler to receive the response from Flutter indicating if the event was handled - */ - sendFlutterKeyEvent(keyEvent: FlutterKeyEvent, - isKeyUp: boolean, - responseHandler: EventResponseHandler): void { - this.channel.send(this.encodeKeyEvent(keyEvent, isKeyUp), - (message: Object) => { - let isEventHandled = false; - try { - if (message != null) { - const tmp: Record = message as Record; - isEventHandled = tmp["handled"] || false; - } - } catch (e) { - Log.e(KeyEventChannel.TAG, "Unable to unpack JSON message: " + e); - } - responseHandler.onFrameworkResponse(isEventHandled); - } - ); - } - - private encodeKeyEvent(keyEvent: FlutterKeyEvent, isKeyUp: boolean): Map { - let message: Map = new Map(); - message.set("type", isKeyUp ? "keyup" : "keydown"); - message.set("keymap", "ohos"); - message.set("keyCode", keyEvent.event.keyCode); - message.set("deviceId", keyEvent.event.deviceId); - message.set("flags", keyEvent.event.keyText); - // the keyEvent of ohos do not support the getMetaState feature, - // so the flutter-ohos side adapts the getMetaState() method - message.set("metaState", keyEvent.getMetaState()); - message.set("source", keyEvent.event.keySource); - message.set("intentionCode", keyEvent.event.intentionCode); - return message; - } - - /** - * Sends a simulated key event for soft-keyboard text-editing in the input method. - * This method is used for virtual keyboard events (e.g., arrow keys, selection keys) - * that are generated programmatically rather than from hardware input. - * @param keyEvent - The SimulateKeyEvent containing the simulated key data - * @param isKeyUp - Whether this is a key up event (true) or key down event (false) - * @param responseHandler - Handler to receive the response from Flutter indicating if the event was handled - */ - simulateSendFlutterKeyEvent(keyEvent: SimulateKeyEvent, - isKeyUp: boolean, - responseHandler: EventResponseHandler): void { - this.channel.send(this.encodeSimulatedKeyEvent(keyEvent, isKeyUp), - (message: Object) => { - let isEventHandled = false; - try { - if (message !== null) { - const tmp: Record = message as Record; - isEventHandled = tmp["handled"] || false; - } - } catch (e) { - Log.e(KeyEventChannel.TAG, "Unable to unpack JSON message: " + e); - } - responseHandler.onFrameworkResponse(isEventHandled); - } - ); - } - - private encodeSimulatedKeyEvent(keyEvent: SimulateKeyEvent, isKeyUp: boolean): Map { - let message: Map = new Map(); - message.set("type", isKeyUp ? "keyup" : "keydown"); - message.set("keymap", "ohos"); - message.set("keyCode", keyEvent.keyCode); - message.set("flags", keyEvent.keyText); - return message; - } -} - -/** - * Interface for handling event responses from the Flutter framework. - * Implementations of this interface receive callbacks when Flutter processes - * key events and indicates whether the event was handled. - */ -export interface EventResponseHandler { - /** - * Called when Flutter responds to a key event. - * This callback is invoked asynchronously after Flutter processes the key event. - * @param isEventHandled - Whether Flutter handled the event (true) or not (false) - */ - onFrameworkResponse: (isEventHandled: boolean) => void; -} - -/** - * Wrapper for OpenHarmony KeyEvent that provides Flutter-compatible meta state information. - * OpenHarmony KeyEvent does not natively support meta state tracking for modifier keys - * (Ctrl, Alt, Shift) in the same way Flutter expects. This class supplements the missing - * functionality by tracking modifier key states and providing a getMetaState() method - * that returns a bitmask compatible with Flutter's key event handling. - */ -export class FlutterKeyEvent { - /** The underlying OpenHarmony KeyEvent instance. */ - event: KeyEvent; - private mMetaState: number; - private isCtrlPressed: boolean | undefined = false; - private isAltPressed: boolean | undefined = false; - private isShiftPressed: boolean | undefined = false; - - /** - * Constructs a new FlutterKeyEvent instance. - * @param ohosKeyEvent - The OpenHarmony KeyEvent to wrap - */ - constructor(ohosKeyEvent: KeyEvent) { - this.event = ohosKeyEvent; - this.mMetaState = ModifierKeyMetaInfo.NONE; - this.isCtrlPressed = ohosKeyEvent.getModifierKeyState && ohosKeyEvent.getModifierKeyState(['Ctrl']); - this.isAltPressed = ohosKeyEvent.getModifierKeyState && ohosKeyEvent.getModifierKeyState(['Alt']); - this.isShiftPressed = ohosKeyEvent.getModifierKeyState && ohosKeyEvent.getModifierKeyState(['Shift']); - this.didUpdateOhosMetaState(); - } - - /** - * Gets the meta state value as a bitmask. - * This supplements the missing metaState feature of OpenHarmony when pressing - * modifier keys (Ctrl, Alt, Shift) to perform combination key operations. - * The meta state is a bitmask that indicates which modifier keys are currently pressed. - * Currently only supports metaState tracking for Ctrl, Alt, and Shift keys. - * @returns The meta state value as a bitmask indicating pressed modifier keys - */ - getMetaState(): number { - return this.mMetaState; - } - - private didUpdateOhosMetaState(): void { - // The ohos platform only supports whether the Ctrl/Alt/Shift key or combination of them is pressed or not, - // and cannot distinguish the left or right directions. - // Here, the left direction key of ctrl/alt/shift is used by default - if (this.isCtrlPressed != undefined) { - this.updateMetaStateIfNeeded(KeyCode.KEYCODE_CTRL_LEFT, this.isCtrlPressed); - } - if (this.isAltPressed != undefined) { - this.updateMetaStateIfNeeded(KeyCode.KEYCODE_ALT_LEFT, this.isAltPressed); - } - if (this.isShiftPressed != undefined) { - this.updateMetaStateIfNeeded(KeyCode.KEYCODE_SHIFT_LEFT, this.isShiftPressed); - } - } - - private updateMetaStateIfNeeded(keyCode: number, isPressed: boolean): void { - const oldMetaState: number = this.mMetaState; - const newMetaState: number = this.updateMetaState(keyCode, isPressed, oldMetaState); - const isMetaStateChanged: number = oldMetaState ^ newMetaState; - if (isMetaStateChanged) { - this.mMetaState = newMetaState; - } - } - - private updateMetaState(keyCode: number, isPressed: boolean, oldMetaState: number): number { - switch (keyCode) { - case KeyCode.KEYCODE_ALT_LEFT: - return this.setMetaState(ModifierKeyMetaInfo.ALT_LEFT, isPressed, oldMetaState); - case KeyCode.KEYCODE_ALT_RIGHT: - return this.setMetaState(ModifierKeyMetaInfo.ALT_RIGHT, isPressed, oldMetaState); - case KeyCode.KEYCODE_SHIFT_LEFT: - return this.setMetaState(ModifierKeyMetaInfo.SHIFT_LEFT, isPressed, oldMetaState); - case KeyCode.KEYCODE_SHIFT_RIGHT: - return this.setMetaState(ModifierKeyMetaInfo.SHIFT_RIGHT, isPressed, oldMetaState); - case KeyCode.KEYCODE_CTRL_LEFT: - return this.setMetaState(ModifierKeyMetaInfo.CTRL_LEFT, isPressed, oldMetaState); - case KeyCode.KEYCODE_CTRL_RIGHT: - return this.setMetaState(ModifierKeyMetaInfo.CTRL_RIGHT, isPressed, oldMetaState); - default: - return oldMetaState; - } - } - - private setMetaState(mask: number, isPressed: boolean, oldMetaState: number): number { - let newMetaState: number; - if (isPressed) { // set the metaState of the pressed modifier key - newMetaState = oldMetaState | mask; - } else { // reset/clear the metaState of all modifier keys (ctrl|alt|shift|win/cmd) - newMetaState = oldMetaState & - ~(mask | ModifierKeyMetaInfo.CTRL | ModifierKeyMetaInfo.ALT | - ModifierKeyMetaInfo.SHIFT | ModifierKeyMetaInfo.META); - } - // Update the non-sided modifier key metaState to match the content of the sided ones. - if (newMetaState & (ModifierKeyMetaInfo.ALT_LEFT | ModifierKeyMetaInfo.ALT_RIGHT)) { - newMetaState |= ModifierKeyMetaInfo.ALT; - } - if (newMetaState & (ModifierKeyMetaInfo.SHIFT_LEFT | ModifierKeyMetaInfo.SHIFT_RIGHT)) { - newMetaState |= ModifierKeyMetaInfo.SHIFT; - } - if (newMetaState & (ModifierKeyMetaInfo.CTRL_LEFT | ModifierKeyMetaInfo.CTRL_RIGHT)) { - newMetaState |= ModifierKeyMetaInfo.CTRL; - } - return newMetaState; - } -} - -/** - * Simulated key event used in soft-keyboard text-editing. - * This class represents a programmatically generated key event, typically used - * for virtual keyboard interactions such as arrow keys, selection keys, or - * other input method editor (IME) operations. Unlike FlutterKeyEvent, this - * does not wrap a hardware KeyEvent and contains only the essential key information. - */ -export class SimulateKeyEvent { - /** The key code value identifying which key was pressed. */ - keyCode: number; - /** The text representation of the key (e.g., "Arrow Up", "Shift"). */ - keyText: string; - /** - * Constructs a new SimulateKeyEvent instance. - * @param keyCode - The key code value (e.g., KeyCode.KEYCODE_DPAD_UP) - * @param keyText - The text representation of the key (e.g., "Arrow Up") - */ - constructor(keyCode: number, keyText: string) { - this.keyCode = keyCode; - this.keyText = keyText; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/KeyboardChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/KeyboardChannel.ets deleted file mode 100644 index 9902e27..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/KeyboardChannel.ets +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2021-2025 Huawei Device Co., Ltd. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE_HW file. - */ - - -import DartExecutor from '../dart/DartExecutor'; -import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; -import MethodCall from '../../../plugin/common/MethodCall'; -import StandardMethodCodec from '../../../plugin/common/StandardMethodCodec'; -import Log from '../../../util/Log'; - -/** - * Channel for handling keyboard-related communication between Flutter and OpenHarmony. - * This channel manages keyboard state queries and keyboard method calls. - */ -export default class KeyboardChannel implements MethodCallHandler { - private static TAG = "KeyboardChannel"; - private static CHANNEL_NAME = "flutter/keyboard"; - private channel: MethodChannel; - private handler: KeyboardMethodHandler | null = null; - - /** - * Handles method calls from Dart. - * @param call - The method call from Dart - * @param result - The result callback to send a response - */ - onMethodCall(call: MethodCall, result: MethodResult): void { - if (this.handler == null) { - Log.i(KeyboardChannel.TAG, "KeyboardMethodHandler is null"); - return; - } - - let method: string = call.method; - switch (method) { - case "getKeyboardState": { - Log.i(KeyboardChannel.TAG, "getKeyboardState enter"); - result.success(this.handler?.getKeyboardState()); - break; - } - default: { - result.notImplemented(); - break; - } - } - } - - /** - * Constructs a new KeyboardChannel instance. - * @param dartExecutor - The DartExecutor for sending messages to Dart - */ - constructor(dartExecutor: DartExecutor) { - this.channel = new MethodChannel(dartExecutor, KeyboardChannel.CHANNEL_NAME, StandardMethodCodec.INSTANCE); - this.channel.setMethodCallHandler(this); - } - - /** - * Sets the keyboard method handler for processing keyboard-related requests. - * @param keyboardMessageHandler - The KeyboardMethodHandler instance, or null to remove - */ - public setKeyboardMethodHandler(keyboardMessageHandler: KeyboardMethodHandler | null): void { - this.handler = keyboardMessageHandler; - } -} - -/** - * Interface for handling keyboard method calls. - */ -export interface KeyboardMethodHandler { - /** - * Gets the current keyboard state. - * @returns A map containing keyboard state information - */ - getKeyboardState(): Map; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/LifecycleChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/LifecycleChannel.ets deleted file mode 100644 index 98b75ff..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/LifecycleChannel.ets +++ /dev/null @@ -1,119 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on LifecycleChannel.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import Log from '../../../util/Log'; -import StringCodec from '../../../plugin/common/StringCodec'; -import DartExecutor from '../dart/DartExecutor'; -import BasicMessageChannel from '../../../plugin/common/BasicMessageChannel'; - -/** - * Channel for handling application lifecycle events. - * This channel manages communication of lifecycle state changes between OpenHarmony and Flutter, - * including resumed, inactive, paused, and detached states. - */ -export default class LifecycleChannel { - private static TAG = "LifecycleChannel"; - private static CHANNEL_NAME = "flutter/lifecycle"; - // These should stay in sync with the AppLifecycleState enum in the framework. - private static RESUMED = "AppLifecycleState.resumed"; - private static INACTIVE = "AppLifecycleState.inactive"; - private static PAUSED = "AppLifecycleState.paused"; - private static DETACHED = "AppLifecycleState.detached"; - private lastOhosState = ""; - private lastFlutterState = ""; - private lastFocus = true; - private channel: BasicMessageChannel; - - /** - * Constructs a new LifecycleChannel instance. - * @param dartExecutor - The DartExecutor for sending messages to Dart - */ - constructor(dartExecutor: DartExecutor) { - this.channel = new BasicMessageChannel(dartExecutor, LifecycleChannel.CHANNEL_NAME, StringCodec.INSTANCE) - } - - /** - * Called when at least one window in the app has focus. - */ - aWindowIsFocused(): void { - this.sendState(this.lastOhosState, true); - } - - /** - * Called when no windows in the app have focus. - */ - noWindowsAreFocused(): void { - this.sendState(this.lastOhosState, false); - } - - /** - * Called when the app is resumed. - */ - appIsResumed(): void { - this.sendState(LifecycleChannel.RESUMED, this.lastFocus); - } - - /** - * Called when the app is inactive. - */ - appIsInactive(): void { - this.sendState(LifecycleChannel.INACTIVE, this.lastFocus); - } - - /** - * Called when the app is paused. - */ - appIsPaused(): void { - this.sendState(LifecycleChannel.PAUSED, this.lastFocus); - } - - /** - * Called when the app is detached. - */ - appIsDetached(): void { - this.sendState(LifecycleChannel.DETACHED, this.lastFocus); - } - - // Here's the state table this implements: - // - // | UIAbility State | Window focused | Flutter state | - // |-----------------|----------------|---------------| - // | onCreate | true | resumed | - // | onCreate | false | inactive | - // | onForeground | true | resumed | - // | onForeground | false | inactive | - // | onBackground | true | paused | - // | onBackground | false | paused | - // | onDestroy | true | detached | - // | onDestroy | false | detached | - - private sendState(state: string, hasFocus: boolean): void { - if (this.lastOhosState == state && hasFocus == this.lastFocus) { - // No inputs changed, so Flutter state could not have changed. - return; - } - let newState: string; - if (state == LifecycleChannel.RESUMED) { - newState = hasFocus ? LifecycleChannel.RESUMED : LifecycleChannel.INACTIVE; - } else { - newState = state; - } - // Keep the last reported values for future updates. - this.lastOhosState = state; - this.lastFocus = hasFocus; - if (newState == this.lastFlutterState) { - // No change in the resulting Flutter state, so don't report anything. - return; - } - Log.i(LifecycleChannel.TAG, "Sending " + newState + " message."); - this.channel.send(newState); - this.lastFlutterState = newState; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/LocalizationChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/LocalizationChannel.ets deleted file mode 100644 index a8ce802..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/LocalizationChannel.ets +++ /dev/null @@ -1,104 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on LocalizationChannel.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import DartExecutor from '../dart/DartExecutor'; -import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; -import MethodCall from '../../../plugin/common/MethodCall'; -import List from '@ohos.util.List'; -import JSONMethodCodec from '../../../plugin/common/JSONMethodCodec'; -import intl from '@ohos.intl'; -import Log from '../../../util/Log'; - -const TAG = "LocalizationChannel"; - -/** - * Channel for handling localization-related communication between Flutter and OpenHarmony. - * This channel manages locale information and string resource retrieval. - */ -export default class LocalizationChannel implements MethodCallHandler { - private static TAG = "LocalizationChannel"; - private static CHANNEL_NAME = "flutter/localization"; - private channel: MethodChannel; - private localizationMessageHandler: LocalizationMessageHandler | null = null; - - /** - * Handles method calls from Dart. - * @param call - The method call from Dart - * @param result - The result callback to send a response - */ - onMethodCall(call: MethodCall, result: MethodResult): void { - if (this.localizationMessageHandler == null) { - Log.e(TAG, "localizationMessageHandler is null"); - return; - } - let method: string = call.method; - switch (method) { - case "Localization.getStringResource": { - Log.i(TAG, "Localization.getStringResource enter"); - let key: string = call.argument("key"); - let localeString: string = ""; - if (call.hasArgument("locale")) { - localeString = call.argument("locale"); - } - result.success(this.localizationMessageHandler?.getStringResource(key, localeString)); - break; - } - default: { - result.notImplemented(); - break; - } - } - } - - /** - * Constructs a new LocalizationChannel instance. - * @param dartExecutor - The DartExecutor for sending messages to Dart - */ - constructor(dartExecutor: DartExecutor) { - this.channel = new MethodChannel(dartExecutor, LocalizationChannel.CHANNEL_NAME, JSONMethodCodec.INSTANCE); - this.channel.setMethodCallHandler(this); - } - - /** - * Sets the localization message handler for processing localization requests. - * @param localizationMessageHandler - The LocalizationMessageHandler instance - */ - setLocalizationMessageHandler(localizationMessageHandler: LocalizationMessageHandler): void { - this.localizationMessageHandler = localizationMessageHandler; - } - - /** - * Sends locale information to Flutter. - * @param locales - Array of locale strings to send - */ - sendLocales(locales: string[]): void { - let data: string[] = []; - for (let i = 0; i < locales.length; i++) { - let locale = new intl.Locale(locales[i]); - data.push(locale.language); - data.push(locale.region); - data.push(locale.script); - data.push(''); // locale.getVariant locale的一种变体 - } - this.channel.invokeMethod("setLocale", data); - } -} - -/** - * Interface for handling localization message requests. - */ -export interface LocalizationMessageHandler { - /** - * Gets a string resource by key and locale. - * @param key - The resource key - * @param local - The locale string - */ - getStringResource(key: string, local: string): void; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/MouseCursorChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/MouseCursorChannel.ets deleted file mode 100644 index 9bba2eb..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/MouseCursorChannel.ets +++ /dev/null @@ -1,104 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on MouseCursorChannel.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import HashMap from '@ohos.util.HashMap'; -import MethodCall from '../../../plugin/common/MethodCall'; -import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; -import StandardMethodCodec from '../../../plugin/common/StandardMethodCodec'; -import Log from '../../../util/Log'; -import DartExecutor from '../dart/DartExecutor'; - -const TAG: string = 'MouseCursorChannel'; - -/** - * Channel for handling mouse cursor changes. - * This channel manages communication between Flutter and OpenHarmony for cursor appearance changes. - */ -export default class MouseCursorChannel implements MethodCallHandler { - /** The MethodChannel for mouse cursor communication with Flutter. */ - public channel: MethodChannel; - private mouseCursorMethodHandler: MouseCursorMethodHandler | null = null; - - /** - * Handles method calls from Dart. - * @param call - The method call from Dart - * @param result - The result callback to send a response - */ - onMethodCall(call: MethodCall, result: MethodResult): void { - if (this.mouseCursorMethodHandler === null) { - // if no explicit mouseCursorMethodHandler has been registered then we don't - // need to formed this call to an API. Return - Log.e(TAG, "mouseCursorMethodHandler is null") - return; - } - - let method: string = call.method; - Log.i(TAG, "Received '" + method + "' message."); - try { - // More methods are expected to be added here, hence the switch. - switch (method) { - case "activateSystemCursor": - let argument: HashMap = call.args; - let kind: string = argument.get("kind"); - try { - this.mouseCursorMethodHandler.activateSystemCursor(kind); - } catch (err) { - result.error("error", "Error when setting cursors: " + JSON.stringify(err), null); - break; - } - result.success(true); - break; - default: - break; - } - } catch (error) { - result.error("error", "UnHandled error: " + JSON.stringify(error), null) - } - } - - /** - * Constructs a new MouseCursorChannel instance. - * @param dartExecutor - The DartExecutor for sending messages to Dart - */ - constructor(dartExecutor: DartExecutor) { - this.channel = new MethodChannel(dartExecutor, "flutter/mousecursor", StandardMethodCodec.INSTANCE); - this.channel.setMethodCallHandler(this); - } - - /** - * Sets the MouseCursorMethodHandler which receives all events and requests that are - * parsed from the underlying platform channel. - * @param mouseCursorMethodHandler - The MouseCursorMethodHandler instance, or null to remove - */ - public setMethodHandler(mouseCursorMethodHandler: MouseCursorMethodHandler | null): void { - this.mouseCursorMethodHandler = mouseCursorMethodHandler; - } - - /** - * Synthesizes a method call for testing purposes. - * @param call - The method call to synthesize - * @param result - The result callback to send a response - */ - public synthesizeMethodCall(call: MethodCall, result: MethodResult): void { - this.onMethodCall(call, result); - } -} - -/** - * Interface for handling mouse cursor method calls. - */ -export interface MouseCursorMethodHandler { - /** - * Called when the pointer should start displaying a system mouse cursor - * specified by the kind parameter. - * @param kind - The cursor kind/type to activate - */ - activateSystemCursor(kind: String): void; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/NativeVsyncChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/NativeVsyncChannel.ets deleted file mode 100644 index b962bde..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/NativeVsyncChannel.ets +++ /dev/null @@ -1,91 +0,0 @@ -/* -* Copyright (c) 2024 Hunan OpenValley Digital Industry Development Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -import Log from '../../../util/Log'; -import DartExecutor from '../dart/DartExecutor'; -import HashMap from '@ohos.util.HashMap'; -import StringUtils from '../../../util/StringUtils'; -import Any from '../../../plugin/common/Any'; -import FlutterNapi from '../FlutterNapi'; -import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; -import MethodCall from '../../../plugin/common/MethodCall'; -import StandardMethodCodec from '../../../plugin/common/StandardMethodCodec'; - -/** - * Types of animation voting. - */ -enum AnimationVotingType { - TRANSLATE = 0, - SCALE, - RATATION, -} - -/** - * Channel for handling native VSync functionality. - * This channel manages VSync switching, animation velocity voting, and LTPO switch state checking. - */ -export default class NativeVsyncChannel implements MethodCallHandler { - private static TAG = "NativeVsyncChannel"; - private static CHANNEL_NAME = "flutter/nativevsync"; - /** The MethodChannel for native VSync communication with Flutter. */ - public channel: MethodChannel; - private flutterNapi: FlutterNapi; - - /** - * Handles method calls from Dart. - * @param call - The method call from Dart - * @param result - The result callback to send a response - */ - onMethodCall(call: MethodCall, result: MethodResult): void { - let method: string = call.method; - try { - switch (method) { - case "isEnable": - // Whether to enable DVsync - let isEnable: boolean = call.argument('isEnable'); - this.flutterNapi.SetDVsyncSwitch(isEnable); - break; - case "sendVelocity": - // Send animation velocity - let type: string = call.argument('type'); - let velocity: number = call.argument('velocity'); - if (type == "translate") { - FlutterNapi.animationVoting(AnimationVotingType.TRANSLATE, velocity); - } - break; - case "checkLTPOSwitchStatus": - // Check LTPO switch state - result.success(FlutterNapi.checkLTPOSwitchState()); - break; - default: - result.notImplemented(); - break; - } - } catch (error) { - result.error("error", "UnHandled error: " + JSON.stringify(error), null) - } - } - - /** - * Constructs a new NativeVsyncChannel instance. - * @param dartExecutor - The DartExecutor for sending messages to Dart - * @param flutterNapi - The FlutterNapi instance for native communication - */ - constructor(dartExecutor: DartExecutor, flutterNapi: FlutterNapi) { - this.channel = new MethodChannel(dartExecutor, NativeVsyncChannel.CHANNEL_NAME, StandardMethodCodec.INSTANCE); - this.channel.setMethodCallHandler(this); - this.flutterNapi = flutterNapi; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/NavigationChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/NavigationChannel.ets deleted file mode 100644 index 027f79d..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/NavigationChannel.ets +++ /dev/null @@ -1,241 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on NavigationChannel.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import { common } from '@kit.AbilityKit'; -import hiTraceMeter from '@ohos.hiTraceMeter'; - -import JSONMethodCodec from '../../../plugin/common/JSONMethodCodec'; -import MethodCall from '../../../plugin/common/MethodCall'; -import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; -import Log from '../../../util/Log'; -import DartExecutor from '../dart/DartExecutor'; -import FlutterManager from '../../ohos/FlutterManager'; -import Any from '../../../plugin/common/Any'; - -/** - * Navigator activity types. - */ -export enum NavigatorActivity { - PUSH = "push", - POP = "pop", -} - -/** - * Navigator status types. - */ -export enum NavigatorStatus { - START = "start", - FINISH = "finish", -} - -/** - * Channel for handling navigation-related communication between Flutter and OpenHarmony. - * This channel manages route navigation, including setting initial routes, pushing routes, - * and popping routes. - */ -export default class NavigationChannel { - private static TAG = "NavigationChannel"; - private channel: MethodChannel; - - /** - * Constructs a new NavigationChannel instance. - * @param dartExecutor - The DartExecutor for sending messages to Dart - * @param context - The application context - */ - constructor(dartExecutor: DartExecutor, context?: common.Context) { - this.channel = new MethodChannel(dartExecutor, "flutter/navigation", JSONMethodCodec.INSTANCE); - // Provide a default handler that returns an empty response to any messages - // on this channel. - this.channel.setMethodCallHandler(new NavigationCallback(dartExecutor, context)); - } - - /** - * Sets the initial route for navigation. - * @param initialRoute - The initial route string - */ - setInitialRoute(initialRoute: string): void { - Log.i(NavigationChannel.TAG, "Sending message to set initial route to '" + initialRoute + "'"); - this.channel.invokeMethod("setInitialRoute", initialRoute); - } - - /** - * Pushes a new route onto the navigation stack. - * @param route - The route string to push - */ - pushRoute(route: string): void { - Log.i(NavigationChannel.TAG, "Sending message to push route '" + route + "'"); - this.channel.invokeMethod("pushRoute", route); - } - - /** - * Pushes route information onto the navigation stack. - * @param route - The route information string to push - */ - pushRouteInformation(route: string): void { - Log.i(NavigationChannel.TAG, "Sending message to push route information '" + route + "'"); - this.channel.invokeMethod("pushRouteInformation", new Map().set("location", route)); - } - - /** - * Pops the current route from the navigation stack. - */ - popRoute(): void { - Log.i(NavigationChannel.TAG, "Sending message to pop route."); - this.channel.invokeMethod("popRoute", null); - } - - /** - * Sets a custom method call handler for navigation events. - * @param handler - The MethodCallHandler to handle navigation method calls - */ - setMethodCallHandler(handler: MethodCallHandler) { - this.channel.setMethodCallHandler(handler); - } -} - -/** - * Default callback handler for navigation channel that returns empty responses. - */ -class NavigationCallback implements MethodCallHandler { - private static TAG = "NavigationChannel"; - private dartExecutor: DartExecutor; - private context?: common.Context; - - constructor(dartExecutor: DartExecutor, context?: common.Context) { - this.dartExecutor = dartExecutor; - this.context = context; - } - - onMethodCall(call: MethodCall, result: MethodResult) { - let method: string = call.method; - let args: Any = call.args; - Log.i(NavigationCallback.TAG, "method = " + method); - switch (method) { - case "reportNavigatorActivity": { - let activity: string = args.get("activity"); - if (activity === undefined) { - Log.e(NavigationCallback.TAG, "reportNavigatorActivity, incorrect parameter activity"); - break; - } - - let status: string = args.get("status"); - if (status === undefined) { - Log.e(NavigationCallback.TAG, "reportNavigatorActivity, incorrect parameter status"); - break; - } - let navigatorStatus: NavigatorStatus = this.getNavigatorStatusFromValue(status); - - let navigatorActivity: NavigatorActivity = this.getNavigatorActivityFromValue(activity); - switch(navigatorActivity) { - case NavigatorActivity.PUSH: - this.reportNavigatorPush(navigatorStatus); - break; - case NavigatorActivity.POP: - this.reportNavigatorPop(navigatorStatus); - break; - } - break; - } - default: { - this.notifyPageChanged(call); - result.success(null); - break; - } - } - } - - private notifyPageChanged(call: MethodCall) { - if (this.dartExecutor == null || this.dartExecutor.flutterNapi == null) { - Log.e(NavigationCallback.TAG, "dartExecutor or flutterNapi is null, cancel OHOS page change notification"); - return; - } - - // Skip notification if context is not provided - if (this.context == null) { - Log.e(NavigationCallback.TAG, "context is not provided, skip OHOS page change notification"); - return; - } - - const argsMap = call.args as Map; - const currentUri: string = argsMap.get('uri') ?? ''; - const currentUriLen: number = currentUri.length; - - // Dynamically get windowId - const windowId: number = FlutterManager.getInstance().getWindowId(this.context); - if (windowId == 0) { - Log.e(NavigationCallback.TAG, "Failed to get windowId, skip OHOS page change notification, uri: " + currentUri); - return; - } - - const notifyResult = this.dartExecutor.flutterNapi.NotifyPageChanged(currentUri, currentUriLen, windowId); - // Return value: 0 means success, non-zero means error - if (notifyResult == 0) { - Log.i(NavigationCallback.TAG, "NotifyPageChanged success, uri: " + currentUri + ", windowId: " + windowId); - } else { - Log.e(NavigationCallback.TAG, "NotifyPageChanged failed, uri: " + currentUri + ", windowId: " + windowId + ", result: " + notifyResult); - } - } - - /** - * Gets a NavigatorActivity from an encoded activity string. - * @param activity - The encoded activity string - * @returns The NavigatorActivity - * @throws Error if the activity string is not recognized - */ - private getNavigatorActivityFromValue(activity: string): NavigatorActivity { - let activityTypes: string[] = [ - NavigatorActivity.PUSH, - NavigatorActivity.POP - ]; - if (activityTypes.includes(activity as NavigatorActivity)) { - return activity as NavigatorActivity; - } - throw new Error("No such NavigatorActivity: " + activity); - } - - /** - * Gets a NavigatorStatus from an encoded status string. - * @param status - The encoded status string - * @returns The NavigatorStatus - * @throws Error if the status string is not recognized - */ - private getNavigatorStatusFromValue(status: string): NavigatorStatus { - let statusTypes: string[] = [ - NavigatorStatus.START, - NavigatorStatus.FINISH - ]; - if (statusTypes.includes(status as NavigatorStatus)) { - return status as NavigatorStatus; - } - throw new Error("No such NavigatorStatus: " + status); - } - - private reportNavigatorPush(navigatorStatus: NavigatorStatus) { - switch(navigatorStatus) { - case NavigatorStatus.START: - hiTraceMeter.startTrace("flutter::NAVIGATOR_PUSH", 0); - break; - case NavigatorStatus.FINISH: - hiTraceMeter.finishTrace("flutter::NAVIGATOR_PUSH", 0); - break; - } - } - - private reportNavigatorPop(navigatorStatus: NavigatorStatus) { - switch(navigatorStatus) { - case NavigatorStatus.START: - hiTraceMeter.startTrace("flutter::NAVIGATOR_POP", 0); - break; - case NavigatorStatus.FINISH: - hiTraceMeter.finishTrace("flutter::NAVIGATOR_POP", 0); - break; - } - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/PlatformChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/PlatformChannel.ets deleted file mode 100644 index 79be8ac..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/PlatformChannel.ets +++ /dev/null @@ -1,674 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on PlatformChannel.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import hiTraceMeter from '@ohos.hiTraceMeter'; -import JSONMethodCodec from '../../../plugin/common/JSONMethodCodec'; -import MethodCall from '../../../plugin/common/MethodCall'; -import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; -import Log from '../../../util/Log'; -import DartExecutor from '../dart/DartExecutor'; -import pasteboard from '@ohos.pasteboard'; -import bundleManager from '@ohos.bundle.bundleManager'; -import window from '@ohos.window'; -import Any from '../../../plugin/common/Any'; -import { BusinessError } from '@kit.BasicServicesKit'; -import FlutterNapi from '../FlutterNapi'; -import flutter from 'libflutter.so'; - -/** - * Channel for handling platform-level communication between Flutter and OpenHarmony. - * This channel manages system UI, clipboard, haptic feedback, orientation, and other platform services. - */ -export default class PlatformChannel { - private static TAG = "PlatformChannel"; - private static CHANNEL_NAME = "flutter/platform"; - flutterNapi: FlutterNapi; - /** The MethodChannel for platform-level communication with Flutter. */ - channel: MethodChannel; - /** The platform message handler for processing platform requests, or null if not set. */ - platformMessageHandler: PlatformMessageHandler | null = null; - - /** - * Constructs a new PlatformChannel instance. - * @param dartExecutor - The DartExecutor for sending messages to Dart - */ - constructor(dartExecutor: DartExecutor, flutterNapi: FlutterNapi) { - this.channel = new MethodChannel(dartExecutor, PlatformChannel.CHANNEL_NAME, JSONMethodCodec.INSTANCE); - let callback = new PlatformMethodCallback(this); - this.channel.setMethodCallHandler(callback); - this.flutterNapi = flutterNapi; - } - - /** - * Sets the platform message handler for processing platform requests. - * @param platformMessageHandler - The PlatformMessageHandler instance, or null to remove - */ - setPlatformMessageHandler(platformMessageHandler: PlatformMessageHandler | null): void { - this.platformMessageHandler = platformMessageHandler; - } - - /** - * Notifies Flutter that system chrome overlays have changed. - * @param areOverlaysVisible - Whether system overlays are visible - */ - systemChromeChanged(areOverlaysVisible: boolean): void { - Log.d(PlatformChannel.TAG, "Sending 'systemUIChange' message."); - this.channel.invokeMethod("SystemChrome.systemUIChange", [areOverlaysVisible]); - } - - /** - * Decodes orientation strings into OpenHarmony orientation values. - * @param encodedOrientations - Array of encoded orientation strings - * @returns The decoded orientation value - */ - decodeOrientations(encodedOrientations: string[]): number { - let requestedOrientation = 0x00; - let firstRequestedOrientation = 0x00; - for (let index = 0; index < encodedOrientations.length; index += 1) { - let encodedOrientation = encodedOrientations[index]; - Log.d(PlatformChannel.TAG, "encodedOrientation[" + index + "]: " + encodedOrientation); - let orientation = this.getDeviceOrientationFromValue(encodedOrientation); - switch (orientation) { - case DeviceOrientation.PORTRAIT_UP: - requestedOrientation |= 0x01; - break; - case DeviceOrientation.PORTRAIT_DOWN: - requestedOrientation |= 0x04; - break; - case DeviceOrientation.LANDSCAPE_LEFT: - requestedOrientation |= 0x08; - break; - case DeviceOrientation.LANDSCAPE_RIGHT: - requestedOrientation |= 0x02; - break; - } - if (firstRequestedOrientation == 0x00) { - firstRequestedOrientation = requestedOrientation; - } - } - - switch (requestedOrientation) { - case 0x00: - return window.Orientation.UNSPECIFIED; - case 0x01: - return window.Orientation.PORTRAIT; - case 0x02: - return window.Orientation.LANDSCAPE_INVERTED; - case 0x03: - case 0x04: - return window.Orientation.PORTRAIT_INVERTED; - case 0x05: - return window.Orientation.AUTO_ROTATION_PORTRAIT; - case 0x06: - case 0x07: - case 0x08: - return window.Orientation.LANDSCAPE; - case 0x09: - case 0x0a: - return window.Orientation.AUTO_ROTATION_LANDSCAPE; - case 0x0b: - return window.Orientation.LOCKED; - case 0x0c: - case 0x0d: - case 0x0e: - switch (firstRequestedOrientation) { - case 0x01: - return bundleManager.DisplayOrientation.PORTRAIT; - case 0x02: - return bundleManager.DisplayOrientation.LANDSCAPE_INVERTED; - case 0x04: - return bundleManager.DisplayOrientation.PORTRAIT_INVERTED; - case 0x08: - return bundleManager.DisplayOrientation.LANDSCAPE; - } - case 0x0f: - return window.Orientation.AUTO_ROTATION_RESTRICTED; - } - return bundleManager.DisplayOrientation.PORTRAIT; - } - - /** - * Gets a HapticFeedbackType from an encoded name. - * @param encodedName - The encoded feedback type name - * @returns The HapticFeedbackType, or STANDARD if not found - */ - getFeedbackTypeFromValue(encodedName: string): HapticFeedbackType { - if (encodedName == null) { - return HapticFeedbackType.STANDARD; - } - let feedbackTypes: string[] = [ - HapticFeedbackType.STANDARD, - HapticFeedbackType.LIGHT_IMPACT, - HapticFeedbackType.MEDIUM_IMPACT, - HapticFeedbackType.HEAVY_IMPACT, - HapticFeedbackType.SELECTION_CLICK - ]; - if (feedbackTypes.includes(encodedName as HapticFeedbackType)) { - return encodedName as HapticFeedbackType; - } else { - Log.e(PlatformChannel.TAG, "No such HapticFeedbackType:" + encodedName); - return HapticFeedbackType.STANDARD; - } - } - - /** - * Gets a ClipboardContentFormat from an encoded name. - * @param encodedName - The encoded format name - * @returns The ClipboardContentFormat, or PLAIN_TEXT if not found - */ - getClipboardContentFormatFromValue(encodedName: string): ClipboardContentFormat { - let clipboardFormats: string[] = [ClipboardContentFormat.PLAIN_TEXT]; - if (clipboardFormats.includes(encodedName as ClipboardContentFormat)) { - return encodedName as ClipboardContentFormat; - } - return ClipboardContentFormat.PLAIN_TEXT; - } - - /** - * Gets a SystemUiOverlay from an encoded name. - * @param encodedName - The encoded overlay name - * @returns The SystemUiOverlay - * @throws Error if the overlay name is not recognized - */ - getSystemUiOverlayFromValue(encodedName: string): SystemUiOverlay { - let systemUiOverlays: string[] = [SystemUiOverlay.TOP_OVERLAYS, SystemUiOverlay.BOTTOM_OVERLAYS]; - if (systemUiOverlays.includes(encodedName as SystemUiOverlay)) { - return encodedName as SystemUiOverlay; - } - throw new Error("No such SystemUiOverlay: " + encodedName); - } - - /** - * Gets a SystemUiMode from an encoded name. - * @param encodedName - The encoded mode name - * @returns The SystemUiMode - * @throws Error if the mode name is not recognized - */ - getSystemUiModeFromValue(encodedName: string): SystemUiMode { - let systemUiModes: string[] = [ - SystemUiMode.LEAN_BACK, SystemUiMode.IMMERSIVE, - SystemUiMode.IMMERSIVE_STICKY, SystemUiMode.EDGE_TO_EDGE - ]; - if (systemUiModes.includes(encodedName as SystemUiMode)) { - return encodedName as SystemUiMode; - } - throw new Error("No such SystemUiOverlay: " + encodedName); - } - - /** - * Gets a Brightness from an encoded name. - * @param encodedName - The encoded brightness name - * @returns The Brightness - * @throws Error if the brightness name is not recognized - */ - getBrightnessFromValue(encodedName: string): Brightness { - let brightnesses: string[] = [Brightness.LIGHT, Brightness.DARK]; - if (brightnesses.includes(encodedName as Brightness)) { - return encodedName as Brightness; - } - throw new Error("No such Brightness: " + encodedName); - } - - /** - * Gets a DeviceOrientation from an encoded name. - * @param encodedName - The encoded orientation name - * @returns The DeviceOrientation - * @throws Error if the orientation name is not recognized - */ - getDeviceOrientationFromValue(encodedName: string): DeviceOrientation { - let deviceOrientations: DeviceOrientation[] = [ - DeviceOrientation.PORTRAIT_UP, DeviceOrientation.PORTRAIT_DOWN, - DeviceOrientation.LANDSCAPE_LEFT, DeviceOrientation.LANDSCAPE_RIGHT - ]; - if (deviceOrientations.includes(encodedName as DeviceOrientation)) { - return encodedName as DeviceOrientation; - } - throw new Error("No such DeviceOrientation: " + encodedName); - } - - /** - * Gets a ScrollActivity from an encoded activity string. - * @param activity - The encoded activity string - * @returns The ScrollActivity - * @throws Error if the activity string is not recognized - */ - getScrollActivityFromValue(activity: string): ScrollActivity { - let activityTypes: string[] = [ - ScrollActivity.START, - ScrollActivity.END - ]; - if (activityTypes.includes(activity as ScrollActivity)) { - return activity as ScrollActivity; - } - throw new Error("No such ScrollActivity: " + activity); - } - -} - -/** - * Types of haptic feedback. - */ -export enum HapticFeedbackType { - STANDARD = "STANDARD", - LIGHT_IMPACT = "HapticFeedbackType.lightImpact", - MEDIUM_IMPACT = "HapticFeedbackType.mediumImpact", - HEAVY_IMPACT = "HapticFeedbackType.heavyImpact", - SELECTION_CLICK = "HapticFeedbackType.selectionClick" -} - -/** - * Interface for handling platform message requests from Flutter. - */ -export interface PlatformMessageHandler { - playSystemSound(soundType: SoundType): void; - - vibrateHapticFeedback(feedbackType: HapticFeedbackType): Promise; - - setPreferredOrientations(ohosOrientation: number, result: MethodResult): void; - - setApplicationSwitcherDescription(description: AppSwitcherDescription): void; - - showSystemOverlays(overlays: SystemUiOverlay[]): void; - - showSystemUiMode(mode: SystemUiMode): void; - - setSystemUiChangeListener(): void; - - restoreSystemUiOverlays(): void; - - setSystemUiOverlayStyle(systemUiOverlayStyle: SystemChromeStyle): void; - - popSystemNavigator(): void; - - getClipboardData(result: MethodResult): void; - - setClipboardData(text: string, result: MethodResult): void; - - clipboardHasStrings(): boolean; -} - -/** - * Clipboard content formats. - */ -export enum ClipboardContentFormat { - PLAIN_TEXT = "text/plain", -} - -/** - * System sound types. - */ -export enum SoundType { - CLICK = "SystemSoundType.click", - ALERT = "SystemSoundType.alert", -} - -/** - * Description for the app switcher. - */ -export class AppSwitcherDescription { - /** The color value for the app switcher. */ - public readonly color: number; - /** The label text for the app switcher. */ - public readonly label: string; - - /** - * Constructs a new AppSwitcherDescription instance. - * @param color - The color value - * @param label - The label text - */ - constructor(color: number, label: string) { - this.color = color; - this.label = label; - } -} - -/** - * System UI overlay positions. - */ -export enum SystemUiOverlay { - TOP_OVERLAYS = "SystemUiOverlay.top", - BOTTOM_OVERLAYS = "SystemUiOverlay.bottom", -} - -/** - * System UI display modes. - */ -export enum SystemUiMode { - LEAN_BACK = "SystemUiMode.leanBack", - IMMERSIVE = "SystemUiMode.immersive", - IMMERSIVE_STICKY = "SystemUiMode.immersiveSticky", - EDGE_TO_EDGE = "SystemUiMode.edgeToEdge", -} - -export enum Brightness { - LIGHT = "Brightness.light", - DARK = "Brightness.dark", -} - -/** - * Style configuration for system chrome (status bar and navigation bar). - */ -export class SystemChromeStyle { - /** The status bar color, or null if not set. */ - public readonly statusBarColor: number | null; - /** The status bar icon brightness, or null if not set. */ - public readonly statusBarIconBrightness: Brightness | null; - /** Whether status bar contrast is enforced, or null if not set. */ - public readonly systemStatusBarContrastEnforced: boolean | null; - /** The navigation bar color, or null if not set. */ - public readonly systemNavigationBarColor: number | null; - /** The navigation bar icon brightness, or null if not set. */ - public readonly systemNavigationBarIconBrightness: Brightness | null; - /** The navigation bar divider color, or null if not set. */ - public readonly systemNavigationBarDividerColor: number | null; - /** Whether navigation bar contrast is enforced, or null if not set. */ - public readonly systemNavigationBarContrastEnforced: boolean | null; - - /** - * Constructs a new SystemChromeStyle instance. - * @param statusBarColor - The status bar color - * @param statusBarIconBrightness - The status bar icon brightness - * @param systemStatusBarContrastEnforced - Whether status bar contrast is enforced - * @param systemNavigationBarColor - The navigation bar color - * @param systemNavigationBarIconBrightness - The navigation bar icon brightness - * @param systemNavigationBarDividerColor - The navigation bar divider color - * @param systemNavigationBarContrastEnforced - Whether navigation bar contrast is enforced - */ - constructor(statusBarColor: number | null, - statusBarIconBrightness: Brightness | null, - systemStatusBarContrastEnforced: boolean | null, - systemNavigationBarColor: number | null, - systemNavigationBarIconBrightness: Brightness | null, - systemNavigationBarDividerColor: number | null, - systemNavigationBarContrastEnforced: boolean | null) { - this.statusBarColor = statusBarColor; - this.statusBarIconBrightness = statusBarIconBrightness; - this.systemStatusBarContrastEnforced = systemStatusBarContrastEnforced; - this.systemNavigationBarColor = systemNavigationBarColor; - this.systemNavigationBarIconBrightness = systemNavigationBarIconBrightness; - this.systemNavigationBarDividerColor = systemNavigationBarDividerColor; - this.systemNavigationBarContrastEnforced = systemNavigationBarContrastEnforced; - } -} - -/** - * Device orientation types. - */ -export enum DeviceOrientation { - PORTRAIT_UP = "DeviceOrientation.portraitUp", - PORTRAIT_DOWN = "DeviceOrientation.portraitDown", - LANDSCAPE_LEFT = "DeviceOrientation.landscapeLeft", - LANDSCAPE_RIGHT = "DeviceOrientation.landscapeRight", -} - -/** - * Scroll activity types. - */ -export enum ScrollActivity { - START = "start", - END = "end", -} - -enum AnimationStatus { - SCROLL_START = 0, - SCROLL_END = 1, -} - -/** - * Method call handler for platform channel requests. - */ -class PlatformMethodCallback implements MethodCallHandler { - private static TAG = "PlatformMethodCallback" - platform: PlatformChannel; - private scrollType: string | null = null; - - /** - * Constructs a new PlatformMethodCallback instance. - * @param platform - The PlatformChannel instance - */ - constructor(platform: PlatformChannel) { - this.platform = platform; - } - - /** - * Handles method calls from Dart. - * @param call - The method call from Dart - * @param result - The result callback to send a response - */ - onMethodCall(call: MethodCall, result: MethodResult) { - if (this.platform.platformMessageHandler == null) { - Log.w(PlatformMethodCallback.TAG, "platformMessageHandler is null"); - return; - } - - let method: string = call.method; - let args: Any = call.args; - Log.d(PlatformMethodCallback.TAG, "Received '" + method + "' message."); - try { - switch (method) { - case "SystemSound.play": - break; - case "HapticFeedback.vibrate": - try { - Log.d(PlatformMethodCallback.TAG, "HapticFeedback: " + args as string); - let feedbackType = this.platform.getFeedbackTypeFromValue(args as string); - this.platform.platformMessageHandler.vibrateHapticFeedback(feedbackType) - .then(() => { - result.success(null); - }) - .catch((e: BusinessError) => { - Log.e(PlatformMethodCallback.TAG, `HapticFeedback.vibrate error: ${e.code} - ${e.message}`); - }); - } catch (e) { - Log.e(PlatformMethodCallback.TAG, "HapticFeedback.vibrate error:" + JSON.stringify(e)); - } - break; - case "SystemChrome.setPreferredOrientations": - Log.d(PlatformMethodCallback.TAG, "setPreferredOrientations: " + JSON.stringify(args)); - let ohosOrientation = this.platform.decodeOrientations(args as string[]); - this.platform.platformMessageHandler.setPreferredOrientations(ohosOrientation, result); - break; - case "SystemChrome.setApplicationSwitcherDescription": - Log.d(PlatformMethodCallback.TAG, "setApplicationSwitcherDescription: " + JSON.stringify(args)); - try { - let description: AppSwitcherDescription = this.decodeAppSwitcherDescription(args); - this.platform.platformMessageHandler.setApplicationSwitcherDescription(description); - result.success(null); - } catch (err) { - Log.e(PlatformMethodCallback.TAG, "setApplicationSwitcherDescription err:" + JSON.stringify(err)); - result.error("error", JSON.stringify(err), null); - } - break; - case "SystemChrome.setEnabledSystemUIOverlays": - try { - let overlays: SystemUiOverlay[] = this.decodeSystemUiOverlays(args); - Log.d(PlatformMethodCallback.TAG, "overlays: " + overlays); - this.platform.platformMessageHandler.showSystemOverlays(overlays); - result.success(null); - } catch (err) { - Log.e(PlatformMethodCallback.TAG, "setEnabledSystemUIOverlays err:" + JSON.stringify(err)); - result.error("error", JSON.stringify(err), null); - } - break; - case "SystemChrome.setEnabledSystemUIMode": - try { - Log.d(PlatformMethodCallback.TAG, "setEnabledSystemUIMode args:" + args as string); - let mode: SystemUiMode = this.decodeSystemUiMode(args as string) - this.platform.platformMessageHandler.showSystemUiMode(mode); - } catch (err) { - Log.e(PlatformMethodCallback.TAG, "setEnabledSystemUIMode err:" + JSON.stringify(err)); - result.error("error", JSON.stringify(err), null); - } - break; - case "SystemChrome.setSystemUIChangeListener": - this.platform.platformMessageHandler.setSystemUiChangeListener(); - result.success(null); - break; - case "SystemChrome.restoreSystemUIOverlays": - this.platform.platformMessageHandler.restoreSystemUiOverlays(); - result.success(null); - break; - case "SystemChrome.setSystemUIOverlayStyle": - try { - Log.d(PlatformMethodCallback.TAG, "setSystemUIOverlayStyle asrgs: " + JSON.stringify(args)); - let systemChromeStyle: SystemChromeStyle = this.decodeSystemChromeStyle(args); - this.platform.platformMessageHandler.setSystemUiOverlayStyle(systemChromeStyle); - result.success(null); - } catch (err) { - Log.e(PlatformMethodCallback.TAG, "setSystemUIOverlayStyle err:" + JSON.stringify(err)); - result.error("error", JSON.stringify(err), null); - } - break; - case "SystemNavigator.pop": - this.platform.platformMessageHandler.popSystemNavigator(); - result.success(null); - break; - case "Clipboard.getData": - this.platform.platformMessageHandler.getClipboardData(result); - break; - case "Clipboard.setData": - let clipboardContent: string = args.get('text'); - this.platform.platformMessageHandler.setClipboardData(clipboardContent, result); - break; - case "Clipboard.hasStrings": - let response: Any = new Map().set("value", false); - let systemPasteboard = pasteboard.getSystemPasteboard(); - systemPasteboard.hasData().then((hasData) => { - response.set("value", hasData); - result.success(response); - }).catch((err: Any) => { - Log.e(PlatformMethodCallback.TAG, "systemPasteboard.hasData err: " + JSON.stringify(err)); - }) - break; - case "Scroll.Activity": - /// Report the behavior of scrolling components. - /// The optional values for Scroll.Activity include [start] and [end]. - this.recordScrollActivity(args as string); - break; - case "Scroll.type": - /// Report the type of the scrolling component. - /// Track scrollable widget names to identify [_PagePosition] instances. - let type: string = args.get("type"); - this.recordTabSwitch(type); - break; - default: - result.notImplemented(); - break; - } - } catch (e) { - result.error("error", JSON.stringify(e), null); - } - } - - private decodeAppSwitcherDescription(encodedDescription: Map): AppSwitcherDescription { - let color: number = encodedDescription.get('color') as number; - let label: string = encodedDescription.get('label') as string; - return new AppSwitcherDescription(color, label); - } - - private decodeSystemUiOverlays(encodedSystemUiOverlay: string[]): SystemUiOverlay[] { - let overlays: SystemUiOverlay[] = []; - for (let i = 0; i < encodedSystemUiOverlay.length; i++) { - const encodedOverlay = encodedSystemUiOverlay[i]; - const overlay = this.platform.getSystemUiOverlayFromValue(encodedOverlay); - switch (overlay) { - case SystemUiOverlay.TOP_OVERLAYS: - overlays.push(SystemUiOverlay.TOP_OVERLAYS); - break; - case SystemUiOverlay.BOTTOM_OVERLAYS: - overlays.push(SystemUiOverlay.BOTTOM_OVERLAYS); - break; - } - } - return overlays; - } - - private decodeSystemUiMode(encodedSystemUiMode: string): SystemUiMode { - let mode: SystemUiMode = this.platform.getSystemUiModeFromValue(encodedSystemUiMode); - switch (mode) { - case SystemUiMode.LEAN_BACK: - return SystemUiMode.LEAN_BACK; - case SystemUiMode.IMMERSIVE: - return SystemUiMode.IMMERSIVE; - case SystemUiMode.IMMERSIVE_STICKY: - return SystemUiMode.IMMERSIVE_STICKY; - case SystemUiMode.EDGE_TO_EDGE: - default: - return SystemUiMode.EDGE_TO_EDGE; - } - } - - private decodeSystemChromeStyle(encodedStyle: Map | null): SystemChromeStyle { - let statusBarColor: number | null = null; - let statusBarIconBrightness: Brightness | null = null; - let systemStatusBarContrastEnforced: boolean | null = null; - let systemNavigationBarColor: number | null = null; - let systemNavigationBarIconBrightness: Brightness | null = null; - let systemNavigationBarDividerColor: number | null = null; - let systemNavigationBarContrastEnforced: boolean | null = null; - if (encodedStyle?.get('statusBarColor') != null) { - statusBarColor = encodedStyle.get('statusBarColor') as number; - } - if (encodedStyle?.get('statusBarIconBrightness') != null) { - statusBarIconBrightness = - this.platform.getBrightnessFromValue(encodedStyle.get('statusBarIconBrightness') as string); - } - if (encodedStyle?.get('systemStatusBarContrastEnforced') != null) { - systemStatusBarContrastEnforced = encodedStyle.get('systemStatusBarContrastEnforced') as boolean; - } - if (encodedStyle?.get('systemNavigationBarColor') != null) { - systemNavigationBarColor = encodedStyle.get('systemNavigationBarColor') as number; - } - if (encodedStyle?.get('systemNavigationBarIconBrightness') != null) { - systemNavigationBarIconBrightness = - this.platform.getBrightnessFromValue(encodedStyle.get('systemNavigationBarIconBrightness') as string); - } - if (encodedStyle?.get('systemNavigationBarDividerColor') != null) { - systemNavigationBarDividerColor = encodedStyle.get('systemNavigationBarDividerColor') as number; - } - if (encodedStyle?.get('systemNavigationBarContrastEnforced') != null) { - systemNavigationBarContrastEnforced = encodedStyle.get('systemNavigationBarContrastEnforced') as boolean; - } - return new SystemChromeStyle( - statusBarColor, - statusBarIconBrightness, - systemStatusBarContrastEnforced, - systemNavigationBarColor, - systemNavigationBarIconBrightness, - systemNavigationBarDividerColor, - systemNavigationBarContrastEnforced - ); - } - - private recordScrollActivity(scrollActivity: string) { - let activityType = this.platform.getScrollActivityFromValue(scrollActivity); - switch(activityType) { - case ScrollActivity.START: - hiTraceMeter.startTrace('flutter::APP_LIST_FLING', 0); - this.platform.flutterNapi.SetAnimationStatus(AnimationStatus.SCROLL_START); - break; - case ScrollActivity.END: - hiTraceMeter.finishTrace('flutter::APP_LIST_FLING', 0); - if (this.scrollType !== null) { - this.scrollType = null; - hiTraceMeter.finishTrace('flutter::TABVIEW_SWITCH', 0); - } - this.platform.flutterNapi.SetAnimationStatus(AnimationStatus.SCROLL_END); - break; - } - } - - private recordTabSwitch(type: string) { - if (type == '_PagePosition') { - hiTraceMeter.startTrace('flutter::TABVIEW_SWITCH', 0); - this.scrollType = type; - } - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/PlatformViewsChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/PlatformViewsChannel.ets deleted file mode 100644 index 2f761a8..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/PlatformViewsChannel.ets +++ /dev/null @@ -1,679 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on PlatformViewsChannel.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ -import Any from '../../../plugin/common/Any'; - -import MethodCall from '../../../plugin/common/MethodCall'; -import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; -import StandardMethodCodec from '../../../plugin/common/StandardMethodCodec'; -import { ByteBuffer } from '../../../util/ByteBuffer'; -import Log from '../../../util/Log'; -import DartExecutor from '../dart/DartExecutor'; - -const TAG = "PlatformViewsChannel"; -const NON_TEXTURE_FALLBACK = -2; - -/** - * System channel that sends 2-way communication between Flutter and OpenHarmony to facilitate - * embedding of OpenHarmony Views within a Flutter application. - * - * Implement PlatformViewsHandler and register it via setPlatformViewsHandler() to implement - * the OpenHarmony side of this channel. - */ -export default class PlatformViewsChannel { - private channel: MethodChannel; - private handler: PlatformViewsHandler | null = null; - private parsingHandler = new ParsingCallback(); - - /** - * Constructs a PlatformViewsChannel that connects OpenHarmony to the Dart - * code running in dartExecutor. - * - * The given dartExecutor is permitted to be idle or executing code. - * - * @param dartExecutor - The DartExecutor for sending messages to Dart - */ - constructor(dartExecutor: DartExecutor) { - this.channel = new MethodChannel(dartExecutor, "flutter/platform_views", StandardMethodCodec.INSTANCE); - this.parsingHandler.platformChannel = this; - this.channel.setMethodCallHandler(this.parsingHandler); - } - - /** - * Sets the PlatformViewsHandler which receives all events and requests that are parsed - * from the underlying platform views channel. - * @param handler - The PlatformViewsHandler instance, or null to remove - */ - public setPlatformViewsHandler(handler: PlatformViewsHandler | null): void { - this.handler = handler; - this.parsingHandler.handler = handler; - } - - /** - * Notifies Flutter that a platform view has gained focus. - * @param viewId - The ID of the platform view that gained focus - */ - public invokeViewFocused(viewId: number): void { - if (this.channel == null) { - return; - } - this.channel.invokeMethod("viewFocused", viewId); - } - - /** - * Handles platform view creation requests. - * @param call - The method call containing creation parameters - * @param result - The result callback to send a response - */ - create(call: MethodCall, result: MethodResult): void { - const createArgs: Map = call.args; - const usesPlatformViewLayer: boolean = createArgs.has("hybrid") && createArgs.get("hybrid") as boolean; - const additionalParams: ByteBuffer = createArgs.has("params") ? createArgs.get("params") : null; - - let direction: Direction = Direction.Ltr; - if (createArgs.get("direction") == 0) { - direction = Direction.Ltr; - } else if (createArgs.get("direction") == 1) { - direction = Direction.Rtl; - } - - try { - if (usesPlatformViewLayer) { - const request: PlatformViewCreationRequest = new PlatformViewCreationRequest( - createArgs.get("id"), - createArgs.get("viewType"), - 0, - 0, - 0, - 0, - direction, - additionalParams, - RequestedDisplayMode.HYBRID_ONLY - ); - this.handler?.createForPlatformViewLayer(request); - result.success(null); - } else { - const hybridFallback: boolean = createArgs.has("hybridFallback") && createArgs.get("hybridFallback"); - const displayMode: RequestedDisplayMode = - hybridFallback ? RequestedDisplayMode.TEXTURE_WITH_HYBRID_FALLBACK - : RequestedDisplayMode.TEXTURE_WITH_VIRTUAL_FALLBACK; - const request: PlatformViewCreationRequest = new PlatformViewCreationRequest( - createArgs.get("id"), - createArgs.get("viewType"), - createArgs.has("top") ? createArgs.get("top") : 0.0, - createArgs.has("left") ? createArgs.get("left") : 0.0, - createArgs.get("width"), - createArgs.get("height"), - direction, - additionalParams, - displayMode - ); - - Log.i(TAG, `Create texture param id:${request.viewId}, - type:${request.viewType}, - w:${request.logicalWidth}, - h:${request.logicalHeight}, - l:${request.logicalLeft}, - t:${request.logicalTop}, - d:${request.direction}`); - - const textureId = this.handler?.createForTextureLayer(request); - if (textureId == NON_TEXTURE_FALLBACK) { - if (!hybridFallback) { - throw new Error( - "Platform view attempted to fall back to hybrid mode when not requested."); - } - - // A fallback to hybrid mode is indicated with a null texture ID. - result.success(null); - } else { - result.success(textureId); - } - } - } catch (err) { - Log.e(TAG, "create failed" + err); - result.error("error", err, null); - } - } - - /** - * Handles platform view disposal requests. - * @param call - The method call containing the view ID to dispose - * @param result - The result callback to send a response - */ - dispose(call: MethodCall, result: MethodResult): void { - const disposeArgs: Map = call.args; - const viewId: number = disposeArgs.get("id"); - try { - this.handler?.dispose(viewId); - result.success(null); - } catch (err) { - Log.e(TAG, "dispose failed", err); - result.error("error", err, null); - } - } - - /** - * Handles platform view resize requests. - * @param call - The method call containing resize parameters - * @param result - The result callback to send a response - */ - resize(call: MethodCall, result: MethodResult): void { - const resizeArgs: Map = call.args; - const resizeRequest: PlatformViewResizeRequest = new PlatformViewResizeRequest( - resizeArgs.get("id"), - resizeArgs.get("width"), - resizeArgs.get("height") - ); - try { - let resizeCallback = new ResizeCallback(); - resizeCallback.result = result; - this.handler?.resize(resizeRequest, resizeCallback); - } catch (err) { - Log.e(TAG, "resize failed", err); - result.error("error", err, null); - } - } - - /** - * Handles platform view offset change requests. - * @param call - The method call containing offset parameters - * @param result - The result callback to send a response - */ - offset(call: MethodCall, result: MethodResult): void { - const offsetArgs: Map = call.args; - try { - this.handler?.offset( - offsetArgs.get("id"), - offsetArgs.get("top"), - offsetArgs.get("left")); - result.success(null); - } catch (err) { - Log.e(TAG, "offset failed", err); - result.error("error", err, null); - } - } - - /** - * Handles touch events on platform views. - * @param call - The method call containing touch event data - * @param result - The result callback to send a response - */ - touch(call: MethodCall, result: MethodResult): void { - const args: Array = call.args; - let index = 0; - const touch: PlatformViewTouch = new PlatformViewTouch( - args[index++], - args[index++], - args[index++], - args[index++], - args[index++], - args[index++], - args[index++], - args[index++], - args[index++], - args[index++], - args[index++], - args[index++], - args[index++], - args[index++], - args[index++], - args[index] - ); - - try { - this.handler?.onTouch(touch); - result.success(null); - } catch (err) { - Log.e(TAG, "offset failed", err); - result.error("error", err, null); - } - } - - /** - * Handles platform view direction change requests. - * @param call - The method call containing direction parameters - * @param result - The result callback to send a response - */ - setDirection(call: MethodCall, result: MethodResult): void { - const setDirectionArgs: Map = call.args; - const newDirectionViewId: number = setDirectionArgs.get("id"); - const direction: number = setDirectionArgs.get("direction"); - - try { - this.handler?.setDirection(newDirectionViewId, direction); - result.success(null); - } catch (err) { - Log.e(TAG, "setDirection failed", err); - result.error("error", err, null); - } - } - - /** - * Handles platform view focus clearing requests. - * @param call - The method call containing the view ID - * @param result - The result callback to send a response - */ - clearFocus(call: MethodCall, result: MethodResult): void { - const viewId: number = call.args; - try { - this.handler?.clearFocus(viewId); - result.success(null); - } catch (err) { - Log.e(TAG, "clearFocus failed", err); - result.error("error", err, null); - } - } - - /** - * Handles requests to synchronize to native view hierarchy. - * @param call - The method call containing synchronization parameters - * @param result - The result callback to send a response - */ - synchronizeToNativeViewHierarchy(call: MethodCall, result: MethodResult): void { - const yes: boolean = call.args; - try { - this.handler?.synchronizeToNativeViewHierarchy(yes); - result.success(null); - } catch (err) { - Log.e(TAG, "synchronizeToNativeViewHierarchy failed", err); - result.error("error", err, null); - } - } - - /** - * Handles hover events on platform views. - * @param call - The method call containing the view ID - * @param result - The result callback to send a response - */ - hover(call: MethodCall, result: MethodResult) { - const viewId: number = call.args; - try { - this.handler?.hover(viewId); - result.success(null); - } catch (err) { - Log.e(TAG, "hover failed", err); - result.error("error", err, null); - } - } -} - -/** - * Handler that receives platform view messages sent from Flutter to OpenHarmony through a given - * PlatformViewsChannel. - * - * To register a PlatformViewsHandler with a PlatformViewsChannel, - * see PlatformViewsChannel.setPlatformViewsHandler. - */ -export interface PlatformViewsHandler { - /** - * The Flutter application would like to display a new OpenHarmony View, i.e., platform view. - * - * The OpenHarmony View is added to the view hierarchy. This view is rendered in the Flutter - * framework by a PlatformViewLayer. - * - * @param request - The metadata sent from the framework - */ - createForPlatformViewLayer(request: PlatformViewCreationRequest): void; - - /** - * The Flutter application would like to display a new OpenHarmony View, i.e., platform view. - * - * The OpenHarmony View is added to the view hierarchy. This view is rendered in the Flutter - * framework by a TextureLayer. - * - * The ID returned by createForTextureLayer to indicate that the requested texture mode - * was not available and the view creation fell back to PlatformViewLayer mode. - * This can only be returned if the PlatformViewCreationRequest sets - * TEXTURE_WITH_HYBRID_FALLBACK as the requested display mode. - * - * @param request - The metadata sent from the framework - * @returns The texture ID, or NON_TEXTURE_FALLBACK if falling back to hybrid mode - */ - createForTextureLayer(request: PlatformViewCreationRequest): number; - - /** - * The Flutter application would like to dispose of an existing OpenHarmony View. - * @param viewId - The ID of the platform view to dispose - */ - dispose(viewId: number): void; - - /** - * The Flutter application would like to resize an existing OpenHarmony View. - * - * @param request - The request to resize the platform view - * @param onComplete - Once the resize is completed, this is the handler to notify the size of the - * platform view buffer - */ - resize(request: PlatformViewResizeRequest, onComplete: PlatformViewBufferResized): void; - - /** - * The Flutter application would like to change the offset of an existing OpenHarmony View. - * @param viewId - The ID of the platform view - * @param top - The new top offset - * @param left - The new left offset - */ - offset(viewId: number, top: number, left: number): void; - - /** - * The user touched a platform view within Flutter. - * - * Touch data is reported in the touch parameter. - * @param touch - The touch event data - */ - onTouch(touch: PlatformViewTouch): void; - - /** - * The Flutter application would like to change the layout direction of an existing OpenHarmony - * View, i.e., platform view. - * @param viewId - The ID of the platform view - * @param direction - The new layout direction - */ - setDirection(viewId: number, direction: Direction): void; - - /** - * Clears the focus from the platform view with a given id if it is currently focused. - * @param viewId - The ID of the platform view - */ - clearFocus(viewId: number): void; - - /** - * Whether the render surface of FlutterView should be converted to a - * FlutterImageView when a PlatformView is added. - * - * This is done to synchronize the rendering of the PlatformView and the FlutterView. Defaults - * to true. - * @param yes - Whether to synchronize to native view hierarchy - */ - synchronizeToNativeViewHierarchy(yes: boolean): void; - - /** - * Handles hover events on a platform view. - * @param viewId - The ID of the platform view - */ - hover(viewId: number): void; -} - -/** Platform view display modes that can be requested at creation time. */ -enum RequestedDisplayMode { - /** Use Texture Layer if possible, falling back to Virtual Display if not. */ - TEXTURE_WITH_VIRTUAL_FALLBACK, - /** Use Texture Layer if possible, falling back to Hybrid Composition if not. */ - TEXTURE_WITH_HYBRID_FALLBACK, - /** Use Hybrid Composition in all cases. */ - HYBRID_ONLY, -} - -/** Request sent from Flutter to create a new platform view. */ -export class PlatformViewCreationRequest { - /** The ID of the platform view as seen by the Flutter side. */ - public viewId: number; - /** The type of view to create for this platform view. */ - public viewType: string; - /** The density independent width to display the platform view. */ - public logicalWidth: number; - /** The density independent height to display the platform view. */ - public logicalHeight: number; - /** The density independent top position to display the platform view. */ - public logicalTop: number; - /** The density independent left position to display the platform view. */ - public logicalLeft: number; - /** The layout direction of the new platform view. */ - public direction: Direction; - /** The requested display mode for the platform view. */ - public displayMode: RequestedDisplayMode; - /** Custom parameters that are unique to the desired platform view. */ - public params: ByteBuffer; - - /** - * Constructs a new PlatformViewCreationRequest instance. - * @param viewId - The ID of the platform view - * @param viewType - The type of view to create - * @param logicalTop - The density-independent top position - * @param logicalLeft - The density-independent left position - * @param logicalWidth - The density-independent width - * @param logicalHeight - The density-independent height - * @param direction - The layout direction - * @param params - Custom parameters for the view - * @param displayMode - The requested display mode (optional) - */ - constructor(viewId: number, viewType: string, logicalTop: number, logicalLeft: number, logicalWidth: number, - logicalHeight: number, direction: Direction, params: ByteBuffer, displayMode?: RequestedDisplayMode) { - this.viewId = viewId; - this.viewType = viewType; - this.logicalTop = logicalTop; - this.logicalLeft = logicalLeft; - this.logicalWidth = logicalWidth; - this.logicalHeight = logicalHeight; - this.direction = direction; - this.displayMode = displayMode ? displayMode : RequestedDisplayMode.TEXTURE_WITH_VIRTUAL_FALLBACK; - this.params = params; - } -} - -/** Request sent from Flutter to resize a platform view. */ -export class PlatformViewResizeRequest { - /** The ID of the platform view as seen by the Flutter side. */ - public viewId: number; - /** The new density independent width to display the platform view. */ - public newLogicalWidth: number; - /** The new density independent height to display the platform view. */ - public newLogicalHeight: number; - - /** - * Constructs a new PlatformViewResizeRequest instance. - * @param viewId - The ID of the platform view - * @param newLogicalWidth - The new density-independent width - * @param newLogicalHeight - The new density-independent height - */ - constructor(viewId: number, newLogicalWidth: number, newLogicalHeight: number) { - this.viewId = viewId; - this.newLogicalWidth = newLogicalWidth; - this.newLogicalHeight = newLogicalHeight; - } -} - -/** The platform view buffer size. */ -export class PlatformViewBufferSize { - /** The width of the screen buffer. */ - public width: number; - /** The height of the screen buffer. */ - public height: number; - - /** - * Constructs a new PlatformViewBufferSize instance. - * @param width - The width of the buffer - * @param height - The height of the buffer - */ - constructor(width: number, height: number) { - this.width = width; - this.height = height; - } -} - -/** Allows to notify when a platform view buffer has been resized. */ -export abstract class PlatformViewBufferResized { - /** - * Called when the platform view buffer has been resized. - * @param bufferSize - The new buffer size - */ - abstract run(bufferSize: PlatformViewBufferSize): void; -} - -/** The state of a touch event in Flutter within a platform view. */ -export class PlatformViewTouch { - /** The ID of the platform view as seen by the Flutter side. */ - public viewId: number; - /** The amount of time that the touch has been pressed. */ - public downTime: number; - /** The time when the event occurred. */ - public eventTime: number; - /** The touch action type. */ - public action: number; - /** The number of pointers (e.g, fingers) involved in the touch event. */ - public pointerCount: number; - /** Properties for each pointer, encoded in a raw format. */ - public rawPointerPropertiesList: Any; - /** Coordinates for each pointer, encoded in a raw format. */ - public rawPointerCoords: Any; - /** The meta state indicating modifier keys pressed. */ - public metaState: number; - /** The button state indicating which buttons are pressed. */ - public buttonState: number; - /** Coordinate precision along the x-axis. */ - public xPrecision: number; - /** Coordinate precision along the y-axis. */ - public yPrecision: number; - /** The ID of the input device that generated the event. */ - public deviceId: number; - /** Edge flags indicating which screen edges were touched. */ - public edgeFlags: number; - /** The event source indicating the type of input device. */ - public source: number; - /** Event flags providing additional information about the event. */ - public flags: number; - /** The motion event ID for tracking the event. */ - public motionEventId: number; - - /** - * Constructs a new PlatformViewTouch instance. - * @param viewId - The ID of the platform view - * @param downTime - The time when the touch was pressed - * @param eventTime - The time of the event - * @param action - The touch action - * @param pointerCount - The number of pointers - * @param rawPointerPropertiesList - Raw pointer properties - * @param rawPointerCoords - Raw pointer coordinates - * @param metaState - The meta state - * @param buttonState - The button state - * @param xPrecision - X-axis coordinate precision - * @param yPrecision - Y-axis coordinate precision - * @param deviceId - The device ID - * @param edgeFlags - Edge flags - * @param source - The event source - * @param flags - Event flags - * @param motionEventId - The motion event ID - */ - constructor(viewId: number, - downTime: number, - eventTime: number, - action: number, - pointerCount: number, - rawPointerPropertiesList: Any, - rawPointerCoords: Any, - metaState: number, - buttonState: number, - xPrecision: number, - yPrecision: number, - deviceId: number, - edgeFlags: number, - source: number, - flags: number, - motionEventId: number) { - this.viewId = viewId; - this.downTime = downTime; - this.eventTime = eventTime; - this.action = action; - this.pointerCount = pointerCount; - this.rawPointerPropertiesList = rawPointerPropertiesList; - this.rawPointerCoords = rawPointerCoords; - this.metaState = metaState; - this.buttonState = buttonState; - this.xPrecision = xPrecision; - this.yPrecision = yPrecision; - this.deviceId = deviceId; - this.edgeFlags = edgeFlags; - this.source = source; - this.flags = flags; - this.motionEventId = motionEventId; - } -} - -/** - * Method call handler for parsing platform view requests. - */ -class ParsingCallback implements MethodCallHandler { - platformChannel: PlatformViewsChannel | null = null; - handler: PlatformViewsHandler | null = null; - - /** - * Handles method calls from Dart. - * @param call - The method call from Dart - * @param result - The result callback to send a response - */ - onMethodCall(call: MethodCall, result: MethodResult) { - if (this.handler == null) { - return; - } - - Log.i(TAG, "Received '" + call.method + "' message."); - switch (call.method) { - case "create": { - this.platformChannel?.create(call, result); - break; - } - case "dispose": { - this.platformChannel?.dispose(call, result); - break; - } - case "resize": { - this.platformChannel?.resize(call, result); - break; - } - case "offset": { - this.platformChannel?.offset(call, result); - break; - } - case "touch": { - this.platformChannel?.touch(call, result); - break; - } - case "setDirection": { - this.platformChannel?.setDirection(call, result); - break; - } - case "clearFocus": { - this.platformChannel?.clearFocus(call, result); - break; - } - case "synchronizeToNativeViewHierarchy": { - this.platformChannel?.synchronizeToNativeViewHierarchy(call, result); - break; - } - case "hover": { - this.platformChannel?.hover(call, result); - break; - } - default: - result.notImplemented(); - } - } -} - -/** - * Callback for handling platform view resize completion. - */ -class ResizeCallback extends PlatformViewBufferResized { - result: MethodResult | null = null; - - /** - * Called when the resize is complete. - * @param bufferSize - The new buffer size - */ - run(bufferSize: PlatformViewBufferSize) { - if (bufferSize == null) { - this.result?.error("error", "Failed to resize the platform view", null); - } else { - const response: Map = new Map(); - response.set("width", bufferSize.width); - response.set("height", bufferSize.height); - this.result?.success(response); - } - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/RestorationChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/RestorationChannel.ets deleted file mode 100644 index b2978c6..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/RestorationChannel.ets +++ /dev/null @@ -1,206 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on RestorationChannel.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ -import Any from '../../../plugin/common/Any'; - -import MethodCall from '../../../plugin/common/MethodCall'; -import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; -import StandardMethodCodec from '../../../plugin/common/StandardMethodCodec'; -import Log from '../../../util/Log'; -import StringUtils from '../../../util/StringUtils'; -import DartExecutor from '../dart/DartExecutor'; - -/** - * System channel to exchange restoration data between framework and engine. - * - * The engine can obtain the current restoration data from the framework via this channel to - * store it on disk and - when the app is relaunched - provide the stored data back to the framework - * to recreate the original state of the app. - * - * The channel can be configured to delay responding to the framework's request for restoration - * data via waitForRestorationData until the engine-side has provided the data. This is - * useful when the engine is pre-warmed at a point in the application's life cycle where the - * restoration data is not available yet. For example, if the engine is pre-warmed as part of the - * Application before an Ability is created, this flag should be set to true because OpenHarmony will - * only provide the restoration data to the Ability during the onCreate callback. - * - * The current restoration data provided by the framework can be read via getRestorationData. - */ -export default class RestorationChannel { - private static TAG = "RestorationChannel"; - private static CHANNEL_NAME = "flutter/restoration"; - /** - * Whether the channel delays responding to the framework's initial request for restoration data - * until setRestorationData has been called. - * - * If the engine never calls setRestorationData this flag must be set to false. If set - * to true, the engine must call setRestorationData either with the actual restoration - * data as argument or null if it turns out that there is no restoration data. - * - * If the response to the framework's request for restoration data is not delayed until the - * data has been set via setRestorationData, the framework may intermittently initialize - * itself to default values until the restoration data has been made available. Setting this flag - * to true avoids that extra work. - */ - public waitForRestorationData: boolean = false; - /** Pending framework restoration channel request waiting for restoration data. */ - public pendingFrameworkRestorationChannelRequest: MethodResult | null = null; - /** Whether the engine has provided restoration data. */ - public engineHasProvidedData: boolean = false; - /** Whether the framework has requested restoration data. */ - public frameworkHasRequestedData: boolean = false; - private restorationData: Uint8Array; - private channel: MethodChannel | null = null; - private handler: MethodCallHandler; - - /** - * Constructs a new RestorationChannel instance. - * @param channelOrExecutor - Either a MethodChannel or DartExecutor instance - * @param waitForRestorationData - Whether to wait for restoration data before responding - */ - constructor(channelOrExecutor: MethodChannel | DartExecutor, waitForRestorationData: boolean) { - if (channelOrExecutor instanceof MethodChannel) { - this.channel = channelOrExecutor; - } else { - this.channel = - new MethodChannel(channelOrExecutor, RestorationChannel.CHANNEL_NAME, StandardMethodCodec.INSTANCE); - } - this.waitForRestorationData = waitForRestorationData; - this.restorationData = new Uint8Array(1).fill(0); - this.handler = new RestorationChannelMethodCallHandler(this); - this.channel.setMethodCallHandler(this.handler); - } - - /** - * Gets the most current restoration data that the framework has provided. - * @returns The restoration data as a Uint8Array - */ - getRestorationData(): Uint8Array { - return this.restorationData; - } - - /** - * Sets the restoration data without sending it to the framework. - * @param data - The restoration data to set - */ - setRestorationDataOnly(data: Uint8Array) { - this.restorationData = data; - } - - /** - * Sets the restoration data from which the framework will restore its state. - * @param data - The restoration data to set - */ - setRestorationData(data: Uint8Array) { - this.engineHasProvidedData = true; - if (this.pendingFrameworkRestorationChannelRequest != null) { - // If their is a pending request from the framework, answer it. - this.pendingFrameworkRestorationChannelRequest.success(RestorationChannelMethodCallHandler.packageData(data)); - this.pendingFrameworkRestorationChannelRequest = null; - this.restorationData = data; - } else if (this.frameworkHasRequestedData) { - // If the framework has previously received the engine's restoration data, push the new data - // directly to it. This case can happen when "waitForRestorationData" is false and the - // framework retrieved the restoration state before it was set via this method. - // Experimentally, this can also be used to restore a previously used engine to another state, - // e.g. when the engine is attached to a new activity. - this.channel?.invokeMethod( - "push", RestorationChannelMethodCallHandler.packageData(data), { - success: (result: Any): void => { - this.restorationData = data; - }, - - error: (errorCode: string, errorMessage: string, errorDetails: Any): void => { - Log.e( - RestorationChannel.TAG, - "Error " + errorCode + " while sending restoration data to framework: " + errorMessage - ); - }, - - notImplemented: (): void => { - // do nothing - } - }) - } else { - // Otherwise, just cache the data until the framework asks for it. - this.restorationData = data; - } - } - - /** - * Clears the current restoration data. - * - * This should be called just prior to a hot restart. Otherwise, after the hot restart the - * state prior to the hot restart will get restored. - */ - clearData() { - this.restorationData = new Uint8Array(1).fill(0); - } -} - -/** - * Method call handler for the restoration channel. - */ -class RestorationChannelMethodCallHandler implements MethodCallHandler { - private channel: RestorationChannel; - - /** - * Constructs a new RestorationChannelMethodCallHandler instance. - * @param channel - The RestorationChannel instance - */ - constructor(channel: RestorationChannel) { - this.channel = channel; - } - - /** - * Handles method calls from Dart. - * @param call - The method call from Dart - * @param result - The result callback to send a response - */ - onMethodCall(call: MethodCall, result: MethodResult): void { - const method = call.method; - const args: Any = call.args; - switch (method) { - case "put": { - this.channel.setRestorationDataOnly(args); - result.success(null); - break; - } - case "get": { - this.channel.frameworkHasRequestedData = true; - if (this.channel.engineHasProvidedData || !this.channel.waitForRestorationData) { - result.success(RestorationChannelMethodCallHandler.packageData(this.channel.getRestorationData())); - // Do not delete the restoration data on the engine side after sending it to the - // framework. We may need to hand this data back to the operating system if the - // framework never modifies the data (and thus doesn't send us any - // data back). - } else { - this.channel.pendingFrameworkRestorationChannelRequest = result; - } - break; - } - default: { - result.notImplemented(); - break; - } - } - } - - /** - * Packages restoration data into a message format. - * @param data - The restoration data to package - * @returns A map containing the packaged restoration data - */ - static packageData(data: Uint8Array): Map { - const packaged: Map = new Map(); - packaged.set("enabled", true); - packaged.set("data", data); - return packaged; - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SensitiveContentChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SensitiveContentChannel.ets deleted file mode 100644 index 55241d0..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SensitiveContentChannel.ets +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2026 Huawei Device Co., Ltd. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE_HW file. - */ - -import Any from '../../../plugin/common/Any'; -import DartExecutor from '../dart/DartExecutor'; -import StandardMethodCodec from '../../../plugin/common/StandardMethodCodec'; -import Log from '../../../util/Log'; -import MethodCall from '../../../plugin/common/MethodCall'; -import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; - -const TAG = "SensitiveContentChannel"; - -export const SENSITIVE_CONTENT_SENSITIVITY = 1; -export const NOT_SENSITIVE_CONTENT_SENSITIVITY = 2; - -export default class SensitiveContentChannel implements MethodCallHandler { - private static CHANNEL_NAME = "flutter/sensitivecontent"; - private channel: MethodChannel; - private sensitiveContentMethodHandler: SensitiveContentMethodHandler | null = null; - - constructor(dartExecutor: DartExecutor) { - this.channel = new MethodChannel(dartExecutor, SensitiveContentChannel.CHANNEL_NAME, StandardMethodCodec.INSTANCE); - this.channel.setMethodCallHandler(this); - } - - onMethodCall(call: MethodCall, result: MethodResult): void { - if (this.sensitiveContentMethodHandler == null) { - // No SensitiveContentChannel registered, call not forwarded to sensitive content API. - return; - } - let method: string = call.method; - Log.d(TAG, "Received '" + method + "' message."); - switch (method) { - case "SensitiveContent.setContentSensitivity": - this.setContentSensitivity(call, result); - break; - case "SensitiveContent.getContentSensitivity": - this.getContentSensitivity(call, result); - break; - case "SensitiveContent.isSupported": - this.isSupported(call, result); - break; - default: - Log.d(TAG, "Method " + method + " is not implemented for the SensitiveContentChannel."); - result.notImplemented(); - break; - } - } - - private setContentSensitivity(call: MethodCall, result: MethodResult): void { - try { - const contentSensitivityLevel: number = call.args as number; - const deserializedValue = this.deserializeContentSensitivity(contentSensitivityLevel); - this.sensitiveContentMethodHandler!.setContentSensitivity(deserializedValue); - result.success(null); - } catch (error) { - result.error("error", (error as Error).message, null); - } - } - - private getContentSensitivity(call: MethodCall, result: MethodResult): void { - try { - const currentContentSensitivity: number = this.sensitiveContentMethodHandler!.getContentSensitivity(); - const serializedValue = this.serializeContentSensitivity(currentContentSensitivity); - result.success(serializedValue); - } catch (error) { - result.error("error", (error as Error).message, null); - } - } - - private isSupported(call: MethodCall, result: MethodResult): void { - const isSupported: boolean = this.sensitiveContentMethodHandler!.isSupported(); - result.success(isSupported); - } - - /** - * Deserializes Flutter content sensitivity index to native value. - */ - private deserializeContentSensitivity(contentSensitivityIndex: number): number { - switch (contentSensitivityIndex) { - case NOT_SENSITIVE_CONTENT_SENSITIVITY: - return NOT_SENSITIVE_CONTENT_SENSITIVITY; - case SENSITIVE_CONTENT_SENSITIVITY: - return SENSITIVE_CONTENT_SENSITIVITY; - default: - throw new Error( - "contentSensitivityIndex " + contentSensitivityIndex + " not known to the SensitiveContentChannel." - ); - } - } - - /** - * Serializes native content sensitivity value to Flutter index. - */ - private serializeContentSensitivity(contentSensitivityValue: number): number { - switch (contentSensitivityValue) { - case NOT_SENSITIVE_CONTENT_SENSITIVITY: - return NOT_SENSITIVE_CONTENT_SENSITIVITY; - case SENSITIVE_CONTENT_SENSITIVITY: - return SENSITIVE_CONTENT_SENSITIVITY; - default: - return NOT_SENSITIVE_CONTENT_SENSITIVITY; - } - } - - /** - * Sets the {@link SensitiveContentMethodHandler} which receives all requests to get and set a - * particular content sensitivity level sent through this channel. - */ - setSensitiveContentMethodHandler(sensitiveContentMethodHandler: SensitiveContentMethodHandler | null): void { - this.sensitiveContentMethodHandler = sensitiveContentMethodHandler; - } -} - -export interface SensitiveContentMethodHandler { - /** - * Requests that a native Flutter OpenHarmony View sets its content sensitivity level to - * {@code requestedContentSensitivity}. - */ - setContentSensitivity(requestedContentSensitivity: number): void; - - /** - * Returns the current content sensitivity level of a Flutter OpenHarmony View. - */ - getContentSensitivity(): number; - - /** - * Returns whether or not setting/getting content sensitivity via OpenHarmony APIs is supported on - * the device. - */ - isSupported(): boolean; -} - diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SettingsChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SettingsChannel.ets deleted file mode 100644 index bd84d1a..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SettingsChannel.ets +++ /dev/null @@ -1,145 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on SettingsChannel.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import BasicMessageChannel from '../../../plugin/common/BasicMessageChannel'; -import JSONMessageCodec from '../../../plugin/common/JSONMessageCodec'; -import Log from '../../../util/Log'; -import DartExecutor from '../dart/DartExecutor'; - -/** - * Platform brightness modes. - */ -export enum PlatformBrightness { - LIGHT = "light", - DARK = "dark" -} - -const TAG = "SettingsChannel"; -const TEXT_SCALE_FACTOR = "textScaleFactor"; -const NATIVE_SPELL_CHECK_SERVICE_DEFINED = "nativeSpellCheckServiceDefined"; -const BRIEFLY_SHOW_PASSWORD = "brieflyShowPassword"; -const ALWAYS_USE_24_HOUR_FORMAT = "alwaysUse24HourFormat"; -const PLATFORM_BRIGHTNESS = "platformBrightness"; - -/** - * Channel for sending system settings to Flutter. - * This channel manages settings such as text scale factor, platform brightness, and other system preferences. - */ -export default class SettingsChannel { - private static CHANNEL_NAME = "flutter/settings"; - private channel: BasicMessageChannel; - - /** - * Constructs a new SettingsChannel instance. - * @param dartExecutor - The DartExecutor for sending messages to Dart - */ - constructor(dartExecutor: DartExecutor) { - this.channel = - new BasicMessageChannel(dartExecutor, SettingsChannel.CHANNEL_NAME, JSONMessageCodec.INSTANCE); - } - - /** - * Starts building a settings message. - * @returns A MessageBuilder instance for constructing the settings message - */ - startMessage(): MessageBuilder { - return new MessageBuilder(this.channel); - } -} - -/** - * Builder for constructing settings messages to send to Flutter. - */ -class MessageBuilder { - private channel: BasicMessageChannel; - private settingsMessage: Map = new Map([ - [TEXT_SCALE_FACTOR, 1.0], - [NATIVE_SPELL_CHECK_SERVICE_DEFINED, false], - [BRIEFLY_SHOW_PASSWORD, false], - [ALWAYS_USE_24_HOUR_FORMAT, false], - [PLATFORM_BRIGHTNESS, PlatformBrightness.LIGHT] - ]); - - /** - * Constructs a new MessageBuilder instance. - * @param channel - The BasicMessageChannel to send messages through - */ - constructor(channel: BasicMessageChannel) { - this.channel = channel; - } - - /** - * Sets the text scale factor. - * @param textScaleFactor - The text scale factor value - * @returns This MessageBuilder instance for method chaining - */ - setTextScaleFactor(textScaleFactor: Number): MessageBuilder { - this.settingsMessage.set(TEXT_SCALE_FACTOR, textScaleFactor); - return this; - } - - /** - * Sets whether native spell check service is defined. - * @param nativeSpellCheckServiceDefined - Whether the service is defined - * @returns This MessageBuilder instance for method chaining - */ - setNativeSpellCheckServiceDefined(nativeSpellCheckServiceDefined: boolean): MessageBuilder { - this.settingsMessage.set(NATIVE_SPELL_CHECK_SERVICE_DEFINED, nativeSpellCheckServiceDefined); - return this; - } - - /** - * Sets whether to briefly show password. - * @param brieflyShowPassword - Whether to briefly show password - * @returns This MessageBuilder instance for method chaining - */ - setBrieflyShowPassword(brieflyShowPassword: boolean): MessageBuilder { - this.settingsMessage.set(BRIEFLY_SHOW_PASSWORD, brieflyShowPassword); - return this; - } - - /** - * Sets whether to always use 24-hour format. - * @param alwaysUse24HourFormat - Whether to always use 24-hour format - * @returns This MessageBuilder instance for method chaining - */ - setAlwaysUse24HourFormat(alwaysUse24HourFormat: boolean): MessageBuilder { - this.settingsMessage.set(ALWAYS_USE_24_HOUR_FORMAT, alwaysUse24HourFormat); - return this; - } - - /** - * Sets the platform brightness. - * @param platformBrightness - The platform brightness mode - * @returns This MessageBuilder instance for method chaining - */ - setPlatformBrightness(platformBrightness: PlatformBrightness): MessageBuilder { - this.settingsMessage.set(PLATFORM_BRIGHTNESS, platformBrightness); - return this; - } - - /** - * Sends the constructed settings message to Flutter. - */ - send(): void { - Log.i(TAG, "Sending message: " - + TEXT_SCALE_FACTOR + " : " - + this.settingsMessage.get(TEXT_SCALE_FACTOR) - + ", " + NATIVE_SPELL_CHECK_SERVICE_DEFINED + " : " - + this.settingsMessage.get(NATIVE_SPELL_CHECK_SERVICE_DEFINED) - + ", " + BRIEFLY_SHOW_PASSWORD + " : " - + this.settingsMessage.get(BRIEFLY_SHOW_PASSWORD) - + ", " + ALWAYS_USE_24_HOUR_FORMAT + " : " - + this.settingsMessage.get(ALWAYS_USE_24_HOUR_FORMAT) - + ", " + PLATFORM_BRIGHTNESS + " : " - + this.settingsMessage.get(PLATFORM_BRIGHTNESS)); - this.channel.send(this.settingsMessage) - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/StatusBarClickChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/StatusBarClickChannel.ets deleted file mode 100644 index 4cef4dc..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/StatusBarClickChannel.ets +++ /dev/null @@ -1,21 +0,0 @@ -/* -* Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_HW file. -*/ - -import DartExecutor from '../dart/DartExecutor'; -import { BinaryMessenger } from '../../../plugin/common/BinaryMessenger'; -import MethodChannel from '../../../plugin/common/MethodChannel'; - -export default class StatusBarClickChannel { - private static CHANNEL_NAME = "flutter/statusBarClick"; - private channel: MethodChannel; - - constructor(binaryMessenger: BinaryMessenger) { - this.channel = new MethodChannel(binaryMessenger, StatusBarClickChannel.CHANNEL_NAME); - } - sendClick() { - this.channel.invokeMethod('onClick', null); - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SystemChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SystemChannel.ets deleted file mode 100644 index c600c7d..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SystemChannel.ets +++ /dev/null @@ -1,43 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on SystemChannel.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import BasicMessageChannel from '../../../plugin/common/BasicMessageChannel'; -import Any from '../../../plugin/common/Any'; -import JSONMessageCodec from '../../../plugin/common/JSONMessageCodec'; -import Log from '../../../util/Log'; -import DartExecutor from '../dart/DartExecutor'; - -const TAG: string = "SystemChannel"; - -/** - * System channel for communicating system-level events between OpenHarmony and Flutter. - * This channel handles events such as memory pressure warnings. - */ -export default class SystemChannel { - /** The BasicMessageChannel for sending system-level messages to Flutter. */ - public channel: BasicMessageChannel; - - /** - * Constructs a new SystemChannel instance. - * @param dartExecutor - The DartExecutor for sending messages to Dart - */ - constructor(dartExecutor: DartExecutor) { - this.channel = new BasicMessageChannel(dartExecutor, "flutter/system", JSONMessageCodec.INSTANCE); - } - - /** - * Sends a memory pressure warning to the Flutter framework. - */ - public sendMemoryPressureWarning(): void { - Log.i(TAG, "Sending memory pressure warning to Flutter"); - let message: Map = new Map().set("type", "memoryPressure"); - this.channel.send(message); - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/TestChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/TestChannel.ets deleted file mode 100644 index d9c1777..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/TestChannel.ets +++ /dev/null @@ -1,45 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import BasicMessageChannel, { MessageHandler, Reply } from '../../../plugin/common/BasicMessageChannel'; -import JSONMessageCodec from '../../../plugin/common/JSONMessageCodec'; -import DartExecutor from '../dart/DartExecutor'; -import Log from '../../../util/Log'; - -const TAG = "TestChannel" - -/** - * Test channel for Flutter testing purposes. - * This channel provides a simple echo mechanism for testing message passing. - */ -export default class TestChannel { - private channel: BasicMessageChannel; - - /** - * Constructs a new TestChannel instance. - * @param dartExecutor - The DartExecutor for sending messages to Dart - */ - constructor(dartExecutor: DartExecutor) { - this.channel = new BasicMessageChannel(dartExecutor, "flutter/test", JSONMessageCodec.INSTANCE); - let callback = new MessageCallback(); - this.channel.setMessageHandler(callback); - } -} - -/** - * Message callback handler for the test channel. - */ -class MessageCallback implements MessageHandler { - /** - * Handles incoming messages and echoes them back. - * @param message - The message received from Dart - * @param reply - The reply callback to send a response - */ - onMessage(message: string, reply: Reply) { - Log.d(TAG, "receive msg = " + message); - reply.reply("收到消息啦:" + message); - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/TextInputChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/TextInputChannel.ets deleted file mode 100644 index 89948f5..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/TextInputChannel.ets +++ /dev/null @@ -1,810 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on TextInputChannel.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import JSONMethodCodec from '../../../plugin/common/JSONMethodCodec'; -import MethodCall from '../../../plugin/common/MethodCall'; -import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; -import TextInputPlugin from '../../../plugin/editing/TextInputPlugin'; -import Log from '../../../util/Log'; -import DartExecutor from '../dart/DartExecutor'; -import inputMethod from '@ohos.inputMethod'; -import ArrayList from '@ohos.util.ArrayList'; -import { TextEditingDelta, TextEditingDeltaJson } from '../../../plugin/editing/TextEditingDelta'; -import Any from '../../../plugin/common/Any'; -import { display } from '@kit.ArkUI' -import { window } from '@kit.ArkUI'; -import { BusinessError, print } from '@kit.BasicServicesKit'; -import { PointerDeviceKind } from '../../ohos/OhosTouchProcessor'; - -const TAG = "TextInputChannel"; -/// 规避换行标识无法显示问题,api修改后再删除 -const NEWLINE_KEY_TYPE: number = 8; - -/** - * TextInputChannel is a platform channel between OpenHarmony and Flutter that is used to - * communicate information about the user's text input. - * - * When the user presses an action button like "done" or "next", that action is sent from - * OpenHarmony to Flutter through this TextInputChannel. - * - * When an input system in the Flutter app wants to show the keyboard, or hide it, or configure - * editing state, etc. a message is sent from Flutter to OpenHarmony through this TextInputChannel. - * - * TextInputChannel comes with a default MethodChannel.MethodCallHandler that parses incoming - * messages from Flutter. Implement TextInputMethodHandler and register it via - * setTextInputMethodHandler() to respond to standard Flutter text input messages. - */ -export default class TextInputChannel { - private static CHANNEL_NAME = "flutter/textinput"; - /** The MethodChannel for text input communication with Flutter. */ - public channel: MethodChannel; - /** The text input method handler for processing text input requests, or null if not set. */ - textInputMethodHandler: TextInputMethodHandler | null = null; - private TextInputCallback: TextInputCallback | null = null; - - /** - * Constructs a new TextInputChannel instance. - * @param dartExecutor - The DartExecutor for sending messages to Dart - */ - constructor(dartExecutor: DartExecutor) { - this.channel = new MethodChannel(dartExecutor, TextInputChannel.CHANNEL_NAME, JSONMethodCodec.INSTANCE); - } - - /** - * Sets the text input method handler. - * @param textInputMethodHandler - The TextInputMethodHandler instance, or null to remove - */ - setTextInputMethodHandler(textInputMethodHandler: TextInputMethodHandler | null): void { - this.textInputMethodHandler = textInputMethodHandler; - this.TextInputCallback = this.textInputMethodHandler == null - ? null : new TextInputCallback(this.textInputMethodHandler); - this.channel.setMethodCallHandler(this.TextInputCallback); - } - - /** - * Requests the existing input state from Flutter. - */ - requestExistingInputState(): void { - this.channel.invokeMethod("TextInputClient.requestExistingInputState", null); - } - - /** - * Creates an editing state JSON object. - * @param text - The text content - * @param selectionStart - The start of the selection - * @param selectionEnd - The end of the selection - * @param composingStart - The start of the composing region - * @param composingEnd - The end of the composing region - * @returns The editing state object - */ - createEditingStateJSON(text: string, - selectionStart: number, - selectionEnd: number, - composingStart: number, - composingEnd: number): EditingState { - let state: EditingState = { - text: text, - selectionBase: selectionStart, - selectionExtent: selectionEnd, - composingBase: composingStart, - composingExtent: composingEnd - }; - return state; - } - - /** - * Creates an editing delta JSON object from a batch of deltas. - * @param batchDeltas - Array list of text editing deltas - * @returns The editing delta object - */ - createEditingDeltaJSON(batchDeltas: ArrayList): EditingDelta { - let deltas: TextEditingDeltaJson[] = []; - batchDeltas.forEach((val, idx, array) => { - deltas.push(val.toJSON()); - }) - - let state: EditingDelta = { - deltas: deltas, - }; - return state; - } - - /** - * Instructs Flutter to update its text input editing state to reflect the given configuration. - */ - updateEditingState(inputClientId: number, - text: string, - selectionStart: number, - selectionEnd: number, - composingStart: number, - composingEnd: number): void { - Log.d(TAG, "updateEditingState:" - + "Text: " + text + " Selection start: " + selectionStart + " Selection end: " - + selectionEnd + " Composing start: " + composingStart + " Composing end: " + composingEnd); - const state: Any = this.createEditingStateJSON(text, selectionStart, selectionEnd, composingStart, composingEnd); - this.channel.invokeMethod('TextInputClient.updateEditingState', [inputClientId, state]); - } - - /** - * Updates the editing state with deltas. - * @param inputClientId - The input client ID - * @param batchDeltas - Array list of text editing deltas - */ - updateEditingStateWithDeltas(inputClientId: number, batchDeltas: ArrayList): void { - Log.d(TAG, "updateEditingStateWithDeltas:" + "batchDeltas length: " + batchDeltas.length); - if(batchDeltas.length > 0){ - const state: Any = this.createEditingDeltaJSON(batchDeltas); - this.channel.invokeMethod('TextInputClient.updateEditingStateWithDeltas', [inputClientId, state]); - } - } - - /** - * Sends a newline action to Flutter. - * @param inputClientId - The input client ID - */ - newline(inputClientId: number): void { - Log.d(TAG, "Sending 'newline' message."); - this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.newline"]); - } - - /** - * Sends a go action to Flutter. - * @param inputClientId - The input client ID - */ - go(inputClientId: number): void { - Log.d(TAG, "Sending 'go' message."); - this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.go"]); - } - - /** - * Sends a search action to Flutter. - * @param inputClientId - The input client ID - */ - search(inputClientId: number): void { - Log.d(TAG, "Sending 'search' message."); - this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.search"]); - } - - /** - * Sends a send action to Flutter. - * @param inputClientId - The input client ID - */ - send(inputClientId: number): void { - Log.d(TAG, "Sending 'send' message."); - this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.send"]); - } - - /** - * Sends a done action to Flutter. - * @param inputClientId - The input client ID - */ - done(inputClientId: number): void { - Log.d(TAG, "Sending 'done' message."); - this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.done"]); - } - - /** - * Sends a next action to Flutter. - * @param inputClientId - The input client ID - */ - next(inputClientId: number): void { - Log.d(TAG, "Sending 'next' message."); - this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.next"]); - } - - /** - * Sends a previous action to Flutter. - * @param inputClientId - The input client ID - */ - previous(inputClientId: number): void { - Log.d(TAG, "Sending 'previous' message."); - this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.previous"]); - } - - /** - * Sends an unspecified action to Flutter. - * @param inputClientId - The input client ID - */ - unspecifiedAction(inputClientId: number): void { - Log.d(TAG, "Sending 'unspecifiedAction' message."); - this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.unspecified"]); - } - - /** - * Sends a commit content action to Flutter. - * @param inputClientId - The input client ID - */ - commitContent(inputClientId: number): void { - Log.d(TAG, "Sending 'commitContent' message."); - this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.commitContent"]); - } - - /** - * Notifies Flutter that the input connection has been closed. - * @param inputClientId - The input client ID - */ - onConnectionClosed(inputClientId: number): void { - Log.d(TAG, "Sending 'onConnectionClosed' message."); - this.channel.invokeMethod("TextInputClient.onConnectionClosed", [inputClientId]); - this.textInputMethodHandler?.hide(); - } - - /** - * Performs a private command. - * @param inputClientId - The input client ID - * @param action - The action string - * @param data - The command data - */ - performPrivateCommand(inputClientId: number, action: string, data: Any) { - - } - - /** - * Sets the window position for text input. - * @param windowPosition - The window position rectangle - */ - public setWindowPosition(windowPosition: window.Rect) { - this.TextInputCallback?.setWindowPosition(windowPosition); - this.TextInputCallback?.setCursorPosition(); - } - - /** - * Sets the device pixel ratio. - * @param devicePixelRatio - The device pixel ratio value - */ - public setDevicePixelRatio(devicePixelRatio: number) { - this.TextInputCallback?.setDevicePixelRatio(devicePixelRatio); - } - - /** - * Gets the keyboard focus state. - * @returns Whether the keyboard has focus - */ - getKeyboardFocusState() { - return this.textInputMethodHandler?.getKeyboardFocusState(); - } - -} - -/** - * Editing state interface. - */ -interface EditingState { - text: string; - selectionBase: number; - selectionExtent: number; - composingBase: number; - composingExtent: number; -} - - -/** - * Editing delta interface. - */ -interface EditingDelta { - deltas: Array; -} - - -/** - * Interface for handling text input method operations. - */ -export interface TextInputMethodHandler { - show(): void; - - hide(): void; - - requestAutofill(): void; - - finishAutofillContext(shouldSave: boolean): void; - - setClient(textInputClientId: number, configuration: Configuration | null): void; - - updateConfig(configuration: Configuration | null): void; - - setPlatformViewClient(id: number, usesVirtualDisplay: boolean): void; - - setEditableSizeAndTransform(width: number, height: number, transform: number[]): void; - - setCursorSizeAndPosition(cursorInfo: inputMethod.CursorInfo): void; - - setEditingState(editingState: TextEditState): void; - - clearClient(): void; - - handleChangeFocus(focusState: boolean): void; - - getKeyboardFocusState(): boolean; - -} - -/** - * A text editing configuration. - */ -export class Configuration { - /** Whether text should be obscured (e.g., for password fields). */ - obscureText: boolean = false; - /** Whether autocorrect is enabled. */ - autocorrect: boolean = false; - /** Whether autofill is enabled. */ - autofill: boolean = false; - /** Whether suggestions are enabled. */ - enableSuggestions: boolean = false; - /** Whether IME personalized learning is enabled. */ - enableIMEPersonalizedLearning: boolean = false; - /** Whether delta model is enabled for text editing. */ - enableDeltaModel: boolean = false; - /** The input type for the text field, or null if not set. */ - inputType: InputType | null = null; - /** The input action to perform when the user submits. */ - inputAction: Number = 0; - /** The label for the action button. */ - actionLabel: String = ""; - /** MIME types for content commit operations. */ - contentCommitMimeTypes: String[] = []; - /** The kind of pointer device being used. */ - deviceKind: PointerDeviceKind = PointerDeviceKind.UNKNOWN; - /** Array of field configurations for autofill. */ - fields: Configuration[] = []; - - /** - * Constructs a new Configuration instance. - * @param obscureText - Whether text should be obscured - * @param autocorrect - Whether autocorrect is enabled - * @param enableSuggestions - Whether suggestions are enabled - * @param enableIMEPersonalizedLearning - Whether IME personalized learning is enabled - * @param enableDeltaModel - Whether delta model is enabled - * @param inputType - The input type - * @param inputAction - The input action - * @param actionLabel - The action label - * @param autofill - Whether autofill is enabled - * @param contentListString - Content commit MIME types - * @param deviceKind - The pointer device kind - * @param fields - Array of field configurations - */ - constructor(obscureText: boolean, - autocorrect: boolean, - enableSuggestions: boolean, - enableIMEPersonalizedLearning: boolean, - enableDeltaModel: boolean, - inputType: InputType, - inputAction: Number, - actionLabel: String, - autofill: boolean, - contentListString: [], - deviceKind: PointerDeviceKind, - fields: Configuration[] - ) { - this.obscureText = obscureText; - this.autocorrect = autocorrect; - this.enableSuggestions = enableSuggestions; - this.enableIMEPersonalizedLearning = enableIMEPersonalizedLearning; - this.enableDeltaModel = enableDeltaModel; - this.inputType = inputType; - this.inputAction = inputAction; - this.actionLabel = actionLabel; - this.autofill = autofill; - this.contentCommitMimeTypes = contentListString; - this.fields = fields - this.deviceKind = deviceKind - } - - private static inputActionFromTextInputAction(inputActionName: string): number { - switch (inputActionName) { - case "TextInputAction.previous": - return inputMethod.EnterKeyType.PREVIOUS - case "TextInputAction.unspecified": - return inputMethod.EnterKeyType.UNSPECIFIED - case "TextInputAction.none": - return inputMethod.EnterKeyType.NONE - case "TextInputAction.go": - return inputMethod.EnterKeyType.GO - case "TextInputAction.search": - return inputMethod.EnterKeyType.SEARCH - case "TextInputAction.send": - return inputMethod.EnterKeyType.SEND - case "TextInputAction.next": - return inputMethod.EnterKeyType.NEXT - case "TextInputAction.newline": - return NEWLINE_KEY_TYPE - case "TextInputAction.done": - return inputMethod.EnterKeyType.DONE - default: - // Present default key if bad input type is given. - return inputMethod.EnterKeyType.UNSPECIFIED - } - } - - /** - * Creates a Configuration instance from JSON. - * @param json - The JSON object - * @returns A new Configuration instance - */ - static fromJson(json: Any) { - const inputActionName: string = json.inputAction; - if (!inputActionName) { - throw new Error("Configuration JSON missing 'inputAction' property."); - } - - let fields: Array = new Array(); - if (json.fields !== null && json.fields !== undefined) { - fields = json.fields.map((field: Any): Any => Configuration.fromJson(field)); - } - - const inputAction: number = Configuration.inputActionFromTextInputAction(inputActionName); - - // Build list of content commit mime types from the data in the JSON list. - const contentList: Array = []; - if (json.contentCommitMimeTypes !== null && json.contentCommitMimeTypes !== undefined) { - json.contentCommitMimeTypes.forEach((type: Any) => { - contentList.push(type); - }); - } - return new Configuration( - json.obscureText ?? false, - json.autocorrect ?? true, - json.enableSuggestions ?? false, - json.enableIMEPersonalizedLearning ?? false, - json.enableDeltaModel ?? false, - InputType.fromJson(json.inputType), - inputAction, - json.actionLabel ?? null, - json.autofill ?? null, - contentList as Any, - json.deviceKind ?? PointerDeviceKind.UNKNOWN, - fields - ); - } - - /** - * Creates a Configuration instance from a map. - * @param map - The map containing configuration data - * @returns A new Configuration instance - */ - static fromMap(map: Map) { - let inputTypeSrc: Any = map.get('inputType'); - let type = TextInputType.get(inputTypeSrc.name) ?? inputMethod.TextInputType.TEXT; - let inputType = new InputType(type, inputTypeSrc.decimal, inputTypeSrc.signed); - let inputAction = Configuration.inputActionFromTextInputAction(map.get('inputAction')); - - let fields: Array = new Array(); - if (map.get('fields')) { - fields = map.get('fields').map((field: Any): Any => Configuration.fromJson(field)); - } - - // Build list of content commit mime types from the data in the JSON list. - const contentList: Array = []; - if (map.get('contentCommitMimeTypes')) { - map.get('contentCommitMimeTypes').forEach((type: Any) => { - contentList.push(type); - }); - } - return new Configuration( - map.get('obscureText') ?? false, - map.get('autocorrect') ?? true, - map.get('enableSuggestions') ?? false, - map.get('enableIMEPersonalizedLearning') ?? false, - map.get('enableDeltaModel') ?? false, - inputType, - inputAction, - map.get('actionLabel') ?? null, - map.get('autofill') ?? null, - contentList as Any, - map.get('deviceKind') ?? PointerDeviceKind.UNKNOWN, - fields - ); - } -} - -/* -/// All possible enum values from flutter. -static const List values = [ - text, multiline, number, phone, datetime, emailAddress, url, visiblePassword, name, streetAddress, none, -]; - -// Corresponding string name for each of the [values]. -static const List _names = [ - 'text', 'multiline', 'number', 'phone', 'datetime', 'emailAddress', 'url', 'visiblePassword', 'name', 'address', 'none', -]; - -// Because TextInputType.name and TextInputType.streetAddress do not exist on ohos, -// these two types will be mapped to the default keyboard. -*/ -const TextInputType: Map = new Map([ - ["TextInputType.text", inputMethod.TextInputType.TEXT], - ["TextInputType.multiline", inputMethod.TextInputType.MULTILINE], - ["TextInputType.number", inputMethod.TextInputType.NUMBER], - ["TextInputType.phone", inputMethod.TextInputType.PHONE], - ["TextInputType.datetime", inputMethod.TextInputType.DATETIME], - ["TextInputType.emailAddress", inputMethod.TextInputType.EMAIL_ADDRESS], - ["TextInputType.url", inputMethod.TextInputType.URL], - ["TextInputType.visiblePassword", inputMethod.TextInputType.VISIBLE_PASSWORD], - ["TextInputType.name", inputMethod.TextInputType.TEXT], - ["TextInputType.address", inputMethod.TextInputType.TEXT], - ["TextInputType.none", inputMethod.TextInputType.NONE], -]); - -/** - * A text input type. - */ -export class InputType { - /** The text input type. */ - type: inputMethod.TextInputType; - /** Whether the input accepts signed numbers. */ - isSigned: boolean; - /** Whether the input accepts decimal numbers. */ - isDecimal: boolean; - - /** - * Constructs a new InputType instance. - * @param type - The text input type - * @param isSigned - Whether the input is signed - * @param isDecimal - Whether the input is decimal - */ - constructor(type: inputMethod.TextInputType, isSigned: boolean, isDecimal: boolean) { - this.type = type; - this.isSigned = isSigned; - this.isDecimal = isDecimal; - } - - /** - * Creates an InputType instance from JSON. - * @param json - The JSON object - * @returns A new InputType instance - * @throws Error if the input type is not recognized - */ - static fromJson(json: Any): InputType { - if (TextInputType.has(json.name as string)) { - return new InputType(TextInputType.get(json.name as string) as inputMethod.TextInputType, - json.signed as boolean, json.decimal as boolean) - } - throw new Error("No such TextInputType: " + json.name as string); - } -} - -/** - * State of an on-going text editing session.. - */ -export class TextEditState { - private static TAG = "TextEditState"; - /** The text content. */ - text: string; - /** The start position of the text selection. */ - selectionStart: number; - /** The end position of the text selection. */ - selectionEnd: number; - /** The start position of the composing region. */ - composingStart: number; - /** The end position of the composing region. */ - composingEnd: number; - - /** - * Constructs a new TextEditState instance. - * @param text - The text content - * @param selectionStart - The start of the selection - * @param selectionEnd - The end of the selection - * @param composingStart - The start of the composing region - * @param composingEnd - The end of the composing region - */ - constructor(text: string, - selectionStart: number, - selectionEnd: number, - composingStart: number, - composingEnd: number) { - if ((selectionStart != -1 || selectionEnd != -1) - && (selectionStart < 0 || selectionEnd < 0)) { - throw new Error("invalid selection: (" + selectionStart + ", " + selectionEnd + ")"); - } - - if ((composingStart != -1 || composingEnd != -1) - && (composingStart < 0 || composingStart > composingEnd)) { - throw new Error("invalid composing range: (" + composingStart + ", " + composingEnd + ")"); - } - - if (composingEnd > text.length) { - throw new Error("invalid composing start: " + composingStart); - } - - if (selectionStart > text.length) { - throw new Error("invalid selection start: " + selectionStart); - } - - if (selectionEnd > text.length) { - throw new Error("invalid selection end: " + selectionEnd); - } - - this.text = text; - this.selectionStart = selectionStart; - this.selectionEnd = selectionEnd; - this.composingStart = composingStart; - this.composingEnd = composingEnd; - } - - hasSelection(): boolean { - // When selectionStart == -1, it's guaranteed that selectionEnd will also - // be -1. - return this.selectionStart >= 0; - } - - /** - * Checks if there is an active composing region. - * @returns True if there is an active composing region, false otherwise - */ - hasComposing(): boolean { - return this.composingStart >= 0 && this.composingEnd > this.composingStart; - } - - /** - * Creates a TextEditState instance from JSON. - * @param textEditState - The JSON object or map - * @returns A new TextEditState instance - */ - static fromJson(textEditState: Any): TextEditState { - if (textEditState.text != null && textEditState.text != undefined && textEditState.text != "") { - return new TextEditState( - textEditState.text, - textEditState.selectionBase, - textEditState.selectionExtent, - textEditState.composingBase, - textEditState.composingExtent - ) - } else { - return new TextEditState( - textEditState.get('text'), - textEditState.get('selectionBase'), - textEditState.get('selectionExtent'), - textEditState.get('composingBase'), - textEditState.get('composingExtent') - ) - } - } -} - -/** - * Method call handler for text input channel requests. - */ -class TextInputCallback implements MethodCallHandler { - /** The text input method handler for processing text input requests. */ - textInputMethodHandler: TextInputMethodHandler; - /** The window position rectangle, or null if not set. */ - windowPosition: window.Rect | null = null; - /** The cursor position rectangle. */ - cursorPosition: window.Rect = { - left: 0, - top: 0, - width: 0, - height: 0, - } - /** The device pixel ratio for converting logical to physical pixels. */ - devicePixelRatio = display.getDefaultDisplaySync()?.densityPixels as number; - /** The input position rectangle. */ - inputPosition: window.Rect = { - left: 0, - top: 0, - width: 0, - height: 0, - } - - /** - * Constructs a new TextInputCallback instance. - * @param handler - The TextInputMethodHandler instance - */ - constructor(handler: TextInputMethodHandler) { - this.textInputMethodHandler = handler; - } - - /** - * Sets the window position. - * @param windowPosition - The window position rectangle - */ - setWindowPosition(windowPosition: window.Rect) { - this.windowPosition = windowPosition; - } - - /** - * Sets the device pixel ratio. - * @param devicePixelRatio - The device pixel ratio value - */ - setDevicePixelRatio(devicePixelRatio: number) { - this.devicePixelRatio = devicePixelRatio; - } - - /** - * Sets the cursor position based on window and input positions. - */ - setCursorPosition() { - const left = (this.windowPosition?.left ?? 0 as number) + (this.cursorPosition.left + this.inputPosition.left) * this.devicePixelRatio; - const top = (this.windowPosition?.top ?? 0 as number) + (this.cursorPosition.top + this.inputPosition.top) * this.devicePixelRatio; - this.textInputMethodHandler.setCursorSizeAndPosition({ - left: left, - top: top, - width: 100, - height: 50, - }) - } - - - /** - * Handles method calls from Dart. - * @param call - The method call from Dart - * @param result - The result callback to send a response - */ - onMethodCall(call: MethodCall, result: MethodResult) { - if (this.textInputMethodHandler == null) { - return; - } - let method: string = call.method; - let args: Any = call.args; - Log.d(TAG, "Received '" + method + "' message."); - switch (method) { - case "TextInput.show": - this.textInputMethodHandler.show(); - Log.d(TAG, "textInputMethodHandler.show()"); - result.success(null); - break; - case "TextInput.hide": - this.textInputMethodHandler.hide(); - result.success(null); - break; - case "TextInput.setClient": - const textInputClientId: number = args[0] as number; - const jsonConfiguration: string = args[1]; - const config: Configuration | null = Configuration.fromJson(jsonConfiguration); - - this.textInputMethodHandler.setClient(textInputClientId, config); - result.success(null); - break; - case 'TextInput.updateConfig': - const newConfig: Configuration | null = Configuration.fromMap(args as Map); - this.textInputMethodHandler.updateConfig(newConfig); - result.success(null); - break; - case "TextInput.requestAutofill": - //TODO: requestAutofill - result.notImplemented(); - break; - case "TextInput.setPlatformViewClient": - //TODO: - result.notImplemented(); - break; - case "TextInput.setEditingState": - this.textInputMethodHandler.setEditingState(TextEditState.fromJson(args)); - result.success(null); - break; - case "TextInput.setCaretRect": - this.cursorPosition.top = args.get('y'); - this.cursorPosition.left = args.get('x'); - this.cursorPosition.width = args.get('width'); - this.cursorPosition.height = args.get('height'); - this.setCursorPosition(); - break; - case "TextInput.setEditableSizeAndTransform": - this.inputPosition.left = args.get('transform')[12]; - this.inputPosition.top = args.get('transform')[13]; - this.setCursorPosition(); - break; - case "TextInput.clearClient": - this.textInputMethodHandler.clearClient(); - result.success(null); - break; - case "TextInput.sendAppPrivateCommand": - //TODO: - result.notImplemented(); - break; - case "TextInput.finishAutofillContext": - //TODO: - result.notImplemented(); - break; - default: - result.notImplemented(); - break; - } - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/workers/PlatformChannelWorker.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/workers/PlatformChannelWorker.ets deleted file mode 100644 index 7219844..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/workers/PlatformChannelWorker.ets +++ /dev/null @@ -1,72 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS'; - -import Log from '../../../util/Log'; -import SendableBinaryMessageHandler from '../../../plugin/common/SendableBinaryMessageHandler'; -import { TaskState } from '../dart/DartMessenger'; - - -const TAG: string = 'PlatformChannelWorker'; -const workerPort: ThreadWorkerGlobalScope = worker.workerPort; - -/** - * Defines the event handler to be called when the worker thread receives a message sent by the host thread. - * The event handler is executed in the worker thread. - * - * @param e - The message event data - */ -workerPort.onmessage = async (e: MessageEvents) => { - let data: TaskState = e.data; - let result: ArrayBuffer | null = await handleMessage(data.handler, data.message, data.args); - workerPort.postMessage(result, [result]); -} - -/** - * Defines the event handler to be called when the worker receives a message that cannot be deserialized. - * The event handler is executed in the worker thread. - * - * @param e - The message event data - */ -workerPort.onmessageerror = (e: MessageEvents) => { - Log.e(TAG, '#onmessageerror = ' + e.data); -} - -/** - * Defines the event handler to be called when an exception occurs during worker execution. - * The event handler is executed in the worker thread. - * - * @param e - The error event - */ -workerPort.onerror = (e: ErrorEvent) => { - Log.e(TAG, '#onerror = ' + e.message); -} - -/** - * Handles a message in the worker thread. - * @param handler - The message handler to execute - * @param message - The message data as an ArrayBuffer - * @param args - Additional arguments to pass to the handler - * @returns A promise that resolves to the reply ArrayBuffer, or null if no reply - */ -async function handleMessage(handler: SendableBinaryMessageHandler, - message: ArrayBuffer, - args: Object[]): Promise { - const result = await new Promise((resolve, reject) => { - try { - handler.onMessage(message, { - reply: (reply: ArrayBuffer | null): void => { - resolve(reply); - } - }, ...args); - } catch (e) { - reject(null); - Log.e(TAG, "Oops! Failed to handle message in the background: ", e); - } - }); - return result; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/EmbeddingNodeController.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/EmbeddingNodeController.ets deleted file mode 100644 index bc53121..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/EmbeddingNodeController.ets +++ /dev/null @@ -1,266 +0,0 @@ -/* -* Copyright (c) 2024 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -*/ -import { BuilderNode, FrameNode, NodeController, NodeRenderType } from '@kit.ArkUI'; -import Any from '../../plugin/common/Any'; -import PlatformView, { Params, PlatformViewVisibleAreaEventOptions } from '../../plugin/platform/PlatformView'; -import Log from '../../util/Log'; -import { DVModel, DVModelChildren, DynamicView } from '../../view/DynamicView/dynamicView'; - - -declare class nodeControllerParams { - surfaceId: string - type: string - renderType: NodeRenderType - embedId: string - width: number - height: number -} - -const TAG = 'EmbeddingNodeController' - -/** - * Node controller for embedding platform views in Flutter. - * This class manages the lifecycle and rendering of platform views using BuilderNode. - */ -export class EmbeddingNodeController extends NodeController { - private builderNode: BuilderNode<[Params]> | undefined | null = null; - private wrappedBuilder: WrappedBuilder<[Params]> | null = null; - private platformView: PlatformView | undefined = undefined; - private embedId: string = ""; - private surfaceId: string = ""; - private renderType: NodeRenderType = NodeRenderType.RENDER_TYPE_DISPLAY; - private direction: Direction = Direction.Auto; - private isDestroy: boolean = false; - private platformViewVisibleAreaEventOptions: PlatformViewVisibleAreaEventOptions | null = null; - - /** - * Sets the render options for the platform view. - * @param platformView - The platform view instance - * @param surfaceId - The surface ID - * @param renderType - The render type - * @param direction - The layout direction - */ - setRenderOption(platformView: PlatformView, surfaceId: string, renderType: NodeRenderType, direction: Direction) { - if (platformView == undefined) { - Log.e(TAG, "platformView undefined"); - } else { - this.wrappedBuilder = platformView.getView(); - } - this.platformView = platformView; - this.surfaceId = surfaceId; - this.renderType = renderType; - this.direction = direction; - } - - /** - * Notify the PlatformView that it has entered an invisible state, and animations on it need to be inactive. - */ - notifyPlatformViewInvisible(): void { - if (!this.platformView || !this.platformViewVisibleAreaEventOptions || - this.platformViewVisibleAreaEventOptions.enable === false) { - return; - } - - this.platformView.onInactive(); - } - - /** - * Set up the callback for monitoring changes in the visible area of the external texture. - */ - setPlatformViewVisibleAreaEventCallback(): void { - if (!this.platformView) { - return; - } - - this.platformViewVisibleAreaEventOptions = - this.platformView.getPlatformViewVisibleAreaEventOptions(); - if (!this.platformViewVisibleAreaEventOptions) { - return; - } - - const options = this.platformViewVisibleAreaEventOptions!; - - Log.i(TAG, - "setPlatformViewVisibleAreaEventCallback surfaceId:" + this.surfaceId + - ", enable:" + options.enable + - ", ratios:" + options.ratios + - ", expectedUpdateInterval:" + options.expectedUpdateInterval + - ", onInactiveThreshold:" + options.onInactiveThreshold + - ", onActiveThreshold:" + options.onActiveThreshold); - if (options.enable === false) { - return; - } - - let node: FrameNode | null | undefined = this.builderNode?.getFrameNode(); - if (!node) { - return; - } - - node?.commonEvent.setOnVisibleAreaApproximateChange( - { ratios: options.ratios, - expectedUpdateInterval: options.expectedUpdateInterval }, - - (isExpanding: boolean, currentRatio: number) => - { - if (!this.platformView) { - return; - } - - Log.i(TAG, - "PlatformViewVisibleAreaEventCallback surfaceId:" + this.surfaceId + - ", isExpanding:" + isExpanding + - ", currentRatio:" + currentRatio); - if (!isExpanding && - currentRatio <= options.onInactiveThreshold) { - // Pause the operation of continuous production of textures - this.platformView.onInactive(); - } else if (isExpanding && - currentRatio >= options.onActiveThreshold) { - // Resume the operation of continuous production of textures - this.platformView.onActive(); - } - } - ) - } - - /** - * Creates a FrameNode for the platform view. - * @param uiContext - The UI context - * @returns The created FrameNode, or null if creation fails - */ - makeNode(uiContext: UIContext): FrameNode | null { - this.builderNode = new BuilderNode(uiContext, { surfaceId: this.surfaceId, type: this.renderType }); - - if (this.platformView) { - this.builderNode.build(this.wrappedBuilder, { direction: this.direction, platformView: this.platformView }); - this.setPlatformViewVisibleAreaEventCallback(); - } - return this.builderNode.getFrameNode(); - } - - /** - * Sets the builder node. - * @param builderNode - The BuilderNode instance, or null - */ - setBuilderNode(builderNode: BuilderNode | null): void { - this.builderNode = builderNode; - } - - /** - * Gets the builder node. - * @returns The BuilderNode instance, or null if not set - */ - getBuilderNode(): BuilderNode<[Params]> | undefined | null { - return this.builderNode; - } - - /** - * Updates the node with new arguments. - * @param arg - The update arguments - */ - updateNode(arg: Object): void { - this.builderNode?.update(arg); - } - - /** - * Gets the embed ID. - * @returns The embed ID string - */ - getEmbedId(): string { - return this.embedId; - } - - /** - * Sets the destroy state and disposes the builder node if needed. - * @param isDestroy - Whether the controller is being destroyed - */ - setDestroy(isDestroy: boolean): void { - this.isDestroy = isDestroy; - if (this.isDestroy) { - this.builderNode?.dispose(); - } - } - - /** - * Disposes the frame node and cleans up resources. - */ - disposeFrameNode() { - this.builderNode?.getFrameNode()?.getRenderNode()?.dispose(); - this.builderNode?.dispose(); - - this.builderNode = null; - this.wrappedBuilder = null; - } - - /** - * Posts a mouse event to the builder node. - * Note: postInputEvent is an API20 interface, so we check for its existence to avoid compilation errors. - * @param event - The mouse event to post - */ - postMouseEvent(event: MouseEvent) { - // Avoid compilation errors: postInputEvent is an API20 interface - if (typeof (this.builderNode as ESObject)?.postInputEvent == 'function') { - (this.builderNode as ESObject)?.postInputEvent(event); - } - } - - /** - * Posts an axis event to the builder node. - * Note: postInputEvent is an API20 interface, so we check for its existence to avoid compilation errors. - * @param event - The axis event to post - */ - postAxisEvent(event: AxisEvent) { - // Avoid compilation errors: postInputEvent is an API20 interface - if (typeof (this.builderNode as ESObject)?.postInputEvent == 'function') { - (this.builderNode as ESObject)?.postInputEvent(event); - } - } - - /** - * Posts a touch event to the builder node. - * @param event - The touch event to post, or undefined - * @param isPx - Whether the coordinates are already in pixels (default: false, will convert from vp to px) - * @returns Whether the event was successfully posted - */ - postEvent(event: TouchEvent | undefined, isPx: boolean = false): boolean { - if (event == undefined) { - return false; - } - - // change vp to px - if (!isPx) { - let changedTouchLen = event.changedTouches.length; - for (let i = 0; i < changedTouchLen; i++) { - event.changedTouches[i].displayX = vp2px(event.changedTouches[i].displayX); - event.changedTouches[i].displayY = vp2px(event.changedTouches[i].displayY); - event.changedTouches[i].windowX = vp2px(event.changedTouches[i].windowX); - event.changedTouches[i].windowY = vp2px(event.changedTouches[i].windowY); - event.changedTouches[i].screenX = vp2px(event.changedTouches[i].screenX); - event.changedTouches[i].screenY = vp2px(event.changedTouches[i].screenY); - event.changedTouches[i].x = vp2px(event.changedTouches[i].x); - event.changedTouches[i].y = vp2px(event.changedTouches[i].y); - Log.d(TAG, "changedTouches[" + i + "] displayX:" + event.changedTouches[i].displayX + " displayY:" + - event.changedTouches[i].displayY + " x:" + event.changedTouches[i].x + " y:" + event.changedTouches[i].y); - } - let touchesLen = event.touches.length; - for (let i = 0; i< touchesLen; i++) { - event.touches[i].displayX = vp2px(event.touches[i].displayX); - event.touches[i].displayY = vp2px(event.touches[i].displayY); - event.touches[i].windowX = vp2px(event.touches[i].windowX); - event.touches[i].windowY = vp2px(event.touches[i].windowY); - event.touches[i].screenX = vp2px(event.touches[i].screenX); - event.touches[i].screenY = vp2px(event.touches[i].screenY); - event.touches[i].x = vp2px(event.touches[i].x); - event.touches[i].y = vp2px(event.touches[i].y); - Log.d(TAG, "touches[" + i + "] displayX:" + event.touches[i].displayX + " displayY:" + - event.touches[i].displayY + " x:" + event.touches[i].x + " y:" + event.touches[i].y); - } - } - - return this.builderNode?.postTouchEvent(event) as boolean - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/ExclusiveAppComponent.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/ExclusiveAppComponent.ets deleted file mode 100644 index 125d035..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/ExclusiveAppComponent.ets +++ /dev/null @@ -1,31 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on ExclusiveAppComponent.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -/** - * Interface for app components that exclusively attach to a FlutterEngine. - * @template T - The type of the underlying app component - */ -export default interface ExclusiveAppComponent { - /** - * Called when another App Component is about to become attached to the - * {@link FlutterEngine} this App Component is currently attached to. - * - * This App Component's connections to the {@link FlutterEngine} - * are still valid at the moment of this call. - */ - detachFromFlutterEngine(): void; - - /** - * Retrieves the App Component behind this exclusive App Component. - * - * @returns The app component - */ - getAppComponent(): T; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbility.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbility.ets deleted file mode 100644 index 2b799f7..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbility.ets +++ /dev/null @@ -1,546 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import UIAbility from '@ohos.app.ability.UIAbility'; -import window from '@ohos.window'; -import { FlutterAbilityAndEntryDelegate, Host } from './FlutterAbilityAndEntryDelegate'; -import Log from '../../util/Log'; -import FlutterEngine from '../engine/FlutterEngine'; -import PlatformPlugin from '../../plugin/PlatformPlugin'; -import SensitiveContentPlugin from '../../plugin/view/SensitiveContentPlugin'; -import FlutterShellArgs from '../engine/FlutterShellArgs'; -import FlutterAbilityLaunchConfigs from './FlutterAbilityLaunchConfigs'; -import common from '@ohos.app.ability.common'; -import Want from '@ohos.app.ability.Want'; -import { FlutterPlugin } from '../engine/plugins/FlutterPlugin'; -import AbilityConstant from '@ohos.app.ability.AbilityConstant'; -import I18n from '@ohos.i18n' -import { PlatformBrightness } from '../engine/systemchannels/SettingsChannel'; -import ConfigurationConstant from '@ohos.app.ability.ConfigurationConstant'; -import { Configuration } from '@ohos.app.ability.Configuration'; -import { deviceInfo } from '@kit.BasicServicesKit'; -import ExclusiveAppComponent from './ExclusiveAppComponent'; -import errorManager from '@ohos.app.ability.errorManager'; -import appRecovery from '@ohos.app.ability.appRecovery'; -import FlutterManager from './FlutterManager'; -import { FlutterView } from '../../view/FlutterView'; -import ApplicationInfoLoader from '../engine/loader/ApplicationInfoLoader'; -import { accessibility } from '@kit.AccessibilityKit'; - -const TAG = "FlutterAbility"; - -/** - * Base Flutter Ability for OpenHarmony. - * Main responsibilities: - * 1. Holds and initializes FlutterAbilityDelegate - * 2. Forwards lifecycle events - * - * Main abilities should inherit from this class. - */ -export class FlutterAbility extends UIAbility implements Host { - private delegate?: FlutterAbilityAndEntryDelegate | null; - private flutterView: FlutterView | null = null; - private mainWindow?: window.Window | null; - private errorManagerId: number = 0; - - /** - * Gets the FlutterView instance. - * @returns The FlutterView instance, or null if not available - */ - getFlutterView(): FlutterView | null { - return this.flutterView; - } - - /** - * Gets the page path for loading content. - * @returns The page path string - */ - pagePath(): string { - return "pages/Index" - } - - /** - * Determines whether FlutterAbility should be full screen by default. - * Can be overridden to customize full screen behavior. - * Default value: based on device type, determines if full screen is needed. - * @returns True if full screen by default, false otherwise - */ - isDefaultFullScreen(): boolean { - return deviceInfo.deviceType != '2in1'; - } - - /** - * Called when the ability is created. - * 1. Creates and attaches delegate - * 2. Configures windows (transparency not needed) - * 3. Handles lifecycle.onCreate - * 4. setContentView() not needed - * @param want - The Want object - * @param launchParam - The launch parameters - */ - onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { - // On cold start, get the current system font size from the context and store it - AppStorage.setOrCreate('fontSizeScale', this.context.config.fontSizeScale); - Log.i(TAG, "this.context.config.fontSizeScale = " + this.context.config.fontSizeScale); - - Log.i(TAG, "bundleCodeDir=" + this.context.bundleCodeDir); - FlutterManager.getInstance().pushUIAbility(this) - - this.delegate = new FlutterAbilityAndEntryDelegate(this); - this?.delegate?.onAttach(this.context); - Log.i(TAG, 'onAttach end'); - this?.delegate?.platformPlugin?.setUIAbilityContext(this.context); - this?.delegate?.onRestoreInstanceState(want); - - if (this.stillAttachedForEvent("onWindowStageCreate")) { - this?.delegate?.onWindowStageCreate(); - } - - Log.i(TAG, 'MyAbility onCreate'); - - let observer: errorManager.ErrorObserver = { - onUnhandledException(errorMsg) { - Log.e(TAG, "onUnhandledException, errorMsg:", errorMsg); - appRecovery.saveAppState(); - appRecovery.restartApp(); - } - } - this.errorManagerId = errorManager.on('error', observer); - - let flutterApplicationInfo = ApplicationInfoLoader.load(this.context); - - if (flutterApplicationInfo.isDebugMode) { - this.delegate?.initWindow(); - } - } - - /** - * Called when the ability is destroyed. - * Cleans up resources and removes the ability from FlutterManager. - */ - onDestroy() { - FlutterManager.getInstance().popUIAbility(this); - - errorManager.off('error', this.errorManagerId); - - if (this.flutterView != null) { - this.flutterView.onDestroy() - this.flutterView = null; - } - - if (this.stillAttachedForEvent("onDestroy")) { - this?.delegate?.onDetach(); - } - - this.release() - } - - /** - * Called to save the ability state. - * @param reason - The reason for saving state - * @param wantParam - The parameters to save state to - * @returns The save result - */ - onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult { - return this?.delegate?.onSaveState(reason, wantParam) ?? AbilityConstant.OnSaveResult.ALL_REJECT; - } - - protected windowStageEventCallback = (data: window.WindowStageEventType) => { - this.delegate?.onWindowStageChanged(data) - } - - /** - * Called when the window stage is created. - * @param windowStage - The WindowStage instance - */ - onWindowStageCreate(windowStage: window.WindowStage) { - FlutterManager.getInstance().pushWindowStage(this, windowStage); - this.delegate?.initWindow(); - this.mainWindow = windowStage.getMainWindowSync(); - try { - windowStage.on('windowStageEvent', this.windowStageEventCallback); - this.flutterView = this.delegate!!.createView(this.context) - Log.i(TAG, 'onWindowStageCreate:' + this.flutterView!!.getId()); - let storage: LocalStorage = new LocalStorage(); - storage.setOrCreate("viewId", this.flutterView!!.getId()) - windowStage.loadContent(this.pagePath(), storage, (err, data) => { - if (err.code) { - Log.e(TAG, 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); - return; - } - this.flutterView?.onWindowCreated(); - - Log.i(TAG, 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); - }); - if (this.isDefaultFullScreen()) { - FlutterManager.getInstance().setUseFullScreen(true, this.context); - } - } catch (exception) { - Log.e(TAG, 'Failed to enable the listener for window stage event changes. Cause:' + JSON.stringify(exception)); - } - } - - /** - * Called when a new Want is received. - * @param want - The new Want object - * @param launchParams - The launch parameters - */ - onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void { - this?.delegate?.onNewWant(want, launchParams) - } - - /** - * Called when the window stage is destroyed. - */ - onWindowStageDestroy() { - FlutterManager.getInstance().popWindowStage(this); - if (this.stillAttachedForEvent("onWindowStageDestroy")) { - this?.delegate?.onWindowStageDestroy(); - } - } - - /** - * Called when the ability comes to foreground. - */ - onForeground() { - if (this.stillAttachedForEvent("onForeground")) { - this?.delegate?.onShow(); - } - } - - /** - * Called when the ability goes to background. - */ - onBackground() { - if (this.stillAttachedForEvent("onBackground")) { - this?.delegate?.onHide(); - } - } - - /** - * Called when the window stage is about to be destroyed. - * @param windowStage - The WindowStage instance - */ - onWindowStageWillDestroy(windowStage: window.WindowStage) { - try { - windowStage.off('windowStageEvent', this.windowStageEventCallback); - } catch (err) { - Log.e(TAG, "windowStage off failed"); - } - } - - /** - * Releases all held objects. - */ - release() { - if (this?.delegate != null) { - this?.delegate?.release(); - this.delegate = null; - } - } - - /** - * Gets the UIAbility instance. - * @returns This UIAbility instance - */ - getAbility(): UIAbility { - return this; - } - - /** - * Gets the FlutterAbilityAndEntryDelegate instance. - * @returns The delegate instance, or null if not available - */ - getFlutterAbilityAndEntryDelegate(): FlutterAbilityAndEntryDelegate | null { - return this.delegate ?? null; - } - - /** - * Determines whether to dispatch app lifecycle state changes. - * @returns True to dispatch lifecycle state, false otherwise - */ - shouldDispatchAppLifecycleState(): boolean { - return true; - } - - /** - * Provides a FlutterEngine instance. - * @param context - The context - * @returns A FlutterEngine instance, or null if not provided - */ - provideFlutterEngine(context: common.Context): FlutterEngine | null { - return null; - } - - /** - * Provides a PlatformPlugin instance. - * @param flutterEngine - The FlutterEngine instance - * @returns A PlatformPlugin instance - */ - providePlatformPlugin(flutterEngine: FlutterEngine): PlatformPlugin | undefined { - return new PlatformPlugin(flutterEngine.getPlatformChannel()!, this.context, this); - } - - /** - * Provides a SensitiveContentPlugin instance. - * @param flutterEngine - The FlutterEngine instance - * @returns A SensitiveContentPlugin instance - */ - provideSensitiveContentPlugin(flutterEngine: FlutterEngine): SensitiveContentPlugin | undefined { - return new SensitiveContentPlugin(flutterEngine.getSensitiveContentChannel()!); - } - - /** - * Configures the Flutter engine. - * @param flutterEngine - The FlutterEngine to configure - */ - configureFlutterEngine(flutterEngine: FlutterEngine) { - - } - - /** - * Cleans up the Flutter engine. - * @param flutterEngine - The FlutterEngine to clean up - */ - cleanUpFlutterEngine(flutterEngine: FlutterEngine) { - - } - - /** - * Gets Flutter shell arguments from the Want. - * @returns A FlutterShellArgs instance - */ - getFlutterShellArgs(): FlutterShellArgs { - return FlutterShellArgs.fromWant(this.getWant()); - } - - /** - * Gets Dart entrypoint arguments from launch parameters. - * @returns Array of entrypoint arguments - */ - getDartEntrypointArgs(): Array { - if (this.launchWant.parameters![FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT_ARGS]) { - return this.launchWant.parameters![FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT_ARGS] as Array; - } - return new Array() - } - - /** - * Detaches from the Flutter engine. - */ - detachFromFlutterEngine() { - if (this?.delegate != null) { - this?.delegate?.onDetach(); - } - } - - /** - * Determines whether to pop the system navigator. - * @returns False by default - */ - popSystemNavigator(): boolean { - return false; - } - - /** - * Determines whether to attach the engine to the ability. - * @returns True to attach the engine, false otherwise - */ - shouldAttachEngineToAbility(): boolean { - return true; - } - - /** - * Gets the Dart entrypoint library URI. - * @returns The library URI string - */ - getDartEntrypointLibraryUri(): string { - return ""; - } - - /** - * Gets the app bundle path. - * @returns The bundle path string - */ - getAppBundlePath(): string { - return ""; - } - - /** - * Gets the Dart entrypoint function name from launch parameters. - * @returns The entrypoint function name, or default if not set - */ - getDartEntrypointFunctionName(): string { - if (this.launchWant.parameters![FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT]) { - return this.launchWant.parameters![FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT] as string; - } - return FlutterAbilityLaunchConfigs.DEFAULT_DART_ENTRYPOINT - } - - /** - * Gets the initial route from launch parameters. - * @returns The initial route string, or empty string if not set - */ - getInitialRoute(): string { - if (this.launchWant.parameters![FlutterAbilityLaunchConfigs.EXTRA_INITIAL_ROUTE]) { - return this.launchWant.parameters![FlutterAbilityLaunchConfigs.EXTRA_INITIAL_ROUTE] as string; - } - return "" - } - - /** - * Gets the Want object. - * @returns The launch Want instance - */ - getWant(): Want { - return this.launchWant; - } - - /** - * Determines whether to destroy the engine when the host is destroyed. - * @returns True to destroy the engine, false otherwise - */ - shouldDestroyEngineWithHost(): boolean { - if ((this.getCachedEngineId() != null && this.getCachedEngineId().length > 0) || - this.delegate!!.isFlutterEngineFromHost()) { - // Only destroy a cached engine if explicitly requested by app developer. - return false; - } - return true; - } - - /** - * Determines whether to automatically attach to the engine. - * @returns True to attach automatically, false otherwise - */ - attachToEngineAutomatically(): boolean { - return true; - } - - /** - * Determines whether to restore and save state. - * @returns True to restore and save state, false otherwise - */ - shouldRestoreAndSaveState(): boolean { - if (this.launchWant.parameters![FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] != undefined) { - return this.launchWant.parameters![FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] as boolean; - } - if (this.getCachedEngineId() != null && this.getCachedEngineId().length > 0) { - // Prevent overwriting the existing state in a cached engine with restoration state. - return false; - } - return true; - } - - /** - * Gets the exclusive app component. - * @returns The ExclusiveAppComponent instance, or null - */ - getExclusiveAppComponent(): ExclusiveAppComponent | null { - return this.delegate ? this.delegate : null - } - - /** - * Gets the cached engine ID from launch parameters. - * @returns The cached engine ID string - */ - getCachedEngineId(): string { - return this.launchWant.parameters![FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] as string - } - - /** - * Gets the cached engine group ID from launch parameters. - * @returns The cached engine group ID string, or null if not set - */ - getCachedEngineGroupId(): string | null { - return this.launchWant.parameters![FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_GROUP_ID] as string - } - - /** - * Checks if the delegate is still attached for an event. - * @param event - The event name - * @returns True if attached, false otherwise - */ - private stillAttachedForEvent(event: string) { - Log.i(TAG, 'Ability ' + event); - if (this?.delegate == null) { - Log.w(TAG, "FlutterAbility " + event + " call after release."); - return false; - } - if (!this?.delegate?.isAttached) { - Log.w(TAG, "FlutterAbility " + event + " call after detach."); - return false; - } - return true; - } - - /** - * Adds a Flutter plugin. - * @param plugin - The FlutterPlugin to add - */ - addPlugin(plugin: FlutterPlugin): void { - if (this?.delegate != null) { - this?.delegate?.addPlugin(plugin) - } - } - - /** - * Removes a Flutter plugin. - * @param plugin - The FlutterPlugin to remove - */ - removePlugin(plugin: FlutterPlugin): void { - if (this?.delegate != null) { - this?.delegate?.removePlugin(plugin) - } - } - - /** - * Called when memory level changes. - * @param level - The memory level - */ - onMemoryLevel(level: AbilityConstant.MemoryLevel): void { - Log.i(TAG, 'onMemoryLevel: ' + level); - if (level === AbilityConstant.MemoryLevel.MEMORY_LEVEL_CRITICAL) { - this?.delegate?.onLowMemory(); - } - this.delegate?.getFlutterNapi()?.SetQosOnLowMemory(level as number); - } - - /** - * Called when configuration is updated. - * @param config - The new configuration - */ - onConfigurationUpdate(config: Configuration) { - Log.i(TAG, 'onConfigurationUpdate config:' + JSON.stringify(config)); - this?.delegate?.flutterEngine?.getSettingsChannel()?.startMessage() - .setNativeSpellCheckServiceDefined(false) - .setBrieflyShowPassword(false) - .setAlwaysUse24HourFormat(I18n.System.is24HourClock()) - .setPlatformBrightness(config.colorMode != ConfigurationConstant.ColorMode.COLOR_MODE_DARK - ? PlatformBrightness.LIGHT : PlatformBrightness.DARK) - .setTextScaleFactor(config.fontSizeScale == undefined ? 1.0 : config.fontSizeScale) - .send(); //热启动生命周期内,实时监听系统设置环境改变并实时发送相应信息 - - //实时获取系统字体加粗系数 - this.delegate?.getFlutterNapi()?.setFontWeightScale(config.fontWeightScale == undefined ? 0 : - config.fontWeightScale); - Log.i(TAG, 'fontWeightScale: ' + JSON.stringify(config.fontWeightScale)); - - if (config.language != '') { - this.getFlutterEngine()?.getLocalizationPlugin()?.sendLocaleToFlutter(); - } - this?.delegate?.onCheckAndReloadFont(); - this.delegate?.changeColorMode(config.colorMode); - } - - /** - * Gets the FlutterEngine instance. - * @returns The FlutterEngine instance, or null if not available - */ - getFlutterEngine(): FlutterEngine | null { - return this.delegate?.flutterEngine || null; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityAndEntryDelegate.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityAndEntryDelegate.ets deleted file mode 100644 index 30bd7fc..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityAndEntryDelegate.ets +++ /dev/null @@ -1,705 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import common from '@ohos.app.ability.common'; -import FlutterEngineConfigurator from './FlutterEngineConfigurator'; -import FlutterEngineProvider from './FlutterEngineProvider'; -import FlutterEngine from '../engine/FlutterEngine'; -import PlatformPlugin, { PlatformPluginDelegate } from '../../plugin/PlatformPlugin'; -import SensitiveContentPlugin from '../../plugin/view/SensitiveContentPlugin'; -import Want from '@ohos.app.ability.Want'; -import FlutterShellArgs from '../engine/FlutterShellArgs'; -import DartExecutor, { DartEntrypoint } from '../engine/dart/DartExecutor'; -import FlutterAbilityLaunchConfigs from './FlutterAbilityLaunchConfigs'; -import Log from '../../util/Log'; -import FlutterInjector from '../../FlutterInjector'; -import UIAbility from '@ohos.app.ability.UIAbility'; -import ExclusiveAppComponent from './ExclusiveAppComponent'; -import AbilityConstant from '@ohos.app.ability.AbilityConstant'; -import { FlutterPlugin } from '../engine/plugins/FlutterPlugin'; -import FlutterEngineCache from '../engine/FlutterEngineCache'; -import FlutterEngineGroupCache from '../engine/FlutterEngineGroupCache'; -import FlutterEngineGroup, { Options } from '../engine/FlutterEngineGroup'; -import FlutterNapi from '../engine/FlutterNapi'; -import { FlutterView } from '../../view/FlutterView'; -import FlutterManager from './FlutterManager'; -import Any from '../../plugin/common/Any'; -import inputMethod from '@ohos.inputMethod'; -import window from '@ohos.window'; -import { ConfigurationConstant } from '@kit.AbilityKit'; -import { resourceManager } from '@kit.LocalizationKit'; -import { EmbeddingNodeController } from './EmbeddingNodeController'; - -const TAG = "FlutterAbilityDelegate"; -const PLUGINS_RESTORATION_BUNDLE_KEY = "plugins"; -const FRAMEWORK_RESTORATION_BUNDLE_KEY = "framework"; - -/** - * Delegate for managing FlutterAbility and FlutterEntry lifecycle. - * Main responsibilities: - * 1. Initializes the Flutter engine - * 2. Handles ability lifecycle callbacks - */ -class FlutterAbilityAndEntryDelegate implements ExclusiveAppComponent { - protected host?: Host | null; - /** The FlutterEngine instance, or null if not created. */ - flutterEngine?: FlutterEngine | null; - /** The PlatformPlugin instance, or undefined if not set. */ - platformPlugin?: PlatformPlugin; - sensitiveContentPlugin?:SensitiveContentPlugin; - protected context?: common.Context; - protected isFlutterEngineFromHostOrCache: boolean = false; - private engineGroup?: FlutterEngineGroup; - private isHost: boolean = false; - private flutterView?: FlutterView; - private inputMethodController: inputMethod.InputMethodController = inputMethod.getController(); - private isPageShow: boolean = false; - private currentColorMode?: ConfigurationConstant.ColorMode; - - /** - * Constructs a new FlutterAbilityAndEntryDelegate instance. - * @param host - The Host instance, optional - */ - constructor(host?: Host) { - this.host = host; - if (this.host) { - this.isHost = true; - } - } - - /** - * Whether the delegate is still attached to the ability. - */ - isAttached = false; - - /** - * Called when the delegate is attached to a context. - * @param context - The application context - */ - onAttach(context: common.Context) { - this.context = context; - this.ensureAlive(); - if (this.flutterEngine == null) { - this.setupFlutterEngine(); - } - - if (this.host?.shouldAttachEngineToAbility()) { - // Notify any plugins that are currently attached to our FlutterEngine that they - // are now attached to an Ability. - Log.d(TAG, "Attaching FlutterEngine to the Ability that owns this delegate."); - this.flutterEngine?.getAbilityControlSurface()?.attachToAbility(this); - } - - this.platformPlugin = this.host?.providePlatformPlugin(this.flutterEngine!) - - this.sensitiveContentPlugin = this.host?.provideSensitiveContentPlugin(this.flutterEngine!) - - this.isAttached = true; - if (this.flutterEngine) { - this.flutterEngine.getSystemLanguages(); - const config = this.context.resourceManager.getConfigurationSync(); - this.currentColorMode = - config.colorMode === resourceManager.ColorMode.DARK ? ConfigurationConstant.ColorMode.COLOR_MODE_DARK : - ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT; - } - if (this.flutterEngine && this.flutterView && this.host?.attachToEngineAutomatically()) { - this.flutterView.attachToFlutterEngine(this.flutterEngine!!); - } - this.host?.configureFlutterEngine(this.flutterEngine!!); - if (this.flutterEngine) { - this.flutterEngine.processPendingMessages(); - } - } - - private doInitialFlutterViewRun(): void { - let initialRoute = this.host?.getInitialRoute(); - if (initialRoute == null && this.host != null) { - initialRoute = this.maybeGetInitialRouteFromIntent(this.host.getWant()); - - } - if (initialRoute == null) { - initialRoute = FlutterAbilityLaunchConfigs.DEFAULT_INITIAL_ROUTE; - } - const libraryUri = this.host?.getDartEntrypointLibraryUri(); - Log.d(TAG, - "Executing Dart entrypoint: " + this.host?.getDartEntrypointFunctionName() + ", library uri: " + libraryUri == - null ? "\"\"" : libraryUri + ", and sending initial route: " + initialRoute); - - // The engine needs to receive the Flutter app's initial route before executing any - // Dart code to ensure that the initial route arrives in time to be applied. - this.flutterEngine?.getNavigationChannel()?.setInitialRoute(initialRoute ?? ''); - - let appBundlePathOverride = this.host?.getAppBundlePath(); - if (appBundlePathOverride == null || appBundlePathOverride == '') { - appBundlePathOverride = FlutterInjector.getInstance().getFlutterLoader().findAppBundlePath(); - } - - const dartEntrypoint: DartEntrypoint = new DartEntrypoint( - appBundlePathOverride, - this.host?.getDartEntrypointLibraryUri() ?? '', - this.host?.getDartEntrypointFunctionName() ?? '' - ); - this.flutterEngine?.dartExecutor.executeDartEntrypoint(dartEntrypoint, this.host?.getDartEntrypointArgs()); - } - - private maybeGetInitialRouteFromIntent(want: Want): string { - return ''; - } - - /** - * Configures the FlutterEngine through parameters. - * @param want - The Want object containing restoration data - */ - onRestoreInstanceState(want: Want) { - let frameworkState: Uint8Array = this.getRestorationData(want.parameters as Record); - if (this.host?.shouldRestoreAndSaveState()) { - this.flutterEngine?.getRestorationChannel()?.setRestorationData(frameworkState); - } - } - - private getRestorationData(wantParam: Record): Uint8Array { - let result: Uint8Array = new Uint8Array(1).fill(0); - if (wantParam == null) { - return result; - } - if (wantParam[FRAMEWORK_RESTORATION_BUNDLE_KEY] == undefined) { - return result - } - if (typeof wantParam[FRAMEWORK_RESTORATION_BUNDLE_KEY] == 'object') { - let data: Record = wantParam[FRAMEWORK_RESTORATION_BUNDLE_KEY] as Record; - let byteArray: Array = new Array; - Object.keys(data).forEach( - key => { - byteArray.push(data[key]); - } - ); - result = Uint8Array.from(byteArray); - } - return result; - } - - /** - * Initializes the FlutterEngine. - * Checks for cached engines, engine groups, or creates a new engine. - */ - setupFlutterEngine() { - // First, check if the host wants to use a cached FlutterEngine. - const cachedEngineId = this.host?.getCachedEngineId(); - Log.d(TAG, "cachedEngineId=" + cachedEngineId); - if (cachedEngineId && cachedEngineId.length > 0) { - this.flutterEngine = FlutterEngineCache.getInstance().get(cachedEngineId); - this.isFlutterEngineFromHostOrCache = true; - if (this.flutterEngine == null) { - throw new Error( - "The requested cached FlutterEngine did not exist in the FlutterEngineCache: '" - + cachedEngineId - + "'"); - } - return; - } - - // Second, defer to subclasses for a custom FlutterEngine. - if (this.host && this.context) { - this.flutterEngine = this.host.provideFlutterEngine(this.context); - } - if (this.flutterEngine != null) { - this.isFlutterEngineFromHostOrCache = true; - return; - } - - // Third, check if the host wants to use a cached FlutterEngineGroup - // and create new FlutterEngine using FlutterEngineGroup#createAndRunEngine - const cachedEngineGroupId = this.host?.getCachedEngineGroupId(); - Log.d(TAG, "cachedEngineGroupId=" + cachedEngineGroupId); - if (cachedEngineGroupId != null) { - const flutterEngineGroup = FlutterEngineGroupCache.instance.get(cachedEngineGroupId); - if (flutterEngineGroup == null) { - throw new Error( - "The requested cached FlutterEngineGroup did not exist in the FlutterEngineGroupCache: '" - + cachedEngineGroupId - + "'"); - } - - if (this.context != null) { - this.flutterEngine = flutterEngineGroup.createAndRunEngineByOptions( - this.addEntrypointOptions(new Options(this.context))); - } - this.isFlutterEngineFromHostOrCache = false; - return; - } - - // Our host did not provide a custom FlutterEngine. Create a FlutterEngine to back our - // FlutterView. - Log.d( - TAG, - "No preferred FlutterEngine was provided. Creating a new FlutterEngine for this FlutterAbility."); - - let group = this.engineGroup; - if (group == null && this.context != null) { - group = new FlutterEngineGroup(); - const flutterShellArgs = this.host ? this.host.getFlutterShellArgs() : new FlutterShellArgs(); - group.checkLoader(this.context, flutterShellArgs.toArray() ?? []); - this.engineGroup = group; - } - if (this.context) { - this.flutterEngine = group?.createAndRunEngineByOptions(this.addEntrypointOptions(new Options(this.context) - .setWaitForRestorationData(this.host?.shouldRestoreAndSaveState() || false))); - } - this.isFlutterEngineFromHostOrCache = false; - } - - /** - * Adds entrypoint options to the engine options. - * @param options - The Options instance to configure - * @returns The configured Options instance - */ - addEntrypointOptions(options: Options): Options { - let appBundlePathOverride = this.host?.getAppBundlePath(); - if (appBundlePathOverride == null || appBundlePathOverride.length == 0) { - appBundlePathOverride = FlutterInjector.getInstance().getFlutterLoader().findAppBundlePath(); - } - - const dartEntrypoint = new DartEntrypoint(appBundlePathOverride ?? '', - '', - this.host?.getDartEntrypointFunctionName() ?? ''); - let initialRoute = this.host?.getInitialRoute(); - if (initialRoute == null && this.host != null) { - initialRoute = this.maybeGetInitialRouteFromIntent(this.host.getWant()); - } - if (initialRoute == null) { - initialRoute = FlutterAbilityLaunchConfigs.DEFAULT_INITIAL_ROUTE; - } - return options - .setDartEntrypoint(dartEntrypoint) - .setInitialRoute(initialRoute) - .setDartEntrypointArgs(this.host?.getDartEntrypointArgs() ?? []); - } - - /** - * Creates a FlutterView instance. - * @param context - The context for creating the view - * @returns A new FlutterView instance - */ - createView(context: Context): FlutterView { - this.flutterView = FlutterManager.getInstance().createFlutterView(context) - if (this.flutterEngine && this.host?.attachToEngineAutomatically()) { - this.flutterView.attachToFlutterEngine(this.flutterEngine!!); - } - this.platformPlugin?.setFlutterView(this.flutterView); - return this.flutterView - } - - /** - * Releases all held objects. - */ - release() { - this.host = null; - this.flutterEngine = null; - this.platformPlugin = undefined; - } - - /** - * Called when the delegate is detached from the ability. - * Cleans up resources and optionally destroys the engine. - */ - onDetach() { - if (this.host?.shouldAttachEngineToAbility()) { - // Notify plugins that they are no longer attached to an Ability. - Log.d(TAG, "Detaching FlutterEngine from the Ability"); - this.flutterEngine?.getAbilityControlSurface()?.detachFromAbility(); - } - this.flutterView?.detachFromFlutterEngine(); - this.host?.cleanUpFlutterEngine(this.flutterEngine!!); - - if (this.host?.shouldDispatchAppLifecycleState() && this.flutterEngine != null) { - this.flutterEngine?.getLifecycleChannel()?.appIsDetached(); - } - - if (this.platformPlugin) { - this.platformPlugin.destroy(); - } - - if (this.sensitiveContentPlugin) { - this.sensitiveContentPlugin.destroy(); - } - - // Destroy our FlutterEngine if we're not set to retain it. - if (this.host?.shouldDestroyEngineWithHost()) { - this.flutterEngine?.destroy(); - if (this.host.getCachedEngineId() != null && this.host.getCachedEngineId().length > 0) { - FlutterEngineCache.getInstance().remove(this.host.getCachedEngineId()); - } - this.flutterEngine = null; - } - - this.isAttached = false; - } - - /** - * Called when the system is running low on memory. - * Notifies Flutter about the memory pressure. - */ - onLowMemory(): void { - this.getFlutterNapi()?.notifyLowMemoryWarning(); - this.flutterEngine?.getSystemChannel()?.sendMemoryPressureWarning(); - } - - /** - * Called when the window stage is created. - * Runs the initial Flutter view. - */ - onWindowStageCreate() { - this.ensureAlive(); - this.doInitialFlutterViewRun(); - } - - /** - * Called when the window stage is destroyed. - */ - onWindowStageDestroy() { - - } - - /** - * Called when the window stage state changes. - * @param stageEventType - The window stage event type - */ - onWindowStageChanged(stageEventType: window.WindowStageEventType) { - switch (stageEventType) { - case window.WindowStageEventType.SHOWN: - Log.i(TAG, 'windowStage shown.'); - break; - case window.WindowStageEventType.ACTIVE: // 获焦状态 - Log.i(TAG, 'windowStage active.'); - this.getFlutterEngine()?.getTextInputChannel()?.textInputMethodHandler?.handleChangeFocus(true); - this.onWindowFocusChanged(true); - break; - case window.WindowStageEventType.INACTIVE: // 失焦状态 - Log.i(TAG, 'windowStage inactive.'); - this.onWindowFocusChanged(false); - break; - case window.WindowStageEventType.PAUSED: - Log.i(TAG, 'windowStage paused.'); - this.onPaused(); - break; - case window.WindowStageEventType.RESUMED: - Log.i(TAG, 'windowStage resumed.'); - this.onResumed(); - break; - case window.WindowStageEventType.HIDDEN: - Log.i(TAG, 'windowStage hidden.'); - break; - } - } - - /** - * Called when window focus changes. - * @param hasFocus - Whether the window has focus - */ - onWindowFocusChanged(hasFocus: boolean): void { - if (this.shouldDispatchAppLifecycleState()) { - this.flutterEngine?.getAbilityControlSurface()?.onWindowFocusChanged(hasFocus); - if (hasFocus) { - this.flutterEngine?.getLifecycleChannel()?.aWindowIsFocused(); - } else { - this.flutterEngine?.getLifecycleChannel()?.noWindowsAreFocused(); - } - } - } - - /** - * Called when the ability is shown. - * Notifies Flutter that the app is resumed. - */ - onShow() { - this.ensureAlive(); - this.isPageShow = true; - this.flutterView?.setActive(true); - if (this.shouldDispatchAppLifecycleState()) { - this.flutterEngine?.getLifecycleChannel()?.appIsResumed(); - } - } - - /** - * Called when the ability is paused. - * Notifies Flutter that the app is inactive. - */ - onPaused() { - if (this.shouldDispatchAppLifecycleState()) { - this.flutterEngine?.getLifecycleChannel()?.appIsInactive(); - } - } - - /** - * Called when the ability is resumed. - * Notifies Flutter that the app is resumed. - */ - onResumed() { - if (this.shouldDispatchAppLifecycleState()) { - this.flutterEngine?.getLifecycleChannel()?.appIsResumed(); - } - } - - /** - * Called when the ability is hidden. - * Notifies Flutter that the app is paused. - */ - onHide() { - if (this.shouldDispatchAppLifecycleState()) { - this.isPageShow = false; - this.flutterView?.setActive(false); - this.flutterEngine?.getLifecycleChannel()?.appIsPaused(); - } - } - - /** - * Checks and reloads fonts if needed. - */ - onCheckAndReloadFont() { - this.getFlutterNapi()?.checkAndReloadFont(); - } - - /** - * Determines whether to dispatch app lifecycle state changes. - * @returns True to dispatch lifecycle state, false otherwise - */ - shouldDispatchAppLifecycleState(): boolean { - if (!this.isHost) { - return this.isAttached; - } - if (this.host == null) { - return false; - } - if (!this.isPageShow) { - return false; - } - return this.host.shouldDispatchAppLifecycleState() && this.isAttached; - } - - /** - * Ensures the delegate is still alive. - * @throws Error if the delegate has been destroyed - */ - ensureAlive() { - if (this.isHost && this.host == null) { - throw new Error("Cannot execute method on a destroyed FlutterAbilityDelegate."); - } - } - - /** - * Gets the FlutterNapi instance. - * @returns The FlutterNapi instance, or null if not available - */ - getFlutterNapi(): FlutterNapi | null { - return this.flutterEngine?.getFlutterNapi() ?? null - } - - /** - * Gets the FlutterEngine instance. - * @returns The FlutterEngine instance, or null if not available - */ - getFlutterEngine(): FlutterEngine | null { - return this.flutterEngine ?? null; - } - - /** - * Detaches from the Flutter engine. - * @throws Error if the engine should not be detached - */ - detachFromFlutterEngine() { - if (this.host?.shouldDestroyEngineWithHost()) { - // The host owns the engine and should never have its engine taken by another exclusive - // ability. - throw new Error( - "The internal FlutterEngine created by " - + this.host - + " has been attached to by another Ability. To persist a FlutterEngine beyond the " - + "ownership of this ability, explicitly create a FlutterEngine"); - } - - // Default, but customizable, behavior is for the host to call {@link #onDetach} - // deterministically as to not mix more events during the lifecycle of the next exclusive - // ability. - this.host?.detachFromFlutterEngine(); - } - - /** - * Gets the app component (UIAbility). - * @returns The UIAbility instance - * @throws Error if the ability is null - */ - getAppComponent(): UIAbility { - const ability = this.host?.getAbility(); - if (ability == null) { - throw new Error( - "FlutterAbilityAndFragmentDelegate's getAppComponent should only " - + "be queried after onAttach, when the host's ability should always be non-null"); - } - return ability; - } - - /** - * Called when a new Want is received. - * @param want - The new Want object - * @param launchParams - The launch parameters - */ - onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void { - this.ensureAlive() - if (this.flutterEngine != null) { - Log.i(TAG, "Forwarding onNewWant() to FlutterEngine and sending pushRouteInformation message."); - this.flutterEngine?.getAbilityControlSurface()?.onNewWant(want, launchParams); - const initialRoute = this.maybeGetInitialRouteFromIntent(want); - if (initialRoute && initialRoute.length > 0) { - this.flutterEngine?.getNavigationChannel()?.pushRouteInformation(initialRoute); - } - } else { - Log.w(TAG, "onNewIntent() invoked before FlutterFragment was attached to an Ability."); - } - } - - /** - * Called to save the ability state. - * @param reason - The reason for saving state - * @param wantParam - The parameters to save state to - * @returns The save result - */ - onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult { - Log.i(TAG, "onSaveInstanceState. Giving framework and plugins an opportunity to save state."); - this.ensureAlive(); - if (this.host?.shouldRestoreAndSaveState()) { - wantParam[FRAMEWORK_RESTORATION_BUNDLE_KEY] = this.flutterEngine!.getRestorationChannel()!.getRestorationData(); - } - if (this.host?.shouldAttachEngineToAbility()) { - const plugins: Record = {} - const result = this.flutterEngine?.getAbilityControlSurface()?.onSaveState(reason, plugins); - wantParam[PLUGINS_RESTORATION_BUNDLE_KEY] = plugins; - return result ?? AbilityConstant.OnSaveResult.ALL_REJECT - } - return AbilityConstant.OnSaveResult.ALL_REJECT - } - - /** - * Adds a Flutter plugin. - * @param plugin - The FlutterPlugin to add - */ - addPlugin(plugin: FlutterPlugin): void { - this.flutterEngine?.getPlugins()?.add(plugin) - } - - /** - * Removes a Flutter plugin. - * @param plugin - The FlutterPlugin to remove - */ - removePlugin(plugin: FlutterPlugin): void { - this.flutterEngine?.getPlugins()?.remove(plugin.getUniqueClassName()) - } - - /** - * Checks if the FlutterEngine was provided by the host or cache. - * @returns True if from host or cache, false if created by delegate - */ - isFlutterEngineFromHost(): boolean { - return this.isFlutterEngineFromHostOrCache; - } - - /** - * Initializes the window. - */ - initWindow() { - if (this.flutterEngine && this.isAttached) { - this.platformPlugin?.initWindow() - } - } - - changeColorMode(colorMode?: ConfigurationConstant.ColorMode) { - if (colorMode !== undefined && this.currentColorMode !== colorMode) { - this.currentColorMode = colorMode; - let length = this.flutterView?.getDVModel()?.children.length ?? 0; - for (let index = length - 1; index >= 0; index--) { - const dvModel = this.flutterView?.getDVModel()?.children[index]; - const params = dvModel?.getLayoutParams() as Record; - const nodeController = params['nodeController'] as EmbeddingNodeController; - if (nodeController && nodeController.rebuild) { - nodeController.rebuild(); - } - } - } - } -} - -/** - * Interface for FlutterAbility host. - * This interface extends FlutterEngineProvider, FlutterEngineConfigurator, and PlatformPluginDelegate. - */ -interface Host extends FlutterEngineProvider, FlutterEngineConfigurator, PlatformPluginDelegate { - - getAbility(): UIAbility; - - shouldDispatchAppLifecycleState(): boolean; - - detachFromFlutterEngine(): void; - - shouldAttachEngineToAbility(): boolean; - - getCachedEngineId(): string; - - getCachedEngineGroupId(): string | null; - - /** - * Returns true if the {@link io.flutter.embedding.engine.FlutterEngine} used in this delegate - * should be destroyed when the host/delegate are destroyed. - */ - shouldDestroyEngineWithHost(): boolean; - - /** Returns the {@link FlutterShellArgs} that should be used when initializing Flutter. */ - getFlutterShellArgs(): FlutterShellArgs; - - /** Returns arguments that passed as a list of string to Dart's entrypoint function. */ - getDartEntrypointArgs(): Array; - - /** - * Returns the URI of the Dart library which contains the entrypoint method (example - * "package:foo_package/main.dart"). If null, this will default to the same library as the - * `main()` function in the Dart program. - */ - getDartEntrypointLibraryUri(): string; - - /** Returns the path to the app bundle where the Dart code exists. */ - getAppBundlePath(): string; - - /** - * Returns the Dart entrypoint that should run when a new {@link io.flutter.embedding.engine.FlutterEngine} is created. - */ - getDartEntrypointFunctionName(): string; - - /** Returns the initial route that Flutter renders. */ - getInitialRoute(): string; - - getWant(): Want; - - shouldRestoreAndSaveState(): boolean; - - getExclusiveAppComponent(): ExclusiveAppComponent | null - - providePlatformPlugin(flutterEngine: FlutterEngine): PlatformPlugin | undefined - - provideSensitiveContentPlugin(flutterEngine: FlutterEngine): SensitiveContentPlugin | undefined - - /** - * Whether to automatically attach the {@link FlutterView} to the engine. - * - * In the add-to-app scenario where multiple {@link FlutterView} share the same {@link FlutterEngine}, - * the host application desires to determine the timing of attaching the {@link FlutterView} - * to the engine, for example, during the {@code onResume} instead of the {@code onCreateView}. - - * - * Defaults to {@code true}. - */ - attachToEngineAutomatically(): boolean; -} - -export { Host, FlutterAbilityAndEntryDelegate } \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityLaunchConfigs.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityLaunchConfigs.ets deleted file mode 100644 index d413496..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityLaunchConfigs.ets +++ /dev/null @@ -1,44 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -/** - * The mode of the background of a Flutter Ability, either opaque or transparent. - */ -enum BackgroundMode { - /** Indicates a Flutter Ability with an opaque background. This is the default. */ - opaque, - /** Indicates a Flutter Ability with a transparent background. */ - transparent -} - -/** - * Configuration constants for Flutter Ability launch parameters. - * This class contains metadata keys, Want extras, and default values for launching Flutter abilities. - */ -export default class FlutterAbilityLaunchConfigs { - static DART_ENTRYPOINT_META_DATA_KEY = "io.flutter.Entrypoint"; - static DART_ENTRYPOINT_URI_META_DATA_KEY = "io.flutter.EntrypointUri"; - static INITIAL_ROUTE_META_DATA_KEY = "io.flutter.InitialRoute"; - static SPLASH_SCREEN_META_DATA_KEY = "io.flutter.embedding.android.SplashScreenDrawable"; - static NORMAL_THEME_META_DATA_KEY = "io.flutter.embedding.android.NormalTheme"; - static HANDLE_DEEPLINKING_META_DATA_KEY = "flutter_deeplinking_enabled"; - // Want extra arguments. - static EXTRA_DART_ENTRYPOINT = "dart_entrypoint"; - static EXTRA_DART_ENTRYPOINT_LIBRARY_URI = "dart_entrypoint_library_uri"; - static EXTRA_INITIAL_ROUTE = "route"; - static EXTRA_BACKGROUND_MODE = "background_mode"; - static EXTRA_CACHED_ENGINE_ID = "cached_engine_id"; - static EXTRA_DART_ENTRYPOINT_ARGS = "dart_entrypoint_args"; - static EXTRA_CACHED_ENGINE_GROUP_ID = "cached_engine_group_id"; - static EXTRA_DESTROY_ENGINE_WITH_ACTIVITY = "destroy_engine_with_activity"; - static EXTRA_ENABLE_STATE_RESTORATION = "enable_state_restoration"; - // Default configuration. - static DEFAULT_DART_ENTRYPOINT = "main"; - static DEFAULT_INITIAL_ROUTE = "/"; - static DEFAULT_BACKGROUND_MODE = BackgroundMode.opaque; - // Preload configuration. - static PRELOAD_VIEWPORT_METRICS_KEY = "viewport_metrics"; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineConfigurator.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineConfigurator.ets deleted file mode 100644 index 3db0dda..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineConfigurator.ets +++ /dev/null @@ -1,29 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on FlutterEngineConfigurator.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import FlutterEngine from '../engine/FlutterEngine'; - -/** - * Interface for configuring FlutterEngine instances. - * Implementations can customize engine setup and cleanup. - */ -export default interface FlutterEngineConfigurator { - /** - * Configures a FlutterEngine instance. - * @param flutterEngine - The FlutterEngine to configure - */ - configureFlutterEngine: (flutterEngine: FlutterEngine) => void; - - /** - * Cleans up a FlutterEngine instance. - * @param flutterEngine - The FlutterEngine to clean up - */ - cleanUpFlutterEngine: (flutterEngine: FlutterEngine) => void; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineProvider.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineProvider.ets deleted file mode 100644 index 59a6bc9..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineProvider.ets +++ /dev/null @@ -1,25 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on FlutterEngineProvider.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import FlutterEngine from '../engine/FlutterEngine'; -import common from '@ohos.app.ability.common'; - -/** - * Interface for providing FlutterEngine instances. - * Implementations of this interface can provide custom FlutterEngine instances. - */ -export default interface FlutterEngineProvider { - /** - * Provides a FlutterEngine instance for the given context. - * @param context - The application context - * @returns A FlutterEngine instance, or null if no engine should be provided - */ - provideFlutterEngine(context: common.Context): FlutterEngine | null; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEntry.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEntry.ets deleted file mode 100644 index 6b449a3..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEntry.ets +++ /dev/null @@ -1,468 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import FlutterEngine from '../engine/FlutterEngine'; -import PlatformPlugin from '../../plugin/PlatformPlugin'; -import Want from '@ohos.app.ability.Want'; -import FlutterShellArgs from '../engine/FlutterShellArgs'; -import UIAbility from '@ohos.app.ability.UIAbility'; -import ExclusiveAppComponent from './ExclusiveAppComponent'; -import { FlutterAbilityAndEntryDelegate, Host } from './FlutterAbilityAndEntryDelegate'; -import FlutterAbilityLaunchConfigs from './FlutterAbilityLaunchConfigs'; -import SensitiveContentPlugin from '../../plugin/view/SensitiveContentPlugin'; -import Log from '../../util/Log'; -import { FlutterView } from '../../view/FlutterView'; -import FlutterManager from './FlutterManager'; -import window from '@ohos.window'; -import FlutterEngineConfigurator from './FlutterEngineConfigurator'; -import { FlutterPlugin } from '../engine/plugins/FlutterPlugin'; -import { BusinessError } from '@ohos.base'; -import { PlatformBrightness } from '../engine/systemchannels/SettingsChannel'; -import ConfigurationConstant from '@ohos.app.ability.ConfigurationConstant'; -import I18n from '@ohos.i18n' -import { AbilityConstant, EnvironmentCallback } from '@kit.AbilityKit'; - -const TAG = "FlutterEntry"; - -/** - * Entry point for Flutter content in a page component. - * This class manages the lifecycle of FlutterView and FlutterEngine within a page context. - */ -export default class FlutterEntry implements Host { - private static ARG_SHOULD_ATTACH_ENGINE_TO_ABILITY: string = "should_attach_engine_to_ability"; - protected uiAbility: UIAbility | null = null - protected delegate: FlutterAbilityAndEntryDelegate | null = null - protected flutterView: FlutterView | null = null - protected context: Context; - protected windowStage: window.WindowStage | null = null - private parameters: Record = {}; - protected engineConfigurator: FlutterEngineConfigurator | null = null - protected hasInit: boolean = false; - protected callbackId: number | undefined = undefined; - - /** - * Constructs a new FlutterEntry instance. - * @param context - The page context - * @param params - Optional parameters for configuration - */ - constructor(context: Context, params: Record = {}) { - this.context = context; - this.uiAbility = FlutterManager.getInstance().getUIAbility(context); - this.parameters = params; - this.windowStage = FlutterManager.getInstance().getWindowStage(this.uiAbility); - this.hasInit = false; - } - - /** - * Callback for window stage events. - * @param data - The window stage event type - */ - protected windowStageEventCallback = (data: window.WindowStageEventType) => { - this.delegate?.onWindowStageChanged(data) - } - - /** - * Called when the page is about to appear. - * Initializes the Flutter delegate and view. - */ - aboutToAppear() { - Log.i(TAG, 'aboutToAppear'); - if (this.hasInit == false) { - this.delegate = new FlutterAbilityAndEntryDelegate(this); - this.flutterView = this.delegate?.createView(this.context); - this.flutterView?.onWindowCreated(); - this?.delegate?.onAttach(this.context); - //this.flutterView?.preDraw(); - //Log.d(TAG, "XComponent aboutToAppear predraw"); - Log.i(TAG, 'onAttach end'); - this?.delegate?.platformPlugin?.setUIAbilityContext(this.uiAbility!!.context); - this.delegate?.onWindowStageCreate() - this.windowStage?.on('windowStageEvent', this.windowStageEventCallback); - this.hasInit = true; - this.delegate?.initWindow(); - this.registerEnvironmentCallback(); - } - } - - /** - * Registers an environment callback to listen for configuration changes. - */ - registerEnvironmentCallback() { - let environmentCallback: EnvironmentCallback = { - onConfigurationUpdated: (config) => { - Log.i(TAG, 'onConfigurationUpdate config: ' + JSON.stringify(config)); - this?.delegate?.flutterEngine?.getSettingsChannel()?.startMessage() - .setNativeSpellCheckServiceDefined(false) - .setBrieflyShowPassword(false) - .setAlwaysUse24HourFormat(I18n.System.is24HourClock()) - .setPlatformBrightness(config.colorMode != ConfigurationConstant.ColorMode.COLOR_MODE_DARK - ? PlatformBrightness.LIGHT : PlatformBrightness.DARK) - .setTextScaleFactor(config.fontSizeScale == undefined ? 1.0 : config.fontSizeScale) - .send(); //热启动生命周期内,实时监听系统设置环境改变并实时发送相应信息 - - //实时获取系统字体加粗系数 - this.delegate?.getFlutterNapi()?.setFontWeightScale(config.fontWeightScale == undefined ? 0 : - config.fontWeightScale); - Log.i(TAG, 'fontWeightScale: ' + JSON.stringify(config.fontWeightScale)); - - if (config.language != '') { - this.delegate?.flutterEngine?.getLocalizationPlugin()?.sendLocaleToFlutter(); - } - this?.delegate?.onCheckAndReloadFont(); - this.delegate?.changeColorMode(config.colorMode); - }, - onMemoryLevel: (level: AbilityConstant.MemoryLevel) => { - this.delegate?.getFlutterNapi()?.SetQosOnLowMemory(level as number); - } - }; - let applicationContext = this.uiAbility?.context.getApplicationContext(); - try { - this.callbackId = applicationContext?.on('environment', environmentCallback); - } catch (paramError) { - Log.e(TAG, 'registerEnvironmentCallback error: ' + (paramError as BusinessError).code + ' message: ' - + (paramError as BusinessError).message); - } - } - - /** - * Unregisters the environment callback. - */ - unregisterEnvironmentCallback() { - let applicationContext = this.uiAbility?.context.getApplicationContext(); - try { - applicationContext?.off('environment', this.callbackId, (error, data) => { - if (error && error.code !== 0) { - Log.e(TAG, 'unregisterEnvironmentCallback fail, error: ' + JSON.stringify(error)); - } - }); - } catch (paramError) { - Log.e(TAG, 'error: ' + (paramError as BusinessError).code + ' message: ' - + (paramError as BusinessError).message); - } - } - - /** - * Sets the Flutter engine configurator. - * @param configurator - The FlutterEngineConfigurator instance - */ - setFlutterEngineConfigurator(configurator: FlutterEngineConfigurator) { - this.engineConfigurator = configurator; - } - - /** - * Gets the FlutterView instance. - * @returns The FlutterView instance - */ - getFlutterView(): FlutterView { - return this.flutterView!! - } - - /** - * Gets the FlutterEngine instance. - * @returns The FlutterEngine instance, or null if not available - */ - getFlutterEngine(): FlutterEngine | null { - return this.delegate?.flutterEngine! - } - - /** - * Called when the page is about to disappear. - * Cleans up resources and detaches from the Flutter engine. - */ - aboutToDisappear() { - Log.d(TAG, "FlutterEntry aboutToDisappear"); - this.unregisterEnvironmentCallback(); - try { - this.windowStage?.off('windowStageEvent', this.windowStageEventCallback); - } catch (err) { - Log.e(TAG, "windowStage off failed"); - } - if (this.flutterView != null) { - this.flutterView.onDestroy(); - this.flutterView = null; - } - if (this.delegate != null) { - this.delegate?.onDetach(); - this.delegate?.release() - } - } - - /** - * Called when the page is shown. - * Notifies the delegate that the page is visible. - */ - onPageShow() { //生命周期 - Log.d(TAG, "FlutterEntry onPageShow"); - this?.delegate?.onShow(); - } - - /** - * Called when the page is hidden. - * Notifies the delegate that the page is hidden. - */ - onPageHide() { //生命周期 - Log.d(TAG, "FlutterEntry onPageHide"); - this?.delegate?.onHide(); - } - - /** - * Called when the back button is pressed. - * Pops the current route in Flutter navigation. - */ - onBackPress() { - Log.d(TAG, "FlutterEntry onBackPress"); - this?.delegate?.flutterEngine?.getNavigationChannel()?.popRoute(); - } - - /** - * Determines whether to dispatch app lifecycle state changes. - * @returns True to dispatch lifecycle state, false otherwise - */ - shouldDispatchAppLifecycleState(): boolean { - return true; - } - - /** - * Detaches from the Flutter engine. - */ - detachFromFlutterEngine() { - if (this?.delegate != null) { - this?.delegate?.onDetach(); - } - } - - /** - * Gets the associated UIAbility. - * @returns The UIAbility instance - */ - getAbility(): UIAbility { - return this.uiAbility!! - } - - /** - * Loads the page content. - * This method is called by the framework. - */ - loadContent() { - - } - - /** - * Determines whether to attach the engine to the ability. - * @returns True to attach the engine, false otherwise - */ - shouldAttachEngineToAbility(): boolean { - let param = this.parameters![FlutterEntry.ARG_SHOULD_ATTACH_ENGINE_TO_ABILITY]; - if (!param) { - return true; - } - return param as boolean - } - - /** - * Gets the cached engine ID from parameters. - * @returns The cached engine ID, or empty string if not set - */ - getCachedEngineId(): string { - let param = this.parameters![FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID]; - if (!param) { - return ""; - } - return param as string - } - - /** - * Gets the cached engine group ID from parameters. - * @returns The cached engine group ID, or null if not set - */ - getCachedEngineGroupId(): string | null { - let param = this.parameters![FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_GROUP_ID]; - if (!param) { - return null; - } - return param as string - } - - /** - * Determines whether to destroy the engine when the host is destroyed. - * @returns True to destroy the engine, false otherwise - */ - shouldDestroyEngineWithHost(): boolean { - if ((this.getCachedEngineId() != null && this.getCachedEngineId().length > 0) || - this.delegate!!.isFlutterEngineFromHost()) { - // Only destroy a cached engine if explicitly requested by app developer. - return false; - } - return true; - } - - /** - * Determines whether to automatically attach to the engine. - * @returns True to attach automatically, false otherwise - */ - attachToEngineAutomatically(): boolean { - return true; - } - - /** - * Gets Flutter shell arguments. - * @returns A FlutterShellArgs instance - */ - getFlutterShellArgs(): FlutterShellArgs { - return new FlutterShellArgs(); - } - - /** - * Gets Dart entrypoint arguments from parameters. - * @returns Array of entrypoint arguments - */ - getDartEntrypointArgs(): string[] { - if (this.parameters![FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT_ARGS]) { - return this.parameters![FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT_ARGS] as Array; - } - return new Array() - } - - /** - * Gets the Dart entrypoint library URI. - * @returns The library URI string - */ - getDartEntrypointLibraryUri(): string { - return ""; - } - - /** - * Gets the app bundle path. - * @returns The bundle path string - */ - getAppBundlePath(): string { - return ""; - } - - /** - * Gets the Dart entrypoint function name from parameters. - * @returns The entrypoint function name, or default if not set - */ - getDartEntrypointFunctionName(): string { - if (this.parameters![FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT]) { - return this.parameters![FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT] as string; - } - return FlutterAbilityLaunchConfigs.DEFAULT_DART_ENTRYPOINT - } - - /** - * Gets the initial route from parameters. - * @returns The initial route string, or empty string if not set - */ - getInitialRoute(): string { - if (this.parameters![FlutterAbilityLaunchConfigs.EXTRA_INITIAL_ROUTE]) { - return this.parameters![FlutterAbilityLaunchConfigs.EXTRA_INITIAL_ROUTE] as string - } - return ""; - } - - /** - * Gets the Want object. - * @returns A new Want instance - */ - getWant(): Want { - return new Want(); - } - - /** - * Determines whether to restore and save state. - * @returns True to restore and save state, false otherwise - */ - shouldRestoreAndSaveState(): boolean { - if (this.parameters![FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] != undefined) { - return this.parameters![FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] as boolean; - } - if (this.getCachedEngineId() != null && this.getCachedEngineId().length > 0) { - // Prevent overwriting the existing state in a cached engine with restoration state. - return false; - } - return true; - } - - /** - * Gets the exclusive app component. - * @returns The ExclusiveAppComponent instance, or null - */ - getExclusiveAppComponent(): ExclusiveAppComponent | null { - return this.delegate ? this.delegate : null - } - - /** - * Provides a FlutterEngine instance. - * @param context - The context - * @returns A FlutterEngine instance, or null if not provided - */ - provideFlutterEngine(context: Context): FlutterEngine | null { - return null; - } - - /** - * Provides a PlatformPlugin instance. - * @param flutterEngine - The FlutterEngine instance - * @returns A PlatformPlugin instance - */ - providePlatformPlugin(flutterEngine: FlutterEngine): PlatformPlugin | undefined { - return new PlatformPlugin(flutterEngine.getPlatformChannel()!, this.context, this); - } - - /** - * Provides a SensitiveContentPlugin instance. - * @param flutterEngine - The FlutterEngine instance - * @returns A SensitiveContentPlugin instance - */ - provideSensitiveContentPlugin(flutterEngine: FlutterEngine): SensitiveContentPlugin | undefined { - return new SensitiveContentPlugin(flutterEngine.getSensitiveContentChannel()!); - } - - /** - * Configures the Flutter engine. - * @param flutterEngine - The FlutterEngine to configure - */ - configureFlutterEngine(flutterEngine: FlutterEngine) { - if (this.engineConfigurator) { - this.engineConfigurator.configureFlutterEngine(flutterEngine) - } - } - - /** - * Cleans up the Flutter engine. - * @param flutterEngine - The FlutterEngine to clean up - */ - cleanUpFlutterEngine(flutterEngine: FlutterEngine) { - if (this.engineConfigurator) { - this.engineConfigurator.cleanUpFlutterEngine(flutterEngine) - } - } - - /** - * Determines whether to pop the system navigator. - * @returns False by default - */ - popSystemNavigator(): boolean { - return false; - } - - /** - * Adds a Flutter plugin. - * @param plugin - The FlutterPlugin to add - */ - addPlugin(plugin: FlutterPlugin): void { - this.delegate?.addPlugin(plugin) - } - - /** - * Removes a Flutter plugin. - * @param plugin - The FlutterPlugin to remove - */ - removePlugin(plugin: FlutterPlugin): void { - this.delegate?.removePlugin(plugin) - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterManager.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterManager.ets deleted file mode 100644 index 81a2780..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterManager.ets +++ /dev/null @@ -1,575 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - - -import { FlutterView } from '../../view/FlutterView'; -import UIAbility from '@ohos.app.ability.UIAbility'; -import window from '@ohos.window'; -import Log from '../../util/Log'; -import HashMap from '@ohos.util.HashMap'; -import List from '@ohos.util.List'; -import { deviceInfo } from '@kit.BasicServicesKit'; -import { common } from '@kit.AbilityKit'; - -const TAG = "FlutterManager" - -/** - * Singleton manager for Flutter views and UI abilities. - * This class manages the lifecycle of FlutterView instances and their association with UI abilities. - */ -export default class FlutterManager { - private static instance: FlutterManager; - - /** - * Gets the singleton instance of FlutterManager. - * @returns The singleton FlutterManager instance - */ - static getInstance(): FlutterManager { - if (FlutterManager.instance == null) { - FlutterManager.instance = new FlutterManager(); - } - return FlutterManager.instance; - } - - private flutterViewList = new Map(); - private flutterViewIndex = 1; - private uiAbilityList = new Array(); - private windowStageList = new Map(); - private mFullScreenListener: FullScreenListener = new DefaultFullScreenListener(); - - private dragEnterCbId: number = 1; - private dragMoveCbId: number = 1; - private dragLeaveCbId: number = 1; - private dropCbId: number = 1; - - private dragEnterCbs: HashMap = new HashMap(); - private dragMoveCbs: HashMap = new HashMap(); - private dragLeaveCbs: HashMap = new HashMap(); - private dropCbs: HashMap = new HashMap(); - - private getValuesFromMap(map: HashMap): List { - let list: List = new List(); - map.forEach((value, key) => { - list.add(value); - }); - return list; - } - - /** - * Gets all drag enter callbacks. - * @returns A list of drag enter callbacks - */ - getDragEnterCbs(): List { - return this.getValuesFromMap(this.dragEnterCbs); - } - - /** - * Gets all drag move callbacks. - * @returns A list of drag move callbacks - */ - getDragMoveCbs(): List { - return this.getValuesFromMap(this.dragMoveCbs); - } - - /** - * Gets all drag leave callbacks. - * @returns A list of drag leave callbacks - */ - getDragLeaveCbs(): List { - return this.getValuesFromMap(this.dragLeaveCbs); - } - - /** - * Gets all drop callbacks. - * @returns A list of drop callbacks - */ - getDropCbs(): List { - return this.getValuesFromMap(this.dropCbs); - } - - /** - * Adds a drag enter callback. - * @param callback - The drag enter callback - * @returns The callback ID - */ - addDragEnterCb(callback: DragDropCallback): number { - this.dragEnterCbs.set(this.dragEnterCbId, callback); - return this.dragEnterCbId++; - } - - /** - * Adds a drag move callback. - * @param callback - The drag move callback - * @returns The callback ID - */ - addDragMoveCb(callback: DragDropCallback): number { - this.dragMoveCbs.set(this.dragMoveCbId, callback); - return this.dragMoveCbId++; - } - - /** - * Adds a drag leave callback. - * @param callback - The drag leave callback - * @returns The callback ID - */ - addDragLeaveCb(callback: DragDropCallback): number { - this.dragLeaveCbs.set(this.dragLeaveCbId, callback); - return this.dragLeaveCbId++; - } - - /** - * Adds a drop callback. - * @param callback - The drop callback - * @returns The callback ID - */ - addDropCb(callback: DragDropCallback): number { - this.dropCbs.set(this.dropCbId, callback); - return this.dropCbId++; - } - - /** - * Removes a drag enter callback. - * @param id - The callback ID to remove - */ - removeDragEnterCb(id: number) { - this.dragEnterCbs.remove(id); - } - - /** - * Removes a drag move callback. - * @param id - The callback ID to remove - */ - removeDragMoveCb(id: number) { - this.dragMoveCbs.remove(id); - } - - /** - * Removes a drag leave callback. - * @param id - The callback ID to remove - */ - removeDragLeaveCb(id: number) { - this.dragLeaveCbs.remove(id); - } - - /** - * Removes a drop callback. - * @param id - The callback ID to remove - */ - removeDropCb(id: number) { - this.dropCbs.remove(id); - } - - /** - * Pushes a UIAbility to the list. - * @param uiAbility - The UIAbility to add - */ - pushUIAbility(uiAbility: UIAbility) { - this.uiAbilityList.push(uiAbility); - } - - /** - * Removes a UIAbility from the list. - * @param uiAbility - The UIAbility to remove - */ - popUIAbility(uiAbility: UIAbility) { - let index = this.uiAbilityList.findIndex((item: UIAbility) => item == uiAbility) - if (index >= 0) { - this.uiAbilityList.splice(index, 1) - } - } - - /** - * Associates a WindowStage with a UIAbility. - * @param uiAbility - The UIAbility - * @param windowStage - The WindowStage to associate - */ - pushWindowStage(uiAbility: UIAbility, windowStage: window.WindowStage) { - this.windowStageList.set(uiAbility, windowStage) - } - - /** - * Removes the WindowStage association for a UIAbility. - * @param uiAbility - The UIAbility - */ - popWindowStage(uiAbility: UIAbility) { - this.windowStageList.delete(uiAbility) - } - - /** - * Gets the WindowStage for a UIAbility. - * @param uiAbility - The UIAbility - * @returns The associated WindowStage - */ - getWindowStage(uiAbility: UIAbility): window.WindowStage { - return this.windowStageList.get(uiAbility)!! - } - - /** - * Gets a UIAbility by context, or returns the first one if no context is provided. - * @param context - Optional context to search for - * @returns The UIAbility instance - */ - getUIAbility(context?: Context): UIAbility { - if (!context && this.uiAbilityList.length > 0) { - return this.uiAbilityList[0]; - } - return this.uiAbilityList.find((item: UIAbility) => item.context == context)!! - } - - /** - * Checks if a FlutterView exists with the given ID. - * @param viewId - The view ID to check - * @returns True if the view exists, false otherwise - */ - hasFlutterView(viewId: string): boolean { - return this.flutterViewList.has(viewId); - } - - /** - * Gets a FlutterView by ID. - * @param viewId - The view ID - * @returns The FlutterView instance, or null if not found - */ - getFlutterView(viewId: string): FlutterView | null { - return this.flutterViewList.get(viewId) ?? null; - } - - /** - * Gets all FlutterView instances. - * @returns A map of all FlutterView instances by ID - */ - getFlutterViewList(): Map { - return this.flutterViewList; - } - - /** - * Stores or removes a FlutterView in the list. - * @param viewId - The view ID - * @param flutterView - The FlutterView instance, or undefined to remove - */ - private putFlutterView(viewId: string, flutterView?: FlutterView): void { - if (flutterView != null) { - this.flutterViewList.set(viewId, flutterView); - } else { - this.flutterViewList.delete(viewId); - } - } - - /** - * Creates a new FlutterView instance. - * It's suggested to keep 'oh_flutter_' as the prefix for xcomponent_id. - * Otherwise it might affect the performance. - * @param context - The context for creating the view - * @returns A new FlutterView instance - */ - createFlutterView(context: Context): FlutterView { - let flutterView = new FlutterView(`oh_flutter_${this.flutterViewIndex++}`, context); - this.putFlutterView(flutterView.getId(), flutterView); - return flutterView; - } - - /** - * Gets the next FlutterView ID that will be used. - * @param idOffset - Optional offset to add to the index - * @returns The next FlutterView ID string - */ - getNextFlutterViewId(idOffset: number = 0): string { - return `oh_flutter_${this.flutterViewIndex + idOffset}`; - } - - /** - * Clears all FlutterView instances. - */ - clear(): void { - this.flutterViewList.clear(); - } - - /** - * Sets the full screen listener. - * @param listener - The FullScreenListener instance - */ - setFullScreenListener(listener: FullScreenListener) { - this.mFullScreenListener = listener - } - - /** - * Gets the full screen listener. - * @returns The FullScreenListener instance - */ - getFullScreenListener(): FullScreenListener { - return this.mFullScreenListener; - } - - /** - * Sets whether to use full screen mode. - * @param use - Whether to use full screen - * @param context - Optional context - */ - setUseFullScreen(use: boolean, context?: Context | null | undefined) { - this.mFullScreenListener.setUseFullScreen(use, context); - } - - /** - * Checks if full screen mode is enabled. - * @returns True if full screen is enabled, false otherwise - */ - useFullScreen(): boolean { - return this.mFullScreenListener.useFullScreen(); - } - - /** - * Deletes a FlutterView from the list. - * @param viewId - The view ID - * @param flutterView - Optional FlutterView instance to verify - */ - deleteFlutterView(viewId: string, flutterView?: FlutterView): void { - if (flutterView != null) { - this.flutterViewList.delete(viewId); - } - } - - /** - * Get window ID for notifyPageChanged. - * @param context The context to get UIAbility - * @returns The window ID, or 0 if failed - */ - getWindowId(context: common.Context): number { - try { - const uiAbility = this.getUIAbility(context); - if (uiAbility == null) { - Log.e(TAG, "getWindowId: uiAbility is null"); - return 0; - } - const windowStage = this.getWindowStage(uiAbility); - if (windowStage == null) { - Log.e(TAG, "getWindowId: windowStage is null"); - return 0; - } - const mainWindow = windowStage.getMainWindowSync(); - if (mainWindow == null) { - Log.e(TAG, "getWindowId: mainWindow is null"); - return 0; - } - // get windowID for notifyPageChanged. - const windowId = mainWindow.getWindowProperties()?.id ?? 0; - return windowId; - } catch (error) { - Log.e(TAG, "getWindowId failed: " + JSON.stringify(error)); - } - return 0; - } - - /** - * Sets the visibility of a specific system bar and applies safe area padding. - * When hiding a system bar, automatically applies padding to avoid content being covered. - * @param flutterViewId - The ID of the FlutterView to apply padding - * @param specificSystemBar - System bar type: 'status' for status bar, 'navigation' for three-key navigation bar, 'navigationIndicator' for gesture navigation bar - * @param isVisible - True to show, false to hide - * @param enableAnimation - Whether to enable animation effect, optional - * @param context - Optional context, uses the first UIAbility if not provided - */ - setSpecificSystemBarEnabled(flutterViewId: string, specificSystemBar: 'status' | 'navigation' | 'navigationIndicator', isVisible: boolean, enableAnimation?: boolean, context?: Context): void { - const flutterView: FlutterView | null = this.getFlutterView(flutterViewId); - if (!flutterView) { - Log.e(TAG, `setSpecificSystemBarEnabled failed: flutterView not found for id ${flutterViewId}`); - return; - } - - try { - const windowStage = this.getWindowStage(this.getUIAbility(context)); - if (!windowStage) { - Log.e(TAG, 'setSpecificSystemBarEnabled failed: windowStage is null'); - return; - } - - const mainWindow = windowStage.getMainWindowSync(); - if (!mainWindow) { - Log.e(TAG, 'setSpecificSystemBarEnabled failed: mainWindow is null'); - return; - } - mainWindow.setSpecificSystemBarEnabled(specificSystemBar, isVisible, enableAnimation); - - switch (specificSystemBar) { - case 'status': - // Apply top padding when hiding status bar to avoid content being covered - const statusBarHeight = mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM).topRect.height; - if (statusBarHeight > 0) { - flutterView.setPaddingTop(statusBarHeight); - } - break; - case 'navigation': - case 'navigationIndicator': - // Apply bottom padding when hiding navigation bar to avoid content being covered - const navHeight = mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR).bottomRect.height; - if (navHeight > 0) { - flutterView.setPaddingBottom(navHeight); - } - break; - } - - Log.i(TAG, `setSpecificSystemBarEnabled: ${specificSystemBar} = ${isVisible}, animation = ${enableAnimation} success`); - } catch (error) { - Log.e(TAG, `setSpecificSystemBarEnabled error: ${JSON.stringify(error)}`); - } - } - - /** - * Adjusts FlutterView top padding to avoid window decoration overlap. - * @param flutterViewId - The FlutterView ID - * @param context - Optional context, defaults to first UIAbility - */ - handleWindowDecorSafeArea(flutterViewId: string, context?: Context | null | undefined): void { - if (!this.isWindowDecorSafeAreaAvoidSupported(context)) { - return; - } - const flutterView = this.getFlutterView(flutterViewId); - if (!flutterView) { - return; - } - const mainWindow = this.getWindowStage(this.getUIAbility(context ?? undefined))?.getMainWindowSync(); - if (!mainWindow) { - return; - } - // Clear padding if window decoration is visible - if (mainWindow.getWindowDecorVisible() ) { - flutterView.setPaddingTop(0); - return; - } - // Clear padding if title buttons are hidden - const titleButtonRect = mainWindow.getTitleButtonRect(); - if (!titleButtonRect || titleButtonRect.height <= 0) { - flutterView.setPaddingTop(0); - return; - } - // Set padding to match title button height - flutterView.setPaddingTop(vp2px(titleButtonRect.height)); - } - - /** - * Checks if window decoration safe area avoidance is supported on the current device. - * Returns true only when the device is in freeform multi-window mode and supports window decoration. - * @param context - Optional context, defaults to first UIAbility - * @returns True if window decoration safe area avoidance is supported, false otherwise - */ - isWindowDecorSafeAreaAvoidSupported(context?: Context | null | undefined): boolean { - // API 18+ required for window decoration APIs - if (deviceInfo.sdkApiVersion < 18) { - return false; - } - const mainWindow = this.getWindowStage(this.getUIAbility(context ?? undefined))?.getMainWindowSync(); - if (!mainWindow) { - return false; - } - try { - // Avoid compilation errors: getWindowDecorVisible is an API18 interface - // Check if getWindowDecorVisible API is available - const result = typeof (mainWindow as ESObject)?.getWindowDecorVisible(); - return result == 'boolean'; - } catch (exception) { - Log.i(TAG, `Failed to check window decor visibility support. Cause code: ${exception.code}, message: ${exception.message}`); - return false; - } - } -} - -/** - * Interface for drag and drop callbacks. - */ -export interface DragDropCallback { - /** - * Handles a drag and drop event. - * @param event - The drag event - * @param extraParams - Additional parameters - */ - do(event: DragEvent, extraParams: string): void; -} - -/** - * Interface for full screen state management. - */ -export interface FullScreenListener { - /** - * Checks if full screen mode is enabled. - * @returns True if full screen is enabled, false otherwise - */ - useFullScreen(): boolean; - - /** - * Sets whether to use full screen mode. - * @param useFullScreen - Whether to use full screen - * @param context - Optional context - */ - setUseFullScreen(useFullScreen: boolean, context?: Context | null | undefined): void; - - /** - * Called when the screen state changes. - * @param data - The window status type - */ - onScreenStateChanged(data: window.WindowStatusType): void; -} - -/** - * Default implementation of FullScreenListener. - */ -export class DefaultFullScreenListener implements FullScreenListener { - private fullScreen: boolean = true; - private skipCheck: boolean = false; - - /** - * Checks if full screen mode is enabled. - * @returns True if full screen is enabled, false otherwise - */ - useFullScreen(): boolean { - return this.fullScreen; - } - - /** - * Sets whether to use full screen mode. - * @param useFullScreen - Whether to use full screen - * @param context - Optional context - */ - setUseFullScreen(useFullScreen: boolean, context?: Context | null | undefined): void { - this.fullScreen = useFullScreen; - this.skipCheck = true; - - context = context??getContext(this); - const currentWindow = FlutterManager.getInstance() - .getWindowStage(FlutterManager.getInstance().getUIAbility(context)); - - currentWindow.getMainWindowSync().setWindowLayoutFullScreen(useFullScreen); - - if (deviceInfo.deviceType === '2in1' && deviceInfo.sdkApiVersion >= 14 && useFullScreen) { - currentWindow.getMainWindowSync().maximize(window.MaximizePresentation.ENTER_IMMERSIVE); - } - - Log.i(TAG, "WindowLayoutFullScreen is on") - } - - /** - * Called when the screen state changes. - * @param data - The window status type - */ - onScreenStateChanged(data: window.WindowStatusType): void { - if (this.skipCheck) { - Log.i(TAG, "onScreenStateChanged: skipCheck is on, WindowStatusType = " + data) - return; - } - switch (data) { - case window.WindowStatusType.FULL_SCREEN: - - case window.WindowStatusType.SPLIT_SCREEN: - case window.WindowStatusType.FLOATING: - case window.WindowStatusType.MAXIMIZE: - this.fullScreen = true; - Log.i(TAG, "onScreenStateChanged: fullScreen = true") - break; - default: - this.fullScreen = false; - Log.i(TAG, "onScreenStateChanged: fullScreen = false") - break; - } - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterPage.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterPage.ets deleted file mode 100644 index ed4c4f7..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterPage.ets +++ /dev/null @@ -1,354 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import Log from '../../util/Log'; -import { FlutterView } from '../../view/FlutterView'; -import FlutterManager from './FlutterManager'; -import { DVModel, DVModelChildren, DynamicView } from '../../view/DynamicView/dynamicView'; -import Any from '../../plugin/common/Any'; -import deviceInfo from '@ohos.deviceInfo'; -import flutter from 'libflutter.so'; -const TAG = "FlutterPage"; - - -/** - * Basic page component that hosts XComponent for Flutter rendering. - * This component handles the display of Flutter content within an OpenHarmony page. - */ -@Component -export struct FlutterPage { - /** Safe area edges to expand, or undefined for default. */ - @Prop safeAreaEdges: SafeAreaEdge[] | undefined = []; - /** Safe area types to expand, or undefined for default. */ - @Prop safeAreaTypes: SafeAreaType[] | undefined = []; - /** The unique identifier for the XComponent view. */ - @Prop viewId: string = "" - /** The XComponent type for rendering. */ - @Prop xComponentType: XComponentType = XComponentType.SURFACE - /** - * renderFit under XComponent has a default setting of RESIZE_FILL. - * If the size of XComponent may change, this property needs to be passed in and set to a size-preserving property, - * such as TOP_LEFT. - */ - @Prop xComponentRenderFit: RenderFit = RenderFit.RESIZE_FILL; - - /** - * A switch for enabling the frame cache. - * When it is true, one frame of response latency will be increased in exchange for higher smoothness, - * and occasional timeouts in rendering frame submissions will not result in frame dropping. - */ - @Prop enableFrameCacheForSmooth: boolean = true; - - /** - * Empty builder function used as default. - */ - @Builder - doNothingBuilder() { - } - - defaultFocusOnTouch = false; - - @BuilderParam splashScreenView: () => void = this.doNothingBuilder; - - /** - * Default page builder that displays Flutter content with XComponent. - */ - @Builder - defaultPage() { - Stack() { - ForEach(this.rootDvModel!!, (child: ESObject) => { - DynamicView({ - model: child as DVModel, - params: child.params, - events: child.events, - children: child.children, - customBuilder: child.builder - }) - }, (child: ESObject) => `${child.id_}`) - - Text("").id("unfocus-xcomponent-node").focusable(true) - - XComponent({ id: this.viewId, type: this.xComponentType, libraryname: 'flutter' }) - .id(this.viewId) - .focusable(true) - .focusOnTouch(this.defaultFocusOnTouch) - .onLoad((context) => { - this.flutterView?.onSurfaceCreated(); - // Callback is triggered when the xcomponent window is partially visible or completely hidden. - if (deviceInfo.sdkApiVersion < 15) { - this.getUIContext()?.getAttachedFrameNodeById(this.viewId)?.commonEvent.setOnVisibleAreaApproximateChange( - { ratios: [0.0, 1.0], expectedUpdateInterval: 0 }, - (isExpanding: boolean, currentRatio: number) => { - if (isExpanding) { - Log.i(TAG, "setOnVisibleAreaApproximateChange -> xcomponentId: " + this.viewId + - " isExpanding: " + isExpanding + " ratio: " + currentRatio); - flutter.nativeUpdateCurrentXComponentId(this.viewId); - } - } - ) - } - Log.d(TAG, "XComponent onLoad "); - }) - .onDestroy(() => { - Log.d(TAG, "XComponent onDestroy "); - this.flutterView?.onSurfaceDestroyed() - }) - .renderFit(this.xComponentRenderFit) - .backgroundColor(this.firstFrameDisplayed && this.xComponentRenderFit == RenderFit.RESIZE_FILL ? - this.xComponentColor : Color.Transparent) - .expandSafeArea(this.safeAreaTypes, this.safeAreaEdges) - .onAreaChange((oldValue: Area, newValue: Area) => { - // Only handle when Y position changes (window decoration state changed) - if (oldValue.globalPosition.y != newValue.globalPosition.y) { - FlutterManager.getInstance().handleWindowDecorSafeArea(this.viewId, this.getUIContext().getHostContext()); - } - }) - if (this.showSplashScreen) { - this.splashScreenView(); - } - } - .defaultFocus(true) - .onKeyPreIme((event: KeyEvent) => { - return this.flutterView?.onKeyPreIme(event) ?? false; - }) - .onKeyEvent((event: KeyEvent) => { - return this.flutterView?.onKeyEvent(event) ?? false; - }) - .onDragEnter((event: DragEvent, extraParams: string) => { - FlutterManager.getInstance().getDragEnterCbs().forEach(dragEnterCb => { - dragEnterCb.do(event, extraParams); - }); - Log.d(TAG, "onDragEnter"); - }) - .onDragMove((event: DragEvent, extraParams: string) => { - FlutterManager.getInstance().getDragMoveCbs().forEach(dragMoveCb => { - dragMoveCb.do(event, extraParams); - }); - Log.d(TAG, "onDragMove"); - }) - .onDragLeave((event: DragEvent, extraParams: string) => { - FlutterManager.getInstance().getDragLeaveCbs().forEach(dragLeaveCb => { - dragLeaveCb.do(event, extraParams); - }); - Log.d(TAG, "onDragLeave"); - }) - .onDrop((event: DragEvent, extraParams: string) => { - FlutterManager.getInstance().getDropCbs().forEach(dropCb => { - dropCb.do(event, extraParams); - }); - Log.d(TAG, "onDrop"); - }) - } - - /** - * Page builder that supports mouse wheel gestures. - */ - @Builder - mouseWheelPage() { - Stack() { - ForEach(this.rootDvModel!!, (child: Any) => { - DynamicView({ - model: child as DVModel, - params: child.params, - events: child.events, - children: child.children, - customBuilder: child.builder - }) - }, (child: ESObject) => `${child.id_}`) - - Text("").id("unfocus-xcomponent-node").focusable(true) - - XComponent({ id: this.viewId, type: this.xComponentType, libraryname: 'flutter' }) - .id(this.viewId) - .focusable(true) - .focusOnTouch(this.defaultFocusOnTouch) - .onLoad((context) => { - this.flutterView?.onSurfaceCreated(); - // Callback is triggered when the xcomponent window is partially visible or completely hidden. - if (deviceInfo.sdkApiVersion < 15) { - this.getUIContext()?.getAttachedFrameNodeById(this.viewId)?.commonEvent.setOnVisibleAreaApproximateChange( - { ratios: [0.0, 1.0], expectedUpdateInterval: 0 }, - (isExpanding: boolean, currentRatio: number) => { - if (isExpanding) { - Log.i(TAG, "setOnVisibleAreaApproximateChange -> xcomponentId: " + this.viewId + - " isExpanding: " + isExpanding + " ratio: " + currentRatio); - flutter.nativeUpdateCurrentXComponentId(this.viewId); - } - } - ) - } - Log.d(TAG, "XComponent onLoad "); - }) - .onDestroy(() => { - Log.d(TAG, "XComponent onDestroy "); - this.flutterView?.onSurfaceDestroyed() - }) - .renderFit(this.xComponentRenderFit) - .backgroundColor(this.firstFrameDisplayed && this.xComponentRenderFit == RenderFit.RESIZE_FILL ? - this.xComponentColor : Color.Transparent) - .expandSafeArea(this.safeAreaTypes, this.safeAreaEdges) - .onAreaChange((oldValue: Area, newValue: Area) => { - // Only handle when Y position changes (window decoration state changed) - if (oldValue.globalPosition.y != newValue.globalPosition.y) { - FlutterManager.getInstance().handleWindowDecorSafeArea(this.viewId, this.getUIContext().getHostContext()); - } - }) - - if (this.showSplashScreen) { - this.splashScreenView(); - } - } - .defaultFocus(true) - .onKeyPreIme((event: KeyEvent) => { - return this.flutterView?.onKeyPreIme(event) ?? false; - }) - .onKeyEvent((event: KeyEvent) => { - this.flutterView?.onKeyEvent(event) - }) - .onDragEnter((event: DragEvent, extraParams: string) => { - FlutterManager.getInstance().getDragEnterCbs().forEach(dragEnterCb => { - dragEnterCb.do(event, extraParams); - }); - Log.d(TAG, "onDragEnter"); - }) - .onDragMove((event: DragEvent, extraParams: string) => { - FlutterManager.getInstance().getDragMoveCbs().forEach(dragMoveCb => { - dragMoveCb.do(event, extraParams); - }); - Log.d(TAG, "onDragMove"); - }) - .onDragLeave((event: DragEvent, extraParams: string) => { - FlutterManager.getInstance().getDragLeaveCbs().forEach(dragLeaveCb => { - dragLeaveCb.do(event, extraParams); - }); - Log.d(TAG, "onDragLeave"); - }) - .onDrop((event: DragEvent, extraParams: string) => { - FlutterManager.getInstance().getDropCbs().forEach(dropCb => { - dropCb.do(event, extraParams); - }); - Log.d(TAG, "onDrop"); - }) - .gesture( - PanGesture(this.panOption) - .onActionStart((event: GestureEvent) => { - this.flutterView?.onMouseWheel("actionStart", event); - }) - .onActionUpdate((event: GestureEvent) => { - this.flutterView?.onMouseWheel("actionUpdate", event); - }) - .onActionEnd((event: GestureEvent) => { - this.flutterView?.onMouseWheel("actionEnd", event); - }) - ) - } - - /** Whether to show the splash screen. */ - @State showSplashScreen: boolean = true; - /** - * To address the black(or other color set by usr) flashing frame when switching between ArkUI and Flutter pages, - * the background color should be kept transparent until the onFirstFrame is called. - * When the window size changes, modifying the renderFit property in the relevant callback does not take effect immediately. - * The first frame will use the old renderFit property and the old background color, resulting in visual artifacts (such as stretching or a black screen). - * Therefore, we cannot automatically change the relevant properties through state variables at this time. - */ - @State firstFrameDisplayed: boolean = false; - /** Background color for the XComponent. */ - @State xComponentColor: Color = Color.Black - - /** Whether to check for full screen mode. */ - @State checkFullScreen: boolean = true; - /** Whether to check for keyboard visibility. */ - @State checkKeyboard: boolean = true; - /** Whether to check for gesture navigation. */ - @State checkGesture: boolean = true; - /** Whether to enable mouse wheel gesture support. */ - @State checkMouseWheel: boolean = true; - /** Whether to check for AI bar. */ - @State checkAiBar: boolean = true; - /** Top padding value, or undefined if not set. */ - @Prop @Watch("onPaddingChange")paddingTop?: number = undefined; - /** Storage link for node width. */ - @StorageLink('nodeWidth') storageLinkWidth: number = 0; - /** Storage link for node height. */ - @StorageLink('nodeHeight') storageLinkHeight: number = 0; - - /** Root dynamic view model children, or undefined if not set. */ - @State rootDvModel: DVModelChildren | undefined = undefined - - private flutterView?: FlutterView | null - private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.Up | PanDirection.Down }); - - /** - * Called when the page is about to appear. - * Initializes the FlutterView and sets up listeners and callbacks. - */ - aboutToAppear() { - this.flutterView = FlutterManager.getInstance().getFlutterView(this.viewId); - this.flutterView?.addFirstFrameListener(this) - this.flutterView?.addFirstPreloadFrameListener(this) - - // api18开始支持getDistance()接口 - if (deviceInfo.sdkApiVersion >= 18) { - this.flutterView?.setTouchSlopCallbackValue(() => { - return this.panOption.getDistance() - }) - } - - this.flutterView?.setCheckFullScreen(this.checkFullScreen) - this.flutterView?.setCheckKeyboard(this.checkKeyboard) - this.flutterView?.setCheckGesture(this.checkGesture) - this.flutterView?.setPaddingTop(this.paddingTop) - this.flutterView?.setCheckAiBar(this.checkAiBar) - this.flutterView?.enableFrameCache(this.enableFrameCacheForSmooth); - - this.rootDvModel = this.flutterView!!.getDVModel().children - } - - /** - * Called when the page is about to disappear. - * Removes frame listeners to clean up resources. - */ - aboutToDisappear() { - this.flutterView?.removeFirstFrameListener(this); - this.flutterView?.removeFirstPreloadFrameListener(this) - } - - /** - * Called when the first frame is displayed. - * Hides the splash screen and marks the first frame as displayed. - */ - onFirstFrame() { - this.showSplashScreen = false; - this.firstFrameDisplayed = true; - } - - /** - * Called when the first preload frame is displayed. - */ - onFirstPreloadFrame() { - } - - /** - * Called when padding changes. - * Updates the FlutterView's padding. - */ - onPaddingChange() { - this.flutterView?.setPaddingTop(this.paddingTop); - } - - /** - * Builds the page UI. - * Selects between mouse wheel page and default page based on configuration. - */ - build() { - if (this.checkMouseWheel) { - this.mouseWheelPage(); - } else { - this.defaultPage(); - } - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/KeyData.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/KeyData.ets deleted file mode 100644 index 8c43af1..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/KeyData.ets +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2021-2025 Huawei Device Co., Ltd. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE_HW file. - */ - -import util from '@ohos.util' - -/** - * Represents key event data for communication between OpenHarmony and Flutter. - * This class can serialize and deserialize key data to/from binary format. - */ -export default class KeyData { - private static TAG = "KeyData"; - public static CHANNEL = "flutter/keydata"; - // If this value changes, update the code in the following files: - // - // * key_data.h (kKeyDataFieldCount) - // * platform_dispatcher.dart (_kKeyDataFieldCount) - private static FIELD_COUNT: number = 6; - private static BYTES_PER_FIELD: number = 8; - /** Timestamp of the key event. */ - public timestamp: number = 0; - /** Type of the key event (KDOWN, KUP, or KREPEAT). */ - public type: Type = Type.KDOWN; - /** Physical key code. */ - public physicalKey: number = 0; - /** Logical key code. */ - public logicalKey: number = 0; - /** Whether this key event was synthesized. */ - public isSynthesized: boolean = false; - /** Type of the input device. */ - public deviceType: DeviceType = DeviceType.KKEYBOARD; - /** Character representation of the key, or null if not applicable. */ - public character: string | null = null; - - /** - * Constructs a new KeyData instance. - * @param buffer - Optional ArrayBuffer to deserialize key data from - */ - constructor(buffer?: ArrayBuffer) { - if (buffer !== undefined) { - const view = new DataView(buffer); - let offset = 0; - - const decoder = new util.TextDecoder("utf-8"); - const charSize = Number(view.getBigInt64(offset, true)); - offset += 8; - - this.timestamp = Number(view.getBigInt64(offset, true)); - offset += 8; - - this.type = Number(view.getBigInt64(offset, true)) as Type; - offset += 8; - - this.physicalKey = Number(view.getBigInt64(offset, true)); - offset += 8; - - this.logicalKey = Number(view.getBigInt64(offset, true)); - offset += 8; - - this.isSynthesized = view.getBigInt64(offset, true) === BigInt(1); - offset += 8; - - this.deviceType = Number(view.getBigInt64(offset, true)) as DeviceType; - offset += 8; - - if (offset + charSize !== buffer.byteLength) { - throw new Error("KeyData corruption: String length does not match remaining bytes in buffer"); - } - - if (charSize != 0) { - const strBytes = new Uint8Array(buffer, offset, charSize); - this.character = decoder.decode(strBytes); - } - } - } - - /** - * Serializes this KeyData instance to a binary ArrayBuffer. - * @returns The serialized key data as an ArrayBuffer - */ - public toBytes(): ArrayBuffer { - const encoder = new util.TextEncoder("utf-8"); - const encodedCharBytes = this.character == null ? null : encoder.encode(this.character); - const charSize = this.character == null ? 0 : this.character.length; - - const totalBytes = (KeyData.FIELD_COUNT + 1) * KeyData.BYTES_PER_FIELD + charSize; - const buffer = new ArrayBuffer(totalBytes); - const view = new DataView(buffer); - let offset = 0; - - view.setBigInt64(offset, BigInt(charSize), true); - offset += 8; - - view.setBigInt64(offset, BigInt(this.timestamp), true); - offset += 8; - - view.setBigInt64(offset, BigInt(this.type), true); - offset += 8; - - view.setBigInt64(offset, BigInt(this.physicalKey), true); - offset += 8; - - view.setBigInt64(offset, BigInt(this.logicalKey), true); - offset += 8; - - view.setBigInt64(offset, this.isSynthesized ? BigInt(1) : BigInt(0), true); - offset += 8; - - view.setBigInt64(offset, BigInt(this.deviceType), true); - offset += 8; - - if (encodedCharBytes != null) { - new Uint8Array(buffer, offset, charSize).set(encodedCharBytes); - } - - return buffer; - } -} - -/** - * Key event types. - */ -export enum Type { - KDOWN = 0, - KUP, - KREPEAT -} - -/** - * Types of input devices. - */ -export enum DeviceType { - KKEYBOARD = 0, - KDIRECTIONALPAD, - KGAMEPAD, - KJOYSTICK, - KHDMI -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/KeyEmbedderResponder.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/KeyEmbedderResponder.ets deleted file mode 100644 index 2d0440a..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/KeyEmbedderResponder.ets +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright (c) 2021-2025 Huawei Device Co., Ltd. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE_HW file. - */ - -import { BinaryMessenger, BinaryReply } from '../../plugin/common/BinaryMessenger'; -import KeyData, { Type, DeviceType } from './KeyData'; -import { Responder } from './KeyboardManager'; -import KeyboardMap, { KeyPair, ModifierGoal } from './KeyboardMap'; -import Log from '../../util/Log'; - -/** - * Task runner for executing event tasks asynchronously. - */ -class EventTaskRunner { - private tasks: Array<() => void> = []; - - /** - * Constructs a new EventTaskRunner instance. - */ - constructor() { - } - - /** - * Adds a task to be executed later. - * @param task - The task function to add - */ - public addTask(task: () => void): void { - this.tasks.push(task); - } - - /** - * Runs all queued tasks. - */ - public runTasks(): void { - this.tasks.forEach(task => task()); - } -} - -/** - * Responder for handling key events using the embedder API. - * This class converts OpenHarmony key events to Flutter key data format and sends them to Flutter. - */ -export default class KeyEmbedderResponder implements Responder { - private static TAG = "KeyEmbedderResponder"; - private messenger: BinaryMessenger; - private pressingRecords: Map = new Map(); - - /** - * Constructs a new KeyEmbedderResponder instance. - * @param binaryMessenger - The BinaryMessenger for sending key events to Flutter - */ - constructor(binaryMessenger: BinaryMessenger) { - this.messenger = binaryMessenger; - } - - private keyOfPlane(key: number, plane: number): number { - return plane | (key & KeyboardMap.kValueMask); - } - - private getEventType(event: KeyEvent): Type { - let physicalKey: number = this.getPhysicalKey(event); - let isPressed: boolean = this.pressingRecords.has(physicalKey); - switch (event.type) { - case KeyType.Down: - return isPressed ? Type.KREPEAT : Type.KDOWN; - break; - case KeyType.Up: - return Type.KUP; - break; - default: - throw new Error("getEventType: Unexpected event type"); - } - } - - private getLogicalKey(event: KeyEvent): number { - let keyCode: number = event.keyCode; - let logicalKey: number | undefined = KeyboardMap.toLogicalKey.get(keyCode); - if (logicalKey !== undefined) { - return logicalKey; - } - return this.keyOfPlane(keyCode, KeyboardMap.kOhosPlane); - } - - private getPhysicalKey(event: KeyEvent): number { - let keyCode: number = event.keyCode; - let physicalKey: number | undefined = KeyboardMap.toPhysicalKey.get(keyCode); - if (physicalKey !== undefined) { - return physicalKey; - } - return this.keyOfPlane(keyCode, KeyboardMap.kOhosPlane); - } - - /** - * Updates the pressing keys record. - * @param physicalKey - The physical key code - * @param logicalKey - The logical key code, or null if the key is released - */ - updatePressingKeys(physicalKey: number, logicalKey: number | null): void { - if (logicalKey != null) { // press - if (this.pressingRecords.has(physicalKey)) { - Log.e(KeyEmbedderResponder.TAG, "updatePressingKeys adding nonempty key"); - } - this.pressingRecords.set(physicalKey, logicalKey); - } else { // release - if (!this.pressingRecords.has(physicalKey)) { - Log.e(KeyEmbedderResponder.TAG, "updatePressingKeys deleting empty key"); - } - this.pressingRecords.delete(physicalKey); - } - } - - /** - * Synchronizes modifier key states to match expected states. - * @param goal - The modifier goal to synchronize - * @param truePressed - Whether the modifier key is actually pressed - * @param logicalKey - The logical key code - * @param physicalKey - The physical key code - * @param event - The key event - * @param postSyncEvents - Task runner for post-synchronization events - */ - synchronizeModifierKey(goal: ModifierGoal, - truePressed: boolean, - logicalKey: number, - physicalKey: number, - event: KeyEvent, - postSyncEvents: EventTaskRunner) { - let nowStates: boolean[] = new Array(goal.keys.length); - let expectedPreStates: boolean[] = new Array(goal.keys.length); - let postAnyPressed: boolean = false; - - for (let keyIdx = 0; keyIdx < goal.keys.length; keyIdx += 1) { - let key: KeyPair = goal.keys[keyIdx]; - nowStates[keyIdx] = this.pressingRecords.has(key.physicalKey); - if (key.logicalKey == logicalKey) { - switch (this.getEventType(event)) { - case Type.KDOWN: - expectedPreStates[keyIdx] = false; - postAnyPressed = true; - if (!truePressed) { - postSyncEvents.addTask(() => { - this.synthesizeEvent(false, event.timestamp, logicalKey, physicalKey); - }); - } - break; - case Type.KUP: - expectedPreStates[keyIdx] = nowStates[keyIdx]; - break; - case Type.KREPEAT: - expectedPreStates[keyIdx] = nowStates[keyIdx]; - postAnyPressed = true; - if (!truePressed) { - postSyncEvents.addTask(() => { - this.synthesizeEvent(false, event.timestamp, logicalKey, physicalKey); - }); - } - break; - } - } else { - postAnyPressed = postAnyPressed || nowStates[keyIdx]; - } - } - - if (truePressed) { - for (let keyIdx = 0; keyIdx < goal.keys.length; keyIdx += 1) { - if (expectedPreStates[keyIdx] !== undefined) { - continue; - } - if (postAnyPressed) { - expectedPreStates[keyIdx] = nowStates[keyIdx]; - } else { - expectedPreStates[keyIdx] = true; - postAnyPressed = true; - } - } - if (!postAnyPressed) { - expectedPreStates[0] = true; - } - } else { - for (let keyIdx = 0; keyIdx < goal.keys.length; keyIdx += 1) { - if (expectedPreStates[keyIdx] !== undefined) { - continue; - } - expectedPreStates[keyIdx] = false; - } - } - - for (let keyIdx = 0; keyIdx < goal.keys.length; keyIdx += 1) { - if (expectedPreStates[keyIdx] != nowStates[keyIdx]) { - let key: KeyPair = goal.keys[keyIdx]; - this.synthesizeEvent(expectedPreStates[keyIdx], event.timestamp, - key.logicalKey, key.physicalKey); - } - } - } - - /** - * Synthesizes a key event. - * @param isDown - Whether the key is down - * @param timestamp - The event timestamp - * @param logicalKey - The logical key code - * @param physicalKey - The physical key code - */ - synthesizeEvent(isDown: boolean, timestamp: number, - logicalKey: number, physicalKey: number) { - const data: KeyData = new KeyData(); - data.timestamp = timestamp; - data.type = isDown ? Type.KDOWN : Type.KUP; - data.logicalKey = logicalKey; - data.physicalKey = physicalKey; - data.character = null; - data.isSynthesized = true; - data.deviceType = DeviceType.KKEYBOARD; - if (physicalKey != 0 && logicalKey != 0) { - this.updatePressingKeys(physicalKey, isDown ? logicalKey : null); - } - - this.sendKeyEvent(data); - } - - /** - * Sends a key event to Flutter. - * @param data - The KeyData to send - */ - sendKeyEvent(data: KeyData) { - this.messenger.send(KeyData.CHANNEL, data.toBytes()); - } - - /** - * Handles a key event from OpenHarmony. - * @param event - The key event to handle - * @returns Whether the event was handled - */ - handleKeyEvent(event: KeyEvent): boolean { - if (event.keyCode == 0) { - return false; - } - - let physicalKey: number = this.getPhysicalKey(event); - let logicalKey: number = this.getLogicalKey(event); - - let postSyncEvents: EventTaskRunner = new EventTaskRunner(); - - for (let goalIdx = 0; goalIdx < KeyboardMap.modifierGoals.length; goalIdx += 1) { - let goal: ModifierGoal = KeyboardMap.modifierGoals[goalIdx]; - if (event.getModifierKeyState != undefined) { - this.synchronizeModifierKey( - goal, - event.getModifierKeyState([goal.name]), - logicalKey, - physicalKey, - event, - postSyncEvents - ); - } - } - - let isDownEvent: boolean; - switch (event.type) { - case KeyType.Down: - isDownEvent = true; - break; - case KeyType.Up: - isDownEvent = false; - break; - default: - isDownEvent = false; - } - - let type: Type; - let lastLogicalKey: number | undefined = this.pressingRecords.get(physicalKey); - if (isDownEvent) { - if (lastLogicalKey === undefined) { - type = Type.KDOWN; - } else { - /* Nothing about repeat found in KeyEvent, so if isDownEvent and the key is - * currently pressed, take this event as a KREPEAT one. - */ - type = Type.KREPEAT; - } - } else { - if (lastLogicalKey === undefined) { - /* Ignore abrupt up events */ - return false; - } else { - type = Type.KUP; - } - } - - if (type != Type.KREPEAT) { - this.updatePressingKeys(physicalKey, isDownEvent ? logicalKey : null); - } - - const data: KeyData = new KeyData(); - data.timestamp = event.timestamp; - data.type = type; - data.physicalKey = physicalKey; - data.logicalKey = logicalKey; - data.character = null; - data.isSynthesized = false; - // no deviceType found in KeyEvent - data.deviceType = DeviceType.KKEYBOARD; - this.sendKeyEvent(data); - - postSyncEvents.runTasks(); - return true; - } - - /** - * Gets the currently pressed keys. - * @returns A map of physical key codes to logical key codes - */ - public getPressedKeys(): Map { - return new Map(this.pressingRecords); - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/KeyEventHandler.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/KeyEventHandler.ets deleted file mode 100644 index 329a7b8..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/KeyEventHandler.ets +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE_HW file. - */ - -import { HashMap } from '@kit.ArkTS'; -import deviceInfo from '@ohos.deviceInfo'; -import TextInputPlugin from '../../plugin/editing/TextInputPlugin'; -import Log from '../../util/Log'; -import { KeyCode } from '@kit.InputKit'; -import { ListenableEditingState } from '../../plugin/editing/ListenableEditingState'; - -const TAG = "KeyEventHandler"; - -/** - * Represents text for a key in normal and shift cases. - */ -class KeyText { - /** The text in normal case. */ - public normalCase: string; - /** The text in shift case. */ - public shiftCase: string; - - /** - * Constructs a new KeyText instance. - * @param normalCase - The text in normal case - * @param shiftCase - The text in shift case - */ - constructor(normalCase: string, shiftCase: string) { - this.normalCase = normalCase; - this.shiftCase = shiftCase; - } -} -; - -/** - * Handler for key events in emulator/hdc tool input scenarios. - * - * In the emulator/hdc tool input scenario, all keyevents will be passed to the onKeyEvent callback, - * so we need to insert the text to textInputPlugin ourselves. In other scenarios like phone/pc/ets, - * the input method will be responsible for inserting the text to textInputPlugin, consuming 'down' events - * and letting 'up' events go which will be captured by onKeyEvent. - * - * There is no need to process the status of the capslock button. Because in the scenario of the emulator/hdc tool, - * if capslock is pressed, os will send a 'shift' keyevent before the keyevent of the input key and we will insert - * uppercase characters correctly. - */ -export class KeyEventHandler { - - private static keyTextMap: Map = new Map([ - [KeyCode.KEYCODE_0, new KeyText('0', ')')], - [KeyCode.KEYCODE_1, new KeyText('1', '!')], - [KeyCode.KEYCODE_2, new KeyText('2', '@')], - [KeyCode.KEYCODE_3, new KeyText('3', '#')], - [KeyCode.KEYCODE_4, new KeyText('4', '$')], - [KeyCode.KEYCODE_5, new KeyText('5', '%')], - [KeyCode.KEYCODE_6, new KeyText('6', '^')], - [KeyCode.KEYCODE_7, new KeyText('7', '&')], - [KeyCode.KEYCODE_8, new KeyText('8', '*')], - [KeyCode.KEYCODE_9, new KeyText('9', '(')], - [KeyCode.KEYCODE_A, new KeyText('a', 'A')], - [KeyCode.KEYCODE_B, new KeyText('b', 'B')], - [KeyCode.KEYCODE_C, new KeyText('c', 'C')], - [KeyCode.KEYCODE_D, new KeyText('d', 'D')], - [KeyCode.KEYCODE_E, new KeyText('e', 'E')], - [KeyCode.KEYCODE_F, new KeyText('f', 'F')], - [KeyCode.KEYCODE_G, new KeyText('g', 'G')], - [KeyCode.KEYCODE_H, new KeyText('h', 'H')], - [KeyCode.KEYCODE_I, new KeyText('i', 'I')], - [KeyCode.KEYCODE_J, new KeyText('j', 'J')], - [KeyCode.KEYCODE_K, new KeyText('k', 'K')], - [KeyCode.KEYCODE_L, new KeyText('l', 'L')], - [KeyCode.KEYCODE_M, new KeyText('m', 'M')], - [KeyCode.KEYCODE_N, new KeyText('n', 'N')], - [KeyCode.KEYCODE_O, new KeyText('o', 'O')], - [KeyCode.KEYCODE_P, new KeyText('p', 'P')], - [KeyCode.KEYCODE_Q, new KeyText('q', 'Q')], - [KeyCode.KEYCODE_R, new KeyText('r', 'R')], - [KeyCode.KEYCODE_S, new KeyText('s', 'S')], - [KeyCode.KEYCODE_T, new KeyText('t', 'T')], - [KeyCode.KEYCODE_U, new KeyText('u', 'U')], - [KeyCode.KEYCODE_V, new KeyText('v', 'V')], - [KeyCode.KEYCODE_W, new KeyText('w', 'W')], - [KeyCode.KEYCODE_X, new KeyText('x', 'X')], - [KeyCode.KEYCODE_Y, new KeyText('y', 'Y')], - [KeyCode.KEYCODE_Z, new KeyText('z', 'Z')], - - [KeyCode.KEYCODE_GRAVE, new KeyText('`', '~')], - [KeyCode.KEYCODE_MINUS, new KeyText('-', '_')], - [KeyCode.KEYCODE_EQUALS, new KeyText('=', '+')], - [KeyCode.KEYCODE_LEFT_BRACKET, new KeyText('[', '{')], - [KeyCode.KEYCODE_RIGHT_BRACKET, new KeyText(']', '}')], - [KeyCode.KEYCODE_BACKSLASH, new KeyText('\\', '|')], - [KeyCode.KEYCODE_SEMICOLON, new KeyText(';', ':')], - [KeyCode.KEYCODE_APOSTROPHE, new KeyText('\'', '"')], - [KeyCode.KEYCODE_COMMA, new KeyText(',', '<')], - [KeyCode.KEYCODE_PERIOD, new KeyText('.', '>')], - [KeyCode.KEYCODE_SLASH, new KeyText('/', '?')], - [KeyCode.KEYCODE_SPACE, new KeyText(' ', ' ')], - - [KeyCode.KEYCODE_NUMPAD_0, new KeyText('0', '')], - [KeyCode.KEYCODE_NUMPAD_1, new KeyText('1', '')], - [KeyCode.KEYCODE_NUMPAD_2, new KeyText('2', '')], - [KeyCode.KEYCODE_NUMPAD_3, new KeyText('3', '')], - [KeyCode.KEYCODE_NUMPAD_4, new KeyText('4', '')], - [KeyCode.KEYCODE_NUMPAD_5, new KeyText('5', '')], - [KeyCode.KEYCODE_NUMPAD_6, new KeyText('6', '')], - [KeyCode.KEYCODE_NUMPAD_7, new KeyText('7', '')], - [KeyCode.KEYCODE_NUMPAD_8, new KeyText('8', '')], - [KeyCode.KEYCODE_NUMPAD_9, new KeyText('9', '')], - [KeyCode.KEYCODE_NUMPAD_DOT, new KeyText('.', '')], - [KeyCode.KEYCODE_NUMPAD_ADD, new KeyText('+', '')], - [KeyCode.KEYCODE_NUMPAD_SUBTRACT, new KeyText('-', '')], - [KeyCode.KEYCODE_NUMPAD_MULTIPLY, new KeyText('*', '')], - [KeyCode.KEYCODE_NUMPAD_DIVIDE, new KeyText('/', '')], - [KeyCode.KEYCODE_NUMPAD_EQUALS, new KeyText('=', '')], - ]); - private textInputPlugin?: TextInputPlugin; - - /** - * Constructs a new KeyEventHandler instance. - * @param textInputPlugin - The TextInputPlugin instance, optional - */ - constructor(textInputPlugin?: TextInputPlugin) { - this.textInputPlugin = textInputPlugin; - } - - /** - * Gets the text representation of a key event. - * @param event - The key event - * @returns The text string for the key, considering shift state - */ - getKeyText(event: KeyEvent) : string { - let keyText = KeyEventHandler.keyTextMap.get(event.keyCode); - if (keyText !== undefined) { - // Check if it's a letter key (A-Z) - const isLetter = event.keyCode >= KeyCode.KEYCODE_A && event.keyCode <= KeyCode.KEYCODE_Z; - // Use event.isCapsLockOn to check CapsLock state - const isCapsLockOn = event.isCapsLockOn !== undefined ? event.isCapsLockOn : false; - // Use getModifierKeyState to check Shift state - const isShiftPressed = this.getModifierKeyStateSafe(event, ['Shift']); - // If CapsLock is enabled, reverse the case for letter keys - if (isLetter && isCapsLockOn) { - // Shift + CapsLock = lowercase (reverses CapsLock effect) - return isShiftPressed ? keyText.normalCase : keyText.shiftCase; - } else { - // Normal case: Shift determines case - return isShiftPressed ? keyText.shiftCase : keyText.normalCase; - } - } - return ''; - } - - /** - * Starts a deletion operation. - * @param code - The key code for deletion - */ - startDeleting(code: number) { - this.textInputPlugin?.getEditingState().startDeleting(code); - } - - /** - * Ends a deletion operation. - * @param code - The key code for deletion - */ - endDeletion(code: number) { - this.textInputPlugin?.getEditingState().endDeletion(code); - } - - /** - * Helper method to safely execute an action on the editing state. - * @param action - The action to execute with the editing state - * @returns True if the action was executed, false otherwise - */ - private withEditingState(action: (editingState: ListenableEditingState) => void): boolean { - const editingState = this.textInputPlugin?.getEditingState(); - if (editingState) { - action(editingState); - return true; - } - return false; - } - - /** - * Safely gets the modifier key state from a key event. - * @param event - The key event - * @param modifierKeys - Array of modifier key names (e.g., ['Shift'], ['Ctrl'], ['Alt']) - * @returns True if the modifier key is pressed, false otherwise - */ - private getModifierKeyStateSafe(event: KeyEvent, modifierKeys: string[]): boolean { - if (!event.getModifierKeyState) { - return false; - } - try { - return event.getModifierKeyState(modifierKeys) || false; - } catch (e) { - const errorMsg = e instanceof Error ? e.message : String(e); - Log.e(TAG, `Failed to get modifier key state for ${modifierKeys.join(', ')}: ${errorMsg}`); - return false; - } - } - - /** - * Handles a key event and inserts text if appropriate. - * @param event - The key event to handle - */ - handleKeyEvent(event: KeyEvent) { - Log.i(TAG, JSON.stringify({ - "name": "handleKeyEvent", - "event": event - })); - if (event.type === KeyType.Down) { - switch (event.keyCode) { - case KeyCode.KEYCODE_ENTER: - case KeyCode.KEYCODE_NUMPAD_ENTER: { - // Handle Enter key (both regular and numpad), insert newline character - this.withEditingState((editingState) => { - editingState.handleInsertTextEvent('\n'); - Log.i(TAG, `ENTER: inserted newline`); - }); - break; - } - default: { - // Check if it's a numpad number key (0-9) - const isNumpadNumberKey = event.keyCode >= KeyCode.KEYCODE_NUMPAD_0 && event.keyCode <= KeyCode.KEYCODE_NUMPAD_9; - // Check if it's NUMPAD_DOT key - const isNumpadDotKey = event.keyCode === KeyCode.KEYCODE_NUMPAD_DOT; - - // Use event.isNumLockOn to check NumLock state - const isNumLockOn = event.isNumLockOn !== undefined ? event.isNumLockOn : true; // Default to true if not available - - // When NumLock is on, block numpad number keys (0-9) and NUMPAD_DOT, allow other special keys to input symbols - if ((isNumpadNumberKey || isNumpadDotKey) && !isNumLockOn) { - Log.i(TAG, `Numpad key ${event.keyCode} blocked: NumLock is off`); - return; - } - // Other special keys (NUMPAD_ADD, NUMPAD_SUBTRACT, etc.) can input symbols even when NumLock is off - - // Use getModifierKeyState to check Ctrl and Alt state - // Returns true if either Ctrl or Alt (or both) is pressed - const isCtrlPressed = this.getModifierKeyStateSafe(event, ['Ctrl']); - const isAltPressed = this.getModifierKeyStateSafe(event, ['Alt']); - const isCombinationMode = isCtrlPressed || isAltPressed; - - // Don't input characters (letters/numbers/symbols) when Ctrl/Alt keys are pressed or data is empty - if (!isCombinationMode && this.getKeyText(event)) { - this.withEditingState((editingState) => { - // Insert character - editingState.handleInsertTextEvent(this.getKeyText(event)); - }); - } - break; - } - } - } - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/KeyboardManager.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/KeyboardManager.ets deleted file mode 100644 index eb8213f..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/KeyboardManager.ets +++ /dev/null @@ -1,87 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on KeyboardManager.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ -import TextInputPlugin from '../../plugin/editing/TextInputPlugin'; -import FlutterEngine from '../engine/FlutterEngine'; -import KeyEventChannel, { FlutterKeyEvent } from '../engine/systemchannels/KeyEventChannel'; -import KeyboardChannel from '../engine/systemchannels/KeyboardChannel'; -import KeyEmbedderResponder from './KeyEmbedderResponder'; -import { BinaryMessenger } from '../../plugin/common/BinaryMessenger'; -import { KeyEventHandler } from './KeyEventHandler'; -import HashSet from '@ohos.util.HashSet'; -import { KeyCode } from '@kit.InputKit'; - -/** - * Manages keyboard events and state for Flutter. - * This class coordinates between key event channels, keyboard channels, and text input handling. - */ -export default class KeyboardManager { - private keyEventChannel: KeyEventChannel | null = null; - private keyboardChannel: KeyboardChannel | null = null; - /** The key embedder responder for handling key events. */ - protected keyEmbedderResponder: KeyEmbedderResponder; - private keyEventHandler: KeyEventHandler; - - /** - * Constructs a new KeyboardManager instance. - * @param engine - The FlutterEngine instance - * @param textInputPlugin - The TextInputPlugin instance - */ - constructor(engine: FlutterEngine, textInputPlugin: TextInputPlugin) { - this.keyEventChannel = new KeyEventChannel(engine.dartExecutor); - this.keyboardChannel = new KeyboardChannel(engine.dartExecutor); - this.keyboardChannel.setKeyboardMethodHandler(this); - this.keyEmbedderResponder = new KeyEmbedderResponder(engine.dartExecutor); - this.keyEventHandler = new KeyEventHandler(textInputPlugin); - } - - /** - * Handles key events before they are processed by the input method editor. - * @param event - The key event - * @returns Whether the event was handled - */ - onKeyPreIme(event: KeyEvent) : boolean { - return false; - } - - /** - * Handles key events. - * @param event - The key event - * @returns Whether the event was handled - */ - onKeyEvent(event: KeyEvent) : boolean { - this.keyEmbedderResponder.handleKeyEvent(event); - - this.keyEventChannel?.sendFlutterKeyEvent(new FlutterKeyEvent(event), event.type == KeyType.Up, { - onFrameworkResponse: (isEventHandled: boolean): void => { - } - }) - this.keyEventHandler.handleKeyEvent(event); - return false; - } - - /** - * Gets the current keyboard state (pressed keys). - * @returns A map of pressed key codes - */ - public getKeyboardState(): Map { - return this.keyEmbedderResponder.getPressedKeys(); - } -} - -/** - * Interface for handling key events. - */ -export interface Responder { - /** - * Handles a key event. - * @param keyEvent - The key event to handle - */ - handleKeyEvent(keyEvent: KeyEvent): void; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/KeyboardMap.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/KeyboardMap.ets deleted file mode 100644 index 52b86e4..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/KeyboardMap.ets +++ /dev/null @@ -1,652 +0,0 @@ -/* - * Copyright (c) 2021-2025 Huawei Device Co., Ltd. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE_HW file. - */ - -/** - * Represents a pair of physical and logical key codes. - */ -export class KeyPair { - /** The physical key code. */ - public physicalKey: number; - /** The logical key code. */ - public logicalKey: number; - - /** - * Constructs a new KeyPair instance. - * @param physicalKey - The physical key code - * @param logicalKey - The logical key code - */ - constructor(physicalKey: number, logicalKey: number) { - this.physicalKey = physicalKey; - this.logicalKey = logicalKey; - } -} - -/** - * Represents a modifier key goal with associated key pairs. - */ -export class ModifierGoal { - /** The modifier name (e.g., "Ctrl", "Shift", "Alt"). */ - public name: string; - /** Array of KeyPair instances for this modifier. */ - public keys: KeyPair[]; - - /** - * Constructs a new ModifierGoal instance. - * @param name - The modifier name (e.g., "Ctrl", "Shift", "Alt") - * @param keys - Array of KeyPair instances for this modifier - */ - constructor(name: string, keys: KeyPair[]) { - this.name = name; - this.keys = keys; - } -} - -/** - * Maps OpenHarmony KeyCodes to Flutter LogicalKeys and PhysicalKeys. - * This class provides static mappings for keyboard key translation between OpenHarmony and Flutter. - */ -export default class KeyboardMap { - /** Map from OpenHarmony KeyCode to Flutter LogicalKey. */ - public static toLogicalKey: Map = - new Map([ - [0x000000007D0, 0x00000000030], // digit0 - [0x000000007D1, 0x00000000031], // digit1 - [0x000000007D2, 0x00000000032], // digit2 - [0x000000007D3, 0x00000000033], // digit3 - [0x000000007D4, 0x00000000034], // digit4 - [0x000000007D5, 0x00000000035], // digit5 - [0x000000007D6, 0x00000000036], // digit6 - [0x000000007D7, 0x00000000037], // digit7 - [0x000000007D8, 0x00000000038], // digit8 - [0x000000007D9, 0x00000000039], // digit9 - [0x000000007DA, 0x0000000002A], // asterisk - [0x000000007DB, 0x00000000023], // numberSign - [0x000000007DC, 0x00100000304], // arrowUp - [0x000000007DD, 0x00100000301], // arrowDown - [0x000000007DE, 0x00100000302], // arrowLeft - [0x000000007DF, 0x00100000303], // arrowRight - [0x000000007E1, 0x00000000061], // keyA - [0x000000007E2, 0x00000000062], // keyB - [0x000000007E3, 0x00000000063], // keyC - [0x000000007E4, 0x00000000064], // keyD - [0x000000007E5, 0x00000000065], // keyE - [0x000000007E6, 0x00000000066], // keyF - [0x000000007E7, 0x00000000067], // keyG - [0x000000007E8, 0x00000000068], // keyH - [0x000000007E9, 0x00000000069], // keyI - [0x000000007EA, 0x0000000006A], // keyJ - [0x000000007EB, 0x0000000006B], // keyK - [0x000000007EC, 0x0000000006C], // keyL - [0x000000007ED, 0x0000000006D], // keyM - [0x000000007EE, 0x0000000006E], // keyN - [0x000000007EF, 0x0000000006F], // keyO - [0x000000007F0, 0x00000000070], // keyP - [0x000000007F1, 0x00000000071], // keyQ - [0x000000007F2, 0x00000000072], // keyR - [0x000000007F3, 0x00000000073], // keyS - [0x000000007F4, 0x00000000074], // keyT - [0x000000007F5, 0x00000000075], // keyU - [0x000000007F6, 0x00000000076], // keyV - [0x000000007F7, 0x00000000077], // keyW - [0x000000007F8, 0x00000000078], // keyX - [0x000000007F9, 0x00000000079], // keyY - [0x000000007FA, 0x0000000007A], // keyZ - [0x000000007FB, 0x0000000002C], // comma - [0x000000007FC, 0x0000000002E], // period - [0x000000007FD, 0x00200000104], // altLeft - [0x000000007FE, 0x00200000105], // altRight - [0x000000007FF, 0x00200000102], // shiftLeft - [0x00000000800, 0x00200000103], // shiftRight - [0x00000000801, 0x00100000009], // tab - [0x00000000802, 0x00000000020], // space - [0x00000000804, 0x00100000B09], // launchWebBrowser - [0x00000000805, 0x00100000B03], // launchMail - [0x00000000806, 0x0010000000D], // enter - [0x00000000807, 0x00100000008], // backspace - [0x00000000808, 0x00000000060], // backquote - [0x00000000809, 0x0000000002D], // minus - [0x0000000080A, 0x0000000003D], // equal - [0x0000000080B, 0x0000000005B], // bracketLeft - [0x0000000080C, 0x0000000005D], // bracketRight - [0x0000000080D, 0x0000000005C], // backslash - [0x0000000080E, 0x0000000003B], // semicolon - [0x0000000080F, 0x00000000022], // apostrophe/quote - [0x00000000810, 0x0000000002F], // slash - [0x00000000813, 0x00100000505], // contextMenu - [0x000000009A2, 0x00100000704], // compose - [0x00000000814, 0x00100000308], // pageUp - [0x00000000815, 0x00100000307], // pageDown - [0x00000000816, 0x0010000001B], // escape - [0x00000000817, 0x0010000007F], // delete - [0x00000000818, 0x00200000100], // controlLeft - [0x00000000819, 0x00200000101], // controlRight - [0x0000000081A, 0x00100000104], // capsLock - [0x0000000081B, 0x0010000010C], // scrollLock - [0x0000000081C, 0x00200000106], // metaLeft - [0x0000000081D, 0x00200000107], // metaRight - [0x0000000081E, 0x00100000106], // fn - [0x0000000081F, 0x00100000608], // printScreen - [0x00000000820, 0x00100000509], // pause - [0x00000000821, 0x00100000306], // home - [0x00000000822, 0x00100000305], // end - [0x00000000823, 0x00100000407], // insert - [0x00000000824, 0x00100000C03], // browserForward - [0x00000000825, 0x00100000D2F], // mediaPlay - [0x00000000A53, 0x0010000050A], // play - [0x00000000826, 0x00100000D2E], // mediaPause - [0x00000000827, 0x00100000D5B], // mediaClose - [0x00000000828, 0x00100000604], // eject - [0x00000000829, 0x00100000D30], // mediaRecord - [0x0000000082A, 0x00100000801], // f1 - [0x0000000082B, 0x00100000802], // f2 - [0x0000000082C, 0x00100000803], // f3 - [0x0000000082D, 0x00100000804], // f4 - [0x0000000082E, 0x00100000805], // f5 - [0x0000000082F, 0x00100000806], // f6 - [0x00000000830, 0x00100000807], // f7 - [0x00000000831, 0x00100000808], // f8 - [0x00000000832, 0x00100000809], // f9 - [0x00000000833, 0x0010000080A], // f10 - [0x00000000834, 0x0010000080B], // f11 - [0x00000000835, 0x0010000080C], // f12 - [0x00000000836, 0x0010000010A], // numLock - [0x00000000837, 0x00200000230], // numpad0 - [0x00000000838, 0x00200000231], // numpad1 - [0x00000000839, 0x00200000232], // numpad2 - [0x0000000083A, 0x00200000233], // numpad3 - [0x0000000083B, 0x00200000234], // numpad4 - [0x0000000083C, 0x00200000235], // numpad5 - [0x0000000083D, 0x00200000236], // numpad6 - [0x0000000083E, 0x00200000237], // numpad7 - [0x0000000083F, 0x00200000238], // numpad8 - [0x00000000840, 0x00200000239], // numpad9 - [0x00000000841, 0x0020000022F], // numpadDivide - [0x00000000842, 0x0020000022A], // numpadMultiply - [0x00000000843, 0x0020000022D], // numpadSubtract - [0x00000000844, 0x0020000022B], // numpadAdd - [0x00000000845, 0x0020000022E], // numpadDecimal - [0x00000000846, 0x0020000022C], // numpadComma - [0x00000000847, 0x0020000020D], // numpadEnter - [0x00000000848, 0x0020000023D], // numpadEqual - [0x00000000849, 0x00200000228], // numpadParenLeft - [0x0000000084A, 0x00200000229], // numpadParenRight - [0x00000000010, 0x00100000A10], // audioVolumeUp - [0x00000000011, 0x00100000A0F], // audioVolumeDown - [0x00000000012, 0x00100000606], // power - [0x00000000016, 0x00100000E09], // microphoneVolumeMute - [0x00000000001, 0x00100000306], // home - [0x00000000002, 0x00100001005], // goBack - [0x00000000013, 0x00100000603], // camera - [0x00000000028, 0x00100000602], // brightnessUp - [0x00000000029, 0x00100000601], // brightnessDown - [0x00000000005, 0x00100000401], // clear - [0x0000000000A, 0x00100000A05], // mediaPlayPause - [0x0000000000B, 0x00100000A07], // mediaStop - [0x0000000000C, 0x00100000A08], // mediaTrackNext - [0x0000000000D, 0x00100000A09], // mediaTrackPrevious - [0x0000000000E, 0x00100000D31], // mediaRewind - [0x0000000000F, 0x00100000D2C], // mediaFastForward - [0x00000000A28, 0x00200000002], // sleep - [0x00000000A29, 0x0010000071D], // zenkakuHankaku - [0x00000000A2C, 0x0010000071A], // katakana - [0x00000000A2D, 0x00100000716], // hiragana - [0x00000000A2E, 0x00100000705], // convert - [0x00000000A2F, 0x00100000717], // hiraganaKatakana - [0x00000000A30, 0x0010000070D], // nonConvert - [0x00000000A37, 0x00200000022], // intlYen - [0x00000000A39, 0x00100000502], // again - [0x00000000A3A, 0x0010000050B], // props - [0x00000000A3B, 0x0010000040A], // undo - [0x00000000A3C, 0x00100000402], // copy - [0x00000000A3D, 0x00100000A0B], // open - [0x00000000A3E, 0x00100000408], // paste - [0x00000000A3F, 0x00100000507], // find - [0x00000000A40, 0x00100000404], // cut - [0x00000000A41, 0x00100000508], // help - [0x00000000A44, 0x00100000C02], // browserFavorites - [0x00000000A46, 0x00100000A05], // mediaPlayPause - [0x00000000A48, 0x00100000A01], // close - [0x00000000003, 0x00100001002], // call - [0x00000000A4B, 0x00100000C05], // browserRefresh - [0x00000000A4C, 0x00100000D15], // exit - [0x00000000A51, 0x00100000409], // redo - [0x00000000A52, 0x00100000A01], // close - [0x00000000A55, 0x00100000A0C], // print - [0x00000000A58, 0x00100000504], // cancel - [0x00000000A5F, 0x00100000A0D], // save - [0x00000000A68, 0x00100000D25], // info - [0x00000000A6B, 0x00100000D47], // subtitle - [0x00000000A70, 0x00100000D49], // tv - [0x00000000A7E, 0x00100000D0C], // colorF0Red - [0x00000000A7F, 0x00100000D0D], // colorF1Green - [0x00000000A80, 0x00100000D0E], // colorF2Yellow - [0x00000000A81, 0x00100000D0F], // colorF3Blue - [0x00000000A82, 0x00100000D0B], // channelUp - [0x00000000A83, 0x00100000D0A], // channelDown - [0x00000000A8A, 0x0010000050D], // zoomIn - [0x00000000A8B, 0x0010000050E], // zoomOut - [0x00000000A98, 0x00100000A0E], // spellCheck - [0x00000000AF2, 0x0010000060B], // wakeUp - [0x00000000AFD, 0x00100000604], // eject - [0x00000000B00, 0x0010000080D], // f13 - [0x00000000B01, 0x0010000080E], // f14 - [0x00000000B02, 0x0010000080F], // f15 - [0x00000000B03, 0x00100000810], // f16 - [0x00000000B04, 0x00100000811], // f17 - [0x00000000B05, 0x00100000812], // f18 - [0x00000000B06, 0x00100000813], // f19 - [0x00000000B07, 0x00100000814], // f20 - [0x00000000B08, 0x00100000815], // f21 - [0x00000000B09, 0x00100000816], // f22 - [0x00000000B0A, 0x00100000817], // f23 - [0x00000000B0B, 0x00100000818], // f24 - [0x00000000B0F, 0x00200000000], // suspend - [0x00000000B12, 0x0000000003F], // question - [0x00000000811, 0x00000000040], // at - [0x00000000006, 0x00100001007], // headsetHook - [0x00000000017, 0x00100000A11], // audioVolumeMute - [0x00000000004, 0x00100001004] // endCall - ]); - /** Map OH KeyCode to Flutter PhysicalKey. - * Should map OH ScanCode to Flutter PhysicalKey, but we use KeyCode here - * instead since there is no ScanCode in OH KeyEvent yet. There may be some - * mistakes and should correct the map as soon as we can access ScanCode. - */ - public static toPhysicalKey: Map = - new Map([ - [0x000000007D0, 0x00000070027], // digit0 - [0x000000007D1, 0x0000007001E], // digit1 - [0x000000007D2, 0x0000007001F], // digit2 - [0x000000007D3, 0x00000070020], // digit3 - [0x000000007D4, 0x00000070021], // digit4 - [0x000000007D5, 0x00000070022], // digit5 - [0x000000007D6, 0x00000070023], // digit6 - [0x000000007D7, 0x00000070024], // digit7 - [0x000000007D8, 0x00000070025], // digit8 - [0x000000007D9, 0x00000070026], // digit9 - [0x000000007DC, 0x00000070052], // arrowUp - [0x000000007DD, 0x00000070051], // arrowDown - [0x000000007DE, 0x00000070050], // arrowLeft - [0x000000007DF, 0x0000007004F], // arrowRight - [0x000000007E1, 0x00000070004], // keyA - [0x000000007E2, 0x00000070005], // keyB - [0x000000007E3, 0x00000070006], // keyC - [0x000000007E4, 0x00000070007], // keyD - [0x000000007E5, 0x00000070008], // keyE - [0x000000007E6, 0x00000070009], // keyF - [0x000000007E7, 0x0000007000A], // keyG - [0x000000007E8, 0x0000007000B], // keyH - [0x000000007E9, 0x0000007000C], // keyI - [0x000000007EA, 0x0000007000D], // keyJ - [0x000000007EB, 0x0000007000E], // keyK - [0x000000007EC, 0x0000007000F], // keyL - [0x000000007ED, 0x00000070010], // keyM - [0x000000007EE, 0x00000070011], // keyN - [0x000000007EF, 0x00000070012], // keyO - [0x000000007F0, 0x00000070013], // keyP - [0x000000007F1, 0x00000070014], // keyQ - [0x000000007F2, 0x00000070015], // keyR - [0x000000007F3, 0x00000070016], // keyS - [0x000000007F4, 0x00000070017], // keyT - [0x000000007F5, 0x00000070018], // keyU - [0x000000007F6, 0x00000070019], // keyV - [0x000000007F7, 0x0000007001A], // keyW - [0x000000007F8, 0x0000007001B], // keyX - [0x000000007F9, 0x0000007001C], // keyY - [0x000000007FA, 0x0000007001D], // keyZ - [0x000000007FB, 0x00000070036], // comma - [0x000000007FC, 0x00000070037], // period - [0x000000007FD, 0x000000700E2], // altLeft - [0x000000007FE, 0x000000700E6], // altRight - [0x000000007FF, 0x000000700E1], // shiftLeft - [0x00000000800, 0x000000700E5], // shiftRight - [0x00000000801, 0x0000007002B], // tab - [0x00000000802, 0x0000007002C], // space - [0x00000000805, 0x000000C018A], // launchMail - [0x00000000806, 0x00000070028], // enter - [0x00000000807, 0x0000007002A], // backspace - [0x00000000808, 0x00000070035], // backquote - [0x00000000809, 0x0000007002D], // minus - [0x0000000080A, 0x0000007002E], // equal - [0x0000000080B, 0x0000007002F], // bracketLeft - [0x0000000080C, 0x00000070030], // bracketRight - [0x0000000080D, 0x00000070031], // backslash - [0x0000000080E, 0x00000070033], // semicolon - [0x0000000080F, 0x00000070034], // apostrophe/quote - [0x00000000810, 0x00000070038], // slash - [0x00000000813, 0x00000070065], // contextMenu - [0x00000000814, 0x0000007004B], // pageUp - [0x00000000815, 0x0000007004E], // pageDown - [0x00000000816, 0x00000070029], // escape - [0x00000000817, 0x0000007004C], // delete - [0x00000000818, 0x000000700E0], // controlLeft - [0x00000000819, 0x000000700E4], // controlRight - [0x0000000081A, 0x00000070039], // capsLock - [0x0000000081B, 0x00000070047], // scrollLock - [0x0000000081C, 0x000000700E3], // metaLeft - [0x0000000081D, 0x000000700E7], // metaRight - [0x0000000081E, 0x00000000012], // fn - [0x0000000081F, 0x00000070046], // printScreen - [0x00000000820, 0x00000070048], // pause - [0x00000000821, 0x0000007004A], // home - [0x00000000822, 0x0000007004D], // end - [0x00000000823, 0x00000070049], // insert - [0x00000000824, 0x000000C0225], // browserForward - [0x00000000825, 0x000000C00B0], // mediaPlay - [0x00000000826, 0x000000C00B1], // mediaPause - [0x00000000828, 0x000000C00B8], // eject - [0x00000000829, 0x000000C00B2], // mediaRecord - [0x0000000082A, 0x0000007003A], // f1 - [0x0000000082B, 0x0000007003B], // f2 - [0x0000000082C, 0x0000007003C], // f3 - [0x0000000082D, 0x0000007003D], // f4 - [0x0000000082E, 0x0000007003E], // f5 - [0x0000000082F, 0x0000007003F], // f6 - [0x00000000830, 0x00000070040], // f7 - [0x00000000831, 0x00000070041], // f8 - [0x00000000832, 0x00000070042], // f9 - [0x00000000833, 0x00000070043], // f10 - [0x00000000834, 0x00000070044], // f11 - [0x00000000835, 0x00000070045], // f12 - [0x00000000836, 0x00000070053], // numLock - [0x00000000837, 0x00000070062], // numpad0 - [0x00000000838, 0x00000070059], // numpad1 - [0x00000000839, 0x0000007005A], // numpad2 - [0x0000000083A, 0x0000007005B], // numpad3 - [0x0000000083B, 0x0000007005C], // numpad4 - [0x0000000083C, 0x0000007005D], // numpad5 - [0x0000000083D, 0x0000007005E], // numpad6 - [0x0000000083E, 0x0000007005F], // numpad7 - [0x0000000083F, 0x00000070060], // numpad8 - [0x00000000840, 0x00000070061], // numpad9 - [0x00000000841, 0x00000070054], // numpadDivide - [0x00000000842, 0x00000070055], // numpadMultiply - [0x00000000843, 0x00000070056], // numpadSubtract - [0x00000000844, 0x00000070057], // numpadAdd - [0x00000000845, 0x00000070063], // numpadDecimal - [0x00000000846, 0x00000070085], // numpadComma - [0x00000000847, 0x00000070058], // numpadEnter - [0x00000000848, 0x00000070067], // numpadEqual - [0x00000000849, 0x000000700B6], // numpadParenLeft - [0x0000000084A, 0x000000700B7], // numpadParenRight - [0x00000000010, 0x00000070080], // audioVolumeUp - [0x00000000011, 0x00000070081], // audioVolumeDown - [0x00000000012, 0x00000070066], // power - [0x00000000001, 0x0000007004A], // home - [0x00000000028, 0x000000C006F], // brightnessUp - [0x00000000029, 0x000000C0070], // brightnessDown - [0x0000000000A, 0x000000C00CD], // mediaPlayPause - [0x0000000000B, 0x000000C00B7], // mediaStop - [0x0000000000C, 0x000000C00B5], // mediaTrackNext - [0x0000000000D, 0x000000C00B6], // mediaTrackPrevious - [0x0000000000E, 0x000000C00B4], // mediaRewind - [0x0000000000F, 0x000000C00B3], // mediaFastForward - [0x00000000A28, 0x00000010082], // sleep - [0x00000000A2E, 0x0000007008A], // convert - [0x00000000A30, 0x0000007008B], // nonConvert - [0x00000000A37, 0x00000070089], // intlYen - [0x00000000A39, 0x00000070079], // again - [0x00000000A3A, 0x000000700A3], // props - [0x00000000A3B, 0x0000007007A], // undo - [0x00000000A3C, 0x0000007007C], // copy - [0x00000000A3D, 0x00000070074], // open - [0x00000000A3E, 0x0000007007D], // paste - [0x00000000A3F, 0x0000007007E], // find - [0x00000000A40, 0x0000007007B], // cut - [0x00000000A41, 0x00000070075], // help - [0x00000000A44, 0x000000C022A], // browserFavorites - [0x00000000A46, 0x000000C00CD], // mediaPlayPause - [0x00000000A48, 0x000000C0203], // close - [0x00000000A4B, 0x000000C0227], // browserRefresh - [0x00000000A4C, 0x000000C0094], // exit - [0x00000000A51, 0x000000C0279], // redo - [0x00000000A52, 0x000000C0203], // close - [0x00000000A55, 0x000000C0208], // print - [0x00000000A5F, 0x000000C0207], // save - [0x00000000A68, 0x000000C0060], // info - [0x00000000A82, 0x000000C009C], // channelUp - [0x00000000A83, 0x000000C009D], // channelDown - [0x00000000A8A, 0x000000C022D], // zoomIn - [0x00000000A8B, 0x000000C022E], // zoomOut - [0x00000000A98, 0x000000C01AB], // spellCheck - [0x00000000AF2, 0x00000010083], // wakeUp - [0x00000000AFD, 0x000000C00B8], // eject - [0x00000000B00, 0x00000070068], // f13 - [0x00000000B01, 0x00000070069], // f14 - [0x00000000B02, 0x0000007006A], // f15 - [0x00000000B03, 0x0000007006B], // f16 - [0x00000000B04, 0x0000007006C], // f17 - [0x00000000B05, 0x0000007006D], // f18 - [0x00000000B06, 0x0000007006E], // f19 - [0x00000000B07, 0x0000007006F], // f20 - [0x00000000B08, 0x00000070070], // f21 - [0x00000000B09, 0x00000070071], // f22 - [0x00000000B0A, 0x00000070072], // f23 - [0x00000000B0B, 0x00000070073], // f24 - [0x00000000B0F, 0x00000000014], // suspend - [0x00000000017, 0x0000007007F] // audioVolumeMute - ]); - /** Map OpenHarmony KeyCode to ScanCode since cannot access ScanCode directly from KeyEvent. */ - public static ohKeyToScanCode: Map = - new Map([ - [0x000000007D0, 0x0000000000B], // digit0 - [0x000000007D1, 0x00000000002], // digit1 - [0x000000007D2, 0x00000000003], // digit2 - [0x000000007D3, 0x00000000004], // digit3 - [0x000000007D4, 0x00000000005], // digit4 - [0x000000007D5, 0x00000000006], // digit5 - [0x000000007D6, 0x00000000007], // digit6 - [0x000000007D7, 0x00000000008], // digit7 - [0x000000007D8, 0x00000000009], // digit8 - [0x000000007D9, 0x0000000000A], // digit9 - [0x000000007DC, 0x00000000067], // arrowUp - [0x000000007DD, 0x0000000006C], // arrowDown - [0x000000007DE, 0x00000000069], // arrowLeft - [0x000000007DF, 0x0000000006A], // arrowRight - [0x000000007E1, 0x0000000001E], // keyA - [0x000000007E2, 0x00000000030], // keyB - [0x000000007E3, 0x0000000002E], // keyC - [0x000000007E4, 0x00000000020], // keyD - [0x000000007E5, 0x00000000012], // keyE - [0x000000007E6, 0x00000000021], // keyF - [0x000000007E7, 0x00000000022], // keyG - [0x000000007E8, 0x00000000023], // keyH - [0x000000007E9, 0x00000000017], // keyI - [0x000000007EA, 0x00000000024], // keyJ - [0x000000007EB, 0x00000000025], // keyK - [0x000000007EC, 0x00000000026], // keyL - [0x000000007ED, 0x00000000032], // keyM - [0x000000007EE, 0x00000000031], // keyN - [0x000000007EF, 0x00000000018], // keyO - [0x000000007F0, 0x00000000019], // keyP - [0x000000007F1, 0x00000000010], // keyQ - [0x000000007F2, 0x00000000013], // keyR - [0x000000007F3, 0x0000000001F], // keyS - [0x000000007F4, 0x00000000014], // keyT - [0x000000007F5, 0x00000000016], // keyU - [0x000000007F6, 0x0000000002F], // keyV - [0x000000007F7, 0x00000000011], // keyW - [0x000000007F8, 0x0000000002D], // keyX - [0x000000007F9, 0x00000000015], // keyY - [0x000000007FA, 0x0000000002C], // keyZ - [0x000000007FB, 0x00000000033], // comma - [0x000000007FC, 0x00000000034], // period - [0x000000007FD, 0x00000000038], // altLeft - [0x000000007FE, 0x00000000064], // altRight - [0x000000007FF, 0x0000000002A], // shiftLeft - [0x00000000800, 0x00000000036], // shiftRight - [0x00000000801, 0x0000000000F], // tab - [0x00000000802, 0x00000000039], // space - [0x00000000805, 0x000000000D7], // launchMail - [0x00000000806, 0x0000000001C], // enter - [0x00000000807, 0x0000000000E], // backspace - [0x00000000808, 0x00000000029], // backquote - [0x00000000809, 0x0000000000C], // minus - [0x0000000080A, 0x0000000000D], // equal - [0x0000000080B, 0x0000000001A], // bracketLeft - [0x0000000080C, 0x0000000001B], // bracketRight - [0x0000000080D, 0x00000000056], // backslash - [0x0000000080E, 0x00000000027], // semicolon - [0x0000000080F, 0x00000000028], // apostrophe/quote - [0x00000000810, 0x00000000035], // slash - [0x00000000813, 0x0000000008B], // contextMenu - [0x00000000814, 0x000000000B1], // pageUp - [0x00000000815, 0x000000000B2], // pageDown - [0x00000000816, 0x00000000001], // escape - [0x00000000817, 0x0000000006F], // delete - [0x00000000818, 0x0000000001D], // controlLeft - [0x00000000819, 0x00000000061], // controlRight - [0x0000000081A, 0x0000000003A], // capsLock - [0x0000000081B, 0x00000000046], // scrollLock - [0x0000000081C, 0x0000000007D], // metaLeft - [0x0000000081D, 0x0000000007E], // metaRight - [0x0000000081E, 0x000000001D0], // fn - [0x0000000081F, 0x00000000063], // printScreen - [0x00000000820, 0x0000000019B], // pause - [0x00000000821, 0x00000000066], // home - [0x00000000822, 0x0000000006B], // end - [0x00000000823, 0x0000000006E], // insert - [0x00000000824, 0x0000000009F], // browserForward - [0x00000000825, 0x000000000CF], // mediaPlay - [0x00000000826, 0x000000000C9], // mediaPause - [0x00000000828, 0x000000000A2], // eject - [0x00000000829, 0x000000000A7], // mediaRecord - [0x0000000082A, 0x0000000003B], // f1 - [0x0000000082B, 0x0000000003C], // f2 - [0x0000000082C, 0x0000000003D], // f3 - [0x0000000082D, 0x0000000003E], // f4 - [0x0000000082E, 0x0000000003F], // f5 - [0x0000000082F, 0x00000000040], // f6 - [0x00000000830, 0x00000000041], // f7 - [0x00000000831, 0x00000000042], // f8 - [0x00000000832, 0x00000000043], // f9 - [0x00000000833, 0x00000000044], // f10 - [0x00000000834, 0x00000000057], // f11 - [0x00000000835, 0x00000000058], // f12 - [0x00000000836, 0x00000000045], // numLock - [0x00000000837, 0x00000000052], // numpad0 - [0x00000000838, 0x0000000004F], // numpad1 - [0x00000000839, 0x00000000050], // numpad2 - [0x0000000083A, 0x00000000051], // numpad3 - [0x0000000083B, 0x0000000004B], // numpad4 - [0x0000000083C, 0x0000000004C], // numpad5 - [0x0000000083D, 0x0000000004D], // numpad6 - [0x0000000083E, 0x00000000047], // numpad7 - [0x0000000083F, 0x00000000048], // numpad8 - [0x00000000840, 0x00000000049], // numpad9 - [0x00000000841, 0x00000000062], // numpadDivide - [0x00000000842, 0x00000000037], // numpadMultiply - [0x00000000843, 0x0000000004A], // numpadSubtract - [0x00000000844, 0x0000000004E], // numpadAdd - [0x00000000845, 0x00000000053], // numpadDecimal - [0x00000000846, 0x00000000079], // numpadComma - [0x00000000847, 0x00000000060], // numpadEnter - [0x00000000848, 0x00000000075], // numpadEqual - [0x00000000849, 0x000000000B3], // numpadParenLeft - [0x0000000084A, 0x000000000B4], // numpadParenRight - [0x00000000010, 0x00000000073], // audioVolumeUp - [0x00000000011, 0x00000000072], // audioVolumeDown - [0x00000000012, 0x00000000098], // power - [0x00000000001, 0x00000000066], // home - [0x00000000028, 0x000000000E1], // brightnessUp - [0x00000000029, 0x000000000E0], // brightnessDown - [0x0000000000A, 0x000000000A4], // mediaPlayPause - [0x0000000000B, 0x000000000A6], // mediaStop - [0x0000000000C, 0x000000000A3], // mediaTrackNext - [0x0000000000D, 0x000000000A5], // mediaTrackPrevious - [0x0000000000E, 0x000000000A8], // mediaRewind - [0x0000000000F, 0x000000000D0], // mediaFastForward - [0x00000000A28, 0x0000000008E], // sleep - [0x00000000A2E, 0x0000000005C], // convert - [0x00000000A30, 0x0000000005E], // nonConvert - [0x00000000A37, 0x0000000007C], // intlYen - [0x00000000A39, 0x00000000081], // again - [0x00000000A3A, 0x00000000082], // props - [0x00000000A3B, 0x00000000083], // undo - [0x00000000A3C, 0x00000000085], // copy - [0x00000000A3D, 0x00000000086], // open - [0x00000000A3E, 0x00000000087], // paste - [0x00000000A3F, 0x00000000088], // find - [0x00000000A40, 0x00000000089], // cut - [0x00000000A41, 0x0000000008A], // help - [0x00000000A44, 0x0000000009C], // browserFavorites - [0x00000000A46, 0x000000000A4], // mediaPlayPause - [0x00000000A48, 0x000000000CE], // close - [0x00000000A4C, 0x000000000AE], // exit - [0x00000000A51, 0x000000000B6], // redo - [0x00000000A52, 0x000000000CE], // close - [0x00000000A55, 0x000000000D2], // print - [0x00000000A68, 0x00000000166], // info - [0x00000000A82, 0x00000000192], // channelUp - [0x00000000A83, 0x00000000193], // channelDown - [0x00000000AF2, 0x0000000008F], // wakeUp - [0x00000000AFD, 0x000000000A2], // eject - [0x00000000B00, 0x000000000B7], // f13 - [0x00000000B01, 0x000000000B8], // f14 - [0x00000000B02, 0x000000000B9], // f15 - [0x00000000B03, 0x000000000BA], // f16 - [0x00000000B04, 0x000000000BB], // f17 - [0x00000000B05, 0x000000000BC], // f18 - [0x00000000B06, 0x000000000BD], // f19 - [0x00000000B07, 0x000000000BE], // f20 - [0x00000000B08, 0x000000000BF], // f21 - [0x00000000B09, 0x000000000C0], // f22 - [0x00000000B0A, 0x000000000C1], // f23 - [0x00000000B0B, 0x000000000C2], // f24 - [0x00000000B0F, 0x000000000CD], // suspend - [0x00000000017, 0x00000000071], // audioVolumeMute - ]); - /** Bitmask for extracting key values. */ - public static kValueMask: number = 0x000FFFFFFFF; - /** Unicode plane identifier. */ - public static kUnicodePlane: number = 0x00000000000; - /** OpenHarmony plane identifier. */ - public static kOhosPlane: number = 0x01900000000; - /** Array of modifier key goals for synchronization. */ - public static modifierGoals: ModifierGoal[] = [ - new ModifierGoal( - "Ctrl", - [ - new KeyPair(0x000700e0, 0x0200000100), // CtrlLeft - new KeyPair(0x000700e4, 0x0200000101) // CtrlRight - ] - ), - new ModifierGoal( - "Shift", - [ - new KeyPair(0x000700e1, 0x0200000102), // ShiftLeft - new KeyPair(0x000700e5, 0x0200000103) // SHIftRight - ] - ), - new ModifierGoal( - "Alt", - [ - new KeyPair(0x000700e2, 0x0200000104), // AltLeft - new KeyPair(0x000700e6, 0x0200000105) // AltRight - ] - ) - ]; -} - -// Due to the lack of ability of metaState in Ohos, and to maintain consistency -// in metaState with other platforms. Hence, flutter-ohos defines these modifier -// key meta values to check whether the following keys are pressed -export class ModifierKeyMetaInfo { - private constructor() {} - static readonly NONE: number = 0; // no modifier keys are pressed - static readonly ALT: number = 0x02; - static readonly ALT_LEFT: number = 0x10; - static readonly ALT_RIGHT: number = 0x20; - static readonly SHIFT: number = 0x01; - static readonly SHIFT_LEFT: number = 0x40; - static readonly SHIFT_RIGHT: number = 0x80; - static readonly CTRL: number = 0x1000; - static readonly CTRL_LEFT: number = 0x2000; - static readonly CTRL_RIGHT: number = 0x4000; - static readonly META: number = 0x10000; - static readonly META_LEFT: number = 0x20000; - static readonly META_RIGHT: number = 0x40000; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/OhosTouchProcessor.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/OhosTouchProcessor.ets deleted file mode 100644 index 5150568..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/OhosTouchProcessor.ets +++ /dev/null @@ -1,67 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import { TouchEvent } from '@ohos.multimodalInput.touchEvent'; -import Any from '../../plugin/common/Any'; - -/** - * Processor for handling touch events from OpenHarmony. - * This class processes touch events and converts them for Flutter. - */ -export default class OhosTouchProcessor { - private static POINTER_DATA_FIELD_COUNT: number = 35; - /** Number of bytes per field in pointer data. */ - static BYTES_PER_FIELD: number = 8; - private static POINTER_DATA_FLAG_BATCHED: number = 1; - - /** - * Processes a touch event. - * @param event - The touch event from OpenHarmony - * @param transformMatrix - The transformation matrix to apply - */ - public onTouchEvent(event: TouchEvent, transformMatrix: Any): void { - - } -} - -/** - * Types of pointer state changes. - */ -export enum PointerChange { - CANCEL = 0, - ADD = 1, - REMOVE = 2, - HOVER = 3, - DOWN = 4, - MOVE = 5, - UP = 6, - PAN_ZOOM_START = 7, - PAN_ZOOM_UPDATE = 8, - PAN_ZOOM_END = 9 -} - -/** - * Types of pointer input devices. - */ -export enum PointerDeviceKind { - TOUCH = 0, - MOUSE = 1, - STYLUS = 2, - INVERTED_STYLUS = 3, - TRACKPAD = 4, - UNKNOWN = 5 -} - -/** - * Types of pointer signal events. - */ -export enum PointerSignalKind { - NONE = 0, - SCROLL = 1, - SCROLL_INERTIA_CANCEL = 2, - SCALE = 3, - UNKNOWN = 4 -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/PlatformViewInfo.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/PlatformViewInfo.ets deleted file mode 100644 index 0aa90fa..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/PlatformViewInfo.ets +++ /dev/null @@ -1,49 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - - -import PlatformView from '../../plugin/platform/PlatformView'; - -/** - * Information about a platform view embedded in Flutter. - */ -export class PlatformViewInfo { - /** The platform view instance. */ - public platformView: PlatformView; - /** The surface ID for rendering. */ - public surfaceId: string; - /** The width of the platform view. */ - public width: number; - /** The height of the platform view. */ - public height: number; - /** The top position of the platform view. */ - public top: number; - /** The left position of the platform view. */ - public left: number; - /** The layout direction for the platform view. */ - public direction: Direction; - - /** - * Constructs a new PlatformViewInfo instance. - * @param platformView - The platform view instance - * @param surfaceId - The surface ID - * @param width - The width of the view - * @param height - The height of the view - * @param top - The top position - * @param left - The left position - * @param direction - The layout direction - */ - constructor(platformView: PlatformView, surfaceId: string, width: number, height: number, top: number, left: number, - direction: Direction) { - this.platformView = platformView; - this.surfaceId = surfaceId; - this.width = width; - this.height = height; - this.top = top; - this.left = left; - this.direction = direction; - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/Settings.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/Settings.ets deleted file mode 100644 index 3633492..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/Settings.ets +++ /dev/null @@ -1,76 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import SettingsChannel, { PlatformBrightness } from '../engine/systemchannels/SettingsChannel' -import I18n from '@ohos.i18n' -import Log from '../../util/Log'; -import { MediaQuery } from '@ohos.arkui.UIContext'; - - -const TAG = "Settings"; - -/** - * Manages and sends system settings to Flutter. - * This class handles theme mode, text scale factor, and other system preferences. - */ -export default class Settings { - /** The SettingsChannel for sending settings to Flutter, or null if not set. */ - settingsChannel: SettingsChannel | null; - - /** - * Constructs a new Settings instance. - * @param settingsChannel - The SettingsChannel instance, or null - */ - constructor(settingsChannel: SettingsChannel | null) { - this.settingsChannel = settingsChannel; - } - - /** - * Sends current system settings to Flutter. - * @param mediaQuery - The MediaQuery instance for detecting theme mode - */ - sendSettings(mediaQuery: MediaQuery): void { - this.settingsChannel?.startMessage() - .setAlwaysUse24HourFormat(I18n.System.is24HourClock()) - .setNativeSpellCheckServiceDefined(false) - .setBrieflyShowPassword(false) - .setPlatformBrightness(this.getThemeMode(mediaQuery)) - .setTextScaleFactor(this.getTextScaleFactor()) - .send(); - } - - /** - * Gets the current theme mode (light or dark). - * @param mediaQuery - The MediaQuery instance for detecting dark mode - * @returns The platform brightness mode - */ - getThemeMode(mediaQuery: MediaQuery): PlatformBrightness { - - let listener = mediaQuery.matchMediaSync('(dark-mode: true)'); - if (listener.matches) { - Log.i(TAG, "return dark"); - return PlatformBrightness.DARK; - } else { - Log.i(TAG, "return light"); - return PlatformBrightness.LIGHT; - } - } - - /** - * Gets the text scale factor from system settings. - * @returns The text scale factor value - */ - getTextScaleFactor() : number { - let sysTextScaleFactor = AppStorage.get('fontSizeScale'); - if(sysTextScaleFactor == undefined) { - sysTextScaleFactor = 1.0; - Log.e(TAG, 'get textScaleFactor error, it is assigned to ' + JSON.stringify(sysTextScaleFactor)); - } - Log.i(TAG, "return textScaleFactor = " + JSON.stringify(sysTextScaleFactor)) - return sysTextScaleFactor; - } - -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/TouchEventProcessor.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/TouchEventProcessor.ets deleted file mode 100644 index e33ab28..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/TouchEventProcessor.ets +++ /dev/null @@ -1,539 +0,0 @@ -/* -* Copyright (c) 2024 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -/** Handle the motion events received by the FlutterNapi. */ -// import PlainArray from '@ohos.util.PlainArray'; -// import { TouchEvent } from '@ohos.multimodalInput.touchEvent'; -// import Queue from '@ohos.util.Queue'; - -import { CustomTouchEvent, CustomTouchObject } from '../../plugin/platform/CustomTouchEvent'; -import display from '@ohos.display'; -import FlutterManager from './FlutterManager'; -import { EmbeddingNodeController } from './EmbeddingNodeController'; -import Any from '../../plugin/common/Any'; - - -const OH_NATIVEXCOMPONENT_UNKNOWN = 4; -const OH_NATIVEXCOMPONENT_TOOL_TYPE_UNKNOWN = 0; - -/** - * Represents a touch point in a native XComponent touch event. - */ -class OH_NativeXComponent_TouchPoint { - id: number = 0; - screenX: number = 0.0; - screenY: number = 0.0; - x: number = 0.0; - y: number = 0.0; - type: number = OH_NATIVEXCOMPONENT_UNKNOWN; - size: number = 0; - force: number = 0; - timeStamp: number = 0; - isPressed: boolean = false; - - /** - * Constructs a new OH_NativeXComponent_TouchPoint instance. - * @param id - The touch point ID - * @param screenX - The screen X coordinate - * @param screenY - The screen Y coordinate - * @param x - The local X coordinate - * @param y - The local Y coordinate - * @param type - The touch type - * @param size - The touch size - * @param force - The touch force - * @param timeStamp - The timestamp - * @param isPressed - Whether the touch is pressed - */ - constructor(id: number, - screenX: number, - screenY: number, - x: number, - y: number, - type: number, - size: number, - force: number, - timeStamp: number, - isPressed: boolean) { - this.id = id; - this.screenX = screenX; - this.screenY = screenY; - this.x = x; - this.y = y; - this.type = type; - this.size = size; - this.force = force; - this.timeStamp = timeStamp; - this.isPressed = isPressed; - } -} - -/** - * Represents a native XComponent touch event. - */ -class OH_NativeXComponent_TouchEvent { - id: number = 0; - screenX: number = 0.0; - screenY: number = 0.0; - x: number = 0.0; - y: number = 0.0; - type: number = OH_NATIVEXCOMPONENT_UNKNOWN; - size: number = 0; - force: number = 0; - deviceId: number = 0; - timeStamp: number = 0; - touchPoints: OH_NativeXComponent_TouchPoint[] = []; - numPoints: number = 0; - - /** - * Constructs a new OH_NativeXComponent_TouchEvent instance. - * @param id - The event ID - * @param screenX - The screen X coordinate - * @param screenY - The screen Y coordinate - * @param x - The local X coordinate - * @param y - The local Y coordinate - * @param type - The touch type - * @param size - The touch size - * @param force - The touch force - * @param deviceId - The device ID - * @param timeStamp - The timestamp - * @param touchPoints - Array of touch points - * @param numPoints - Number of touch points - */ - constructor(id: number, - screenX: number, - screenY: number, - x: number, - y: number, - type: number, - size: number, - force: number, - deviceId: number, - timeStamp: number, - touchPoints: OH_NativeXComponent_TouchPoint[], - numPoints: number) { - this.id = id; - this.screenX = screenX; - this.screenY = screenY; - this.x = x; - this.y = y; - this.type = type; - this.size = size; - this.force = force; - this.deviceId = deviceId; - this.timeStamp = timeStamp; - this.touchPoints = touchPoints; - this.numPoints = numPoints; - } -} - -/** - * Packet containing touch event data and tool information. - */ -class TouchPacket { - touchEvent: OH_NativeXComponent_TouchEvent; - toolType: number = OH_NATIVEXCOMPONENT_TOOL_TYPE_UNKNOWN; - tiltX: number = 0; - tiltY: number = 0; - - /** - * Constructs a new TouchPacket instance. - * @param touchEvent - The touch event - * @param toolType - The tool type - * @param tiltX - The X-axis tilt - * @param tiltY - The Y-axis tilt - */ - constructor(touchEvent: OH_NativeXComponent_TouchEvent, - toolType: number, - tiltX: number, - tiltY: number) { - this.touchEvent = touchEvent; - this.toolType = toolType; - this.tiltX = tiltX; - this.tiltY = tiltY; - } -} - -/** - * Packet containing mouse event data. - */ -class MousePacket { - offset: number; - x: number; - y: number; - screenX: number; - screenY: number; - timestamp: number; - action: number; - button: number; - - /** - * Constructs a new MousePacket instance. - * @param offset - The offset value - * @param x - The local X coordinate - * @param y - The local Y coordinate - * @param screenX - The screen X coordinate - * @param screenY - The screen Y coordinate - * @param timestamp - The timestamp - * @param action - The mouse action - * @param button - The mouse button - */ - constructor( offset: number, - x: number, - y: number, - screenX: number, - screenY: number, - timestamp: number, - action: number, - button: number) { - this.offset = offset; - this.x = x; - this.y = y; - this.screenX = screenX; - this.screenY = screenY; - this.timestamp = timestamp; - this.action = action; - this.button = button; - } -} - -/** - * Processor for handling touch events received by FlutterNapi. - * This class processes and converts touch events from native format to Flutter format. - */ -export default class TouchEventProcessor { - private static instance: TouchEventProcessor; - - /** - * Gets the singleton instance of TouchEventProcessor. - * @returns The singleton TouchEventProcessor instance - */ - static getInstance(): TouchEventProcessor { - if (TouchEventProcessor.instance == null) { - TouchEventProcessor.instance = new TouchEventProcessor(); - } - return TouchEventProcessor.instance; - } - - private decodeTouchPacket(strings: Array, densityPixels: number, top: number, left: number): TouchPacket { - let offset: number = 0; - let numPoint: number = parseInt(strings[offset++]); - let changesId: number = parseInt(strings[offset++]); - let changesscreenX: number = (parseFloat(strings[offset++]) / densityPixels); - let changesscreenY: number = (parseFloat(strings[offset++]) / densityPixels); - let changesX: number = ((parseFloat(strings[offset++]) / densityPixels) - left); - let changesY: number = ((parseFloat(strings[offset++]) / densityPixels) - top); - let changesType: number = parseInt(strings[offset++]); - let changesSize: number = parseFloat(strings[offset++]); - let changesForce: number = parseFloat(strings[offset++]); - let changesDeviceId: number = parseInt(strings[offset++]); - let changesTimeStamp: number = parseInt(strings[offset++]); - - const touchPoints: OH_NativeXComponent_TouchPoint[] = []; - for (let i = 0; i < numPoint; i++) { - const touchPoint: OH_NativeXComponent_TouchPoint = new OH_NativeXComponent_TouchPoint( - parseInt(strings[offset++]), - (parseFloat(strings[offset++]) / densityPixels), - (parseFloat(strings[offset++]) / densityPixels), - ((parseFloat(strings[offset++]) / densityPixels) - left), - ((parseFloat(strings[offset++]) / densityPixels) - top), - parseInt(strings[offset++]), - parseFloat(strings[offset++]), - parseFloat(strings[offset++]), - parseInt(strings[offset++]), - parseInt(strings[offset++]) === 1 ? true : false - ); - touchPoints.push(touchPoint); - } - - const touchEventInput: OH_NativeXComponent_TouchEvent = new OH_NativeXComponent_TouchEvent( - changesId, - changesscreenX, - changesscreenY, - changesX, - changesY, - changesType, - changesSize, - changesForce, - changesDeviceId, - changesTimeStamp, - touchPoints, - numPoint - ); - - let toolTypeInput: number = parseInt(strings[offset++]); - let tiltXTouch: number = parseInt(strings[offset++]); - let tiltYTouch: number = parseInt(strings[offset++]); - - const touchPointEventPacket: TouchPacket = new TouchPacket( - touchEventInput, - toolTypeInput, - tiltXTouch, - tiltYTouch - ); - return touchPointEventPacket; - } - - private constructCustomTouchEventImpl(touchPacket: TouchPacket): CustomTouchEvent { - let changes1: CustomTouchObject = new CustomTouchObject( - touchPacket.touchEvent.type, - touchPacket.touchEvent.id, - touchPacket.touchEvent.screenX, - touchPacket.touchEvent.screenY, - touchPacket.touchEvent.screenX, - touchPacket.touchEvent.screenY, - touchPacket.touchEvent.screenX, - touchPacket.touchEvent.screenY, - touchPacket.touchEvent.x, - touchPacket.touchEvent.y - ); - - let touches: CustomTouchObject[] = []; - let touchPointer: number = touchPacket.touchEvent.numPoints; - for (let i = 0; i < touchPointer; i++) { - let touchesItem: CustomTouchObject = new CustomTouchObject( - touchPacket.touchEvent.touchPoints[i].type, - touchPacket.touchEvent.touchPoints[i].id, - touchPacket.touchEvent.touchPoints[i].screenX, - touchPacket.touchEvent.touchPoints[i].screenY, - touchPacket.touchEvent.touchPoints[i].screenX, - touchPacket.touchEvent.touchPoints[i].screenY, - touchPacket.touchEvent.touchPoints[i].screenX, - touchPacket.touchEvent.touchPoints[i].screenY, - touchPacket.touchEvent.touchPoints[i].x, - touchPacket.touchEvent.touchPoints[i].y - ); - touches.push(touchesItem); - } - - let customTouchEvent1: CustomTouchEvent = new CustomTouchEvent( - touchPacket.touchEvent.type, - touches, - [changes1], - touchPacket.touchEvent.timeStamp, - SourceType.TouchScreen, - touchPacket.touchEvent.force, - touchPacket.tiltX, - touchPacket.tiltY, - touchPacket.toolType - ); - - return customTouchEvent1; - } - - /** - * Constructs a CustomTouchEvent from string array data. - * @param strings - Array of string values representing touch data - * @param top - The top offset - * @param left - The left offset - * @returns A CustomTouchEvent instance - */ - public constructCustomTouchEvent(strings: Array, top: number, left: number): CustomTouchEvent { - let densityPixels: number = display.getDefaultDisplaySync().densityPixels; - - let touchPacket: TouchPacket = this.decodeTouchPacket(strings, densityPixels, top, left); - let customTouchEvent: CustomTouchEvent = this.constructCustomTouchEventImpl(touchPacket); - return customTouchEvent; - } - - /** - * Posts an axis/scroll event to platform views. - * Axis/wheel coordinates are passed to nodes through this method. - * @param strings - Array of string values representing axis event data - */ - public postAxisEvent(strings: Array) { - FlutterManager.getInstance().getFlutterViewList().forEach((value) => { - if (!value.getActive()) { - return - } - let length = value.getDVModel().children.length - for (let index = length - 1; index >= 0; index--) { - const dvModel = value.getDVModel().children[index] - const params = dvModel.getLayoutParams() as Record; - if (!params["hover"]) { - continue; - } - const left = params['left'] as number ?? 0; - const top = params['top'] as number ?? 0; - const densityPixels: number = display.getDefaultDisplaySync().densityPixels; - - let offset: number = 0; - const action: number = parseFloat(strings[offset++]); - const x: number = vp2px((parseInt(strings[offset++])) / densityPixels - left); - const y: number = vp2px((parseInt(strings[offset++])) / densityPixels - top); - const windowX: number = vp2px(parseFloat(strings[offset++]) / densityPixels); - const windowY: number = vp2px(parseFloat(strings[offset++]) / densityPixels); - const displayX: number = vp2px(parseFloat(strings[offset++]) / densityPixels); - const displayY: number = vp2px(parseFloat(strings[offset++]) / densityPixels); - const scroll: number = parseFloat(strings[offset++]); - - // 构造AxisEvent数据 - const axisEvent: AxisEvent = { - action: action, - x: x, - y: y, - windowX: x, - windowY: y, - displayX: displayX, - displayY: displayY, - scrollStep: scroll, - axisVertical: scroll - } as AxisEvent; - - let nodeController = params['nodeController'] as EmbeddingNodeController; - nodeController.postAxisEvent(axisEvent) - } - }); - } - - /** - * Posts a touch event to platform views. - * @param strings - Array of string values representing touch event data - */ - public postTouchEvent(strings: Array) { - FlutterManager.getInstance().getFlutterViewList().forEach((value) => { - if (!value.getActive()) { - return - } - let length = value.getDVModel().children.length - for (let index = length - 1; index >= 0; index--) { - let dvModel = value.getDVModel().children[index] - let params = dvModel.getLayoutParams() as Record; - let left = params['left'] as number ?? 0; - let top = params['top'] as number ?? 0; - let down = params['down'] as boolean ?? false; - if (down) { - //如果flutter端判断当前platformView是可点击的,则将事件分发出去 - let touchEvent: CustomTouchEvent = TouchEventProcessor.getInstance().constructCustomTouchEvent(strings, top, left); - let nodeController = params['nodeController'] as EmbeddingNodeController; - nodeController.postEvent(touchEvent) - } else { - //如果触摸事件为OH_NATIVEXCOMPONENT_DOWN=0,且只有一个手指,说明是下一次点击了,这时候需要清空上一次的数据 - if (strings[6] == '0' && strings[0] == '1') { - params['touchEvent'] = undefined - } - //如果触摸事件为OH_NATIVEXCOMPONENT_DOWN=0类型,且在flutter端还没判断当前view是否处于点击区域内,则 - //将点击事件存储在list列表中。 - let touchEvent: CustomTouchEvent = TouchEventProcessor.getInstance().constructCustomTouchEvent(strings, top, left); - let array: Array | undefined = params['touchEvent'] as Array - if (array == undefined) { - array = [] - params['touchEvent'] = array - } - array.push(touchEvent) - } - } - }); - } - - private decodeMousePacket(strings: Array, densityPixels: number, top: number, left: number): MousePacket { - let offset: number = 0; - let x: number = vp2px((parseInt(strings[offset++])) / densityPixels - left); - let y: number = vp2px((parseInt(strings[offset++])) / densityPixels - top); - let screenX: number = vp2px(parseFloat(strings[offset++]) / densityPixels); - let screenY: number = vp2px(parseFloat(strings[offset++]) / densityPixels); - let timestamp: number = parseFloat(strings[offset++]); - let action: number = parseFloat(strings[offset++]); - let button: number = parseFloat(strings[offset++]); - - const mouseEventPacket: MousePacket = new MousePacket( - offset, - x, - y, - screenX, - screenY, - timestamp, - action, - button - ); - return mouseEventPacket; - } - - private constructMouseEventImpl(mousePacket: MousePacket): MouseEvent { - // 构造MouseEvent数据 - const mouseEvent: MouseEvent = { - button: mousePacket.button, - action: mousePacket.action, - displayX: mousePacket.x, - displayY: mousePacket.y, - windowX: mousePacket.x, - windowY: mousePacket.y, - screenX: mousePacket.screenX, - screenY: mousePacket.screenY, - x: mousePacket.x, - y: mousePacket.y, - stopPropagation: () => {}, - timestamp: mousePacket.timestamp, - pressure: 0, - tiltX: mousePacket.x, - tiltY: mousePacket.y, - } as MouseEvent; - - return mouseEvent; - } - - /** Construct the MouseEvent and return. */ - public constructMouseEvent(strings: Array, top: number, left: number): MouseEvent { - let densityPixels: number = display.getDefaultDisplaySync().densityPixels; - - let mousePacket: MousePacket = this.decodeMousePacket(strings, densityPixels, top, left); - let mouseEvent: MouseEvent = this.constructMouseEventImpl(mousePacket); - return mouseEvent; - } - - // 鼠标坐标通过postInputEvent传入到节点 - /** - * Posts a mouse event to platform views. - * @param strings - Array of string values representing mouse event data - */ - public postMouseEvent(strings: Array) { - FlutterManager.getInstance().getFlutterViewList().forEach((value) => { - if (!value.getActive()) { - return - } - let length = value.getDVModel().children.length - for (let index = length - 1; index >= 0; index--) { - const dvModel = value.getDVModel().children[index] - const params = dvModel.getLayoutParams() as Record; - const left = params['left'] as number ?? 0; - const top = params['top'] as number ?? 0; - let down = params['down'] as boolean ?? false; - let mouseEvent: MouseEvent = TouchEventProcessor.getInstance().constructMouseEvent(strings, top, left); - - if (mouseEvent.action != MouseAction.Press && mouseEvent.action != MouseAction.Release && params["hover"]) { - // 如果鼠标事件不是OH_NATIVEXCOMPONENT_MOUSE_PRESS类型或OH_NATIVEXCOMPONENT_MOUSE_RELEASE类型,则 - // 直接分发出去 - let nodeController = params['nodeController'] as EmbeddingNodeController; - nodeController.postMouseEvent(mouseEvent) - } else if (down) { - // 如果flutter端判断当前platformView是可点击的,则将事件分发出去,并结束分发 - let nodeController = params['nodeController'] as EmbeddingNodeController; - nodeController.postMouseEvent(mouseEvent) - break; - } else { - // 如果鼠标事件为OH_NATIVEXCOMPONENT_MOUSE_PRESS,说明是下一次点击了,这时候需要清空上一次的数据 - if (strings[5] == '1') { - params['mouseEvent'] = undefined - } - // 如果鼠标事件为OH_NATIVEXCOMPONENT_MOUSE_PRESS类型,且在flutter端还没判断当前view是否处于点击区域内,则将点击事件存储在list列表中。 - let array: Array | undefined = params['mouseEvent'] as Array - if (array == undefined) { - array = [] - params['mouseEvent'] = array - } - array.push(mouseEvent) - } - } - }); - } - - public checkHitPlatformView(left: number, top: number, width: number, height: number, x: number, y: number): boolean { - if (x >= left && x <= (left + width) && y >= top && y <= (top + height)) { - return true; - } else { - return false; - } - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/TouchEventTracker.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/TouchEventTracker.ets deleted file mode 100644 index dfc30b0..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/TouchEventTracker.ets +++ /dev/null @@ -1,113 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ -/** Tracks the motion events received by the FlutterView. */ -import PlainArray from '@ohos.util.PlainArray'; -import { TouchEvent } from '@ohos.multimodalInput.touchEvent'; -import Queue from '@ohos.util.Queue'; - -/** - * Tracks touch events and provides unique identifiers for them. - * This class maintains a singleton instance for managing touch event tracking. - */ -export class TouchEventTracker { - private eventById: PlainArray; - private unusedEvents: Queue; - private static INSTANCE: TouchEventTracker; - - /** - * Gets the singleton instance of TouchEventTracker. - * @returns The singleton TouchEventTracker instance - */ - public static getInstance(): TouchEventTracker { - if (TouchEventTracker.INSTANCE == null) { - TouchEventTracker.INSTANCE = new TouchEventTracker(); - } - return TouchEventTracker.INSTANCE; - } - - /** - * Constructs a new TouchEventTracker instance. - */ - constructor() { - this.eventById = new PlainArray(); - this.unusedEvents = new Queue(); - } - - /** - * Tracks the event and returns a unique TouchEventId identifying the event. - * @param event - The touch event to track - * @returns A unique TouchEventId for the event - */ - public track(event: TouchEvent): TouchEventId { - const eventId: TouchEventId = TouchEventId.createUnique(); - this.eventById.add(eventId.getId(), event); - this.unusedEvents.add(eventId.getId()); - return eventId; - } - - /** - * Returns the TouchEvent corresponding to the eventId while discarding all the motion events - * that occurred prior to the event represented by the eventId. - * @param eventId - The TouchEventId to retrieve - * @returns The TouchEvent corresponding to the eventId - */ - public pop(eventId: TouchEventId): TouchEvent { - // remove all the older events. - while (this.unusedEvents.length != 0 && this.unusedEvents.getFirst() < eventId.getId()) { - this.eventById.remove(this.unusedEvents.pop()); - } - - // remove the current event from the heap if it exists. - if (this.unusedEvents.length != 0 && this.unusedEvents.getFirst() == eventId.getId()) { - this.unusedEvents.pop(); - } - - const event: TouchEvent = this.eventById.get(eventId.getId()); - this.eventById.remove(eventId.getId()); - return event; - } -} - -/** - * Represents a unique identifier corresponding to a touch event. - */ -export class TouchEventId { - private static ID_COUNTER: number = 0; - private id: number; - - /** - * Constructs a new TouchEventId instance. - * @param id - The ID value - */ - constructor(id: number) { - this.id = id; - } - - /** - * Creates a TouchEventId from a given ID. - * @param id - The ID value - * @returns A new TouchEventId instance - */ - public static from(id: number): TouchEventId { - return new TouchEventId(id); - } - - /** - * Creates a unique TouchEventId with an auto-incremented ID. - * @returns A new unique TouchEventId instance - */ - public static createUnique(): TouchEventId { - return new TouchEventId(TouchEventId.ID_COUNTER++); - } - - /** - * Gets the ID value. - * @returns The ID value - */ - public getId(): number { - return this.id; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/WindowInfoRepositoryCallbackAdapterWrapper.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/WindowInfoRepositoryCallbackAdapterWrapper.ets deleted file mode 100644 index d262cef..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/WindowInfoRepositoryCallbackAdapterWrapper.ets +++ /dev/null @@ -1,18 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import UIAbility from '@ohos.app.ability.UIAbility'; - -/** - * Wrapper adapter for window information repository callbacks. - */ -export default class WindowInfoRepositoryCallbackAdapterWrapper { - /** - * Constructs a new WindowInfoRepositoryCallbackAdapterWrapper instance. - */ - constructor() { - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/PlatformPlugin.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/PlatformPlugin.ets deleted file mode 100644 index 39904c8..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/PlatformPlugin.ets +++ /dev/null @@ -1,551 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on PlatformPlugin.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ -import abilityAccessCtrl from '@ohos.abilityAccessCtrl'; -import { BusinessError } from '@kit.BasicServicesKit'; -import PlatformChannel, { - AppSwitcherDescription, - Brightness, - ClipboardContentFormat, - HapticFeedbackType, - PlatformMessageHandler, - SoundType, - SystemChromeStyle, - SystemUiMode, - SystemUiOverlay -} from '../embedding/engine/systemchannels/PlatformChannel'; -import FlutterManager from '../embedding/ohos/FlutterManager'; -import pasteboard from '@ohos.pasteboard'; -import Log from '../util/Log'; -import vibrator from '@ohos.vibrator'; -import window from '@ohos.window'; -import common from '@ohos.app.ability.common'; -import { MethodResult } from './common/MethodChannel'; -import Any from './common/Any'; -import router from '@ohos.router'; -import { PasteboardUtils } from '../util/PasteboardUtils'; -import { FlutterView } from '../view/FlutterView'; - -/** - * Plugin for handling platform-specific functionality in Flutter applications. - * This class manages system UI, clipboard, haptic feedback, and other platform services. - */ -export default class PlatformPlugin { - private static TAG = "PlatformPlugin"; - /** The callback handler for platform messages. */ - callback = new PlatformPluginCallback(); - - /** - * Constructs a new PlatformPlugin instance. - * @param platformChannel - The PlatformChannel for communication with Flutter. - * @param context - The application context. - * @param platformPluginDelegate - Optional delegate for platform-specific behavior. - */ - constructor(platformChannel: PlatformChannel, context: common.Context, - platformPluginDelegate?: PlatformPluginDelegate) { - this.callback.platformChannel = platformChannel; - this.callback.context = context; - this.callback.applicationContext = context?.getApplicationContext(); - this.callback.platform = this; - this.callback.platformPluginDelegate = platformPluginDelegate ?? null; - this.callback.platformChannel?.setPlatformMessageHandler(this.callback); - } - - /** - * Initializes the window references for system UI management. - */ - initWindow() { - try { - let context = this.callback.context!! - window.getLastWindow(context, (err, data) => { - if (err.code) { - Log.e(PlatformPlugin.TAG, "Failed to obtain the top window. Cause: " + JSON.stringify(err)); - return; - } - this.callback.lastWindow = data; - }); - const uiAbility = FlutterManager.getInstance().getUIAbility(context); - const windowStage = FlutterManager.getInstance().getWindowStage(uiAbility); - this.callback.mainWindow = windowStage.getMainWindowSync(); - } catch (err) { - Log.e(PlatformPlugin.TAG, "Failed to obtain the top window. Cause: " + JSON.stringify(err)); - } - } - - - /** - * Updates the system UI overlays (status bar and navigation bar) visibility. - */ - updateSystemUiOverlays(): void { - this.callback.mainWindow?.setWindowSystemBarEnable(this.callback.showBarOrNavigation); - - if (FlutterManager.getInstance().isWindowDecorSafeAreaAvoidSupported(this.callback.context)) { - const shouldHideWindowDecor = this.callback.shouldHideWindowDecor(); - this.callback.mainWindow?.setWindowDecorVisible(!shouldHideWindowDecor); - - // Adjust padding based on window decoration visibility - if (shouldHideWindowDecor) { - const titleButtonRect = this.callback.mainWindow?.getTitleButtonRect(); - const paddingHeight = (titleButtonRect && titleButtonRect.height > 0) ? titleButtonRect.height : 0; - this.callback.flutterView?.setPaddingTop(vp2px(paddingHeight)); - } else { - this.callback.flutterView?.setPaddingTop(0); - } - } - - if (this.callback.currentTheme != null) { - this.callback.setSystemChromeSystemUIOverlayStyle(this.callback.currentTheme); - } - } - - /** - * Sets the UIAbility context for platform operations. - * @param context - The UIAbility context - */ - setUIAbilityContext(context: common.UIAbilityContext): void { - this.callback.uiAbilityContext = context; - } - - /** - * Sets up a listener for system configuration changes. - */ - setSystemChromeChangeListener(): void { - if (this.callback.callbackId == null && this.callback.applicationContext != null) { - let that = this; - this.callback.callbackId = this.callback.applicationContext?.on('environment', { - onConfigurationUpdated(config) { - Log.d(PlatformPlugin.TAG, "onConfigurationUpdated: " + that.callback.showBarOrNavigation); - that.callback.platformChannel?.systemChromeChanged(that.callback.showBarOrNavigation.includes('status')); - }, - onMemoryLevel(level) { - } - }) - } - } - - /** - * Binds a FlutterView to this plugin. - * @param flutterView - The FlutterView instance - */ - setFlutterView(flutterView: FlutterView): void { - this.callback.flutterView = flutterView; - } - - /** - * Destroys the platform plugin and cleans up resources. - */ - public destroy() { - this.callback.platformChannel?.setPlatformMessageHandler(null); - } -} - -/** - * Delegate interface for platform-specific behavior. - */ -export interface PlatformPluginDelegate { - /** - * Called when the system navigator should be popped. - * @returns True if the delegate handled the pop, false otherwise. - */ - popSystemNavigator(): boolean; -} - -/** - * Callback implementation for handling platform messages from Flutter. - */ -export class PlatformPluginCallback implements PlatformMessageHandler { - private static TAG = "PlatformPluginCallback"; - /** The PlatformPlugin instance this callback is associated with. */ - platform: PlatformPlugin | null = null; - /** The main window for system UI operations. */ - mainWindow: window.Window | null = null; - /** The last window reference. */ - lastWindow: window.Window | null = null; - /** The PlatformChannel for communication with Flutter. */ - platformChannel: PlatformChannel | null = null; - /** The delegate for platform-specific behavior. */ - platformPluginDelegate: PlatformPluginDelegate | null = null; - /** The application context. */ - context: common.Context | null = null; - /** Array indicating which system bars should be shown ('status' and/or 'navigation'). */ - showBarOrNavigation: ('status' | 'navigation')[] = ['status', 'navigation']; - /** The UIAbility context for platform operations. */ - uiAbilityContext: common.UIAbilityContext | null = null; - /** The callback ID for system configuration changes. */ - callbackId: number | null = null; - /** The application context. */ - applicationContext: common.ApplicationContext | null = null; - /** The current system UI theme style. */ - currentTheme: SystemChromeStyle | null = null; - /** The FlutterView instance for padding control. */ - flutterView: FlutterView | null = null; - - /** - * Plays a system sound. - * @param soundType - The type of sound to play. - */ - playSystemSound(soundType: SoundType) { - } - - /** - * Triggers haptic feedback vibration. - * @param feedbackType - The type of haptic feedback - */ - async vibrateHapticFeedback(feedbackType: HapticFeedbackType) { - switch (feedbackType) { - case HapticFeedbackType.STANDARD: - await vibrator.startVibration({ type: 'time', duration: 75 }, - { id: 0, usage: 'touch' }); - break; - case HapticFeedbackType.LIGHT_IMPACT: - await vibrator.startVibration({ type: 'time', duration: 25 }, - { id: 0, usage: 'touch' }); - break; - case HapticFeedbackType.MEDIUM_IMPACT: - await vibrator.startVibration({ type: 'time', duration: 150 }, - { id: 0, usage: 'touch' }); - break; - case HapticFeedbackType.HEAVY_IMPACT: - await vibrator.startVibration({ type: 'time', duration: 300 }, - { id: 0, usage: 'touch' }); - break; - case HapticFeedbackType.SELECTION_CLICK: - await vibrator.startVibration({ type: 'time', duration: 100 }, - { id: 0, usage: 'touch' }); - break; - } - } - - /** - * Sets the preferred screen orientation. - * @param ohosOrientation - The orientation value. - * @param result - The method result callback. - */ - setPreferredOrientations(ohosOrientation: number, result: MethodResult) { - try { - Log.d(PlatformPluginCallback.TAG, "ohosOrientation: " + ohosOrientation); - this.mainWindow!.setPreferredOrientation(ohosOrientation, (err: BusinessError) => { - const errCode: number = err.code; - if (errCode) { - Log.e(PlatformPluginCallback.TAG, "Failed to set window orientation:" + JSON.stringify(err)); - result.error("error", JSON.stringify(err), null); - return; - } - result.success(null); - }); - } catch (exception) { - Log.e(PlatformPluginCallback.TAG, "Failed to set window orientation:" + JSON.stringify(exception)); - result.error("error", JSON.stringify(exception), null); - } - } - - /** - * Sets the application switcher description (mission label). - * @param description - The app switcher description. - */ - setApplicationSwitcherDescription(description: AppSwitcherDescription) { - Log.d(PlatformPluginCallback.TAG, "setApplicationSwitcherDescription: " + JSON.stringify(description)); - try { - let label: string = description?.label; - this.uiAbilityContext?.setMissionLabel(label).then(() => { - Log.d(PlatformPluginCallback.TAG, "Succeeded in seting mission label"); - }) - } catch (err) { - Log.d(PlatformPluginCallback.TAG, "Failed to set mission label: " + JSON.stringify(err)); - } - } - - /** - * Shows the specified system UI overlays. - * @param overlays - Array of overlays to show. - */ - showSystemOverlays(overlays: SystemUiOverlay[]) { - this.setSystemChromeEnabledSystemUIOverlays(overlays); - } - - /** - * Sets the system UI mode. - * @param mode - The system UI mode to set. - */ - showSystemUiMode(mode: SystemUiMode) { - this.setSystemChromeEnabledSystemUIMode(mode); - } - - /** - * Sets up a listener for system UI changes. - */ - setSystemUiChangeListener() { - this.platform?.setSystemChromeChangeListener(); - } - - /** - * Restores the system UI overlays to their previous state. - */ - restoreSystemUiOverlays() { - this.platform?.updateSystemUiOverlays(); - } - - /** - * Sets the system UI overlay style (colors, brightness, etc.). - * @param systemUiOverlayStyle - The style to apply. - */ - setSystemUiOverlayStyle(systemUiOverlayStyle: SystemChromeStyle) { - Log.d(PlatformPluginCallback.TAG, "systemUiOverlayStyle:" + JSON.stringify(systemUiOverlayStyle)); - this.setSystemChromeSystemUIOverlayStyle(systemUiOverlayStyle); - } - - /** - * Pops the system navigator (goes back in navigation stack). - */ - popSystemNavigator() { - if (this.platformPluginDelegate != null && this.platformPluginDelegate?.popSystemNavigator()) { - return; - } - router.back(); - } - - /** - * Gets data from the system clipboard. - * @param result - The method result callback. - */ - getClipboardData(result: MethodResult): void { - let atManager = abilityAccessCtrl.createAtManager(); - atManager.requestPermissionsFromUser(this.uiAbilityContext, ['ohos.permission.READ_PASTEBOARD']).then((data) => { - // https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-permissionrequestresult-V5 - // Permission request result codes: - // -1: Not authorized, permission is configured but requires user to modify in Settings - // 0: Granted - // 2: Not authorized, request is invalid, possible reasons: - // - Target permission not declared in configuration file - // - Invalid permission name - // - Special conditions for certain permissions not met - enum AuthResultStatus { - NOT_CONFIGURED = -1, - GRANTED = 0, - INVALID_REQ = 2 - } - - let message: string = 'Failed to request permissions from user.'; - let authResult: number = data.authResults[0]; - switch (authResult) { - case AuthResultStatus.GRANTED: { - let systemPasteboard: pasteboard.SystemPasteboard = pasteboard.getSystemPasteboard(); - systemPasteboard.getData().then(async (pasteData: pasteboard.PasteData) => { - let pasteText: string = ''; - const recordCount: number = pasteData.getRecordCount(); - for (let i = 0; i < recordCount; i++) { - const record = pasteData.getRecord(i); - let text: string = ''; - if (typeof record.getValidTypes === 'function') { - // For api14 and above, click here. More formats are supported - text = await PasteboardUtils.getTargetTypesData(record); - } else if (record.mimeType === pasteboard.MIMETYPE_TEXT_HTML) { - const htmlText: StyledString = await StyledString.fromHtml(record.htmlText); - text = htmlText.getString(); - } else if (record.mimeType === pasteboard.MIMETYPE_TEXT_PLAIN) { - text = record.plainText; - } - pasteText += text; - } - let response: Any = new Map().set("text", pasteText); - result.success(response); - }).catch((err: BusinessError) => { - Log.e(PlatformPluginCallback.TAG, "Failed to get PasteData. Cause: " + JSON.stringify(err)); - result.error("error", JSON.stringify(err), null); - }); - break; - } - case AuthResultStatus.NOT_CONFIGURED: { - message += 'Cause: Not configured in Settings'; - Log.i(PlatformPluginCallback.TAG, message); - result.success(null); - break; - } - case AuthResultStatus.INVALID_REQ: { - message += 'Cause: Invalid request'; - Log.i(PlatformPluginCallback.TAG, message); - result.success(null); - break; - } - default: { - message += `Unknown error: authResult=${authResult}`; - result.error("error", message, null); - break; - } - } - }).catch((err: BusinessError) => { - Log.e(PlatformPluginCallback.TAG, "Failed to request permissions from user. Cause: " + JSON.stringify(err)); - result.error("error", JSON.stringify(err), null); - }) - } - - /** - * Sets data to the system clipboard. - * @param text - The text to set - * @param result - The method result callback - */ - setClipboardData(text: string, result: MethodResult) { - let pasteData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, text); - let systemPasteboard: pasteboard.SystemPasteboard = pasteboard.getSystemPasteboard(); - try { - systemPasteboard.setDataSync(pasteData); - result.success(null); - } catch (err) { - Log.d(PlatformPluginCallback.TAG, "Failed to set PasteData. Cause: " + JSON.stringify(err)); - result.error("error", JSON.stringify(err), null); - } - } - - /** - * Checks if the clipboard contains string data. - * @returns True if clipboard has strings, false otherwise - */ - clipboardHasStrings(): boolean { - return false; - } - - /** - * Sets the system UI mode (fullscreen, immersive, etc.). - * @param mode - The system UI mode to set - */ - setSystemChromeEnabledSystemUIMode(mode: SystemUiMode): void { - Log.d(PlatformPluginCallback.TAG, "mode: " + mode); - let uiConfig: ('status' | 'navigation')[] = []; - if (mode == SystemUiMode.LEAN_BACK) { - // Full screen mode, status and navigation bars can be shown by tapping anywhere on the display - FlutterManager.getInstance().setUseFullScreen(true, null); - } else if (mode == SystemUiMode.IMMERSIVE) { - // Full screen mode, status and navigation bars can be shown by swiping from display edges, gesture not received by app - FlutterManager.getInstance().setUseFullScreen(true, null); - } else if (mode == SystemUiMode.IMMERSIVE_STICKY) { - // Full screen mode, status and navigation bars can be shown by swiping from display edges, gesture received by app - FlutterManager.getInstance().setUseFullScreen(true, null); - } else if (mode == SystemUiMode.EDGE_TO_EDGE) { - uiConfig = ['status', 'navigation']; - } else { - return; - } - this.showBarOrNavigation = uiConfig; - this.platform?.updateSystemUiOverlays(); - } - - /** - * Sets the system UI overlay style with colors and brightness. - * @param systemChromeStyle - The style configuration - */ - setSystemChromeSystemUIOverlayStyle(systemChromeStyle: SystemChromeStyle): void { - let isStatusBarLightIconValue: boolean = false; - let statusBarContentColorValue: string | undefined = undefined; - let statusBarColorValue: string | undefined = undefined; - let navigationBarColorValue: string | undefined = undefined; - let isNavigationBarLightIconValue: boolean = false; - - const currentProps = this.mainWindow?.getWindowSystemBarProperties(); - - if (systemChromeStyle.statusBarIconBrightness != null) { - switch (systemChromeStyle.statusBarIconBrightness) { - case Brightness.DARK: - isStatusBarLightIconValue = false; - statusBarContentColorValue = '#000000'; - break; - case Brightness.LIGHT: - isStatusBarLightIconValue = true; - statusBarContentColorValue = '#FFFFFF'; - break; - } - } else { - isStatusBarLightIconValue = currentProps?.isStatusBarLightIcon ?? false - } - - if (systemChromeStyle.statusBarColor != null) { - statusBarColorValue = "#" + systemChromeStyle.statusBarColor.toString(16).padStart(8, '0'); - } else { - statusBarColorValue = currentProps?.statusBarColor - } - - if (systemChromeStyle.systemStatusBarContrastEnforced != null) { - - } - - if (systemChromeStyle.systemNavigationBarIconBrightness != null) { - switch (systemChromeStyle.systemNavigationBarIconBrightness) { - case Brightness.DARK: - isNavigationBarLightIconValue = true; - break; - case Brightness.LIGHT: - isNavigationBarLightIconValue = false; - } - } else { - isNavigationBarLightIconValue = currentProps?.isNavigationBarLightIcon ?? false - } - - if (systemChromeStyle.systemNavigationBarColor != null) { - navigationBarColorValue = "#" + systemChromeStyle.systemNavigationBarColor.toString(16).padStart(8, '0'); - } else { - navigationBarColorValue = currentProps?.navigationBarColor - } - - if (systemChromeStyle.systemNavigationBarContrastEnforced != null) { - - } - this.currentTheme = systemChromeStyle; - const systemBarProperties: window.SystemBarProperties = { - statusBarColor: statusBarColorValue, - isStatusBarLightIcon: isStatusBarLightIconValue, - statusBarContentColor: statusBarContentColorValue, - navigationBarColor: navigationBarColorValue, - isNavigationBarLightIcon: isNavigationBarLightIconValue, - navigationBarContentColor: currentProps?.navigationBarContentColor, - enableStatusBarAnimation: currentProps?.enableStatusBarAnimation, - enableNavigationBarAnimation: currentProps?.enableNavigationBarAnimation, - } - Log.d(PlatformPluginCallback.TAG, "systemBarProperties: " + JSON.stringify(systemBarProperties)); - this.mainWindow?.setWindowSystemBarProperties(systemBarProperties); - } - - /** - * Sets which system UI overlays should be enabled. - * @param overlays - Array of overlays to enable - */ - setSystemChromeEnabledSystemUIOverlays(overlays: SystemUiOverlay[]): void { - let uiConfig: ('status' | 'navigation')[] = []; - if (overlays.length == 0) { - - } - for (let index = 0; index < overlays.length; ++index) { - let overlayToShow = overlays[index]; - switch (overlayToShow) { - case SystemUiOverlay.TOP_OVERLAYS: - uiConfig.push('status'); //hide navigation - break; - case SystemUiOverlay.BOTTOM_OVERLAYS: - uiConfig.push('navigation'); //hide bar - break; - } - } - this.showBarOrNavigation = uiConfig; - this.platform?.updateSystemUiOverlays(); - } - - /** - * Determines whether to hide window decoration based on system UI overlay settings. - * @returns True to hide window decoration, false to show it - */ - shouldHideWindowDecor(): boolean { - const hasStatus = this.showBarOrNavigation.includes('status'); - const hasNavigation = this.showBarOrNavigation.includes('navigation'); - - // Fullscreen: [] → hide - // Edge-to-edge: ['status', 'navigation'] → hide - // Bottom only: ['navigation'] → hide - // Top only: ['status'] → show - - return !hasStatus || hasNavigation; - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/Any.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/Any.ets deleted file mode 100644 index acc6e58..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/Any.ets +++ /dev/null @@ -1,9 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -declare type Any = ESObject; - -export default Any; \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BackgroundBasicMessageChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BackgroundBasicMessageChannel.ets deleted file mode 100644 index c818e9c..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BackgroundBasicMessageChannel.ets +++ /dev/null @@ -1,165 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ -import MessageChannelUtils from '../../util/MessageChannelUtils'; -import Log from '../../util/Log'; -import { BinaryReply } from './BinaryMessenger'; -import { TaskQueue } from './BinaryMessenger'; -import MessageCodec from './MessageCodec'; -import { BinaryMessenger } from './BinaryMessenger'; -import SendableBinaryMessageHandler from './SendableBinaryMessageHandler' -import SendableMessageCodec from './SendableMessageCodec'; -import SendableMessageHandler from './SendableMessageHandler'; -import StringUtils from '../../util/StringUtils'; - -/** - * A named channel for communicating with Flutter using basic, asynchronous message passing - * on background threads. This channel uses sendable codecs that can be passed across thread boundaries. - * - * Messages are encoded into binary before being sent, and binary messages received are decoded - * into objects. The {@link SendableMessageCodec} used must be compatible with the one used by the - * Flutter application. This can be achieved by creating a `BasicMessageChannel` counterpart of this channel - * on the Dart side. The type of messages sent and received - * is {@code Any}, but only values supported by the specified {@link SendableMessageCodec} can be used. - * - * The logical identity of the channel is given by its name. Identically named channels will - * interfere with each other's communication. - * @template T - The type of message being sent/received - */ -export default class BackgroundBasicMessageChannel { - /** Tag for logging. */ - public static TAG = "BackgroundBasicMessageChannel#"; - /** Channel name for buffer management. */ - public static CHANNEL_BUFFERS_CHANNEL = "dev.flutter/channel-buffers"; - private messenger: BinaryMessenger; - private name: string; - private codec: SendableMessageCodec; - private taskQueue: TaskQueue; - - /** - * Constructs a new BackgroundBasicMessageChannel instance. - * @param messenger - The BinaryMessenger to use for communication - * @param name - The channel name - * @param codec - The SendableMessageCodec to use for encoding/decoding messages - * @param taskQueue - Optional TaskQueue for background processing, defaults to a new background task queue - */ - constructor(messenger: BinaryMessenger, name: string, codec: SendableMessageCodec, taskQueue?: TaskQueue) { - this.messenger = messenger - this.name = name - this.codec = codec - this.taskQueue = taskQueue ?? messenger.makeBackgroundTaskQueue() - } - - /** - * Sends the specified message to the Flutter application, optionally expecting a reply. - * - * Any uncaught exception thrown by the reply callback will be caught and logged. - * - * @param message - The message, possibly null - * @param callback - A reply callback, possibly null - */ - send(message: T, callback?: (reply: T) => void): void { - this.messenger.send(this.name, this.codec.encodeMessage(message), - callback == null ? null : new IncomingReplyHandler(callback, this.codec)); - } - - /** - * Registers a message handler on this channel for receiving messages sent from the Flutter - * application. - * - * Overrides any existing handler registration for (the name of) this channel. - * - * If no handler has been registered, any incoming message on this channel will be handled - * silently by sending a null reply. - * - * @param handler - A {@link SendableMessageHandler}, or null to deregister - */ - setMessageHandler(handler: SendableMessageHandler | null): void { - this.messenger.setMessageHandler(this.name, - handler == null ? null : new IncomingSendableMessageHandler(handler, this.codec), this.taskQueue); - } - - /** - * Adjusts the number of messages that will get buffered when sending messages to channels that - * aren't fully set up yet. For example, the engine isn't running yet or the channel's message - * handler isn't set up on the Dart side yet. - * @param newSize - The new buffer size - */ - resizeChannelBuffer(newSize: number): void { - MessageChannelUtils.resizeChannelBuffer(this.messenger, this.name, newSize); - } -} - - -/** - * Internal handler for incoming replies from Flutter in background threads. - * @template T - The type of message being handled - */ -class IncomingReplyHandler implements BinaryReply { - private callback: (reply: T) => void; - private codec: SendableMessageCodec - - /** - * Constructs a new IncomingReplyHandler instance. - * @param callback - The callback to invoke with the decoded reply - * @param codec - The SendableMessageCodec to use for decoding - */ - constructor(callback: (reply: T) => void, codec: SendableMessageCodec) { - this.callback = callback - this.codec = codec - } - - /** - * Handles a binary reply from Flutter. - * @param reply - The binary reply, possibly null - */ - reply(reply: ArrayBuffer | null) { - try { - this.callback(this.codec.decodeMessage(reply)); - } catch (e) { - Log.e(BackgroundBasicMessageChannel.TAG, "Failed to handle message reply", e); - } - } -} - -/** - * Internal handler for incoming messages from Flutter in background threads. - * @template T - The type of message being handled - */ -@Sendable -class IncomingSendableMessageHandler implements SendableBinaryMessageHandler { - private handler: SendableMessageHandler - private codec: SendableMessageCodec - - /** - * Constructs a new IncomingSendableMessageHandler instance. - * @param handler - The SendableMessageHandler to delegate to - * @param codec - The SendableMessageCodec to use for encoding/decoding - */ - constructor(handler: SendableMessageHandler, codec: SendableMessageCodec) { - this.handler = handler; - this.codec = codec - } - - /** - * Handles a binary message from Flutter. - * @param message - The binary message - * @param callback - The BinaryReply callback to send a response - */ - onMessage(message: ArrayBuffer, callback: BinaryReply) { - try { - this.handler.onMessage( - this.codec.decodeMessage(message), - { - reply: (reply: T): void => { - callback.reply(this.codec.encodeMessage(reply)); - } - }); - } catch (e) { - Log.e('WARNNING', "Failed to handle message: ", e); - callback.reply(StringUtils.stringToArrayBuffer("")); - } - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BackgroundMethodChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BackgroundMethodChannel.ets deleted file mode 100644 index 9a3913b..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BackgroundMethodChannel.ets +++ /dev/null @@ -1,185 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ -import Log from '../../util/Log'; -import MessageChannelUtils from '../../util/MessageChannelUtils'; -import StringUtils from '../../util/StringUtils'; -import { BinaryMessenger, BinaryReply, TaskQueue } from './BinaryMessenger'; -import Any from './Any'; -import MethodCall from './MethodCall'; -import MethodCodec from './MethodCodec'; -import { MethodResult } from './MethodChannel' -import SendableStandardMethodCodec from './SendableStandardMethodCodec'; -import SendableMethodCallHandler from './SendableMethodCallHandler' -import SendableMethodCodec from './SendableMethodCodec' -import SendableBinaryMessageHandler from './SendableBinaryMessageHandler' - -/** - * A named channel for communicating with Flutter using asynchronous method calls on background threads. - * This channel uses sendable codecs that can be passed across thread boundaries. - * - * Incoming method calls are decoded from binary on receipt, and results are encoded into - * binary before being transmitted back to Flutter. The {@link MethodCodec} used must be compatible - * with the one used by the Flutter application. This can be achieved by creating a `MethodChannel` - * counterpart of this channel on the Dart side. The type of method call arguments and results - * is {@code Any}, but only values supported by the specified {@link MethodCodec} can be used. - * - * The logical identity of the channel is given by its name. Identically named channels will - * interfere with each other's communication. - */ -export default class BackgroundMethodChannel { - /** Tag for logging. */ - static TAG = "BackgroundMethodChannel#"; - private messenger: BinaryMessenger; - private name: string; - private codec: SendableMethodCodec; - private taskQueue: TaskQueue; - private args: Object[]; - - /** - * Constructs a new BackgroundMethodChannel instance. - * @param messenger - The BinaryMessenger to use for communication - * @param name - The channel name - * @param codec - The SendableMethodCodec to use for encoding/decoding, defaults to SendableStandardMethodCodec.INSTANCE - * @param taskQueue - Optional TaskQueue for background processing, defaults to a new background task queue - * @param args - Additional arguments to pass to message handlers - */ - constructor(messenger: BinaryMessenger, - name: string, - codec: SendableMethodCodec = SendableStandardMethodCodec.INSTANCE, - taskQueue?: TaskQueue, - ...args: Object[]) { - this.messenger = messenger - this.name = name - this.codec = codec - this.taskQueue = taskQueue ?? messenger.makeBackgroundTaskQueue() - this.args = args - } - - /** - * Invokes a method on this channel, optionally expecting a result. - * - * Any uncaught exception thrown by the result callback will be caught and logged. - * - * @param method - The name of the method - * @param args - The arguments for the invocation, possibly null - * @param callback - A {@link MethodResult} callback for the invocation result, or null - */ - invokeMethod(method: string, args: Any, callback?: MethodResult): void { - this.messenger.send(this.name, - this.codec.encodeMethodCall(new MethodCall(method, args)), - callback == null ? null : new IncomingSendableResultHandler(callback, this.codec)); - } - - /** - * Registers a method call handler on this channel. - * - * Overrides any existing handler registration for (the name of) this channel. - * - * If no handler has been registered, any incoming method call on this channel will be handled - * silently by sending a null reply. This results in a `MissingPluginException` - * on the Dart side, unless an `OptionalMethodChannel` is used. - * - * @param handler - A {@link SendableMethodCallHandler}, or null to deregister - */ - setMethodCallHandler(handler: SendableMethodCallHandler | null): void { - this.messenger.setMessageHandler(this.name, - handler == null ? null : new IncomingSendableMethodCallHandler(handler, this.codec), - this.taskQueue, ...this.args); - } - - /** - * Adjusts the number of messages that will get buffered when sending messages to channels that - * aren't fully set up yet. For example, the engine isn't running yet or the channel's message - * handler isn't set up on the Dart side yet. - * @param newSize - The new buffer size - */ - resizeChannelBuffer(newSize: number): void { - MessageChannelUtils.resizeChannelBuffer(this.messenger, this.name, newSize); - } -} - -/** - * Internal handler for incoming method call results from Flutter in background threads. - */ -export class IncomingSendableResultHandler implements BinaryReply { - private callback: MethodResult; - private codec: SendableMethodCodec; - - /** - * Constructs a new IncomingSendableResultHandler instance. - * @param callback - The MethodResult callback to invoke - * @param codec - The SendableMethodCodec to use for decoding - */ - constructor(callback: MethodResult, codec: SendableMethodCodec) { - this.callback = callback; - this.codec = codec - } - - /** - * Handles a binary reply from Flutter. - * @param reply - The binary reply, possibly null - */ - reply(reply: ArrayBuffer | null): void { - try { - if (reply == null) { - this.callback.notImplemented(); - } else { - try { - this.callback.success(this.codec.decodeEnvelope(reply)); - } catch (e) { - this.callback.error(e.code, e.getMessage(), e.details); - } - } - } catch (e) { - Log.e(BackgroundMethodChannel.TAG, "Failed to handle method call result", e); - } - } -} - -/** - * Internal handler for incoming method calls from Flutter in background threads. - */ -@Sendable -export class IncomingSendableMethodCallHandler implements SendableBinaryMessageHandler { - private handler: SendableMethodCallHandler; - private codec: SendableMethodCodec; - - /** - * Constructs a new IncomingSendableMethodCallHandler instance. - * @param handler - The SendableMethodCallHandler to delegate to - * @param codec - The SendableMethodCodec to use for encoding/decoding - */ - constructor(handler: SendableMethodCallHandler, codec: SendableMethodCodec) { - this.handler = handler; - this.codec = codec; - } - - /** - * Handles a binary method call from Flutter. - * @param message - The binary message containing the method call - * @param reply - The BinaryReply callback to send a response - * @param args - Additional arguments passed to the handler - */ - onMessage(message: ArrayBuffer, reply: BinaryReply, ...args: Object[]): void { - try { - this.handler.onMethodCall( - this.codec.decodeMethodCall(message), - { - success: (result: Any): void => { - reply.reply(this.codec.encodeSuccessEnvelope(result)); - }, - error: (errorCode: string, errorMessage: string, errorDetails: Any): void => { - reply.reply(this.codec.encodeErrorEnvelope(errorCode, errorMessage, errorDetails)); - }, - notImplemented: (): void => { - reply.reply(StringUtils.stringToArrayBuffer("")); - } - }, ...args); - } catch (e) { - reply.reply(this.codec.encodeErrorEnvelopeWithStacktrace("error", e.getMessage(), null, e)); - } - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel.ets deleted file mode 100644 index ca7057b..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel.ets +++ /dev/null @@ -1,200 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on BasicMessageChannel.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ -import MessageChannelUtils from '../../util/MessageChannelUtils'; -import { BinaryMessageHandler } from './BinaryMessenger'; -import Log from '../../util/Log'; -import { BinaryReply } from './BinaryMessenger'; -import { TaskQueue } from './BinaryMessenger'; -import MessageCodec from './MessageCodec'; -import { BinaryMessenger } from './BinaryMessenger'; -import StringUtils from '../../util/StringUtils'; - -/** - * A named channel for communicating with the Flutter application using basic, asynchronous message - * passing. - * - * Messages are encoded into binary before being sent, and binary messages received are decoded - * into objects. The {@link MessageCodec} used must be compatible with the one used by the - * Flutter application. This can be achieved by creating a `BasicMessageChannel` - * counterpart of this channel on the Dart side. The static type of messages sent and received - * is `Object`, but only values supported by the specified {@link MessageCodec} can be used. - * - * The logical identity of the channel is given by its name. Identically named channels will - * interfere with each other's communication. - */ -export default class BasicMessageChannel { - /** Tag for logging. */ - public static TAG = "BasicMessageChannel#"; - /** Channel name for buffer management. */ - public static CHANNEL_BUFFERS_CHANNEL = "dev.flutter/channel-buffers"; - private messenger: BinaryMessenger; - private name: string; - private codec: MessageCodec; - - /** - * Constructs a new BasicMessageChannel instance. - * @param messenger - The BinaryMessenger to use for communication - * @param name - The channel name - * @param codec - The MessageCodec to use for encoding/decoding messages - */ - constructor(messenger: BinaryMessenger, name: string, codec: MessageCodec) { - this.messenger = messenger - this.name = name - this.codec = codec - } - - /** - * Sends the specified message to the Flutter application, optionally expecting a reply. - * - * Any uncaught exception thrown by the reply callback will be caught and logged. - * - * @param message - The message, possibly null - * @param callback - A {@link Reply} callback, possibly null - */ - send(message: T, callback?: (reply: T) => void): void { - this.messenger.send(this.name, this.codec.encodeMessage(message), - callback == null ? null : new IncomingReplyHandler(callback, this.codec)); - } - - /** - * Registers a message handler on this channel for receiving messages sent from the Flutter - * application. - * - * Overrides any existing handler registration for (the name of) this channel. - * - * If no handler has been registered, any incoming message on this channel will be handled - * silently by sending a null reply. - * - * @param handler - A {@link MessageHandler}, or null to deregister - */ - setMessageHandler(handler: MessageHandler | null): void { - this.messenger.setMessageHandler(this.name, - handler == null ? null : new IncomingMessageHandler(handler, this.codec)); - } - - /** - * Adjusts the number of messages that will get buffered when sending messages to channels that - * aren't fully set up yet. For example, the engine isn't running yet or the channel's message - * handler isn't set up on the Dart side yet. - * @param newSize - The new buffer size - */ - resizeChannelBuffer(newSize: number): void { - MessageChannelUtils.resizeChannelBuffer(this.messenger, this.name, newSize); - } -} - -/** - * Interface for handling message replies in BasicMessageChannel. - * @template T - The type of message being replied to - */ -export interface Reply { - /** - * Handles the specified message reply. - * - * @param reply - The reply, possibly null - */ - reply: (reply: T) => void; -} - -/** - * Interface for handling incoming messages in BasicMessageChannel. - * @template T - The type of message being handled - */ -export interface MessageHandler { - - /** - * Handles the specified message received from Flutter. - * - * Handler implementations must reply to all incoming messages, by submitting a single reply - * message to the given {@link Reply}. Failure to do so will result in lingering Flutter reply - * handlers. The reply may be submitted asynchronously and invoked on any thread. - * - * Any uncaught exception thrown by this method, or the preceding message decoding, will be - * caught by the channel implementation and logged, and a null reply message will be sent back - * to Flutter. - * - * Any uncaught exception thrown during encoding a reply message submitted to the {@link Reply} - * is treated similarly: the exception is logged, and a null reply is sent to Flutter. - * - * @param message - The message, possibly null - * @param reply - A {@link Reply} for sending a single message reply back to Flutter - */ - onMessage(message: T, reply: Reply): void; -} - -/** - * Internal handler for incoming replies from Flutter. - * @template T - The type of message being handled - */ -class IncomingReplyHandler implements BinaryReply { - private callback: (reply: T) => void; - private codec: MessageCodec - - /** - * Constructs a new IncomingReplyHandler instance. - * @param callback - The callback to invoke with the decoded reply - * @param codec - The MessageCodec to use for decoding - */ - constructor(callback: (reply: T) => void, codec: MessageCodec) { - this.callback = callback - this.codec = codec - } - - /** - * Handles a binary reply from Flutter. - * @param reply - The binary reply, possibly null - */ - reply(reply: ArrayBuffer | null) { - try { - this.callback(this.codec.decodeMessage(reply)); - } catch (e) { - Log.e(BasicMessageChannel.TAG, "Failed to handle message reply", e); - } - } -} - -/** - * Internal handler for incoming messages from Flutter. - * @template T - The type of message being handled - */ -class IncomingMessageHandler implements BinaryMessageHandler { - private handler: MessageHandler - private codec: MessageCodec - - /** - * Constructs a new IncomingMessageHandler instance. - * @param handler - The MessageHandler to delegate to - * @param codec - The MessageCodec to use for encoding/decoding - */ - constructor(handler: MessageHandler, codec: MessageCodec) { - this.handler = handler; - this.codec = codec - } - - /** - * Handles a binary message from Flutter. - * @param message - The binary message - * @param callback - The BinaryReply callback to send a response - */ - onMessage(message: ArrayBuffer, callback: BinaryReply) { - try { - this.handler.onMessage( - this.codec.decodeMessage(message), - { - reply: (reply: T): void => { - callback.reply(this.codec.encodeMessage(reply)); - } - }); - } catch (e) { - Log.e(BasicMessageChannel.TAG, "Failed to handle message", e); - callback.reply(StringUtils.stringToArrayBuffer("")); - } - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryCodec.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryCodec.ets deleted file mode 100644 index bf64447..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryCodec.ets +++ /dev/null @@ -1,58 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on BinaryCodec.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import MessageCodec from './MessageCodec'; - -/** - * A {@link MessageCodec} using unencoded binary messages, represented as {@link ArrayBuffer}s. - * - * This codec is guaranteed to be compatible with the corresponding `BinaryCodec` on the Dart side. - * These parts of the Flutter SDK are evolved synchronously. - * - * On the Dart side, messages are represented using {@code ByteData}. - */ - -export default class BinaryCodec implements MessageCodec { - private returnsDirectByteBufferFromDecoding: boolean = false; - /** Direct instance that returns the direct buffer from decoding. */ - static readonly INSTANCE_DIRECT = new BinaryCodec(true); - - /** - * Constructs a new BinaryCodec instance. - * @param returnsDirectByteBufferFromDecoding - Whether to return the direct buffer from decoding - */ - constructor(returnsDirectByteBufferFromDecoding: boolean) { - this.returnsDirectByteBufferFromDecoding = returnsDirectByteBufferFromDecoding; - } - - /** - * Encodes a binary message (no-op for binary codec). - * @param message - The ArrayBuffer message to encode - * @returns The same ArrayBuffer - */ - encodeMessage(message: ArrayBuffer): ArrayBuffer { - return message - } - - /** - * Decodes a binary message. - * @param message - The ArrayBuffer message to decode, possibly null - * @returns The decoded ArrayBuffer, or a copy depending on configuration - */ - decodeMessage(message: ArrayBuffer | null): ArrayBuffer { - if (message == null) { - return new ArrayBuffer(0); - } else if (this.returnsDirectByteBufferFromDecoding) { - return message; - } else { - return message.slice(0, message.byteLength); - } - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger.ets deleted file mode 100644 index ccdade6..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger.ets +++ /dev/null @@ -1,197 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on BinaryMessenger.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -/** - * An abstraction over the threading policy used to invoke message handlers. - * - * These are generated by calling methods like {@link BinaryMessenger#makeBackgroundTaskQueue(TaskQueueOptions)} and can - * be passed into platform channels' constructors to control the threading policy for handling platform channels' messages. - */ - -import SendableBinaryMessageHandler from './SendableBinaryMessageHandler' - -/** - * An abstraction over the threading policy used to invoke message handlers. - * Task queues are used to control which thread handles platform channel messages. - */ -export interface TaskQueue {} - -/** - * The priority of task execution - * - * This priority is guaranteed to be compatible with `taskpool` - * ({@link https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-taskpool-V5#priority}). - * - */ -export enum TaskPriority { - HIGH = 0, - MEDIUM = 1, - LOW = 2, - IDLE = 3 -} - -/** - * Options that control how a TaskQueue should operate and be created. - */ -export class TaskQueueOptions { - private isSerial: boolean = true; - private isSingleThread: boolean = false; - private priority: TaskPriority = TaskPriority.MEDIUM; - - /** - * Gets whether tasks should be executed serially. - * @returns True if tasks are executed serially, false otherwise - */ - getIsSerial():boolean { - return this.isSerial; - } - - /** - * Sets whether tasks should be executed serially. - * @param isSerial - True to execute tasks serially, false for concurrent execution - * @returns This TaskQueueOptions instance for method chaining - */ - setIsSerial(isSerial: boolean): TaskQueueOptions { - this.isSerial = isSerial; - return this; - } - - /** - * Gets the task priority. - * @returns The current task priority - */ - getPriority(): TaskPriority { - return this.priority; - } - - /** - * Sets the task priority. - * @param priority - The task priority to set - * @returns This TaskQueueOptions instance for method chaining - */ - setPriority(priority: TaskPriority): TaskQueueOptions { - this.priority = priority; - return this; - } - - /** - * Checks if single thread mode is enabled. - * @returns True if single thread mode is enabled, false otherwise - */ - isSingleThreadMode(): boolean { - return this.isSingleThread; - } - - /** - * Sets single thread mode. - * @param isSingleThread - True to enable single thread mode, false otherwise - * @returns This TaskQueueOptions instance for method chaining - */ - setSingleThreadMode(isSingleThread: boolean): TaskQueueOptions { - this.isSingleThread = isSingleThread; - return this; - } -} - -/** - * Binary message reply callback. Used to submit a reply to an incoming message from Flutter. Also - * used in the dual capacity to handle a reply received from Flutter after sending a message. - */ -export interface BinaryReply { - /** - * Handles the specified reply. - * - * @param reply - The reply payload, an {@link ArrayBuffer} or null. Senders of - * outgoing replies must place the reply bytes in the buffer. - * Reply receivers can read from the buffer directly. - */ - reply: (reply: ArrayBuffer | null) => void; -} - -/** Handler for incoming binary messages from Flutter. */ -export interface BinaryMessageHandler { - /** - * Handles the specified message. - * - * Handler implementations must reply to all incoming messages, by submitting a single reply - * message to the given {@link BinaryReply}. Failure to do so will result in lingering Flutter - * reply handlers. The reply may be submitted asynchronously. - * - * Any uncaught exception thrown by this method will be caught by the messenger - * implementation and logged, and a null reply message will be sent back to Flutter. - * - * @param message - The message {@link ArrayBuffer} payload, possibly null - * @param reply - A {@link BinaryReply} used for submitting a reply back to Flutter - */ - onMessage(message: ArrayBuffer, reply: BinaryReply): void; -} - -/** - * Facility for communicating with Flutter using asynchronous message passing with binary messages. - * The Flutter Dart code should use `BinaryMessages` to participate. - * - * BinaryMessenger is expected to be utilized from a single thread throughout the - * duration of its existence. If created on the main thread, then all invocations should take place - * on the main thread. If created on a background thread, then all invocations should take place on - * that background thread. - * - * @see BasicMessageChannel , which supports message passing with Strings and semi-structured - * messages. - * @see MethodChannel , which supports communication using asynchronous method invocation. - * @see EventChannel , which supports communication using event streams. - */ - -export interface BinaryMessenger { - /** - * Creates a background task queue for handling messages on background threads. - * @param options - Optional TaskQueueOptions to configure the task queue - * @returns A TaskQueue instance - */ - makeBackgroundTaskQueue(options?: TaskQueueOptions): TaskQueue; - - /** - * Sends a binary message to the Flutter application. - * - * @param channel - The name of the logical channel used for the message - * @param message - The message payload, an {@link ArrayBuffer} or null - */ - send(channel: String, message: ArrayBuffer | null): void; - - /** - * Sends a binary message to the Flutter application, optionally expecting a reply. - * - * Any uncaught exception thrown by the reply callback will be caught and logged. - * - * @param channel - The name of the logical channel used for the message - * @param message - The message payload, an {@link ArrayBuffer} or null - * @param callback - A {@link BinaryReply} callback invoked when the Flutter application responds to - * the message, possibly null - */ - send(channel: String, message: ArrayBuffer, callback?: BinaryReply | null): void; - - /** - * Registers a handler to be invoked when the Flutter application sends a message to its host - * platform. - * - * Registration overwrites any previous registration for the same channel name. Use a null - * handler to deregister. - * - * If no handler has been registered for a particular channel, any incoming message on that - * channel will be handled silently by sending a null reply. - * - * @param channel - The name of the channel - * @param handler - A {@link BinaryMessageHandler} to be invoked on incoming messages, or null - * @param taskQueue - A {@link BinaryMessenger.TaskQueue} that specifies what thread will execute - * the handler. Specifying null means execute on the platform thread - * @param args - Additional arguments - */ - setMessageHandler(channel: String, handler: BinaryMessageHandler | SendableBinaryMessageHandler | null, - taskQueue?: TaskQueue, ...args: Object[]): void; -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/EventChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/EventChannel.ets deleted file mode 100644 index e736f8f..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/EventChannel.ets +++ /dev/null @@ -1,334 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on EventChannel.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import Log from '../../util/Log'; -import { BinaryMessageHandler, BinaryMessenger, BinaryReply, TaskQueue } from './BinaryMessenger'; -import Any from './Any'; -import MethodCodec from './MethodCodec'; -import StandardMethodCodec from './StandardMethodCodec'; - -const TAG = "EventChannel#"; - -/** - * A named channel for communicating with the Flutter application using asynchronous event streams. - * - * Incoming requests for event stream setup are decoded from binary on receipt, and - * responses and events are encoded into binary before being transmitted back to Flutter. The {@link MethodCodec} - * used must be compatible with the one used by the Flutter application. This can be achieved by creating an - * `EventChannel` counterpart of this channel on the Dart side. The type of stream configuration arguments, events, - * and error details is {@code Any}, but only values supported by the specified {@link MethodCodec} can be used. - * - * The logical identity of the channel is given by its name. Identically named channels will - * interfere with each other's communication. - */ -export default class EventChannel { - private messenger: BinaryMessenger; - private name: string; - private codec: MethodCodec; - private taskQueue: TaskQueue | null; - - /** - * Constructs a new EventChannel instance. - * @param messenger - The BinaryMessenger to use for communication - * @param name - The channel name - * @param codec - The MethodCodec to use for encoding/decoding, defaults to StandardMethodCodec.INSTANCE - * @param taskQueue - Optional TaskQueue for background processing - */ - constructor(messenger: BinaryMessenger, name: string, codec?: MethodCodec, taskQueue?: TaskQueue) { - this.messenger = messenger - this.name = name - this.codec = codec ? codec : StandardMethodCodec.INSTANCE - // TODO:(0xZOne): 实现后台处理 - // this.taskQueue = taskQueue ?? null - this.taskQueue = null - } - - - /** - * Registers a stream handler on this channel. - * - * Overrides any existing handler registration for (the name of) this channel. - * - * If no handler has been registered, any incoming stream setup requests will be handled - * silently by providing an empty stream. - * - * @param handler - A {@link StreamHandler}, or null to deregister - */ - setStreamHandler(handler: StreamHandler): void { - // We call the 2 parameter variant specifically to avoid breaking changes in - // mock verify calls. - // See https://github.com/flutter/flutter/issues/92582. - if (this.taskQueue != null) { - this.messenger.setMessageHandler( - this.name, - handler == null ? null : new IncomingStreamRequestHandler(handler, this.name, this.codec, this.messenger), - this.taskQueue); - } else { - this.messenger.setMessageHandler( - this.name, - handler == null ? null : new IncomingStreamRequestHandler(handler, this.name, this.codec, this.messenger)); - } - } -} - -/** - * Handler of stream setup and teardown requests. - * - * Implementations must be prepared to accept sequences of alternating calls to onListen and onCancel. - * Implementations should ideally consume no resources when the last such call is not onListen. - * In typical situations, this means that the implementation should register itself with - * platform-specific event sources onListen and deregister again onCancel. - */ -export interface StreamHandler { - /** - * Handles a request to set up an event stream. - * - * Any uncaught exception thrown by this method will be caught by the channel implementation - * and logged. An error result message will be sent back to Flutter. - * - * @param args - Stream configuration arguments, possibly null - * @param events - An {@link EventSink} for emitting events to the Flutter receiver - */ - onListen(args: Any, events: EventSink): void; - - /** - * Handles a request to tear down the most recently created event stream. - * - * Any uncaught exception thrown by this method will be caught by the channel implementation - * and logged. An error result message will be sent back to Flutter. - * - * The channel implementation may call this method with null arguments to separate a pair of - * two consecutive set up requests. Such request pairs may occur during Flutter hot restart. Any - * uncaught exception thrown in this situation will be logged without notifying Flutter. - * - * @param args - Stream configuration arguments, possibly null - */ - onCancel(args: Any): void; -} - -/** - * Event callback. Supports dual use: Producers of events to be sent to Flutter act as clients of - * this interface for sending events. Consumers of events sent from Flutter implement this - * interface for handling received events (the latter facility has not been implemented yet). - */ -export interface EventSink { - /** - * Consumes a successful event. - * - * @param event - The event, possibly null - */ - success(event: Any): void; - - /** - * Consumes an error event. - * - * @param errorCode - An error code string - * @param errorMessage - A human-readable error message, possibly null - * @param errorDetails - Error details, possibly null - */ - error(errorCode: string, errorMessage: string, errorDetails: Any): void; - - /** - * Consumes end of stream. Ensuing calls to success or error, if any, are ignored. - */ - endOfStream(): void; -} - -/** - * Internal handler for incoming stream requests from Flutter. - */ -class IncomingStreamRequestHandler implements BinaryMessageHandler { - private handler: StreamHandler; - private activeSink = new AtomicReference(null); - private codec: MethodCodec; - private name: string; - private messenger: BinaryMessenger; - - /** - * Constructs a new IncomingStreamRequestHandler instance. - * @param handler - The StreamHandler to delegate to - * @param name - The channel name - * @param codec - The MethodCodec to use for encoding/decoding - * @param messenger - The BinaryMessenger to use for sending events - */ - constructor(handler: StreamHandler, name: string, codec: MethodCodec, messenger: BinaryMessenger) { - this.handler = handler; - this.codec = codec; - this.name = name; - this.messenger = messenger; - } - - /** - * Handles a binary stream request from Flutter. - * @param message - The binary message containing the request - * @param reply - The BinaryReply callback to send a response - */ - onMessage(message: ArrayBuffer, reply: BinaryReply): void { - const call = this.codec.decodeMethodCall(message); - if (call.method == "listen") { - this.onListen(call.args, reply); - } else if (call.method == "cancel") { - this.onCancel(call.args, reply); - } else { - reply.reply(null); - } - } - - /** - * Handles a request to set up an event stream. - * @param args - Stream configuration arguments - * @param callback - The BinaryReply callback to send a response - */ - onListen(args: Any, callback: BinaryReply): void { - const eventSink = new EventSinkImplementation(this.activeSink, this.name, this.codec, this.messenger); - const oldSink = this.activeSink.getAndSet(eventSink); - if (oldSink != null) { - // Repeated calls to onListen may happen during hot restart. - // We separate them with a call to onCancel. - try { - this.handler.onCancel(null); - } catch (e) { - Log.e(TAG + this.name, "Failed to close existing event stream", e); - } - } - try { - this.handler.onListen(args, eventSink); - callback.reply(this.codec.encodeSuccessEnvelope(null)); - } catch (e) { - this.activeSink.set(null); - Log.e(TAG + this.name, "Failed to open event stream", e); - callback.reply(this.codec.encodeErrorEnvelope("error", e.getMessage(), null)); - } - } - - /** - * Handles a request to tear down an event stream. - * @param args - Stream configuration arguments - * @param callback - The BinaryReply callback to send a response - */ - onCancel(args: Any, callback: BinaryReply): void { - const oldSink = this.activeSink.getAndSet(null); - if (oldSink != null) { - try { - this.handler.onCancel(args); - callback.reply(this.codec.encodeSuccessEnvelope(null)); - } catch (e) { - Log.e(TAG + this.name, "Failed to close event stream", e); - callback.reply(this.codec.encodeErrorEnvelope("error", e.getMessage(), null)); - } - } else { - callback.reply(this.codec.encodeErrorEnvelope("error", "No active stream to cancel", null)); - } - } -} - -/** - * Implementation of EventSink for sending events to Flutter. - */ -class EventSinkImplementation implements EventSink { - private hasEnded = false; - private activeSink: AtomicReference; - private messenger: BinaryMessenger; - private codec: MethodCodec; - private name: string; - - /** - * Constructs a new EventSinkImplementation instance. - * @param activeSink - The AtomicReference to track the active sink - * @param name - The channel name - * @param codec - The MethodCodec to use for encoding - * @param messenger - The BinaryMessenger to use for sending events - */ - constructor(activeSink: AtomicReference, name: string, codec: MethodCodec, messenger: BinaryMessenger) { - this.activeSink = activeSink; - this.codec = codec; - this.name = name; - this.messenger = messenger; - } - - /** - * Sends a successful event to Flutter. - * @param event - The event data, possibly null - */ - success(event: Any): void { - if (this.hasEnded || this.activeSink.get() != this) { - return; - } - this.messenger.send(this.name, this.codec.encodeSuccessEnvelope(event)); - } - - /** - * Sends an error event to Flutter. - * @param errorCode - The error code - * @param errorMessage - The error message, possibly null - * @param errorDetails - Error details, possibly null - */ - error(errorCode: string, errorMessage: string, errorDetails: Any) { - if (this.hasEnded || this.activeSink.get() != this) { - return; - } - this.messenger.send( - this.name, this.codec.encodeErrorEnvelope(errorCode, errorMessage, errorDetails)); - } - - /** - * Signals the end of the event stream. - */ - endOfStream(): void { - if (this.hasEnded || this.activeSink.get() != this) { - return; - } - this.hasEnded = true; - this.messenger.send(this.name, new ArrayBuffer(0)); - } -} - -/** - * A simple atomic reference implementation for thread-safe value access. - * @template T - The type of value being referenced - */ -class AtomicReference { - private value: T | null; - - /** - * Constructs a new AtomicReference instance. - * @param value - The initial value, possibly null - */ - constructor(value: T | null) { - this.value = value - } - - /** - * Gets the current value. - * @returns The current value, possibly null - */ - get(): T | null { - return this.value; - } - - /** - * Sets a new value. - * @param newValue - The new value to set, possibly null - */ - set(newValue: T | null): void { - this.value = newValue; - } - - /** - * Atomically gets the current value and sets a new value. - * @param newValue - The new value to set, possibly null - * @returns The old value, possibly null - */ - getAndSet(newValue: T | null) { - const oldValue = this.value; - this.value = newValue; - return oldValue; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/FlutterException.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/FlutterException.ets deleted file mode 100644 index 31f8525..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/FlutterException.ets +++ /dev/null @@ -1,39 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on FlutterException.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ -import Any from './Any'; - -/** - * Exception class for Flutter platform channel errors. - * This class represents errors that occur during communication between Flutter and the platform. - */ -export default class FlutterException implements Error { - /** Optional stack trace for the error. */ - stack?: string; - /** The error message. */ - message: string; - /** The error name. */ - name: string = ""; - /** The error code. */ - code: string; - /** Additional error details. */ - details: Any - - /** - * Constructs a new FlutterException instance. - * @param code - The error code - * @param message - The error message - * @param details - Additional error details - */ - constructor(code: string, message: string, details: Any) { - this.message = message; - this.code = code; - this.details = details; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMessageCodec.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMessageCodec.ets deleted file mode 100644 index 054e1c7..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMessageCodec.ets +++ /dev/null @@ -1,111 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on JSONMessageCodec.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ -import StringUtils from '../../util/StringUtils'; - -import MessageCodec from './MessageCodec'; -import StringCodec from './StringCodec'; -import TreeMap from '@ohos.util.TreeMap'; -import HashMap from '@ohos.util.HashMap'; -import LightWeightMap from '@ohos.util.LightWeightMap'; -import PlainArray from '@ohos.util.PlainArray'; -import List from '@ohos.util.List'; -import LinkedList from '@ohos.util.LinkedList'; -import Any from './Any'; - -/** - * A {@link MessageCodec} using UTF-8 encoded JSON messages. - * - * This codec is guaranteed to be compatible with the corresponding `JSONMessageCodec` on the Dart side. - * These parts of the Flutter SDK are evolved synchronously. - * - * On the Dart side, JSON messages are handled by the JSON facilities of the `dart:convert` package. - */ -export default class JSONMessageCodec implements MessageCodec { - /** Singleton instance of JSONMessageCodec. */ - static INSTANCE = new JSONMessageCodec(); - - /** - * Encodes a message into JSON binary format. - * @param message - The message to encode, possibly null - * @returns The encoded message as an ArrayBuffer - */ - encodeMessage(message: Any): ArrayBuffer { - if (message == null) { - return StringUtils.stringToArrayBuffer(""); - } - return StringCodec.INSTANCE.encodeMessage(JSON.stringify(this.toBaseData(message))); - } - - /** - * Decodes a binary message from JSON format. - * @param message - The binary message to decode, possibly null - * @returns The decoded message object - * @throws Error if the JSON is invalid - */ - decodeMessage(message: ArrayBuffer | null): Any { - if (message == null) { - return StringUtils.stringToArrayBuffer(""); - } - try { - const jsonStr = StringCodec.INSTANCE.decodeMessage(message); - let jsonObj: Record = JSON.parse(jsonStr); - if (jsonObj instanceof Object) { - const list = Object.keys(jsonObj); - if (list.includes('args')) { - let args: Any = jsonObj['args']; - if (args instanceof Object && !(args instanceof Array)) { - let argsMap: Map = new Map(); - Object.keys(args).forEach(key => { - argsMap.set(key, args[key]); - }) - jsonObj['args'] = argsMap; - } - } - } - return jsonObj; - } catch (e) { - throw new Error("Invalid JSON"); - } - } - - /** - * Converts a message to base data types suitable for JSON serialization. - * @param message - The message to convert - * @returns The converted message with base data types - */ - toBaseData(message: Any): Any { - if (message == null || message == undefined) { - return null; - } else if (message instanceof List || message instanceof LinkedList) { - return this.toBaseData(message.convertToArray()); - } else if (message instanceof Map || message instanceof HashMap || message instanceof TreeMap - || message instanceof LightWeightMap || message instanceof PlainArray) { - let messageObj: Any = {}; - message.forEach((value: Any, key: Any) => { - messageObj[this.toBaseData(key)] = this.toBaseData(value); - }); - return messageObj; - } else if (message instanceof Array) { - let messageArr: Array = []; - message.forEach((value: Any) => { - messageArr.push(this.toBaseData(value)); - }) - return messageArr; - } else if (message instanceof Object) { - let messageObj: Any = {}; - Object.keys(message).forEach((key: Any) => { - messageObj[this.toBaseData(key)] = this.toBaseData(message[key]); - }) - return messageObj; - } else { - return message; - } - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMethodCodec.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMethodCodec.ets deleted file mode 100644 index 97fb142..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMethodCodec.ets +++ /dev/null @@ -1,132 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on JSONMethodCodec.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ -import Log from '../../util/Log'; - -import ToolUtils from '../../util/ToolUtils'; -import FlutterException from './FlutterException'; -import Any from './Any'; -import JSONMessageCodec from './JSONMessageCodec'; -import MethodCall from './MethodCall'; -import MethodCodec from './MethodCodec'; - -/** - * A {@link MethodCodec} using UTF-8 encoded JSON method calls and result envelopes. - * - * This codec is guaranteed to be compatible with the corresponding `JSONMethodCodec` on - * the Dart side. These parts of the Flutter SDK are evolved synchronously. - * - * Values supported as methods arguments and result payloads are those supported by {@link JSONMessageCodec}. - */ -export default class JSONMethodCodec implements MethodCodec { - /** Singleton instance of JSONMethodCodec. */ - static INSTANCE = new JSONMethodCodec(); - - /** - * Encodes a method call into JSON binary format. - * @param methodCall - The MethodCall to encode - * @returns The encoded method call as an ArrayBuffer - * @throws Error if encoding fails - */ - encodeMethodCall(methodCall: MethodCall): ArrayBuffer { - try { - const map: Record = { - "method": methodCall.method, "args": methodCall.args - } - - return JSONMessageCodec.INSTANCE.encodeMessage(map); - } catch (e) { - throw new Error("Invalid JSON"); - } - } - - /** - * Decodes a method call from JSON binary format. - * @param message - The binary message to decode - * @returns The decoded MethodCall - * @throws Error if decoding fails or the message is invalid - */ - decodeMethodCall(message: ArrayBuffer): MethodCall { - try { - const json: Any = JSONMessageCodec.INSTANCE.decodeMessage(message); - if (ToolUtils.isObj(json)) { - const method: string = json["method"]; - const args: Any = json["args"]; - if (typeof method == 'string') { - return new MethodCall(method, args); - } - } - throw new Error("Invalid method call: " + json); - } catch (e) { - throw new Error("Invalid JSON:" + JSON.stringify(e)); - } - } - - /** - * Encodes a successful result into a JSON envelope. - * @param result - The result value, possibly null - * @returns The encoded envelope as an ArrayBuffer - */ - encodeSuccessEnvelope(result: Any): ArrayBuffer { - return JSONMessageCodec.INSTANCE.encodeMessage([result]); - } - - /** - * Encodes an error result into a JSON envelope. - * @param errorCode - The error code - * @param errorMessage - The error message, possibly null - * @param errorDetails - Error details, possibly null - * @returns The encoded envelope as an ArrayBuffer - */ - encodeErrorEnvelope(errorCode: Any, errorMessage: string, errorDetails: Any): ArrayBuffer { - return JSONMessageCodec.INSTANCE.encodeMessage([errorCode, errorMessage, errorDetails]); - } - - /** - * Encodes an error result into a JSON envelope with stacktrace. - * @param errorCode - The error code - * @param errorMessage - The error message, possibly null - * @param errorDetails - Error details, possibly null - * @param errorStacktrace - The platform stacktrace, possibly null - * @returns The encoded envelope as an ArrayBuffer - */ - encodeErrorEnvelopeWithStacktrace(errorCode: string, errorMessage: string, errorDetails: Any, - errorStacktrace: string): ArrayBuffer { - return JSONMessageCodec.INSTANCE.encodeMessage([errorCode, errorMessage, errorDetails, errorStacktrace]) - } - - /** - * Decodes a result envelope from JSON binary format. - * @param envelope - The binary envelope to decode - * @returns The decoded result value - * @throws FlutterException if the envelope contains an error - * @throws Error if the envelope is invalid - */ - decodeEnvelope(envelope: ArrayBuffer): Any { - try { - const json: Any = JSONMessageCodec.INSTANCE.decodeMessage(envelope); - if (json instanceof Array) { - if (json.length == 1) { - return json[0]; - } - if (json.length == 3) { - const code: string = json[0]; - const message: string = json[1]; - const details: Any = json[2]; - if (typeof code == 'string' && (message == null || typeof message == 'string')) { - throw new FlutterException(code, message, details); - } - } - } - throw new Error("Invalid envelope: " + json); - } catch (e) { - throw new Error("Invalid JSON"); - } - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec.ets deleted file mode 100644 index cbd3690..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec.ets +++ /dev/null @@ -1,29 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on MessageCodec.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -/** - * A message encoding/decoding mechanism. - * @template T - The type of message being encoded/decoded - */ -export default interface MessageCodec { - /** - * Encodes the specified message into binary. - * @param message - The message to encode - * @returns The encoded message as an ArrayBuffer - */ - encodeMessage(message: T): ArrayBuffer; - - /** - * Decodes the specified message from binary. - * @param message - The binary message to decode, possibly null - * @returns The decoded message - */ - decodeMessage(message: ArrayBuffer | null): T; -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCall.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCall.ets deleted file mode 100644 index de9e96e..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCall.ets +++ /dev/null @@ -1,76 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on MethodCall.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import ToolUtils from '../../util/ToolUtils'; -import TreeMap from '@ohos.util.TreeMap'; -import HashMap from '@ohos.util.HashMap'; -import LightWeightMap from '@ohos.util.LightWeightMap'; -import Any from './Any'; - -/** - * Command object representing a method call on a MethodChannel. - */ -export default class MethodCall { - /** The name of the called method. */ - method: string; - /** - * Arguments for the call. - * - * Consider using the argument() method for cases where a particular run-time type is expected. - * Consider using argument(key) when that run-time type is Map or Object. - */ - args: Any; - - /** - * Constructs a new MethodCall instance. - * @param method - The name of the method to call - * @param args - The arguments for the method call - */ - constructor(method: string, args: Any) { - this.method = method; - this.args = args; - } - - /** - * Gets an argument value by key. - * @param key - The argument key - * @returns The argument value, or null if not found - * @throws Error if the args cannot be cast to a Map or Object - */ - argument(key: string): Any { - if (this.args == null) { - return null; - } else if (this.args instanceof Map) { - return (this.args as Map).get(key); - } else if (ToolUtils.isObj(this.args)) { - return this.args[key]; - } else { - throw new Error("ClassCastException"); - } - } - - /** - * Checks if an argument exists for the given key. - * @param key - The argument key to check - * @returns True if the argument exists, false otherwise - * @throws Error if the args cannot be cast to a Map or Object - */ - hasArgument(key: string): boolean { - if (this.args == null) { - return false; - } else if (this.args instanceof Map) { - return (this.args as Map).has(key); - } else if (ToolUtils.isObj(this.args)) { - return this.args.hasOwnProperty(key); - } else { - throw new Error("ClassCastException"); - } - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel.ets deleted file mode 100644 index b8fcab6..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel.ets +++ /dev/null @@ -1,231 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on MethodChannel.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import Log from '../../util/Log'; -import MessageChannelUtils from '../../util/MessageChannelUtils'; -import StringUtils from '../../util/StringUtils'; -import { BinaryMessageHandler, BinaryMessenger, BinaryReply } from './BinaryMessenger'; -import Any from './Any'; -import MethodCall from './MethodCall'; -import MethodCodec from './MethodCodec'; -import StandardMethodCodec from './StandardMethodCodec'; - -/** - * A named channel for communicating with the Flutter application using asynchronous method calls. - * - * Incoming method calls are decoded from binary on receipt, and results are encoded into - * binary before being transmitted back to Flutter. The {@link MethodCodec} used must be compatible - * with the one used by the Flutter application. This can be achieved by creating a `MethodChannel` counterpart of this - * channel on the Dart side. The type of method call arguments and results is {@code Any}, - * but only values supported by the specified {@link MethodCodec} can be used. - * - * The logical identity of the channel is given by its name. Identically named channels will - * interfere with each other's communication. - */ - -export default class MethodChannel { - /** Tag for logging. */ - static TAG = "MethodChannel#"; - private messenger: BinaryMessenger; - private name: string; - private codec: MethodCodec; - - /** - * Constructs a new MethodChannel instance. - * @param messenger - The BinaryMessenger to use for communication - * @param name - The channel name - * @param codec - The MethodCodec to use for encoding/decoding, defaults to StandardMethodCodec.INSTANCE - */ - constructor(messenger: BinaryMessenger, name: string, codec: MethodCodec = StandardMethodCodec.INSTANCE) { - this.messenger = messenger - this.name = name - this.codec = codec - } - - /** - * Invokes a method on this channel, optionally expecting a result. - * - * Any uncaught exception thrown by the result callback will be caught and logged. - * - * @param method - The name of the method - * @param args - The arguments for the invocation, possibly null - * @param callback - A {@link MethodResult} callback for the invocation result, or null - */ - invokeMethod(method: string, args: Any, callback?: MethodResult): void { - this.messenger.send(this.name, this.codec.encodeMethodCall(new MethodCall(method, args)), - callback == null ? null : new IncomingResultHandler(callback, this.codec)); - } - - /** - * Registers a method call handler on this channel. - * - * Overrides any existing handler registration for (the name of) this channel. - * - * If no handler has been registered, any incoming method call on this channel will be handled - * silently by sending a null reply. This results in a `MissingPluginException` on the Dart side, unless an - * `OptionalMethodChannel` is used. - * - * @param handler - A {@link MethodCallHandler}, or null to deregister - */ - setMethodCallHandler(handler: MethodCallHandler | null): void { - this.messenger.setMessageHandler(this.name, - handler == null ? null : new IncomingMethodCallHandler(handler, this.codec)); - } - - /** - * Adjusts the number of messages that will get buffered when sending messages to channels that - * aren't fully set up yet. For example, the engine isn't running yet or the channel's message - * handler isn't set up on the Dart side yet. - * @param newSize - The new buffer size - */ - resizeChannelBuffer(newSize: number): void { - MessageChannelUtils.resizeChannelBuffer(this.messenger, this.name, newSize); - } -} - -/** A handler of incoming method calls. */ -export interface MethodCallHandler { - /** - * Handles the specified method call received from Flutter. - * - * Handler implementations must submit a result for all incoming calls, by making a single - * call on the given {@link MethodResult} callback. Failure to do so will result in lingering Flutter - * result handlers. The result may be submitted asynchronously and on any thread. Calls to - * unknown or unimplemented methods should be handled using the notImplemented method of {@link MethodResult}. - * - * Any uncaught exception thrown by this method will be caught by the channel implementation - * and logged, and an error result will be sent back to Flutter. - * - * The handler is called on the platform thread (OpenHarmony main thread) by default, or otherwise on the thread - * specified by the {@link TaskQueue} provided to the associated {@link MethodChannel} when it was created. - * - * @param call - A {@link MethodCall} - * @param result - A {@link MethodResult} used for submitting the result of the call - */ - onMethodCall(call: MethodCall, result: MethodResult): void; -} - -/** - * Method call result callback. Supports dual use: Implementations of methods to be invoked by - * Flutter act as clients of this interface for sending results back to Flutter. Invokers of - * Flutter methods provide implementations of this interface for handling results received from - * Flutter. - * - * All methods of this class can be invoked on any thread. - */ -export interface MethodResult { - /** - * Handles a successful result. - * - * @param result - The result, possibly null. The result must be an Object type supported by the - * codec. For instance, if you are using {@link StandardMessageCodec} (default), please see - * its documentation on what types are supported. - */ - success: (result: Any) => void; - - /** - * Handles an error result. - * - * @param errorCode - An error code string - * @param errorMessage - A human-readable error message, possibly null - * @param errorDetails - Error details, possibly null. The details must be an Object type - * supported by the codec. For instance, if you are using {@link StandardMessageCodec} - * (default), please see its documentation on what types are supported. - */ - error: (errorCode: string, errorMessage: string, errorDetails: Any) => void; - - /** Handles a call to an unimplemented method. */ - notImplemented: () => void; -} - -/** - * Internal handler for incoming method call results from Flutter. - */ -export class IncomingResultHandler implements BinaryReply { - private callback: MethodResult; - private codec: MethodCodec; - - /** - * Constructs a new IncomingResultHandler instance. - * @param callback - The MethodResult callback to invoke - * @param codec - The MethodCodec to use for decoding - */ - constructor(callback: MethodResult, codec: MethodCodec) { - this.callback = callback; - this.codec = codec - } - - /** - * Handles a binary reply from Flutter. - * @param reply - The binary reply, possibly null - */ - reply(reply: ArrayBuffer | null): void { - try { - if (reply == null) { - this.callback.notImplemented(); - } else { - try { - this.callback.success(this.codec.decodeEnvelope(reply)); - } catch (e) { - this.callback.error(e.code, e.getMessage(), e.details); - } - } - } catch (e) { - Log.e(MethodChannel.TAG, "Failed to handle method call result", e); - } - } -} - -/** - * Internal handler for incoming method calls from Flutter. - */ -export class IncomingMethodCallHandler implements BinaryMessageHandler { - private handler: MethodCallHandler; - private codec: MethodCodec; - - /** - * Constructs a new IncomingMethodCallHandler instance. - * @param handler - The MethodCallHandler to delegate to - * @param codec - The MethodCodec to use for encoding/decoding - */ - constructor(handler: MethodCallHandler, codec: MethodCodec) { - this.handler = handler; - this.codec = codec - } - - /** - * Handles a binary method call from Flutter. - * @param message - The binary message containing the method call - * @param reply - The BinaryReply callback to send a response - */ - onMessage(message: ArrayBuffer, reply: BinaryReply): void { - const call = this.codec.decodeMethodCall(message); - try { - this.handler.onMethodCall( - call, { - success: (result: Any): void => { - reply.reply(this.codec.encodeSuccessEnvelope(result)); - }, - - error: (errorCode: string, errorMessage: string, errorDetails: Any): void => { - reply.reply(this.codec.encodeErrorEnvelope(errorCode, errorMessage, errorDetails)); - }, - - notImplemented: (): void => { - Log.w(MethodChannel.TAG, "method not implemented"); - reply.reply(null); - } - }); - } catch (e) { - Log.e(MethodChannel.TAG, "Failed to handle method call", e); - reply.reply(this.codec.encodeErrorEnvelopeWithStacktrace("error", e.getMessage(), null, e)); - } - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCodec.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCodec.ets deleted file mode 100644 index 00efea1..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCodec.ets +++ /dev/null @@ -1,79 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on MethodCodec.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ -import Any from './Any'; - -import MethodCall from './MethodCall'; - -/** - * A codec for method calls and enveloped results. - * - * Method calls are encoded as binary messages with enough structure that the codec can extract a - * method name and arguments. These data items are used to populate a {@link MethodCall}. - * - * All operations throw an Error if conversion fails. - */ -export default interface MethodCodec { - /** - * Encodes a message call into binary. - * - * @param methodCall - A {@link MethodCall} - * @returns An {@link ArrayBuffer} containing the encoded method call - */ - encodeMethodCall(methodCall: MethodCall): ArrayBuffer; - - /** - * Decodes a message call from binary. - * - * @param methodCall - The binary encoding of the method call as an {@link ArrayBuffer} - * @returns A {@link MethodCall} representation of the binary data - */ - decodeMethodCall(methodCall: ArrayBuffer): MethodCall; - - /** - * Encodes a successful result into a binary envelope message. - * - * @param result - The result value, possibly null - * @returns An {@link ArrayBuffer} containing the encoded envelope - */ - encodeSuccessEnvelope(result: Any): ArrayBuffer; - - /** - * Encodes an error result into a binary envelope message. - * - * @param errorCode - An error code string - * @param errorMessage - An error message string, possibly null - * @param errorDetails - Error details, possibly null. Consider supporting {@link Error} in your - * codec. This is the most common value passed to this field. - * @returns An {@link ArrayBuffer} containing the encoded envelope - */ - encodeErrorEnvelope(errorCode: string, errorMessage: string, errorDetails: Any): ArrayBuffer; - - /** - * Encodes an error result into a binary envelope message with the native stacktrace. - * - * @param errorCode - An error code string - * @param errorMessage - An error message string, possibly null - * @param errorDetails - Error details, possibly null. Consider supporting {@link Error} in your - * codec. This is the most common value passed to this field. - * @param errorStacktrace - Platform stacktrace for the error, possibly null - * @returns An {@link ArrayBuffer} containing the encoded envelope - */ - encodeErrorEnvelopeWithStacktrace(errorCode: string, errorMessage: string, errorDetails: Any, - errorStacktrace: string): ArrayBuffer - - /** - * Decodes a result envelope from binary. - * - * @param envelope - The binary encoding of a result envelope as an {@link ArrayBuffer} - * @returns The enveloped result value - * @throws FlutterException if the envelope was an error envelope - */ - decodeEnvelope(envelope: ArrayBuffer): Any -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableBinaryCodec.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableBinaryCodec.ets deleted file mode 100644 index 5a174d5..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableBinaryCodec.ets +++ /dev/null @@ -1,63 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on BinaryCodec.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import SendableMessageCodec from './SendableMessageCodec'; - -/** - * A {@link SendableMessageCodec} using unencoded binary messages, represented as {@link ArrayBuffer}s. - * - * This codec is guaranteed to be compatible with the corresponding `BinaryCodec` on the - * Dart side. These parts of the Flutter SDK are evolved synchronously. - * - * On the Dart side, messages are represented using {@code ByteData}. - */ - -/** - * A sendable MessageCodec using unencoded binary messages. - * This codec can be used in background threads and worker contexts. - */ -@Sendable -export default class SendableBinaryCodec implements SendableMessageCodec { - private returnsDirectByteBufferFromDecoding: boolean = false; - /** Direct instance that returns the direct buffer from decoding. */ - static readonly INSTANCE_DIRECT: SendableBinaryCodec = new SendableBinaryCodec(true); - - /** - * Constructs a new SendableBinaryCodec instance. - * @param returnsDirectByteBufferFromDecoding - Whether to return the direct buffer from decoding - */ - constructor(returnsDirectByteBufferFromDecoding: boolean) { - this.returnsDirectByteBufferFromDecoding = returnsDirectByteBufferFromDecoding; - } - - /** - * Encodes a binary message (no-op for binary codec). - * @param message - The ArrayBuffer message to encode - * @returns The same ArrayBuffer - */ - encodeMessage(message: ArrayBuffer): ArrayBuffer { - return message - } - - /** - * Decodes a binary message. - * @param message - The ArrayBuffer message to decode, possibly null - * @returns The decoded ArrayBuffer, or a copy depending on configuration - */ - decodeMessage(message: ArrayBuffer | null): ArrayBuffer { - if (message == null) { - return new ArrayBuffer(0); - } else if (this.returnsDirectByteBufferFromDecoding) { - return message; - } else { - return message.slice(0, message.byteLength); - } - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableBinaryMessageHandler.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableBinaryMessageHandler.ets deleted file mode 100644 index 10a9c05..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableBinaryMessageHandler.ets +++ /dev/null @@ -1,23 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ -import { lang } from '@kit.ArkTS'; -import { BinaryReply } from './BinaryMessenger'; - -type ISendable = lang.ISendable; - -/** - * Interface for sendable binary message handlers that can be used in background threads. - * This interface extends ISendable to allow handlers to be passed across thread boundaries. - */ -export default interface SendableBinaryMessageHandler extends ISendable { - /** - * Handles a binary message received from Flutter. - * @param message - The binary message received - * @param reply - The reply callback to send a response - * @param args - Additional arguments passed to the handler - */ - onMessage(message: ArrayBuffer, reply: BinaryReply, ...args: Object[]): void; -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableJSONMessageCodec.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableJSONMessageCodec.ets deleted file mode 100644 index 6870cba..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableJSONMessageCodec.ets +++ /dev/null @@ -1,116 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on JSONMessageCodec.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ -import StringUtils from '../../util/StringUtils'; - -import SendableMessageCodec from './SendableMessageCodec'; -import StringCodec from './StringCodec'; -import TreeMap from '@ohos.util.TreeMap'; -import HashMap from '@ohos.util.HashMap'; -import LightWeightMap from '@ohos.util.LightWeightMap'; -import PlainArray from '@ohos.util.PlainArray'; -import List from '@ohos.util.List'; -import LinkedList from '@ohos.util.LinkedList'; -import Any from './Any'; - -/** - * A {@link SendableMessageCodec} using UTF-8 encoded JSON messages. - * - * This codec is guaranteed to be compatible with the corresponding `JSONMessageCodec` on - * the Dart side. These parts of the Flutter SDK are evolved synchronously. - * - * On the Dart side, JSON messages are handled by the JSON facilities of the `dart:convert` package. - */ -/** - * A sendable MessageCodec using UTF-8 encoded JSON messages. - * This codec can be used in background threads and worker contexts. - */ -@Sendable -export default class SendableJSONMessageCodec implements SendableMessageCodec { - /** Singleton instance of SendableJSONMessageCodec. */ - static INSTANCE: SendableJSONMessageCodec = new SendableJSONMessageCodec(); - - /** - * Encodes a message into JSON binary format. - * @param message - The message to encode, possibly null - * @returns The encoded message as an ArrayBuffer - */ - encodeMessage(message: Any): ArrayBuffer { - if (message == null) { - return StringUtils.stringToArrayBuffer(""); - } - return StringCodec.INSTANCE.encodeMessage(JSON.stringify(this.toBaseData(message))); - } - - /** - * Decodes a binary message from JSON format. - * @param message - The binary message to decode, possibly null - * @returns The decoded message object - * @throws Error if the JSON is invalid - */ - decodeMessage(message: ArrayBuffer | null): Any { - if (message == null) { - return StringUtils.stringToArrayBuffer(""); - } - try { - const jsonStr = StringCodec.INSTANCE.decodeMessage(message); - let jsonObj: Record = JSON.parse(jsonStr); - if (jsonObj instanceof Object) { - const list = Object.keys(jsonObj); - if (list.includes('args')) { - let args: Any = jsonObj['args']; - if (args instanceof Object && !(args instanceof Array)) { - let argsMap: Map = new Map(); - Object.keys(args).forEach(key => { - argsMap.set(key, args[key]); - }) - jsonObj['args'] = argsMap; - } - } - } - return jsonObj; - } catch (e) { - throw new Error("Invalid JSON"); - } - } - - /** - * Converts a message to base data types suitable for JSON serialization. - * @param message - The message to convert - * @returns The converted message with base data types - */ - toBaseData(message: Any): Any { - if (message == null || message == undefined) { - return ""; - } else if (message instanceof List || message instanceof LinkedList) { - return this.toBaseData(message.convertToArray()); - } else if (message instanceof Map || message instanceof HashMap || message instanceof TreeMap - || message instanceof LightWeightMap || message instanceof PlainArray) { - let messageObj: Any = {}; - message.forEach((value: Any, key: Any) => { - messageObj[this.toBaseData(key)] = this.toBaseData(value); - }); - return messageObj; - } else if (message instanceof Array) { - let messageArr: Array = []; - message.forEach((value: Any) => { - messageArr.push(this.toBaseData(value)); - }) - return messageArr; - } else if (message instanceof Object) { - let messageObj: Any = {}; - Object.keys(message).forEach((key: Any) => { - messageObj[this.toBaseData(key)] = this.toBaseData(message[key]); - }) - return messageObj; - } else { - return message; - } - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableJSONMethodCodec.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableJSONMethodCodec.ets deleted file mode 100644 index 250b1c9..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableJSONMethodCodec.ets +++ /dev/null @@ -1,135 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on JSONMethodCodec.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ -import ToolUtils from '../../util/ToolUtils'; -import FlutterException from './FlutterException'; -import Any from './Any'; -import SendableJSONMessageCodec from './SendableJSONMessageCodec'; -import MethodCall from './MethodCall'; -import SendableMethodCodec from './SendableMethodCodec'; - -/** - * A {@link SendableMethodCodec} using UTF-8 encoded JSON method calls and result envelopes. - * - * This codec is guaranteed to be compatible with the corresponding `JSONMethodCodec` on - * the Dart side. These parts of the Flutter SDK are evolved synchronously. - * - * Values supported as methods arguments and result payloads are those supported by {@link SendableJSONMessageCodec}. - */ -/** - * A sendable MethodCodec using UTF-8 encoded JSON method calls and result envelopes. - * This codec can be used in background threads and worker contexts. - */ -@Sendable -export default class SendableJSONMethodCodec implements SendableMethodCodec { - /** Singleton instance of SendableJSONMethodCodec. */ - static INSTANCE: SendableJSONMethodCodec = new SendableJSONMethodCodec(); - - /** - * Encodes a method call into JSON binary format. - * @param methodCall - The MethodCall to encode - * @returns The encoded method call as an ArrayBuffer - * @throws Error if encoding fails - */ - encodeMethodCall(methodCall: MethodCall): ArrayBuffer { - try { - const map: Record = { - "method": methodCall.method, "args": methodCall.args - } - - return SendableJSONMessageCodec.INSTANCE.encodeMessage(map); - } catch (e) { - throw new Error("Invalid JSON"); - } - } - - /** - * Decodes a method call from JSON binary format. - * @param message - The binary message to decode - * @returns The decoded MethodCall - * @throws Error if decoding fails or the message is invalid - */ - decodeMethodCall(message: ArrayBuffer): MethodCall { - try { - const json: Any = SendableJSONMessageCodec.INSTANCE.decodeMessage(message); - if (ToolUtils.isObj(json)) { - const method: string = json["method"]; - const args: Any = json["args"]; - if (typeof method == 'string') { - return new MethodCall(method, args); - } - } - throw new Error("Invalid method call: " + json); - } catch (e) { - throw new Error("Invalid JSON:" + JSON.stringify(e)); - } - } - - /** - * Encodes a successful result into a JSON envelope. - * @param result - The result value, possibly null - * @returns The encoded envelope as an ArrayBuffer - */ - encodeSuccessEnvelope(result: Any): ArrayBuffer { - return SendableJSONMessageCodec.INSTANCE.encodeMessage([result]); - } - - /** - * Encodes an error result into a JSON envelope. - * @param errorCode - The error code - * @param errorMessage - The error message, possibly null - * @param errorDetails - Error details, possibly null - * @returns The encoded envelope as an ArrayBuffer - */ - encodeErrorEnvelope(errorCode: Any, errorMessage: string, errorDetails: Any) { - return SendableJSONMessageCodec.INSTANCE.encodeMessage([errorCode, errorMessage, errorDetails]); - } - - /** - * Encodes an error result into a JSON envelope with stacktrace. - * @param errorCode - The error code - * @param errorMessage - The error message, possibly null - * @param errorDetails - Error details, possibly null - * @param errorStacktrace - The platform stacktrace, possibly null - * @returns The encoded envelope as an ArrayBuffer - */ - encodeErrorEnvelopeWithStacktrace(errorCode: string, errorMessage: string, errorDetails: Any, - errorStacktrace: string): ArrayBuffer { - return SendableJSONMessageCodec.INSTANCE.encodeMessage([errorCode, errorMessage, errorDetails, errorStacktrace]) - } - - /** - * Decodes a result envelope from JSON binary format. - * @param envelope - The binary envelope to decode - * @returns The decoded result value - * @throws FlutterException if the envelope contains an error - * @throws Error if the envelope is invalid - */ - decodeEnvelope(envelope: ArrayBuffer): Any { - try { - const json: Any = SendableJSONMessageCodec.INSTANCE.decodeMessage(envelope); - if (json instanceof Array) { - if (json.length == 1) { - return json[0]; - } - if (json.length == 3) { - const code: string = json[0]; - const message: string = json[1]; - const details: Any = json[2]; - if (typeof code == 'string' && (message == null || typeof message == 'string')) { - throw new FlutterException(code, message, details); - } - } - } - throw new Error("Invalid envelope: " + json); - } catch (e) { - throw new Error("Invalid JSON"); - } - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableMessageCodec.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableMessageCodec.ets deleted file mode 100644 index 953de40..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableMessageCodec.ets +++ /dev/null @@ -1,33 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on MessageCodec.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ -import { lang } from '@kit.ArkTS'; - -type ISendable = lang.ISendable; - -/** - * Interface for sendable message codecs that can be used in background threads. - * This interface extends ISendable to allow codecs to be passed across thread boundaries. - * @template T - The type of message being encoded/decoded - */ -export default interface SendableMessageCodec extends ISendable { - /** - * Encodes the specified message into binary. - * @param message - The message to encode - * @returns The encoded message as an ArrayBuffer - */ - encodeMessage(message: T): ArrayBuffer; - - /** - * Decodes the specified message from binary. - * @param message - The binary message to decode, possibly null - * @returns The decoded message - */ - decodeMessage(message: ArrayBuffer | null): T; -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableMessageHandler.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableMessageHandler.ets deleted file mode 100644 index 763067b..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableMessageHandler.ets +++ /dev/null @@ -1,23 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ -import { lang } from '@kit.ArkTS'; -import { Reply } from './BasicMessageChannel'; - -type ISendable = lang.ISendable; - -/** - * Interface for sendable message handlers that can be used in background threads. - * This interface extends ISendable to allow handlers to be passed across thread boundaries. - * @template T - The type of message being handled - */ -export default interface SendableMessageHandler extends ISendable { - /** - * Handles a message received from Flutter. - * @param message - The message received - * @param reply - The reply callback to send a response - */ - onMessage(message: T, reply: Reply): void; -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableMethodCallHandler.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableMethodCallHandler.ets deleted file mode 100644 index 2d9be00..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableMethodCallHandler.ets +++ /dev/null @@ -1,38 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ -import { lang } from '@kit.ArkTS'; - -import MethodCall from './MethodCall'; -import { MethodResult } from './MethodChannel'; - -type ISendable = lang.ISendable; - -/** - * Interface for sendable method call handlers that can be used in background threads. - * This interface extends ISendable to allow handlers to be passed across thread boundaries. - */ -export default interface SendableMethodCallHandler extends ISendable { - /** - * Handles the specified method call received from Flutter. - * - * Handler implementations must submit a result for all incoming calls, by making a single - * call on the given {@link MethodResult} callback. Failure to do so will result in lingering Flutter - * result handlers. The result may be submitted asynchronously and on any thread. Calls to - * unknown or unimplemented methods should be handled using {@link MethodResult#notImplemented()}. - * - * Any uncaught exception thrown by this method will be caught by the channel implementation - * and logged, and an error result will be sent back to Flutter. - * - * The handler is called on the platform thread (OpenHarmony main thread) by default, or - * otherwise on the thread specified by the {@link BinaryMessenger.TaskQueue} provided to the - * associated {@link MethodChannel} when it was created. - * - * @param call - A {@link MethodCall} - * @param result - A {@link MethodResult} used for submitting the result of the call - * @param args - Additional arguments - */ - onMethodCall(call: MethodCall, result: MethodResult, ...args: Object[]): void; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableMethodCodec.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableMethodCodec.ets deleted file mode 100644 index d7f9e69..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableMethodCodec.ets +++ /dev/null @@ -1,82 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on MethodCodec.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ -import { lang } from '@kit.ArkTS'; - -import Any from './Any'; -import MethodCall from './MethodCall'; - -/** - * A codec for method calls and enveloped results. - * - * Method calls are encoded as binary messages with enough structure that the codec can extract a - * method name and arguments. These data items are used to populate a {@link MethodCall}. - * - * All operations throw an Error if conversion fails. - */ -type ISendable = lang.ISendable; - -export default interface SendableMethodCodec extends ISendable { - /** - * Encodes a message call into binary. - * - * @param methodCall - A {@link MethodCall} - * @returns An {@link ArrayBuffer} containing the encoded method call - */ - encodeMethodCall(methodCall: MethodCall): ArrayBuffer; - - /** - * Decodes a message call from binary. - * - * @param methodCall - The binary encoding of the method call as an {@link ArrayBuffer} - * @returns A {@link MethodCall} representation of the binary data - */ - decodeMethodCall(methodCall: ArrayBuffer): MethodCall; - - /** - * Encodes a successful result into a binary envelope message. - * - * @param result - The result value, possibly null - * @returns An {@link ArrayBuffer} containing the encoded envelope - */ - encodeSuccessEnvelope(result: Any): ArrayBuffer; - - /** - * Encodes an error result into a binary envelope message. - * - * @param errorCode - An error code string - * @param errorMessage - An error message string, possibly null - * @param errorDetails - Error details, possibly null. Consider supporting {@link Error} in your - * codec. This is the most common value passed to this field. - * @returns An {@link ArrayBuffer} containing the encoded envelope - */ - encodeErrorEnvelope(errorCode: string, errorMessage: string, errorDetails: Any): ArrayBuffer; - - /** - * Encodes an error result into a binary envelope message with the native stacktrace. - * - * @param errorCode - An error code string - * @param errorMessage - An error message string, possibly null - * @param errorDetails - Error details, possibly null. Consider supporting {@link Error} in your - * codec. This is the most common value passed to this field. - * @param errorStacktrace - Platform stacktrace for the error, possibly null - * @returns An {@link ArrayBuffer} containing the encoded envelope - */ - encodeErrorEnvelopeWithStacktrace(errorCode: string, errorMessage: string, errorDetails: Any, - errorStacktrace: string): ArrayBuffer; - - /** - * Decodes a result envelope from binary. - * - * @param envelope - The binary encoding of a result envelope as an {@link ArrayBuffer} - * @returns The enveloped result value - * @throws FlutterException if the envelope was an error envelope - */ - decodeEnvelope(envelope: ArrayBuffer): Any; -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableStandardMessageCodec.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableStandardMessageCodec.ets deleted file mode 100644 index f1e2278..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableStandardMessageCodec.ets +++ /dev/null @@ -1,413 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on StandardMessageCodec.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import Any from './Any'; - -import { ByteBuffer } from '../../util/ByteBuffer'; -import SendableMessageCodec from './SendableMessageCodec'; -import StringUtils from '../../util/StringUtils'; -import TreeMap from '@ohos.util.TreeMap'; -import HashMap from '@ohos.util.HashMap'; -import LightWeightMap from '@ohos.util.LightWeightMap'; -import PlainArray from '@ohos.util.PlainArray'; -import List from '@ohos.util.List'; -import LinkedList from '@ohos.util.LinkedList'; - -/** - * MessageCodec using the Flutter standard binary encoding. - * - * This codec is guaranteed to be compatible with the corresponding `SendableStandardMessageCodec` - * on the Dart side. These parts of the Flutter SDK are evolved synchronously. - * - * Supported messages are acyclic values of these forms: - * null - * Booleans - * number - * BigIntegers (see below) - * Int8Array, Int32Array, Float32Array, Float64Array - * Strings - * Array[] - * Lists of supported values - * Maps with supported keys and values - * - * On the Dart side, these values are represented as follows: - * null: null - * Boolean: bool - * Byte, Short, Integer, Long: int - * Float, Double: double - * String: String - * byte[]: Uint8List - * int[]: Int32List - * long[]: Int64List - * float[]: Float32List - * double[]: Float64List - * List: List - * Map: Map - * - * BigIntegers are represented in Dart as strings with the hexadecimal representation of the - * integer's value. - * - * To extend the codec, overwrite the writeValue and readValueOfType methods. - */ -/** - * A sendable MessageCodec using the Flutter standard binary encoding. - * This codec can be used in background threads and worker contexts. - */ -@Sendable -export default class SendableStandardMessageCodec implements SendableMessageCodec { - /** Singleton instance of SendableStandardMessageCodec. */ - static INSTANCE: SendableStandardMessageCodec = new SendableStandardMessageCodec(); - - /** - * Encodes a message into binary format using the standard encoding. - * @param message - The message to encode - * @returns The encoded message as an ArrayBuffer - */ - encodeMessage(message: Any): ArrayBuffer { - const stream = ByteBuffer.from(new ArrayBuffer(1024)) - this.writeValue(stream, message); - return stream.buffer - } - - /** - * Decodes a binary message from the standard encoding. - * @param message - The binary message to decode, possibly null - * @returns The decoded message - */ - decodeMessage(message: ArrayBuffer | null): Any { - if (message == null) { - return null - } - const buffer = ByteBuffer.from(message) - return this.readValue(buffer) - } - - private static NULL: number = 0; - private static TRUE: number = 1; - private static FALSE: number = 2; - private static INT32: number = 3; - private static INT64: number = 4; - private static BIGINT: number = 5; - private static FLOAT64: number = 6; - private static STRING: number = 7; - private static UINT8_ARRAY: number = 8; - private static INT32_ARRAY: number = 9; - private static INT64_ARRAY: number = 10; - private static FLOAT64_ARRAY: number = 11; - private static LIST: number = 12; - private static MAP: number = 13; - private static FLOAT32_ARRAY: number = 14; - - /** - * Writes a value to the byte buffer using the standard encoding. - * @param stream - The ByteBuffer to write to - * @param value - The value to write - * @returns The ByteBuffer stream - */ - writeValue(stream: ByteBuffer, value: Any): Any { - if (value == null || value == undefined) { - stream.writeInt8(SendableStandardMessageCodec.NULL); - } else if (typeof value === "boolean") { - stream.writeInt8(value ? SendableStandardMessageCodec.TRUE : SendableStandardMessageCodec.FALSE) - } else if (typeof value === "number") { - if (Number.isInteger(value)) { //整型 - if (-0x7fffffff - 1 <= value && value <= 0x7fffffff) { //int32 - stream.writeInt8(SendableStandardMessageCodec.INT32); - stream.writeInt32(value, true); - } else if (Number.MIN_SAFE_INTEGER <= value && value <= Number.MAX_SAFE_INTEGER) { //int64 number整型取值范围 - stream.writeInt8(SendableStandardMessageCodec.INT64); - stream.writeInt64(value, true); - } else { //被判为整型的double型 - stream.writeInt8(SendableStandardMessageCodec.FLOAT64); - this.writeAlignment(stream, 8); - stream.writeFloat64(value, true); - } - } else { //浮点型 - stream.writeInt8(SendableStandardMessageCodec.FLOAT64); - this.writeAlignment(stream, 8); - stream.writeFloat64(value, true); - } - } else if (typeof value === "bigint") { - // - // The format is first the type byte (0x05), then the actual number - // as an ASCII string giving the hexadecimal representation of the - // integer, with the string's length as encoded by writeSize - // followed by the string bytes. - stream.writeInt8(SendableStandardMessageCodec.BIGINT); - // Convert bigint to a hexadecimal string - const hexString = value.toString(16); - // Map each character in the hexadecimal string to its ASCII code - const asciiString = hexString.split('').map(char => char.charCodeAt(0)); - this.writeBytes(stream, Uint8Array.from(asciiString)); - } else if (typeof value === "string") { - stream.writeInt8(SendableStandardMessageCodec.STRING); - let stringBuff = StringUtils.stringToArrayBuffer(value); - this.writeBytes(stream, new Uint8Array(stringBuff)); - } else if (value instanceof Uint8Array) { - stream.writeInt8(SendableStandardMessageCodec.UINT8_ARRAY); - this.writeBytes(stream, value) - } else if (value instanceof Int32Array) { - stream.writeInt8(SendableStandardMessageCodec.INT32_ARRAY); - this.writeSize(stream, value.length); - this.writeAlignment(stream, 4); - value.forEach(item => stream.writeInt32(item, true)); - } else if (value instanceof BigInt64Array) { - stream.writeInt8(SendableStandardMessageCodec.INT64_ARRAY); - this.writeSize(stream, value.length); - this.writeAlignment(stream, 8); - value.forEach(item => stream.writeBigInt64(item, true)); - } else if (value instanceof Float32Array) { - stream.writeInt8(SendableStandardMessageCodec.FLOAT32_ARRAY); - this.writeSize(stream, value.length); - this.writeAlignment(stream, 4); - value.forEach(item => stream.writeFloat32(item, true)); - } else if (value instanceof Float64Array) { - stream.writeInt8(SendableStandardMessageCodec.FLOAT64_ARRAY); - this.writeSize(stream, value.length); - this.writeAlignment(stream, 8); - value.forEach(item => stream.writeFloat64(item, true)); - } else if (value instanceof Array || value instanceof Int8Array || value instanceof Int16Array - || value instanceof Uint16Array || value instanceof Uint32Array || value instanceof List - || value instanceof LinkedList) { - stream.writeInt8(SendableStandardMessageCodec.LIST) - this.writeSize(stream, value.length); - value.forEach((item: Any): void => this.writeValue(stream, item)); - } else if (value instanceof Map) { - stream.writeInt8(SendableStandardMessageCodec.MAP); - this.writeSize(stream, value.size); - value.forEach((value: Any, key: Any) => { - this.writeValue(stream, key); - this.writeValue(stream, value); - }); - } else if (value instanceof HashMap || value instanceof TreeMap || value instanceof LightWeightMap - || value instanceof PlainArray) { - stream.writeInt8(SendableStandardMessageCodec.MAP); - this.writeSize(stream, value.length); - value.forEach((value: Any, key: Any) => { - this.writeValue(stream, key); - this.writeValue(stream, value); - }); - } else if (typeof value == 'object') { - let map: Map = new Map(); - Object.keys(value).forEach(key => { - map.set(key, value[key]); - }); - this.writeValue(stream, map); - } else { - throw new Error("Unsupported value: " + value); - stream.writeInt8(SendableStandardMessageCodec.NULL); - } - return stream; - } - - /** - * Writes alignment padding to the stream. - * @param stream - The ByteBuffer to write to - * @param alignment - The alignment requirement (e.g., 4, 8) - */ - writeAlignment(stream: ByteBuffer, alignment: number) { - let mod: number = stream.byteOffset % alignment; - if (mod != 0) { - for (let i = 0; i < alignment - mod; i++) { - stream.writeInt8(0); - } - } - } - - /** - * Writes a size value to the stream using compact encoding. - * @param stream - The ByteBuffer to write to - * @param value - The size value to write - */ - writeSize(stream: ByteBuffer, value: number) { - if (value < 254) { - stream.writeUint8(value); - } else if (value <= 0xffff) { - stream.writeUint8(254); - stream.writeUint16(value, true); - } else { - stream.writeUint8(255); - stream.writeUint32(value, true); - } - } - - /** - * Writes a byte array to the stream. - * @param stream - The ByteBuffer to write to - * @param bytes - The byte array to write - */ - writeBytes(stream: ByteBuffer, bytes: Uint8Array) { - this.writeSize(stream, bytes.length) - stream.writeUint8Array(bytes); - } - - /** - * Reads a size value from the buffer using compact encoding. - * @param buffer - The ByteBuffer to read from - * @returns The size value - */ - readSize(buffer: ByteBuffer) { - let value = buffer.readUint8() & 0xff; - if (value < 254) { - return value; - } else if (value == 254) { - return buffer.readUint16(true); - } else { - return buffer.readUint32(true); - } - } - - /** - * Reads alignment padding from the buffer. - * @param buffer - The ByteBuffer to read from - * @param alignment - The alignment requirement (e.g., 4, 8) - */ - readAlignment(buffer: ByteBuffer, alignment: number) { - let mod = buffer.byteOffset % alignment; - if (mod != 0) { - buffer.skip(alignment - mod); - } - } - - /** - * Reads a value from the buffer using the standard encoding. - * @param buffer - The ByteBuffer to read from - * @returns The decoded value - */ - readValue(buffer: ByteBuffer): Any { - let type = buffer.readUint8() - return this.readValueOfType(type, buffer); - } - - /** - * Reads a byte array from the buffer. - * @param buffer - The ByteBuffer to read from - * @returns The byte array - */ - readBytes(buffer: ByteBuffer): Uint8Array { - let length = this.readSize(buffer); - let bytesBuffer = new ArrayBuffer(length); - let bytes = new Uint8Array(bytesBuffer); - bytes.set(buffer.readUint8Array(length)); - return bytes; - } - - /** - * Reads a value of a specific type from the buffer. - * @param type - The type code to read - * @param buffer - The ByteBuffer to read from - * @returns The decoded value - * @throws Error if the type is unknown or the message is corrupted - */ - readValueOfType(type: number, buffer: ByteBuffer): Any { - let result: Any; - switch (type) { - case SendableStandardMessageCodec.NULL: - result = null; - break; - case SendableStandardMessageCodec.TRUE: - result = true; - break; - case SendableStandardMessageCodec.FALSE: - result = false; - break; - case SendableStandardMessageCodec.INT32: - result = buffer.readInt32(true); - break; - case SendableStandardMessageCodec.INT64: - result = buffer.readInt64(true); - if (Number.MIN_SAFE_INTEGER <= result && result <= Number.MAX_SAFE_INTEGER) { - result = Number(result); - } - break; - case SendableStandardMessageCodec.BIGINT: - let bytes: Uint8Array = this.readBytes(buffer); - // Convert the byte array to a UTF-8 encoded string - const hexString: string = String.fromCharCode(...bytes); - // Parse the string as a hexadecimal BigInt - result = BigInt(`0x${hexString}`); - break; - case SendableStandardMessageCodec.FLOAT64: - this.readAlignment(buffer, 8); - result = buffer.readFloat64(true) - break; - case SendableStandardMessageCodec.STRING: { - let bytes: Uint8Array = this.readBytes(buffer); - result = StringUtils.uint8ArrayToString(bytes); - break; - } - case SendableStandardMessageCodec.UINT8_ARRAY: { - result = this.readBytes(buffer); - break; - } - case SendableStandardMessageCodec.INT32_ARRAY: { - let length = this.readSize(buffer); - let array = new Int32Array(length) - this.readAlignment(buffer, 4); - for (let i = 0; i < length; i++) { - array[i] = buffer.readInt32(true) - } - result = array; - break; - } - case SendableStandardMessageCodec.INT64_ARRAY: { - let length = this.readSize(buffer); - let array = new BigInt64Array(length) - this.readAlignment(buffer, 8); - for (let i = 0; i < length; i++) { - array[i] = buffer.readBigInt64(true) - } - result = array; - break; - } - case SendableStandardMessageCodec.FLOAT64_ARRAY: { - let length = this.readSize(buffer); - let array = new Float64Array(length) - this.readAlignment(buffer, 8); - for (let i = 0; i < length; i++) { - array[i] = buffer.readFloat64(true) - } - result = array; - break; - } - case SendableStandardMessageCodec.LIST: { - let length = this.readSize(buffer); - let array: Array = new Array(length) - for (let i = 0; i < length; i++) { - array[i] = this.readValue(buffer) - } - result = array; - break; - } - case SendableStandardMessageCodec.MAP: { - let size = this.readSize(buffer); - let map: Map = new Map() - for (let i = 0; i < size; i++) { - map.set(this.readValue(buffer), this.readValue(buffer)); - } - result = map; - break; - } - case SendableStandardMessageCodec.FLOAT32_ARRAY: { - let length = this.readSize(buffer); - let array = new Float32Array(length); - this.readAlignment(buffer, 4); - for (let i = 0; i < length; i++) { - array[i] = buffer.readFloat32(true) - } - result = array; - break; - } - default: - throw new Error("Message corrupted, type=" + type); - } - return result; - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableStandardMethodCodec.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableStandardMethodCodec.ets deleted file mode 100644 index dd31884..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableStandardMethodCodec.ets +++ /dev/null @@ -1,158 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on StandardMethodCodec.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import { ByteBuffer } from '../../util/ByteBuffer'; -import FlutterException from './FlutterException'; -import Any from './Any'; -import MethodCall from './MethodCall'; -import SendableMethodCodec from './SendableMethodCodec'; -import SendableStandardMessageCodec from './SendableStandardMessageCodec'; - -/** - * A {@link SendableMethodCodec} using the Flutter standard binary encoding. - * - * This codec is guaranteed to be compatible with the corresponding `StandardMethodCodec` - * on the Dart side. These parts of the Flutter SDK are evolved synchronously. - * - * Values supported as method arguments and result payloads are those supported by {@link StandardMessageCodec}. - */ -/** - * A sendable MethodCodec using the Flutter standard binary encoding. - * This codec can be used in background threads and worker contexts. - */ -@Sendable -export default class SendableStandardMethodCodec implements SendableMethodCodec { - private static TAG: string = "SendableStandardMethodCodec"; - /** Singleton instance of SendableStandardMethodCodec. */ - public static INSTANCE: SendableStandardMethodCodec = - new SendableStandardMethodCodec(SendableStandardMessageCodec.INSTANCE); - private messageCodec: SendableStandardMessageCodec; - - /** - * Creates a new method codec based on the specified message codec. - * @param messageCodec - The SendableStandardMessageCodec to use for encoding/decoding - */ - constructor(messageCodec: SendableStandardMessageCodec) { - this.messageCodec = messageCodec; - } - - /** - * Encodes a method call into binary format. - * @param methodCall - The MethodCall to encode - * @returns The encoded method call as an ArrayBuffer - */ - encodeMethodCall(methodCall: MethodCall): ArrayBuffer { - const stream = ByteBuffer.from(new ArrayBuffer(1024)); - this.messageCodec.writeValue(stream, methodCall.method); - this.messageCodec.writeValue(stream, methodCall.args); - return stream.buffer; - } - - /** - * Decodes a method call from binary format. - * @param methodCall - The binary message to decode - * @returns The decoded MethodCall - * @throws Error if the method call is corrupted - */ - decodeMethodCall(methodCall: ArrayBuffer): MethodCall { - const buffer = ByteBuffer.from(methodCall); - const method: Any = this.messageCodec.readValue(buffer); - const args: Any = this.messageCodec.readValue(buffer); - if (typeof method == 'string' && !buffer.hasRemaining()) { - return new MethodCall(method, args); - } - throw new Error("Method call corrupted"); - } - - /** - * Encodes a successful result into a binary envelope. - * @param result - The result value, possibly null - * @returns The encoded envelope as an ArrayBuffer - */ - encodeSuccessEnvelope(result: Any): ArrayBuffer { - const stream = ByteBuffer.from(new ArrayBuffer(1024)); - stream.writeInt8(0); - this.messageCodec.writeValue(stream, result); - return stream.buffer; - } - - /** - * Encodes an error result into a binary envelope. - * @param errorCode - The error code - * @param errorMessage - The error message, possibly null - * @param errorDetails - Error details, possibly null - * @returns The encoded envelope as an ArrayBuffer - */ - encodeErrorEnvelope(errorCode: string, errorMessage: string, errorDetails: Any): ArrayBuffer { - const stream = ByteBuffer.from(new ArrayBuffer(1024)); - stream.writeInt8(1); - this.messageCodec.writeValue(stream, errorCode); - this.messageCodec.writeValue(stream, errorMessage); - if (errorDetails instanceof Error) { - this.messageCodec.writeValue(stream, errorDetails.stack); - } else { - this.messageCodec.writeValue(stream, errorDetails); - } - return stream.buffer; - } - - /** - * Encodes an error result into a binary envelope with stacktrace. - * @param errorCode - The error code - * @param errorMessage - The error message, possibly null - * @param errorDetails - Error details, possibly null - * @param errorStacktrace - The platform stacktrace, possibly null - * @returns The encoded envelope as an ArrayBuffer - */ - encodeErrorEnvelopeWithStacktrace(errorCode: string, errorMessage: string, errorDetails: Any, - errorStacktrace: string): ArrayBuffer { - const stream = ByteBuffer.from(new ArrayBuffer(1024)); - stream.writeInt8(1); - this.messageCodec.writeValue(stream, errorCode); - this.messageCodec.writeValue(stream, errorMessage); - if (errorDetails instanceof Error) { - this.messageCodec.writeValue(stream, errorDetails.stack); - } else { - this.messageCodec.writeValue(stream, errorDetails); - } - this.messageCodec.writeValue(stream, errorStacktrace); - return stream.buffer; - } - - /** - * Decodes a result envelope from binary format. - * @param envelope - The binary envelope to decode - * @returns The decoded result value - * @throws FlutterException if the envelope contains an error - * @throws Error if the envelope is corrupted - */ - decodeEnvelope(envelope: ArrayBuffer): Any { - const buffer = ByteBuffer.from(envelope); - const flag = buffer.readInt8(); - switch (flag) { - case 0: { - const result: Any = this.messageCodec.readValue(buffer); - if (!buffer.hasRemaining()) { - return result; - } - // Falls through intentionally. - } - case 1: { - const code: Any = this.messageCodec.readValue(buffer); - const message: Any = this.messageCodec.readValue(buffer); - const details: Any = this.messageCodec.readValue(buffer); - if (typeof code == 'string' && (message == null || typeof message == 'string') && !buffer.hasRemaining()) { - throw new FlutterException(code, message, details); - } - } - } - throw new Error("Envelope corrupted"); - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableStringCodec.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableStringCodec.ets deleted file mode 100644 index 8d53c83..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/SendableStringCodec.ets +++ /dev/null @@ -1,52 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on StringCodec.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import SendableMessageCodec from './SendableMessageCodec'; -import StringUtils from '../../util/StringUtils'; - -/** - * A {@link SendableMessageCodec} using UTF-8 encoded String messages. - * - * This codec is guaranteed to be compatible with the corresponding `StringCodec` on the Dart side. - * These parts of the Flutter SDK are evolved synchronously. - */ -/** - * A sendable MessageCodec using UTF-8 encoded String messages. - * This codec can be used in background threads and worker contexts. - */ -@Sendable -export default class SendableStringCodec implements SendableMessageCodec { - /** Singleton instance of SendableStringCodec. */ - static readonly INSTANCE: SendableStringCodec = new SendableStringCodec(); - - /** - * Encodes a string message into binary format. - * @param message - The string message to encode, possibly null - * @returns The encoded message as an ArrayBuffer - */ - encodeMessage(message: string): ArrayBuffer { - if (message == null) { - return StringUtils.stringToArrayBuffer(""); - } - return StringUtils.stringToArrayBuffer(message); - } - - /** - * Decodes a binary message into a string. - * @param message - The binary message to decode, possibly null - * @returns The decoded string - */ - decodeMessage(message: ArrayBuffer | null): string { - if (message == null) { - return ""; - } - return StringUtils.arrayBufferToString(message); - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec.ets deleted file mode 100644 index cf50f69..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec.ets +++ /dev/null @@ -1,416 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on StandardMessageCodec.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import { ByteBuffer } from '../../util/ByteBuffer'; -import StringUtils from '../../util/StringUtils'; -import MessageCodec from './MessageCodec'; -import TreeMap from '@ohos.util.TreeMap'; -import HashMap from '@ohos.util.HashMap'; -import LightWeightMap from '@ohos.util.LightWeightMap'; -import PlainArray from '@ohos.util.PlainArray'; -import List from '@ohos.util.List'; -import LinkedList from '@ohos.util.LinkedList'; -import Any from './Any'; -import { ArrayList } from '@kit.ArkTS'; - -/** - * MessageCodec using the Flutter standard binary encoding. - * - * This codec is guaranteed to be compatible with the corresponding `StandardMessageCodec` - * on the Dart side. These parts of the Flutter SDK are evolved synchronously. - * - * Supported messages are acyclic values of these forms: - * null - * Booleans - * number - * BigIntegers (see below) - * Int8Array, Int32Array, Float32Array, Float64Array - * Strings - * Array[] - * Lists of supported values - * Maps with supported keys and values - * - * - * On the Dart side, these values are represented as follows: - * null: null - * Boolean: bool - * Byte, Short, Integer, Long: int - * Float, Double: double - * String: String - * byte[]: Uint8List - * int[]: Int32List - * long[]: Int64List - * float[]: Float32List - * double[]: Float64List - * List: List - * Map: Map - * - * BigIntegers are represented in Dart as strings with the hexadecimal representation of the - * integer's value. - * - * To extend the codec, overwrite the writeValue and readValueOfType methods. - */ -export default class StandardMessageCodec implements MessageCodec { - private static TAG = "StandardMessageCodec#"; - /** Singleton instance of StandardMessageCodec. */ - static INSTANCE = new StandardMessageCodec(); - - /** - * Encodes a message into binary format using the standard encoding. - * @param message - The message to encode - * @returns The encoded message as an ArrayBuffer - */ - encodeMessage(message: Any): ArrayBuffer { - const stream = ByteBuffer.from(new ArrayBuffer(1024)) - this.writeValue(stream, message); - return stream.buffer - } - - /** - * Decodes a binary message from the standard encoding. - * @param message - The binary message to decode, possibly null - * @returns The decoded message - */ - decodeMessage(message: ArrayBuffer | null): Any { - if (message == null) { - return null - } - const buffer = ByteBuffer.from(message) - return this.readValue(buffer) - } - - private static NULL = 0; - private static TRUE = 1; - private static FALSE = 2; - private static INT32 = 3; - private static INT64 = 4; - private static BIGINT = 5; - private static FLOAT64 = 6; - private static STRING = 7; - private static UINT8_ARRAY = 8; - private static INT32_ARRAY = 9; - private static INT64_ARRAY = 10; - private static FLOAT64_ARRAY = 11; - private static LIST = 12; - private static MAP = 13; - private static FLOAT32_ARRAY = 14; - private INT64_MAX = 9223372036854775807; - private INT64_MIN = -9223372036854775808; - - /** - * Writes a value to the byte buffer using the standard encoding. - * @param stream - The ByteBuffer to write to - * @param value - The value to write - * @returns The ByteBuffer stream - */ - writeValue(stream: ByteBuffer, value: Any): Any { - if (value == null || value == undefined) { - stream.writeInt8(StandardMessageCodec.NULL); - } else if (typeof value === "boolean") { - stream.writeInt8(value ? StandardMessageCodec.TRUE : StandardMessageCodec.FALSE) - } else if (typeof value === "number") { - if (Number.isInteger(value)) { //整型 - if (-0x7fffffff - 1 <= value && value <= 0x7fffffff) { //int32 - stream.writeInt8(StandardMessageCodec.INT32); - stream.writeInt32(value, true); - } else if (Number.MIN_SAFE_INTEGER <= value && value <= Number.MAX_SAFE_INTEGER) { //int64 number整型取值范围 - stream.writeInt8(StandardMessageCodec.INT64); - stream.writeInt64(value, true); - } else { //被判为整型的double型 - stream.writeInt8(StandardMessageCodec.FLOAT64); - this.writeAlignment(stream, 8); - stream.writeFloat64(value, true); - } - } else { //浮点型 - stream.writeInt8(StandardMessageCodec.FLOAT64); - this.writeAlignment(stream, 8); - stream.writeFloat64(value, true); - } - } else if (typeof value === "bigint") { - // The format is first the type byte (0x05), then the actual number - // as an ASCII string giving the hexadecimal representation of the - // integer, with the string's length as encoded by writeSize - // followed by the string bytes. - if (value >= this.INT64_MIN && value <= this.INT64_MAX) { - stream.writeInt8(StandardMessageCodec.INT64); - stream.writeBigInt64(value, true); - } else { - // Convert bigint to a hexadecimal string - stream.writeInt8(StandardMessageCodec.BIGINT); - const hexString = value.toString(16); - // Map each character in the hexadecimal string to its ASCII code - const asciiString = hexString.split('').map(char => char.charCodeAt(0)); - this.writeBytes(stream, Uint8Array.from(asciiString)); - } - } else if (typeof value === "string") { - stream.writeInt8(StandardMessageCodec.STRING); - let stringBuff = StringUtils.stringToArrayBuffer(value); - this.writeBytes(stream, new Uint8Array(stringBuff)); - } else if (value instanceof Uint8Array) { - stream.writeInt8(StandardMessageCodec.UINT8_ARRAY); - this.writeBytes(stream, value) - } else if (value instanceof Int32Array) { - stream.writeInt8(StandardMessageCodec.INT32_ARRAY); - this.writeSize(stream, value.length); - this.writeAlignment(stream, 4); - value.forEach(item => stream.writeInt32(item, true)); - } else if (value instanceof BigInt64Array) { - stream.writeInt8(StandardMessageCodec.INT64_ARRAY); - this.writeSize(stream, value.length); - this.writeAlignment(stream, 8); - value.forEach(item => stream.writeBigInt64(item, true)); - } else if (value instanceof Float32Array) { - stream.writeInt8(StandardMessageCodec.FLOAT32_ARRAY); - this.writeSize(stream, value.length); - this.writeAlignment(stream, 4); - value.forEach(item => stream.writeFloat32(item, true)); - } else if (value instanceof Float64Array) { - stream.writeInt8(StandardMessageCodec.FLOAT64_ARRAY); - this.writeSize(stream, value.length); - this.writeAlignment(stream, 8); - value.forEach(item => stream.writeFloat64(item, true)); - } else if (value instanceof Array || value instanceof Int8Array || value instanceof Int16Array - || value instanceof Uint16Array || value instanceof Uint32Array || value instanceof List - || value instanceof LinkedList || value instanceof ArrayList) { - stream.writeInt8(StandardMessageCodec.LIST) - this.writeSize(stream, value.length); - value.forEach((item: Any): void => this.writeValue(stream, item)); - } else if (value instanceof Map) { - stream.writeInt8(StandardMessageCodec.MAP); - this.writeSize(stream, value.size); - value.forEach((value: Any, key: Any) => { - this.writeValue(stream, key); - this.writeValue(stream, value); - }); - } else if (value instanceof HashMap || value instanceof TreeMap || value instanceof LightWeightMap - || value instanceof PlainArray) { - stream.writeInt8(StandardMessageCodec.MAP); - this.writeSize(stream, value.length); - value.forEach((value: Any, key: Any) => { - this.writeValue(stream, key); - this.writeValue(stream, value); - }); - } else if (typeof value == 'object') { - let map: Map = new Map(); - Object.keys(value).forEach(key => { - map.set(key, value[key]); - }); - this.writeValue(stream, map); - } else { - throw new Error("Unsupported value: " + value); - stream.writeInt8(StandardMessageCodec.NULL); - } - return stream; - } - - /** - * Writes alignment padding to the stream. - * @param stream - The ByteBuffer to write to - * @param alignment - The alignment requirement (e.g., 4, 8) - */ - writeAlignment(stream: ByteBuffer, alignment: number) { - let mod: number = stream.byteOffset % alignment; - if (mod != 0) { - for (let i = 0; i < alignment - mod; i++) { - stream.writeInt8(0); - } - } - } - - /** - * Writes a size value to the stream using compact encoding. - * @param stream - The ByteBuffer to write to - * @param value - The size value to write - */ - writeSize(stream: ByteBuffer, value: number) { - if (value < 254) { - stream.writeUint8(value); - } else if (value <= 0xffff) { - stream.writeUint8(254); - stream.writeUint16(value, true); - } else { - stream.writeUint8(255); - stream.writeUint32(value, true); - } - } - - /** - * Writes a byte array to the stream. - * @param stream - The ByteBuffer to write to - * @param bytes - The byte array to write - */ - writeBytes(stream: ByteBuffer, bytes: Uint8Array) { - this.writeSize(stream, bytes.length) - stream.writeUint8Array(bytes); - } - - /** - * Reads a size value from the buffer using compact encoding. - * @param buffer - The ByteBuffer to read from - * @returns The size value - */ - readSize(buffer: ByteBuffer) { - let value = buffer.readUint8() & 0xff; - if (value < 254) { - return value; - } else if (value == 254) { - return buffer.readUint16(true); - } else { - return buffer.readUint32(true); - } - } - - /** - * Reads alignment padding from the buffer. - * @param buffer - The ByteBuffer to read from - * @param alignment - The alignment requirement (e.g., 4, 8) - */ - readAlignment(buffer: ByteBuffer, alignment: number) { - let mod = buffer.byteOffset % alignment; - if (mod != 0) { - buffer.skip(alignment - mod); - } - } - - /** - * Reads a value from the buffer using the standard encoding. - * @param buffer - The ByteBuffer to read from - * @returns The decoded value - */ - readValue(buffer: ByteBuffer): Any { - let type = buffer.readUint8() - return this.readValueOfType(type, buffer); - } - - /** - * Reads a byte array from the buffer. - * @param buffer - The ByteBuffer to read from - * @returns The byte array - */ - readBytes(buffer: ByteBuffer): Uint8Array { - let length = this.readSize(buffer); - let bytesBuffer = new ArrayBuffer(length); - let bytes = new Uint8Array(bytesBuffer); - bytes.set(buffer.readUint8Array(length)); - return bytes; - } - - /** - * Reads a value of a specific type from the buffer. - * @param type - The type code to read - * @param buffer - The ByteBuffer to read from - * @returns The decoded value - * @throws Error if the type is unknown or the message is corrupted - */ - readValueOfType(type: number, buffer: ByteBuffer): Any { - let result: Any; - switch (type) { - case StandardMessageCodec.NULL: - result = null; - break; - case StandardMessageCodec.TRUE: - result = true; - break; - case StandardMessageCodec.FALSE: - result = false; - break; - case StandardMessageCodec.INT32: - result = buffer.readInt32(true); - break; - case StandardMessageCodec.INT64: - result = buffer.readInt64(true); - if (Number.MIN_SAFE_INTEGER <= result && result <= Number.MAX_SAFE_INTEGER) { - result = Number(result); - } - break; - case StandardMessageCodec.BIGINT: - let bytes: Uint8Array = this.readBytes(buffer); - // Convert the byte array to a UTF-8 encoded string - const hexString: string = String.fromCharCode(...bytes); - // Parse the string as a hexadecimal BigInt - result = BigInt(`0x${hexString}`); - break; - case StandardMessageCodec.FLOAT64: - this.readAlignment(buffer, 8); - result = buffer.readFloat64(true) - break; - case StandardMessageCodec.STRING: { - let bytes: Uint8Array = this.readBytes(buffer); - result = StringUtils.uint8ArrayToString(bytes); - break; - } - case StandardMessageCodec.UINT8_ARRAY: { - result = this.readBytes(buffer); - break; - } - case StandardMessageCodec.INT32_ARRAY: { - let length = this.readSize(buffer); - let array = new Int32Array(length) - this.readAlignment(buffer, 4); - for (let i = 0; i < length; i++) { - array[i] = buffer.readInt32(true) - } - result = array; - break; - } - case StandardMessageCodec.INT64_ARRAY: { - let length = this.readSize(buffer); - let array = new BigInt64Array(length) - this.readAlignment(buffer, 8); - for (let i = 0; i < length; i++) { - array[i] = buffer.readBigInt64(true) - } - result = array; - break; - } - case StandardMessageCodec.FLOAT64_ARRAY: { - let length = this.readSize(buffer); - let array = new Float64Array(length) - this.readAlignment(buffer, 8); - for (let i = 0; i < length; i++) { - array[i] = buffer.readFloat64(true) - } - result = array; - break; - } - case StandardMessageCodec.LIST: { - let length = this.readSize(buffer); - let array: Array = new Array(length) - for (let i = 0; i < length; i++) { - array[i] = this.readValue(buffer) - } - result = array; - break; - } - case StandardMessageCodec.MAP: { - let size = this.readSize(buffer); - let map: Map = new Map() - for (let i = 0; i < size; i++) { - map.set(this.readValue(buffer), this.readValue(buffer)); - } - result = map; - break; - } - case StandardMessageCodec.FLOAT32_ARRAY: { - let length = this.readSize(buffer); - let array = new Float32Array(length); - this.readAlignment(buffer, 4); - for (let i = 0; i < length; i++) { - array[i] = buffer.readFloat32(true) - } - result = array; - break; - } - default: - throw new Error("Message corrupted, type=" + type); - } - return result; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMethodCodec.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMethodCodec.ets deleted file mode 100644 index f6059c0..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMethodCodec.ets +++ /dev/null @@ -1,152 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on StandardMethodCodec.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import { ByteBuffer } from '../../util/ByteBuffer'; -import FlutterException from './FlutterException'; -import Any from './Any'; -import MethodCall from './MethodCall'; -import MethodCodec from './MethodCodec'; -import StandardMessageCodec from './StandardMessageCodec'; - -/** - * A {@link MethodCodec} using the Flutter standard binary encoding. - * - * This codec is guaranteed to be compatible with the corresponding StandardMethodCodec - * on the Dart side. These parts of the Flutter SDK are evolved synchronously. - * - * Values supported as method arguments and result payloads are those supported by {@link StandardMessageCodec}. - */ -export default class StandardMethodCodec implements MethodCodec { - private static TAG = "StandardMethodCodec"; - /** Singleton instance of StandardMethodCodec. */ - public static INSTANCE = new StandardMethodCodec(StandardMessageCodec.INSTANCE); - private messageCodec: StandardMessageCodec; - - /** - * Creates a new method codec based on the specified message codec. - * @param messageCodec - The StandardMessageCodec to use for encoding/decoding - */ - constructor(messageCodec: StandardMessageCodec) { - this.messageCodec = messageCodec; - } - - /** - * Encodes a method call into binary format. - * @param methodCall - The MethodCall to encode - * @returns The encoded method call as an ArrayBuffer - */ - encodeMethodCall(methodCall: MethodCall): ArrayBuffer { - const stream = ByteBuffer.from(new ArrayBuffer(1024)); - this.messageCodec.writeValue(stream, methodCall.method); - this.messageCodec.writeValue(stream, methodCall.args); - return stream.buffer; - } - - /** - * Decodes a method call from binary format. - * @param methodCall - The binary message to decode - * @returns The decoded MethodCall - * @throws Error if the method call is corrupted - */ - decodeMethodCall(methodCall: ArrayBuffer): MethodCall { - const buffer = ByteBuffer.from(methodCall); - const method: Any = this.messageCodec.readValue(buffer); - const args: Any = this.messageCodec.readValue(buffer); - if (typeof method == 'string' && !buffer.hasRemaining()) { - return new MethodCall(method, args); - } - throw new Error("Method call corrupted"); - } - - /** - * Encodes a successful result into a binary envelope. - * @param result - The result value, possibly null - * @returns The encoded envelope as an ArrayBuffer - */ - encodeSuccessEnvelope(result: Any): ArrayBuffer { - const stream = ByteBuffer.from(new ArrayBuffer(1024)); - stream.writeInt8(0); - this.messageCodec.writeValue(stream, result); - return stream.buffer; - } - - /** - * Encodes an error result into a binary envelope. - * @param errorCode - The error code - * @param errorMessage - The error message, possibly null - * @param errorDetails - Error details, possibly null - * @returns The encoded envelope as an ArrayBuffer - */ - encodeErrorEnvelope(errorCode: string, errorMessage: string, errorDetails: Any): ArrayBuffer { - const stream = ByteBuffer.from(new ArrayBuffer(1024)); - stream.writeInt8(1); - this.messageCodec.writeValue(stream, errorCode); - this.messageCodec.writeValue(stream, errorMessage); - if (errorDetails instanceof Error) { - this.messageCodec.writeValue(stream, errorDetails.stack); - } else { - this.messageCodec.writeValue(stream, errorDetails); - } - return stream.buffer; - } - - /** - * Encodes an error result into a binary envelope with stacktrace. - * @param errorCode - The error code - * @param errorMessage - The error message, possibly null - * @param errorDetails - Error details, possibly null - * @param errorStacktrace - The platform stacktrace, possibly null - * @returns The encoded envelope as an ArrayBuffer - */ - encodeErrorEnvelopeWithStacktrace(errorCode: string, errorMessage: string, errorDetails: Any, - errorStacktrace: string): ArrayBuffer { - const stream = ByteBuffer.from(new ArrayBuffer(1024)); - stream.writeInt8(1); - this.messageCodec.writeValue(stream, errorCode); - this.messageCodec.writeValue(stream, errorMessage); - if (errorDetails instanceof Error) { - this.messageCodec.writeValue(stream, errorDetails.stack); - } else { - this.messageCodec.writeValue(stream, errorDetails); - } - this.messageCodec.writeValue(stream, errorStacktrace); - return stream.buffer; - } - - /** - * Decodes a result envelope from binary format. - * @param envelope - The binary envelope to decode - * @returns The decoded result value - * @throws FlutterException if the envelope contains an error - * @throws Error if the envelope is corrupted - */ - decodeEnvelope(envelope: ArrayBuffer): Any { - const buffer = ByteBuffer.from(envelope); - const flag = buffer.readInt8(); - switch (flag) { - case 0: { - const result: Any = this.messageCodec.readValue(buffer); - if (!buffer.hasRemaining()) { - return result; - } - // Falls through intentionally. - } - case 1: { - const code: Any = this.messageCodec.readValue(buffer); - const message: Any = this.messageCodec.readValue(buffer); - const details: Any = this.messageCodec.readValue(buffer); - if (typeof code == 'string' && (message == null || typeof message == 'string') && !buffer.hasRemaining()) { - throw new FlutterException(code, message, details); - } - } - } - throw new Error("Envelope corrupted"); - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StringCodec.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StringCodec.ets deleted file mode 100644 index 2205dd7..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StringCodec.ets +++ /dev/null @@ -1,47 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on StringCodec.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import StringUtils from '../../util/StringUtils'; -import MessageCodec from './MessageCodec'; - -/** - * A {@link MessageCodec} using UTF-8 encoded String messages. - * - * This codec is guaranteed to be compatible with the corresponding `StringCodec` on the - * Dart side. These parts of the Flutter SDK are evolved synchronously. - */ -export default class StringCodec implements MessageCodec { - /** Singleton instance of StringCodec. */ - static readonly INSTANCE = new StringCodec(); - - /** - * Encodes a string message into binary format. - * @param message - The string message to encode, possibly null - * @returns The encoded message as an ArrayBuffer - */ - encodeMessage(message: string): ArrayBuffer { - if (message == null) { - return StringUtils.stringToArrayBuffer(""); - } - return StringUtils.stringToArrayBuffer(message); - } - - /** - * Decodes a binary message into a string. - * @param message - The binary message to decode, possibly null - * @returns The decoded string - */ - decodeMessage(message: ArrayBuffer | null): string { - if (message == null) { - return ""; - } - return StringUtils.arrayBufferToString(message); - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/ListenableEditingState.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/ListenableEditingState.ets deleted file mode 100644 index 2a6858a..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/ListenableEditingState.ets +++ /dev/null @@ -1,974 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on ListenableEditingState.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import { TextEditState } from '../../embedding/engine/systemchannels/TextInputChannel'; -import Log from '../../util/Log'; -import inputMethod from '@ohos.inputMethod'; -import ArrayList from '@ohos.util.ArrayList'; -import { TextEditingDelta } from './TextEditingDelta'; -import TextInputChannel from '../../embedding/engine/systemchannels/TextInputChannel'; -import { FlutterTextUtils } from './TextUtils'; -import { KeyCode } from '@kit.InputKit'; -import KeyEventChannel, { SimulateKeyEvent } from '../../embedding/engine/systemchannels/KeyEventChannel'; -import { PasteboardUtils } from '../../util/PasteboardUtils'; - -const TAG = "ListenableEditingState"; - -/** - * Enumeration of delete operation states. - */ -enum DeleteStates { - /** Delete operation has started */ - START, - /** Delete operation is in progress */ - MOVING, - /** Delete operation has ended */ - END -} - -/** - * Manages the editable text state and notifies listeners of changes. - * This class tracks text content, selection, composing regions, and preview text. - */ -export class ListenableEditingState { - private TextInputChannel: TextInputChannel | null = null; - private keyEventChannel: KeyEventChannel | undefined; - private client: number = 0 - private leftDeleteState: DeleteStates = DeleteStates.END - private rightDeleteState: DeleteStates = DeleteStates.END - //Cache used to storage software keyboard input action - private mStringCache: string; - private mSelectionStartCache: number = 0; - private mSelectionEndCache: number = 0; - private mComposingStartCache: number = 0; - private mComposingEndCache: number = 0; - //used to compare with Cache - - private mListeners: ArrayList = new ArrayList(); - private mPendingListeners: ArrayList = new ArrayList(); - private mBatchTextEditingDeltas: ArrayList = new ArrayList(); - private mChangeNotificationDepth: number = 0; - private mBatchEditNestDepth: number = 0; - private mTextWhenBeginBatchEdit: string; - private mSelectionStartWhenBeginBatchEdit: number = 0; - private mSelectionEndWhenBeginBatchEdit: number = 0; - private mComposingStartWhenBeginBatchEdit: number = 0; - private mComposingEndWhenBeginBatchEdit: number = 0; - - // preview text - private mPreviewText: string = ""; - private mPreviewTextStart: number = 0; - private mPreviewTextEnd: number = 0; - private mLeftIdxOfPreviewTextRange: number = 0; - private mRightIdxOfPreviewTextRange: number = 0; - private mIsCursorIdxOutOfPreviewTextRange: boolean = false; - private mIsEnglishPreviewMode: boolean = false; - - /** - * Constructs a new ListenableEditingState instance. - * @param TextInputChannel - The TextInputChannel for communication, possibly null - * @param client - The client ID - * @param keyEventChannel - Optional KeyEventChannel for key event handling - */ - constructor(TextInputChannel:TextInputChannel | null,client:number, keyEventChannel?: KeyEventChannel) { - this.TextInputChannel = TextInputChannel; - this.keyEventChannel = keyEventChannel; - this.client = client - this.mStringCache = ""; - this.mTextWhenBeginBatchEdit = ""; - this.mSelectionStartCache = 0; - this.mSelectionEndCache = 0; - this.mComposingStartCache = -1; - this.mComposingEndCache = -1; - this.mPreviewText = ""; - } - - /** - * Extracts and clears the batch of text editing deltas. - * @returns A list of TextEditingDelta objects representing the changes - */ - extractBatchTextEditingDeltas(): ArrayList { - let currentBatchDeltas = new ArrayList(); - this.mBatchTextEditingDeltas.forEach((data) => { - currentBatchDeltas.add(data); - }) - this.mBatchTextEditingDeltas.clear(); - return currentBatchDeltas; - } - - /** - * Clears all batched text editing deltas. - */ - clearBatchDeltas(): void { - this.mBatchTextEditingDeltas.clear(); - } - - /** - * Replaces a range of text with new text. - * @param start - The start position of the range to replace - * @param end - The end position of the range to replace - * @param tb - The replacement text - * @param tbStart - The start position within the replacement text - * @param tbEnd - The end position within the replacement text - */ - replace(start: number, end: number, tb: String, tbStart: number, tbEnd: number): void { - const placeIndex = - this.mSelectionStartCache < this.mSelectionEndCache ? this.mSelectionStartCache : this.mSelectionEndCache; - - this.mBatchTextEditingDeltas.add( - new TextEditingDelta( - this.mStringCache.toString(), - placeIndex + tbEnd, - placeIndex + tbEnd, - this.getComposingStart(), - this.getComposingEnd(), - start, - end + tbStart, - tb.toString() - )); - } - - /** - * Gets the current selection start position. - * @returns The selection start position - */ - getSelectionStart(): number { - return this.mSelectionStartCache; - } - - /** - * Gets the current selection end position. - * @returns The selection end position - */ - getSelectionEnd(): number { - return this.mSelectionEndCache; - } - - /** - * Gets the current composing region start position. - * @returns The composing start position, or -1 if no composing region - */ - getComposingStart(): number { - return this.mComposingStartCache; - } - - /** - * Gets the current composing region end position. - * @returns The composing end position, or -1 if no composing region - */ - getComposingEnd(): number { - return this.mComposingEndCache; - } - - /** - * Gets the current text content. - * @returns The text string - */ - getStringCache(): string { - return this.mStringCache; - } - - /** - * Gets the currently selected text. - * @returns The selected text, or empty string if selection is invalid - */ - getSelectionString(): string { - if (this.mSelectionStartCache < 0 || this.mSelectionEndCache > this.mStringCache.length) { - return ""; - } - return this.mStringCache.substring(this.mSelectionStartCache, this.mSelectionEndCache); - } - - /** - * Gets the current preview text from the input method. - * @returns The preview text - */ - getPreviewText(): string { - return this.mPreviewText; - } - - /** - * Gets the start position of the preview text in the original text. - * @returns The preview text start position - */ - getPreviewTextStart(): number { - return this.mPreviewTextStart; - } - - /** - * Gets the end position of the preview text in the original text. - * @returns The preview text end position - */ - getPreviewTextEnd(): number { - return this.mPreviewTextEnd; - } - - /** - * Gets the right index of the preview text range in the string cache. - * @returns The right index of the preview text range - */ - getRightIdxOfPreviewTextRange() : number { - return this.mRightIdxOfPreviewTextRange; - } - - /** - * Gets the left index of the preview text range in the string cache. - * @returns The left index of the preview text range - */ - getLeftIdxOfPreviewTextRange() : number { - return this.mLeftIdxOfPreviewTextRange; - } - - /** - * Sets the preview text. - * @param previewText - The preview text to set - */ - setPreviewText(previewText: string): void { - this.mPreviewText = previewText; - } - - /** - * Sets the start position of the preview text. - * @param previewTextStart - The start position - */ - setPreviewTextStart(previewTextStart: number): void { - this.mPreviewTextStart = previewTextStart; - } - - /** - * Sets the end position of the preview text. - * @param previewTextEnd - The end position - */ - setPreviewTextEnd(previewTextEnd: number): void { - this.mPreviewTextEnd = previewTextEnd; - } - - /** - * Updates the preview text range indices. - * @param leftIdx - The left index in the string cache - * @param rightIdx - The right index in the string cache - */ - updatePreviewTextRange(leftIdx: number, rightIdx: number): void { - this.mLeftIdxOfPreviewTextRange = leftIdx; - this.mRightIdxOfPreviewTextRange = rightIdx; - } - - /** - * Clears all preview text contents and resets related indices. - */ - clearPreviewTextContents() : void { - this.mPreviewText = ""; - this.mPreviewTextStart = 0; - this.mPreviewTextEnd = 0; - this.mLeftIdxOfPreviewTextRange = 0; - this.mRightIdxOfPreviewTextRange = 0; - } - - /** - * Sets whether the cursor index is out of the preview text range. - * @param hasChanged - True if the cursor is out of range, false otherwise - */ - setIsCursorIdxOutOfPreviewTextRange(hasChanged: boolean): void { - this.mIsCursorIdxOutOfPreviewTextRange = hasChanged; - } - - /** - * Gets whether the cursor index is out of the preview text range. - * @returns True if the cursor is out of range, false otherwise - */ - getIsCursorIdxOutOfPreviewTextRange(): boolean { - return this.mIsCursorIdxOutOfPreviewTextRange; - } - - /** - * Sets the selection start position. - * @param newSelectionStart - The new selection start position - */ - setSelectionStart(newSelectionStart: number): void { - this.mSelectionStartCache = newSelectionStart; - } - - /** - * Sets the selection end position. - * @param newSelectionEnd - The new selection end position - */ - setSelectionEnd(newSelectionEnd: number): void { - this.mSelectionEndCache = newSelectionEnd; - } - - /** - * Sets the composing region start position. - * @param newComposingStart - The new composing start position, or -1 to clear - */ - setComposingStart(newComposingStart: number): void { - this.mComposingStartCache = newComposingStart; - } - - /** - * Sets the composing region end position. - * @param newComposingEnd - The new composing end position, or -1 to clear - */ - setComposingEnd(newComposingEnd: number): void { - this.mComposingEndCache = newComposingEnd; - } - - /** - * Sets the text content. - * @param newStringCache - The new text content - */ - setStringCache(newStringCache: string): void { - this.mStringCache = newStringCache; - } - - /** - * Notifies a single listener of editing state changes. - * @param listener - The listener to notify - * @param textChanged - Whether the text has changed - * @param selectionChanged - Whether the selection has changed - * @param composingChanged - Whether the composing region has changed - */ - notifyListener(listener: EditingStateWatcher, - textChanged: boolean, - selectionChanged: boolean, - composingChanged: boolean): void { - this.mChangeNotificationDepth++; - listener.didChangeEditingState(textChanged, selectionChanged, composingChanged); - this.mChangeNotificationDepth--; - } - - /** - * Notifies all listeners if any changes have occurred. - * @param textChanged - Whether the text has changed - * @param selectionChanged - Whether the selection has changed - * @param composingChanged - Whether the composing region has changed - */ - notifyListenersIfNeeded(textChanged: boolean, selectionChanged: boolean, composingChanged: boolean) { - if (textChanged || selectionChanged || composingChanged) { - for (const listener of this.mListeners) { - this.notifyListener(listener, textChanged, selectionChanged, composingChanged); - } - } - } - - /** - * Handles insertion of preview text from the input method. - * @param text - The preview text to insert - * @param range - The range in the original text where preview text applies - */ - handleInsertPreviewTextEvent(text: string, range: inputMethod.Range): void { - // Determine whether it is in English preview input mode - if (range.start != -1 && range.end != -1 && text.indexOf("'") == -1) { - this.mIsEnglishPreviewMode = true; - } - // preview text callback with complete text contents,like a, a'b, a'b'c - // its text char do not appear one by one - this.setPreviewText(text); - this.setPreviewTextStart(range.start); - this.setPreviewTextEnd(range.end); - - // update preview text start idx and end idx - let leftIdxOfPreviewText: number = this.getSelectionStart(); - let rightIdxOfPreviewText: number = this.getSelectionStart() + text.length; - this.updatePreviewTextRange(leftIdxOfPreviewText, rightIdxOfPreviewText) - - if (this.mListeners == null) { - Log.e(TAG, "handleInsertPreviewTextEvent, mListeners is null"); - return; - } - this.notifyListenersIfNeeded(true, true, false); - } - - /** - * Handles insertion of final text from the input method. - * @param text - The text to insert - */ - handleInsertTextEvent(text: string): void { - // clear preview text cache before insert the final texts - if (this.getPreviewText().length != 0) { - this.setPreviewText(""); - } - // When previewTextChangeSelection async callback has been invoked, covering the previous preview text. - // But if that callback did not work, then manually insert the candidate word, covering the previous preview text. - if (this.getLeftIdxOfPreviewTextRange() < this.mSelectionStartCache && - (this.getLeftIdxOfPreviewTextRange() != this.getRightIdxOfPreviewTextRange())) { - this.mSelectionStartCache = this.getLeftIdxOfPreviewTextRange(); - this.mSelectionEndCache = this.getRightIdxOfPreviewTextRange(); - } else if (this.mIsEnglishPreviewMode) { - // To comply with the specifications of Xiaoyi-InputMethod, change the - // range of inserted English chars and add a space at the backend - this.mSelectionStartCache = this.getPreviewTextStart(); - this.mSelectionEndCache = this.getPreviewTextEnd(); - text += " "; - } - - let start = - this.mSelectionStartCache < this.mSelectionEndCache ? this.mSelectionStartCache : this.mSelectionEndCache; - let end = this.mSelectionStartCache > this.mSelectionEndCache ? this.mSelectionStartCache : this.mSelectionEndCache; - const length = text.length; - this.replace(start, end, text, 0, length); - - if (this.mStringCache.length == this.mSelectionStartCache) { - //Insert text one by one - let tempStr: string = this.mStringCache.substring(0, start) + text + this.mStringCache.substring(end); - this.mStringCache = tempStr; - this.setSelectionStart(this.mStringCache.length); - this.setSelectionEnd(this.mStringCache.length); - } else if (this.mStringCache.length > this.mSelectionStartCache) { - //Insert text in the middle of string - let tempStr: string = this.mStringCache.substring(0, start) + text + this.mStringCache.substring(end); - this.mStringCache = tempStr; - this.mSelectionStartCache = start + text.length; - this.mSelectionEndCache = this.mSelectionStartCache; - } - if (this.mListeners == null) { - Log.e(TAG, "mListeners is null"); - return; - } - this.notifyListenersIfNeeded(true, true, false); - // when preview text did insert, reset the params - this.updatePreviewTextRange(0, 0); - this.setPreviewTextStart(-1); - this.setPreviewTextEnd(-1); - this.mIsEnglishPreviewMode = false; - } - - /** - * Updates the text input state from Flutter. - * @param state - The new text edit state - */ - updateTextInputState(state: TextEditState): void { - if (this.leftDeleteState === DeleteStates.START) { - this.leftDeleteState = DeleteStates.MOVING; - } - if (this.rightDeleteState === DeleteStates.START) { - this.rightDeleteState = DeleteStates.MOVING; - } - this.beginBatchEdit(); - this.setStringCache(state.text); - if (state.hasSelection()) { - this.setSelectionStart(state.selectionStart); - this.setSelectionEnd(state.selectionEnd); - } else { - this.setSelectionStart(0); - this.setSelectionEnd(0); - } - this.endBatchEdit(); - } - - /** - * Begins a batch edit operation. - * Multiple edits can be batched together to reduce notifications. - */ - beginBatchEdit(): void { - this.mBatchEditNestDepth++; - if (this.mChangeNotificationDepth > 0) { - Log.e(TAG, "editing state should not be changed in a listener callback"); - } - if (this.mBatchEditNestDepth == 1 && !this.mListeners.isEmpty()) { - this.mTextWhenBeginBatchEdit = this.getStringCache(); - this.mSelectionStartWhenBeginBatchEdit = this.getSelectionStart(); - this.mSelectionEndWhenBeginBatchEdit = this.getSelectionEnd(); - this.mComposingStartWhenBeginBatchEdit = this.getComposingStart(); - this.mComposingEndWhenBeginBatchEdit = this.getComposingEnd(); - } - } - - /** - * Ends a batch edit operation and notifies listeners of all changes. - */ - endBatchEdit(): void { - if (this.mBatchEditNestDepth == 0) { - Log.e(TAG, "endBatchEdit called without a matching beginBatchEdit"); - return; - } - if (this.mBatchEditNestDepth == 1) { - Log.d(TAG, "mBatchEditNestDepth == 1"); - for (const listener of this.mPendingListeners) { - this.notifyListener(listener, true, true, true); - } - - if (!this.mListeners.isEmpty()) { - Log.d(TAG, "didFinishBatchEdit with " + this.mListeners.length + " listener(s)"); - const textChanged = !(this.mStringCache == this.mTextWhenBeginBatchEdit); - const selectionChanged = this.mSelectionStartWhenBeginBatchEdit != this.getSelectionStart() - || this.mSelectionEndWhenBeginBatchEdit != this.getSelectionEnd(); - const composingRegionChanged = this.mComposingStartWhenBeginBatchEdit != this.getComposingStart() - || this.mComposingEndWhenBeginBatchEdit != this.getComposingEnd(); - Log.d(TAG, "textChanged: " + textChanged + " selectionChanged: " + selectionChanged + - " composingRegionChanged: " + composingRegionChanged); - this.notifyListenersIfNeeded(textChanged, selectionChanged, composingRegionChanged); - } - } - for (const listener of this.mPendingListeners) { - this.mListeners.add(listener); - } - this.mPendingListeners.clear(); - this.mBatchEditNestDepth--; - } - - /** - * Adds a listener to be notified of editing state changes. - * @param listener - The listener to add - */ - addEditingStateListener(listener: EditingStateWatcher): void { - if (this.mChangeNotificationDepth > 0) { - Log.e(TAG, "adding a listener " + JSON.stringify(listener) + " in a listener callback"); - } - if (this.mBatchEditNestDepth > 0) { - Log.d(TAG, "a listener was added to EditingState while a batch edit was in progress"); - this.mPendingListeners.add(listener); - } else { - this.mListeners.add(listener); - } - } - - /** - * Removes an editing state listener. - * @param listener - The listener to remove - */ - removeEditingStateListener(listener: EditingStateWatcher): void { - if (this.mChangeNotificationDepth > 0) { - Log.e(TAG, "removing a listener " + JSON.stringify(listener) + " in a listener callback"); - } - this.mListeners.remove(listener); - if (this.mBatchEditNestDepth > 0) { - this.mPendingListeners.remove(listener); - } - } - - /** - * Marks the start of a deletion operation. - * @param code - The key code that triggered the deletion - */ - startDeleting(code: number) { - if (code === KeyCode.KEYCODE_FORWARD_DEL) { - this.rightDeleteState = DeleteStates.START - } else { - this.leftDeleteState = DeleteStates.START - } - } - - /** - * Marks the end of a deletion operation. - * @param code - The key code that triggered the deletion - */ - endDeletion(code: number) { - if (code === KeyCode.KEYCODE_FORWARD_DEL) { - this.rightDeleteState = DeleteStates.END - } else { - this.leftDeleteState = DeleteStates.END - } - } - - /** - * Handles a delete event from the input method. - * @param leftOrRight - True for delete right (forward delete), false for delete left (backspace) - * @param length - The number of characters to delete - * @param enableDeltaModel - Whether delta model is enabled - */ - handleDeleteEvent(leftOrRight: boolean, length: number, enableDeltaModel: boolean | undefined): void { - if (length === 0) { - return; - } - // clear preview text cache - if (this.getPreviewText().length != 0) { - this.setPreviewText(""); - } - - if (enableDeltaModel) { - let selectionStart = this.getSelectionStart(); - let selectionEnd = this.getSelectionEnd(); - if(selectionStart === 0 && selectionEnd === 0){ - // [selectionStart]和[selectionEnd]都为0时,删除文本范围为空 - return; - } - if (selectionStart === selectionEnd) { - // [selectionStart]和[selectionEnd]一致时为普通删除操作,需要修改偏移量 - this.setSelectionStart(this.mSelectionStartCache - length); - } - } - - let start = - this.mSelectionStartCache < this.mSelectionEndCache ? this.mSelectionStartCache : this.mSelectionEndCache; - let end = this.mSelectionStartCache > this.mSelectionEndCache ? this.mSelectionStartCache : this.mSelectionEndCache; - - if (leftOrRight == false && this.leftDeleteState !== DeleteStates.MOVING) { - //delete left - if (start == 0 && end == 0) { - return; - } - - let unicodeStart = start; - if (start == end) { - for (let i = 0; i < length; i++) { - unicodeStart = FlutterTextUtils.getOffsetBefore(this.mStringCache, unicodeStart); - if (unicodeStart === 0) { - break; - } - } - } - this.replace(unicodeStart, end, "", 0, 0); - this.mSelectionStartCache = unicodeStart; - let tempStr: string = this.mStringCache.slice(0, unicodeStart) + this.mStringCache.slice(end); - this.mStringCache = tempStr; - this.mSelectionEndCache = this.mSelectionStartCache; - } else if (leftOrRight == true && this.rightDeleteState !== DeleteStates.MOVING) { - //delete right - if (start == this.mStringCache.length) { - return; - } - let unicodeEnd = end; - if (start == end) { - for (let i = 0; i < length; i++) { - unicodeEnd = FlutterTextUtils.getOffsetAfter(this.mStringCache, unicodeEnd); - if (unicodeEnd === this.mStringCache.length) { - break; - } - } - } - this.replace(start, unicodeEnd, "", 0, 0); - this.mSelectionEndCache = start; - let tempStr: string = this.mStringCache.slice(0, start) + - (unicodeEnd >= this.mStringCache.length ? "" : this.mStringCache.slice(unicodeEnd)); - this.mStringCache = tempStr; - this.mSelectionStartCache = this.mSelectionEndCache; - } - this.notifyListenersIfNeeded(true, true, false); - } - - /** - * Handles a newline event from the input method. - */ - handleNewlineEvent(): void { - // 获取光标所在位置; - // 当光标移动前位置小于移动后的位置时,获取光标移动前位置;反之获取移动后位置 - let start = - this.mSelectionStartCache < this.mSelectionEndCache ? this.mSelectionStartCache : this.mSelectionEndCache; - // 当光标移动前位置大于移动后的位置时,获取光标移动前位置;反之获取移动后位置 - let end = this.mSelectionStartCache > this.mSelectionEndCache ? this.mSelectionStartCache : this.mSelectionEndCache; - - this.replace(start, end, '\n', 0, 1); - // 对光标位置和字符串长度进行对比,决定光标位置的计算方法 - if (this.mStringCache.length == this.mSelectionStartCache) { - //Insert newline one by one - let tempStr: string = this.mStringCache.substring(0, start) + '\n' + this.mStringCache.substring(end); - this.mStringCache = tempStr; - this.setSelectionStart(this.mStringCache.length); - this.setSelectionEnd(this.mStringCache.length); - } else if (this.mStringCache.length > this.mSelectionStartCache) { - //Insert newline in the middle of string - let tempStr: string = this.mStringCache.substring(0, start) + '\n' + this.mStringCache.substring(end); - this.mStringCache = tempStr; - this.mSelectionStartCache = start + 1; - this.mSelectionEndCache = this.mSelectionStartCache; - } - if (this.mListeners == null) { - Log.e(TAG, "mListeners is null"); - return; - } - this.notifyListenersIfNeeded(true, true, false); - } - - /** - * Handles a function key event from the input method. - * @param functionKey - The function key that was pressed - */ - handleFunctionKey(functionKey: inputMethod.FunctionKey): void { - if (!this.TextInputChannel) { - return - } - switch (functionKey.enterKeyType) { - case inputMethod.EnterKeyType.PREVIOUS: - this.TextInputChannel.previous(this.client); - break; - case inputMethod.EnterKeyType.UNSPECIFIED: - this.TextInputChannel.unspecifiedAction(this.client); - break; - case inputMethod.EnterKeyType.NEWLINE: - this.TextInputChannel.newline(this.client); - break; - case inputMethod.EnterKeyType.GO: - this.TextInputChannel.go(this.client); - break; - case inputMethod.EnterKeyType.SEARCH: - this.TextInputChannel.search(this.client); - break; - case inputMethod.EnterKeyType.SEND: - this.TextInputChannel.send(this.client); - break; - case inputMethod.EnterKeyType.NEXT: - this.TextInputChannel.next(this.client); - break; - case inputMethod.EnterKeyType.DONE: - this.TextInputChannel.done(this.client); - break; - } - } - - /** - * Handles a text selection by range event. - * @param range - The range to select - */ - handleSelectByRangeEvent(range: inputMethod.Range): void { - if (range.start === 0) { // cursor index updated at the start pos of text - this.setSelectionStart(0); - this.setSelectionEnd(0); - } else { // cursor index updated at the end pos of text - this.setSelectionStart(this.getStringCache().length); - this.setSelectionEnd(this.getStringCache().length); - } - this.notifyListenersIfNeeded(false, true, false); - } - - /** - * cursor moved at 2D-text with 4 directions - * aaaaaa aaaaaa| - * bbbbbbb|b -(cursor_up)-> bbbbbbbb - * cccc cccc - * - * aaaaaa aaaaaa - * bbbbbbb|b -(cursor_down)-> bbbbbbbb - * cccc cccc| - * - * aaaaaa aaaaaa - * bbbbbbb|b -(cursor_right)-> bbbbbbbb| - * cccc cccc - * - * aaaaaa aaaaaa - * bbbbbbb|b -(cursor_left)-> bbbbbb|bb - * cccc cccc - */ - /** - * Handles cursor movement events in 2D text. - * @param direction - The direction to move the cursor - */ - handleMoveCursorEvent(direction: inputMethod.Direction): void { - switch (direction) { - case inputMethod.Direction.CURSOR_LEFT: - case inputMethod.Direction.CURSOR_RIGHT: - case inputMethod.Direction.CURSOR_UP: - case inputMethod.Direction.CURSOR_DOWN: - // simulate the hardware-keyboard arrow-key pressed with any directions, - // and the cursor index in text cache will be moved - this.simulateHardwareCursorMovement(direction, false); - break; - default: - Log.w(TAG, `"Unknown cursor movement direction: ${direction}"`); - break; - } - } - - /** - * text-selection changed with cursor moving at 2D-text - * (...) -> denotes the selection range of text - * aaaaaa aaaa(aa - * bbbb|bbbb -(cursor_up)-> bbbb)bbbb - * cccc cccc - * - * aaaaaa aaaaaa - * bbbbbbb|b -(cursor_down)-> bbbbbbb(b - * cccc cccc) - * - * aaaaaa aaaaaa - * bb|bbbbbb -(cursor_right)-> bb(b)bbbbb - * cccc cccc - * - * aaaaaa aaaaaa - * bbbbbbb|b -(cursor_left)-> bbbbbb(b)b - * cccc cccc - */ - /** - * Handles text selection changes with cursor movement. - * @param movement - The movement that triggers the selection change - */ - handleSelectByMovementEvent(movement: inputMethod.Movement) : void { - switch (movement.direction) { - case inputMethod.Direction.CURSOR_LEFT: - case inputMethod.Direction.CURSOR_RIGHT: - case inputMethod.Direction.CURSOR_UP: - case inputMethod.Direction.CURSOR_DOWN: - // simulate the hardware-keyboard shift-key combined with arrow-key simultaneously pressed, - // and the text selection changed with cursor movement - this.simulateHardwareCursorMovement(movement.direction, true); - break; - default: - Log.w(TAG, `"Unknown cursor movement direction: ${movement.direction}"`); - break; - } - } - - /** - * Gets the text to the left of the cursor. - * @param length - The maximum number of characters to return - * @returns The text to the left of the cursor - */ - getLeftTextOfCursor(length: number) : string { - if (length <= 0) { - return ""; - } - const strCacheLen = this.getStringCache().length; - if (!strCacheLen) { - return ""; - } - const cursorIdx = this.getSelectionStart(); - let startIdx = cursorIdx - length; - if (startIdx < 0) { - startIdx = 0; - } - return this.getStringCache().substring(startIdx, cursorIdx); - } - - /** - * Gets the text to the right of the cursor. - * @param length - The maximum number of characters to return - * @returns The text to the right of the cursor - */ - getRightTextOfCursor(length: number) : string { - if (length <= 0) { - return ""; - } - const strCacheLen = this.getStringCache().length; - if (!strCacheLen) { - return ""; - } - const cursorIdx = this.getSelectionEnd(); - let endIdx = cursorIdx + length; - if (endIdx >= strCacheLen) { - endIdx = strCacheLen; - } - return this.getStringCache().substring(cursorIdx, endIdx); - } - - /** - * Handles extended actions like select all, cut, copy, and paste. - * @param action - The action to perform - */ - handleExtendActionEvent(action: inputMethod.ExtendAction) : void { - switch (action) { - case inputMethod.ExtendAction.SELECT_ALL: - // select all text from the start to end, and notify cursor state updating - this.setSelectionStart(0); - this.setSelectionEnd(this.getStringCache().length); - this.notifyListenersIfNeeded(false, true, false); - break; - case inputMethod.ExtendAction.CUT: - // set to copy text before cutting - const cutText = this.getStringCache().substring(this.getSelectionStart(), this.getSelectionEnd()); - PasteboardUtils.setCopyData(cutText); - // based on the text selection length (endIdx - startIdx) for cutting - this.handleDeleteEvent(false, this.getSelectionEnd() - this.getSelectionStart(), false); - break; - case inputMethod.ExtendAction.COPY: - // obtain the current selection range of text cache as the copy text - const copyText = this.getStringCache().substring(this.getSelectionStart(), this.getSelectionEnd()); - PasteboardUtils.setCopyData(copyText); - break; - case inputMethod.ExtendAction.PASTE: - // PasteboardUtils.getPasteDataAsync() is a async function, so must await the async paste operatopn - // in sync func, otherwise there can be a problem of timing inconsistency in the insertion of pasted text here. - const handlePasteDataAsync = async () => { - try { - const pasteText = await PasteboardUtils.getPasteDataAsync(); - if (pasteText) { // insert the paste text into the editing box - this.handleInsertTextEvent(pasteText); - } - } catch (err) { - Log.e(TAG, "get PasteData error: " + err); - } - }; - handlePasteDataAsync(); - break; - default: - Log.w(TAG, `"Unknown ExtendAction: ${action}"`); - break; - } - } - - /** - * This method is used to simulate the hard-keyboard key event in soft-keyboard mode, - * Case 1: cursor moving is simulated by sending arrow-key event to flutter SDK (Dart-side), - * hence the cursor will move up/down/left/right in editing box. - * Case 2: text-selection changed with cursor moving is simulated by sending shift-key combined with arrow-key events - * to flutter SDK, hence the text-selection range will be updated by moving cursor up/down/left/right in editing box. - * @param direction: cursor move direction from IMC callback - * @param isShiftPressed: determine whether shift-key is pressed - */ - /** - * Simulates hardware keyboard cursor movement by sending key events to Flutter. - * @param direction - The direction to move the cursor - * @param isShiftPressed - Whether shift key is pressed (for text selection) - * @private - */ - private simulateHardwareCursorMovement(direction: inputMethod.Direction, isShiftPressed: boolean) : void { - // Here, '选择' button in '文本编辑' function of soft-keyboard inputMethod apps is a simulation for hardware shift-key. - // Therefore, when '选择' button is pressed in soft-keyboard equals to shift-key pressed in hard-keyboard - enum SimulatedKeyText { - KEY_SHIFT = 'KEYCODE_SHIFT_LEFT', - KEY_ARROW_UP = 'KEYCODE_DPAD_UP', - KEY_ARROW_DOWN = 'KEYCODE_DPAD_DOWN', - KEY_ARROW_LEFT = 'KEYCODE_DPAD_LEFT', - KEY_ARROW_RIGHT = 'KEYCODE_DPAD_RIGHT', - KEY_UNKNOWN = 'KEYCODE_UNKNOWN' - } - if (isShiftPressed) { // simulate shift-key down - this.sendSimulatedKeyEvent(new SimulateKeyEvent(KeyCode.KEYCODE_SHIFT_LEFT, SimulatedKeyText.KEY_SHIFT), false); - } - let arrowEvent: SimulateKeyEvent; - switch (direction) { - case inputMethod.Direction.CURSOR_UP: // simulate hardware arrow-up key event - arrowEvent = new SimulateKeyEvent(KeyCode.KEYCODE_DPAD_UP, SimulatedKeyText.KEY_ARROW_UP); - break; - case inputMethod.Direction.CURSOR_DOWN: // simulate hardware arrow-down key event - arrowEvent = new SimulateKeyEvent(KeyCode.KEYCODE_DPAD_DOWN, SimulatedKeyText.KEY_ARROW_DOWN); - break; - case inputMethod.Direction.CURSOR_LEFT: // simulate hardware arrow-left key event - arrowEvent = new SimulateKeyEvent(KeyCode.KEYCODE_DPAD_LEFT, SimulatedKeyText.KEY_ARROW_LEFT); - break; - case inputMethod.Direction.CURSOR_RIGHT: // simulate hardware arrow-right key event - arrowEvent = new SimulateKeyEvent(KeyCode.KEYCODE_DPAD_RIGHT, SimulatedKeyText.KEY_ARROW_RIGHT); - break; - default: - arrowEvent = new SimulateKeyEvent(KeyCode.KEYCODE_UNKNOWN, SimulatedKeyText.KEY_UNKNOWN); - break; - } - this.sendSimulatedKeyEvent(arrowEvent, false); // simulate arrow-key down - this.sendSimulatedKeyEvent(arrowEvent, true); // simulate arrow-key up - if (isShiftPressed) { // simulate shift-key up - this.sendSimulatedKeyEvent(new SimulateKeyEvent(KeyCode.KEYCODE_SHIFT_LEFT, SimulatedKeyText.KEY_SHIFT), true); - } - } - - /** - * Sends a simulated key event to Flutter. - * @param event - The key event to simulate - * @param isKeyUp - True for key up event, false for key down event - * @private - */ - private sendSimulatedKeyEvent(event: SimulateKeyEvent, isKeyUp: boolean) : void { - this.keyEventChannel?.simulateSendFlutterKeyEvent( - event, isKeyUp, { - onFrameworkResponse: (isEventHandled: boolean): void => {} - }); - } -} - -/** - * Interface for objects that watch for editing state changes. - * Changing the editing state in a didChangeEditingState callback may cause unexpected behavior. - */ -export interface EditingStateWatcher { - /** - * Called when the editing state changes. - * @param textChanged - Whether the text has changed - * @param selectionChanged - Whether the selection has changed - * @param composingRegionChanged - Whether the composing region has changed - */ - didChangeEditingState(textChanged: boolean, selectionChanged: boolean, composingRegionChanged: boolean): void; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextEditingDelta.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextEditingDelta.ets deleted file mode 100644 index 3ca1533..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextEditingDelta.ets +++ /dev/null @@ -1,117 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on TextEditingDelta.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import Log from '../../util/Log'; - -/** - * Represents a delta (change) in text editing state. - * This class tracks changes to text, selection, and composing regions. - */ -export class TextEditingDelta { - private static TAG = "TextEditingDelta"; - private oldText: string = ""; - private deltaText: string = ""; - private deltaStart: number = 0; - private deltaEnd: number = 0; - private newSelectionStart: number; - private newSelectionEnd: number; - private newComposingStart: number; - private newComposingEnd: number; - - /** - * Constructs a new TextEditingDelta instance. - * @param oldEditable - The text before the change - * @param selectionStart - The new selection start position - * @param selectionEnd - The new selection end position - * @param composingStart - The new composing region start position - * @param composingEnd - The new composing region end position - * @param replacementDestinationStart - Optional start position of the replacement destination - * @param replacementDestinationEnd - Optional end position of the replacement destination - * @param replacementSource - Optional replacement text - */ - constructor(oldEditable: string, - selectionStart: number, - selectionEnd: number, - composingStart: number, - composingEnd: number, - replacementDestinationStart?: number, - replacementDestinationEnd?: number, - replacementSource?: string) { - this.newSelectionStart = selectionStart; - this.newSelectionEnd = selectionEnd; - this.newComposingStart = composingStart; - this.newComposingEnd = composingEnd; - if (replacementDestinationStart === undefined || - replacementDestinationEnd === undefined || - replacementSource === undefined) { - this.setDeltas(oldEditable, "", -1, -1); - } else { - this.setDeltas( - oldEditable, - replacementSource, - replacementDestinationStart, - replacementDestinationEnd); - } - } - - /** - * Sets the delta information for this change. - * @param oldText - The text before the change - * @param newText - The replacement text - * @param newStart - The start position of the replacement - * @param newExtent - The end position of the replacement - */ - setDeltas(oldText: string, newText: string, newStart: number, newExtent: number): void { - this.oldText = oldText; - this.deltaText = newText; - this.deltaStart = newStart; - this.deltaEnd = newExtent; - } - - /** - * Converts this delta to a JSON representation. - * @returns A JSON object containing all delta information - */ - toJSON(): TextEditingDeltaJson { - let state: TextEditingDeltaJson = { - oldText: this.oldText.toString(), - deltaText: this.deltaText.toString(), - deltaStart: this.deltaStart, - deltaEnd: this.deltaEnd, - selectionBase: this.newSelectionStart, - selectionExtent: this.newSelectionEnd, - composingBase: this.newComposingStart, - composingExtent: this.newComposingEnd, - }; - return state; - } -} - -/** - * JSON representation of a text editing delta. - */ -export interface TextEditingDeltaJson { - /** The text before the change */ - oldText: string; - /** The replacement text */ - deltaText: string; - /** The start position of the replacement */ - deltaStart: number; - /** The end position of the replacement */ - deltaEnd: number; - /** The new selection start position */ - selectionBase: number; - /** The new selection end position */ - selectionExtent: number; - /** The new composing region start position */ - composingBase: number; - /** The new composing region end position */ - composingExtent: number; -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextInputPlugin.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextInputPlugin.ets deleted file mode 100644 index 664800a..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextInputPlugin.ets +++ /dev/null @@ -1,941 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on TextInputPlugin.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import TextInputChannel, { - Configuration, - TextEditState, - TextInputMethodHandler -} from '../../embedding/engine/systemchannels/TextInputChannel'; -import inputMethod from '@ohos.inputMethod'; -import Log from '../../util/Log'; -import { EditingStateWatcher, ListenableEditingState } from './ListenableEditingState'; -import Any from '../common/Any'; -import { inputDevice } from '@kit.InputKit'; -import { BusinessError } from '@kit.BasicServicesKit'; -import { PointerDeviceKind } from '../../embedding/ohos/OhosTouchProcessor'; -import deviceInfo from '@ohos.deviceInfo'; -import KeyEventChannel from '../../embedding/engine/systemchannels/KeyEventChannel'; -import { appManager, bundleManager } from '@kit.AbilityKit'; - -const INPUT_SUPPORT_API = 15; -const PREIVEW_TEXT_SUPPORT_API = 17; -const sdkApiVersion: number = deviceInfo.sdkApiVersion; - -/** - * Plugin for handling text input in Flutter applications. - * This class manages the interaction between Flutter's text input system - * and the OpenHarmony input method framework. - */ -export default class TextInputPlugin implements EditingStateWatcher { - private static TAG = "TextInputPlugin"; - private textInputChannel: TextInputChannel; - private keyEventChannel: KeyEventChannel | undefined; - private mTextInputHandler: TextInputMethodHandlerImpl; - - /** - * Constructs a new TextInputPlugin instance. - * @param textInputChannel - The TextInputChannel for communication with Flutter - * @param viewId - The view ID for focus management - * @param keyEventChannel - Optional KeyEventChannel for key event handling - */ - constructor(textInputChannel: TextInputChannel, viewId: string, keyEventChannel?: KeyEventChannel) { - this.textInputChannel = textInputChannel; - this.keyEventChannel = keyEventChannel; - // viewId is used for requestFocus - this.mTextInputHandler = new TextInputMethodHandlerImpl(this, viewId); - this.textInputChannel.setTextInputMethodHandler(this.mTextInputHandler); - } - - /** - * Clears the current text input client. - */ - public clearTextInputClient() { - this.textInputChannel.textInputMethodHandler?.clearClient(); - } - - /** - * Sets the text input editing state. - * @param state - The new editing state - */ - setTextInputEditingState(state: TextEditState) { - - } - - /** - * Gets the current editing state. - * @returns The current ListenableEditingState instance - */ - getEditingState() { - return this.mTextInputHandler.mEditable; - } - - /** - * Handles changes to preview text editing state. - * This method updates the editing widget with preview text from the input method. - * @param inputTarget - The input target - * @param editable - The editable state containing preview text - */ - didChangePreviewTextEditingState(inputTarget: InputTarget, editable: ListenableEditingState): void { - let stringCache: string = editable.getStringCache(); - // obtain the start index of editing preview text - let startIdx: number = editable.getLeftIdxOfPreviewTextRange(); - let leftStringCache = stringCache.substring(0, startIdx); - let rightStringCache = stringCache.substring(startIdx, stringCache.length); - // concat the string cache and preview text and show on the TextField - let finalStringCache = leftStringCache + editable.getPreviewText() + rightStringCache; - // update the selection range - let newSelectionStart: number = startIdx + editable.getPreviewText().length; - let newSelectionEnd: number = startIdx + editable.getPreviewText().length; - - this.textInputChannel.updateEditingState(inputTarget.id, finalStringCache, - newSelectionStart, newSelectionEnd, - editable.getComposingStart(), editable.getComposingEnd()) - // notify current cursor index to the InputMethodFramework - this.mTextInputHandler.inputMethodController.changeSelection(finalStringCache, - newSelectionStart, newSelectionEnd); - } - - /** - * Called when the editing state changes. - * @param textChanged - Whether the text has changed - * @param selectionChanged - Whether the selection has changed - * @param composingRegionChanged - Whether the composing region has changed - */ - didChangeEditingState(textChanged: boolean, selectionChanged: boolean, composingRegionChanged: boolean): void { - let editable = this.mTextInputHandler.mEditable; - let inputTarget = this.mTextInputHandler.inputTarget; - let configuration = this.mTextInputHandler.configuration; - if (configuration != null && configuration.enableDeltaModel) { - this.textInputChannel.updateEditingStateWithDeltas(inputTarget.id, editable.extractBatchTextEditingDeltas()); - editable.clearBatchDeltas(); - } else if (sdkApiVersion >= PREIVEW_TEXT_SUPPORT_API && editable.getPreviewText() != "") { - this.didChangePreviewTextEditingState(inputTarget, editable); - } - else { - this.textInputChannel.updateEditingState(inputTarget.id, editable.getStringCache(), - editable.getSelectionStart(), editable.getSelectionEnd(), - editable.getComposingStart(), editable.getComposingEnd()) - } - } - - /** - * Detaches the text input plugin from the input method framework. - */ - detach(): void { - this.mTextInputHandler.inputMethodController.detach((err) => { - if (err) { - Log.e(TextInputPlugin.TAG, "Failed to detach: " + JSON.stringify(err)); - } - }) - } - - /** - * Destroys the text input plugin, hiding the keyboard and cleaning up resources. - */ - destroy() { - // Since the Dart side no longer listens to the lifecycle, - // the keyboard must be explicitly hidden before the engine is destroyed. - this.mTextInputHandler.hide(); - this.textInputChannel.setTextInputMethodHandler(null); - } -} - -const INPUT_TYPE_NAME = - ['NONE', 'TEXT', 'MULTILINE', 'NUMBER', 'PHONE', 'DATETIME', 'EMAIL_ADDRESS', 'URL', 'VISIBLE_PASSWORD'] - -/** - * Implementation of TextInputMethodHandler for OpenHarmony input method framework. - * This class handles all interactions with the system input method. - */ -class TextInputMethodHandlerImpl implements TextInputMethodHandler { - private static TAG = "TextInputMethodHandlerImpl"; - private textConfig: inputMethod.TextConfig; - /** The input method controller for managing the keyboard. */ - inputMethodController: inputMethod.InputMethodController; - /** The current input target. */ - inputTarget: InputTarget; - /** The current text input configuration, or null if not set. */ - public configuration: Configuration | null = null; - private lastKind?: PointerDeviceKind; - /** The editable state for text input. */ - mEditable: ListenableEditingState; - private mRestartInputPending: boolean = false; - private plugin: EditingStateWatcher | Any; - private imcFlag: boolean = false; - private keyboardStatus: inputMethod.KeyboardStatus = inputMethod.KeyboardStatus.HIDE; - private inputAttribute: inputMethod.InputAttribute = - { textInputType: inputMethod.TextInputType.TEXT, enterKeyType: inputMethod.EnterKeyType.NONE }; - private keyboardFocusState: boolean = false; - private focusViewId: string = ""; - // Record the type of soft keyboard that was triggered last time - private lastInputType?: inputMethod.TextInputType; - private isInputMethodAttached: boolean = false; - - /** - * Constructs a new TextInputMethodHandlerImpl instance. - * @param plugin - The TextInputPlugin instance - * @param viewId - The view ID for focus management - */ - constructor(plugin: TextInputPlugin | Any, viewId: string) { - this.textConfig = { - inputAttribute: this.inputAttribute - }; - this.plugin = plugin; - this.mEditable = new ListenableEditingState(null, 0); - this.inputMethodController = inputMethod.getController(); - this.inputTarget = new InputTarget(Type.NO_TARGET, 0); - this.focusViewId = viewId; - } - - /** - * Shows the text input keyboard if appropriate. - * The keyboard is only shown if the input type is not NONE. - */ - show(): void { - try { - let isPhysicalKeyboard = false; - inputDevice.getDeviceList((Error: Error, ids: Array) => { - for (let i = 0; i < ids.length; i++) { - const type = inputDevice.getKeyboardTypeSync(ids[i]); - if (type === inputDevice.KeyboardType.ALPHABETIC_KEYBOARD || - type === inputDevice.KeyboardType.DIGITAL_KEYBOARD) { - isPhysicalKeyboard = true; - break; - } - } - // 适配api20,在外接键盘状态下,阻止软键盘重复拉起 - if (isPhysicalKeyboard) { - this.keyboardStatus = inputMethod.KeyboardStatus.SHOW; - } - }) - } catch (error) { - Log.e(TextInputMethodHandlerImpl.TAG, - `Show function failed to query device. Code is ${error.code}, message is ${error.message}`) - } - if (this.canShowTextInput()) { - // Ensure the Xcomponent gains focus before the soft keyboard is displayed. - focusControl.requestFocus(this.focusViewId); - this.keyboardFocusState = true; - this.showTextInput(); - } else { - this.hide(); - } - } - - /** - * Hides the text input keyboard. - */ - hide(): void { - // Ensure the Xcomponent loses focus before the soft keyboard is hided. - focusControl.requestFocus("unfocus-xcomponent-node"); - this.keyboardFocusState = false; - this.hideTextInput(); - } - - /** - * Gets the current keyboard focus state. - * @returns True if the keyboard has focus, false otherwise - */ - getKeyboardFocusState() { - return this.keyboardFocusState; - } - - /** - * Requests autofill functionality. - */ - requestAutofill(): void { - - } - - /** - * Finishes the autofill context. - * @param shouldSave - Whether to save the autofill data - */ - finishAutofillContext(shouldSave: boolean): void { - - } - - /** - * Sets the text input client. - * @param textInputClientId - The client ID - * @param configuration - The input configuration - */ - setClient(textInputClientId: number, configuration: Configuration | null): void { - this.setTextInputClient(textInputClientId, configuration); - } - - /** - * Updates the input configuration. - * @param configuration - The new input configuration - */ - updateConfig(configuration: Configuration | null) { - if (configuration) { - this.lastKind = this.configuration?.deviceKind; - this.configuration = configuration; - if (configuration.inputType) { - this.textConfig.inputAttribute.textInputType = configuration.inputType.type; - this.textConfig.inputAttribute.enterKeyType = configuration.inputAction as Any; - } - } - } - - /** - * Sets the platform view client for text input. - * @param id - The platform view ID - * @param usesVirtualDisplay - Whether the platform view uses a virtual display - */ - setPlatformViewClient(id: number, usesVirtualDisplay: boolean): void { - - } - - /** - * Sets the editable size and transform. - * @param width - The width of the editable area - * @param height - The height of the editable area - * @param transform - The transformation matrix - */ - setEditableSizeAndTransform(width: number, height: number, transform: number[]): void { - - } - - /** - * Sets the cursor size and position. - * @param cursorInfo - The cursor information - */ - setCursorSizeAndPosition(cursorInfo: inputMethod.CursorInfo) { - try { - this.inputMethodController.updateCursor(cursorInfo, (err: BusinessError) => { - if (err) { - Log.e(TextInputMethodHandlerImpl.TAG, "Failed to updateCursor:" + JSON.stringify(err)); - return; - } - }) - } catch (err) { - Log.e(TextInputMethodHandlerImpl.TAG, "Failed to updateCursor:" + JSON.stringify(err)); - } - } - - /** - * Sets the editing state from Flutter. - * @param editingState - The new editing state - */ - setEditingState(editingState: TextEditState): void { - Log.d(TextInputMethodHandlerImpl.TAG, - "text:" + editingState.text + " selectionStart:" + editingState.selectionStart + " selectionEnd:" - + editingState.selectionEnd + " composingStart:" + editingState.composingStart + " composingEnd" + - editingState.composingEnd); - this.mEditable.setPreviewText(""); - this.mEditable.setIsCursorIdxOutOfPreviewTextRange(false); - this.mEditable.updateTextInputState(editingState); - // notify current cursor index or selection range to the InputMethodFramework - this.inputMethodController.changeSelection("", - -1, -1, (err: BusinessError) => { - if (err) { - Log.e(TextInputMethodHandlerImpl.TAG, `Failed to changeSelection, code: ${err.code}, message: ${err.message}`); - return; - } - this.inputMethodController.changeSelection(editingState.text, - editingState.selectionStart, editingState.selectionEnd); - }); - if (sdkApiVersion >= PREIVEW_TEXT_SUPPORT_API) { - this.previewTextChangeSelection(editingState); - } - } - - /** - * Handles selection changes when preview text is active. - * If the cursor moves outside the preview text range, the preview text is inserted. - * @param editingState - The current editing state - */ - previewTextChangeSelection(editingState: TextEditState): void { - // if users only modify the cursor index without typing new preview text, - // clear the current preview text cache for avoiding inserting redundant preview text - // to insert at the current cursor position - let currCursorIndex: number = editingState.selectionStart; - let leftIdxOfPreviewText: number = this.mEditable.getLeftIdxOfPreviewTextRange(); - let rightIdxOfPreviewText: number = this.mEditable.getRightIdxOfPreviewTextRange(); - - let isCursorIdxOutOfPreviewTextRange = (leftIdxOfPreviewText != rightIdxOfPreviewText) && - (currCursorIndex < leftIdxOfPreviewText || currCursorIndex > rightIdxOfPreviewText) - // if user move the current cursor index out of editing preview text range, - // immediately inserting the first candidate word into the editing widget - if (isCursorIdxOutOfPreviewTextRange) { - // change selection async callback - this.inputMethodController.changeSelection(editingState.text, leftIdxOfPreviewText, rightIdxOfPreviewText) - .then(() => { - // force the cursor position at the end of editing preview text - editingState.selectionStart = rightIdxOfPreviewText; - editingState.selectionEnd = rightIdxOfPreviewText; - // update TextInputState and reset the preview text state - this.mEditable.updateTextInputState(editingState); - this.mEditable.setPreviewText(""); - }) - .catch((err: BusinessError) => { - console.error(`Failed to previewTextChangeSelection: ${JSON.stringify(err)}`); - }) - } - } - - /** - * Clears the current text input client. - */ - clearClient(): void { - this.clearTextInputClient(); - } - - private async showTextInput(): Promise { - if (!this.lastInputType) { - this.setLastInputType(this.configuration?.inputType?.type); - } - if (this.lastKind === undefined && this.configuration?.deviceKind !== undefined) { - this.lastKind = this.configuration.deviceKind; - } - if (this.keyboardStatus == inputMethod.KeyboardStatus.SHOW) { - // 增加键盘拉起状态时也调用attach,参数false则attach不会拉起键盘 - await this.attach(false); - if (this.lastKind != this.configuration?.deviceKind || - this.hasSecureKeyboardInSwitch()) { - if (deviceInfo.sdkApiVersion >= INPUT_SUPPORT_API) { - await this.inputMethodController.showTextInput(this.getRequestReason()); - } else { - await this.inputMethodController.showTextInput(); - } - if (this.configuration?.deviceKind !== undefined) { - this.lastKind = this.configuration.deviceKind; - } - } - this.setLastInputType(this.configuration?.inputType?.type); - return; - } - this.setLastInputType(this.configuration?.inputType?.type); - await this.attach(true); - if (this.configuration?.deviceKind !== undefined) { - this.lastKind = this.configuration.deviceKind; - } - if (!this.imcFlag) { - this.listenKeyBoardEvent(); - } - } - - private async hideTextInput(): Promise { - await this.inputMethodController.detach().then(() => { - this.keyboardStatus = inputMethod.KeyboardStatus.HIDE; - this.cancelListenKeyBoardEvent(); - }).catch((err: BusinessError) => { - Log.e(TextInputMethodHandlerImpl.TAG, "Failed to detach: " + JSON.stringify(err)); - this.keyboardStatus = inputMethod.KeyboardStatus.NONE; - }); - } - - /** - * Attaches to the input method controller. - * @param showKeyboard - Whether to show the keyboard immediately - * @private - */ - async attach(showKeyboard: boolean): Promise { - try { - // must register previewtext callbacks before attachment - if (sdkApiVersion >= PREIVEW_TEXT_SUPPORT_API) { - this.registerPreviewTextCallbacks(); - } - if (deviceInfo.sdkApiVersion >= INPUT_SUPPORT_API) { - await this.inputMethodController.attach(showKeyboard, this.textConfig, this.getRequestReason()).then(async () => { - await this.handleAttach(showKeyboard); - }); - } else { - await this.inputMethodController.attach(showKeyboard, this.textConfig).then(async () => { - await this.handleAttach(showKeyboard); - }); - } - } catch (err) { - Log.e(TextInputMethodHandlerImpl.TAG, "Failed to attach:" + JSON.stringify(err)); - this.keyboardStatus = inputMethod.KeyboardStatus.NONE; - } - } - - private async handleAttach(showKeyboard: boolean): Promise { - let isDetached = false; - if (showKeyboard) { - isDetached = await this.detachIfBackground(); - } - if (isDetached) { - this.isInputMethodAttached = false; - this.keyboardStatus = inputMethod.KeyboardStatus.NONE; - } else { - this.isInputMethodAttached = true; - this.cacheMethodCall(); - this.keyboardStatus = inputMethod.KeyboardStatus.SHOW; - } - } - - private async detachIfBackground(): Promise { - try { - const bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION; - const bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleFlags); - const currentInfo = await appManager.getRunningProcessInformation(); - const targetBundleName = bundleInfo?.name; - const currentProcess = currentInfo.find(info => info.bundleNames?.includes(targetBundleName)); - //STATE_FOREGROUND 代表进程处于前台,界面获焦并显示时状态为STATE_ACTIVE,参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-app-ability-appmanager#processstate10 - if ( - currentProcess && - (currentProcess.state === appManager.ProcessState.STATE_FOREGROUND || - currentProcess.state === appManager.ProcessState.STATE_BACKGROUND) - ) { - await this.inputMethodController.hideTextInput(); - return true; - } - } catch (err) { - Log.e( - TextInputMethodHandlerImpl.TAG, - `detachIfBackground error: ${JSON.stringify(err)}`, - ); - } - return false; - } - - cacheMethodCall(): void { - // Cache method calls when input method is attached; no-op if not used by this version - } - - /** - * Gets the request reason for showing the keyboard based on the input device kind. - * @returns The request reason for keyboard display - */ - getRequestReason() : inputMethod.RequestKeyboardReason { - let deviceKind : PointerDeviceKind = this.configuration?.deviceKind ?? PointerDeviceKind.UNKNOWN - Log.i(TextInputMethodHandlerImpl.TAG, "getRequestReason: deviceKind=" + deviceKind); - switch (deviceKind) { - case PointerDeviceKind.TOUCH: - return inputMethod.RequestKeyboardReason.TOUCH; - case PointerDeviceKind.MOUSE: - return inputMethod.RequestKeyboardReason.MOUSE; - case PointerDeviceKind.STYLUS: - case PointerDeviceKind.INVERTED_STYLUS: - case PointerDeviceKind.TRACKPAD: - return inputMethod.RequestKeyboardReason.OTHER; - default: - return inputMethod.RequestKeyboardReason.NONE; - } - } - - /** - * Handles focus state changes. - * @param focusState - The new focus state - */ - handleChangeFocus(focusState: boolean) { - if (focusState && this.keyboardFocusState) { - // When the app loses focus, the system automatically detaches the input method. - // Upon regaining focus, if the input method should be displayed, it must be reattached. - this.show(); - } - try { - inputDevice.getDeviceList((Error: Error, ids: Array) => { - let isPhysicalKeyboard = false; - for (let i = 0; i < ids.length; i++) { - const type = inputDevice.getKeyboardTypeSync(ids[i]); - if (type == inputDevice.KeyboardType.ALPHABETIC_KEYBOARD || type == inputDevice.KeyboardType.DIGITAL_KEYBOARD) { - isPhysicalKeyboard = true; - break; - } - } - - if(focusState && isPhysicalKeyboard && this.keyboardFocusState) { - this.cancelListenKeyBoardEvent(); - this.inputMethodController.detach().then(async () =>{ - await this.attach(true); - this.listenKeyBoardEvent(); - }) - } - }) - } catch (error) { - Log.e(TextInputMethodHandlerImpl.TAG, `Failed to query device. Code is ${error.code}, message is ${error.message}`) - } - } - - /** - * Updates the input attribute configuration. - */ - async updateAttribute(): Promise { - if (this.keyboardStatus != inputMethod.KeyboardStatus.SHOW) { - return; - } - try { - await this.inputMethodController.updateAttribute(this.inputAttribute); - } catch (err) { - Log.e(TextInputMethodHandlerImpl.TAG, "Failed to updateAttribute:" + JSON.stringify(err)); - } - } - - /** - * Sets the text input client with the given configuration. - * @param client - The client ID - * @param configuration - The input configuration - */ - setTextInputClient(client: number, configuration: Configuration | null): void { - if (configuration) { - this.lastKind = this.configuration?.deviceKind; - this.configuration = configuration; - if (configuration.inputType) { - this.textConfig.inputAttribute.textInputType = configuration.inputType.type; - this.textConfig.inputAttribute.enterKeyType = configuration.inputAction as Any; - } - } - if (this.canShowTextInput()) { - this.inputTarget = new InputTarget(Type.FRAMEWORK_CLIENT, client); - } else { - this.inputTarget = new InputTarget(Type.NO_TARGET, client); - } - this.mEditable.removeEditingStateListener(this.plugin); - - this.mEditable = new ListenableEditingState( - this.plugin.textInputChannel, this.inputTarget.id, this.plugin.keyEventChannel); - - this.mRestartInputPending = true; - this.mEditable.addEditingStateListener(this.plugin); - - this.inputAttribute = this.textConfig.inputAttribute; - - this.updateAttribute(); - } - - setLastInputType(inputType?: inputMethod.TextInputType): void { - this.lastInputType = inputType; - } - - // It is used to determine whether there is a safe keyboard for the keyboard type - // awakened by the two input boxes when a soft keyboard is already suspended - // and switching input boxes - hasSecureKeyboardInSwitch(): boolean { - // Since this method is called in showTextInput to determine whether a secure - // keyboard needs to be pulled up, the parameter must be true - this.handleAttach(true); - return this.lastInputType === inputMethod.TextInputType.VISIBLE_PASSWORD || - this.configuration?.inputType?.type === inputMethod.TextInputType.VISIBLE_PASSWORD; - } - - /** - * Checks if text input can be shown. - * @returns True if text input can be shown, false if input type is NONE - */ - canShowTextInput(): boolean { - if (this.configuration == null || this.configuration.inputType == null) { - return true; - } - return this.configuration.inputType.type != inputMethod.TextInputType.NONE; - } - - /** - * Registers callbacks for preview text functionality. - */ - registerPreviewTextCallbacks(): void { - try { - this.inputMethodController.on("setPreviewText", this.setPreviewTextCallback) - } catch (err) { - Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe setPreviewText:" + JSON.stringify(err)); - this.unregisterPreviewTextCallbacks(); - return; - } - - try { - this.inputMethodController.on("finishTextPreview", this.finishPreviewTextCallback) - } catch (err) { - Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe finishTextPreview:" + JSON.stringify(err)); - this.unregisterPreviewTextCallbacks(); - return; - } - } - - /** - * Unregisters preview text callbacks. - */ - unregisterPreviewTextCallbacks(): void { - this.inputMethodController?.off("setPreviewText", this.setPreviewTextCallback) - this.inputMethodController?.off("finishTextPreview", this.finishPreviewTextCallback); - } - - /** - * Registers listeners for keyboard events from the input method framework. - */ - listenKeyBoardEvent(): void { - try { - this.inputMethodController.on('insertText', this.insertTextCallback); - } catch (err) { - Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe insertText:" + JSON.stringify(err)); - this.cancelListenKeyBoardEvent(); - return; - } - - try { - this.inputMethodController.on('deleteLeft', this.deleteLeftCallback) - } catch (err) { - Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe deleteLeft:" + JSON.stringify(err)); - this.cancelListenKeyBoardEvent(); - return; - } - - try { - this.inputMethodController.on('deleteRight', this.deleteRightCallback) - } catch (err) { - Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe deleteRight:" + JSON.stringify(err)); - this.cancelListenKeyBoardEvent(); - return; - } - - try { - this.inputMethodController.on('sendFunctionKey', this.sendFunctionKeyCallback) - } catch (err) { - Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe sendFunctionKey:" + JSON.stringify(err)); - this.cancelListenKeyBoardEvent(); - return; - } - - try { - this.inputMethodController.on('sendKeyboardStatus', this.sendKeyboardStatusCallback) - } catch (err) { - Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe sendKeyboardStatus:" + JSON.stringify(err)); - this.cancelListenKeyBoardEvent(); - return; - } - - try { - this.inputMethodController.on('selectByRange', this.selectByRangeCallback) - } catch (err) { - Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe selectByRange:" + JSON.stringify(err)); - this.cancelListenKeyBoardEvent(); - return; - } - - try { - this.inputMethodController.on('moveCursor', this.moveCursorCallback) - } catch (err) { - Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe moveCursor:" + JSON.stringify(err)); - this.cancelListenKeyBoardEvent(); - return; - } - - try { - this.inputMethodController.on('handleExtendAction', this.handleExtendActionCallback) - } catch (err) { - Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe handleExtendAction:" + JSON.stringify(err)); - this.cancelListenKeyBoardEvent(); - return; - } - try { - this.inputMethodController.on('selectByMovement', this.selectByMovementCallback) - } catch (err) { - Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe selectByMovement:" + JSON.stringify(err)); - this.cancelListenKeyBoardEvent(); - return; - } - try { - this.inputMethodController.on('getLeftTextOfCursor', this.getLeftTextOfCursorCallback) - } catch (err) { - Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe getLeftTextOfCursor:" + JSON.stringify(err)); - this.cancelListenKeyBoardEvent(); - return; - } - try { - this.inputMethodController.on('getRightTextOfCursor', this.getRightTextOfCursorCallback) - } catch (err) { - Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe getRightTextOfCursor:" + JSON.stringify(err)); - this.cancelListenKeyBoardEvent(); - return; - } - try { - this.inputMethodController.on('getTextIndexAtCursor', this.getTextIndexAtCursorCallback) - } catch (err) { - Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe getTextIndexAtCursor:" + JSON.stringify(err)); - this.cancelListenKeyBoardEvent(); - return; - } - - Log.d(TextInputMethodHandlerImpl.TAG, "listenKeyBoardEvent success"); - this.imcFlag = true; - } - - private setPreviewTextCallback = (text: string, range: inputMethod.Range) => { - Log.i(TextInputMethodHandlerImpl.TAG, - "setPreviewTextCallback: text = " + text + " range = " + JSON.stringify(range)); - this.mEditable.handleInsertPreviewTextEvent(text, range); - } - - private finishPreviewTextCallback = () => { - Log.i(TextInputMethodHandlerImpl.TAG, "finishPreviewTextCallback"); - // When editing preview text, meanwhile switch the app to the background and - // the preview text will automatically insert into the string cache of TextField - this.mEditable.handleInsertTextEvent(this.mEditable.getPreviewText()); - this.mEditable.clearPreviewTextContents(); - } - - private insertTextCallback = (text: string) => { - this.mEditable.handleInsertTextEvent(text); - // notify the current cursor index to InputMethodFramework for preview mode - this.inputMethodController.changeSelection(this.mEditable.getStringCache(), this.mEditable.getSelectionStart(), - this.mEditable.getSelectionEnd()); - } - - private deleteLeftCallback = (length: number) => { - this.mEditable.handleDeleteEvent(false, length, this.configuration?.enableDeltaModel); - this.inputMethodController.changeSelection(this.mEditable.getStringCache(), this.mEditable.getSelectionStart(), - this.mEditable.getSelectionEnd()); - } - - private deleteRightCallback = (length: number) => { - this.mEditable.handleDeleteEvent(true, length, this.configuration?.enableDeltaModel); - this.inputMethodController.changeSelection(this.mEditable.getStringCache(), this.mEditable.getSelectionStart(), - this.mEditable.getSelectionEnd()); - } - - private sendFunctionKeyCallback = (functionKey: inputMethod.FunctionKey) => { - if (functionKey.enterKeyType == inputMethod.EnterKeyType.NEWLINE) { - // insertText回调不会通知换行事件,需要在这里进行处理 - this.mEditable.handleNewlineEvent(); - } - this.mEditable.handleFunctionKey(functionKey); - } - - private sendKeyboardStatusCallback = (state: inputMethod.KeyboardStatus) => { - // api20开始,外接键盘状态下,点击输入框会拉起软键盘,此时要阻止onConnectionClosed,否则输入框会无法输入 - try { - let isPhysicalKeyboard = false; - inputDevice.getDeviceList((Error: Error, ids: Array) => { - for (let i = 0; i < ids.length; i++) { - const type = inputDevice.getKeyboardTypeSync(ids[i]); - if (type === inputDevice.KeyboardType.ALPHABETIC_KEYBOARD || - type === inputDevice.KeyboardType.DIGITAL_KEYBOARD) { - isPhysicalKeyboard = true; - return; - } - } - this.keyboardStatus = state; - if (state === inputMethod.KeyboardStatus.HIDE) { - this.plugin.textInputChannel.onConnectionClosed(this.inputTarget.id); - } - }) - } catch (error) { - Log.e(TextInputMethodHandlerImpl.TAG, - `SendKeyboardStatusCallback function failed to query device. Code is ${error.code}, message is ${error.message}`) - } - } - - // obtain the range to update cursor idx to start/end of text cache - private selectByRangeCallback = (range: inputMethod.Range) => { - this.mEditable.handleSelectByRangeEvent(range); - this.inputMethodController.changeSelection(this.mEditable.getStringCache(), this.mEditable.getSelectionStart(), - this.mEditable.getSelectionEnd()); - } - - // move cursor postion with left, right, up and down in editing widget - private moveCursorCallback = (direction: inputMethod.Direction) => { - this.mEditable.handleMoveCursorEvent(direction); - this.inputMethodController.changeSelection(this.mEditable.getStringCache(), this.mEditable.getSelectionStart(), - this.mEditable.getSelectionEnd()); - } - - // handle extend clipboard actions, like 'select all', 'cut', 'copy' and 'paste' - private handleExtendActionCallback = (action: inputMethod.ExtendAction) => { - this.mEditable.handleExtendActionEvent(action); - this.inputMethodController.changeSelection(this.mEditable.getStringCache(), this.mEditable.getSelectionStart(), - this.mEditable.getSelectionEnd()); - } - - // text selection range changed with cursor direction movement - private selectByMovementCallback = (movement: inputMethod.Movement) => { - this.mEditable.handleSelectByMovementEvent(movement); - this.inputMethodController.changeSelection(this.mEditable.getStringCache(), this.mEditable.getSelectionStart(), - this.mEditable.getSelectionEnd()); - } - - // return the left-side text string of current cursor index ("abc|345" -> return "abc") - private getLeftTextOfCursorCallback = (length: number) : string => { - const retText = this.mEditable.getLeftTextOfCursor(length); - Log.i(TextInputMethodHandlerImpl.TAG, "getLeftTextOfCursor: " + retText); - return retText; - } - - // return the right-side text string of current cursor index ("abc|345" -> return "345") - private getRightTextOfCursorCallback = (length: number) : string => { - const retText = this.mEditable.getRightTextOfCursor(length); - Log.i(TextInputMethodHandlerImpl.TAG, "getRightTextOfCursor: " + retText); - return retText; - } - - // return the current cursor index of editing text - private getTextIndexAtCursorCallback = () => { - const cursorIdx = this.mEditable.getSelectionStart(); - Log.i(TextInputMethodHandlerImpl.TAG, "getTextIndexAtCursor: " + cursorIdx); - return cursorIdx; - } - - /** - * Cancels all keyboard event listeners. - */ - cancelListenKeyBoardEvent(): void { - this.inputMethodController?.off('insertText', this.insertTextCallback); - this.inputMethodController?.off('deleteLeft', this.deleteLeftCallback); - this.inputMethodController?.off('deleteRight', this.deleteRightCallback); - this.inputMethodController?.off('sendFunctionKey', this.sendFunctionKeyCallback); - this.inputMethodController?.off('sendKeyboardStatus', this.sendKeyboardStatusCallback); - this.inputMethodController?.off('selectByRange', this.selectByRangeCallback); - this.inputMethodController?.off('moveCursor', this.moveCursorCallback); - this.inputMethodController?.off('handleExtendAction', this.handleExtendActionCallback); - this.inputMethodController?.off('selectByMovement', this.selectByMovementCallback); - this.inputMethodController?.off('getLeftTextOfCursor', this.getLeftTextOfCursorCallback); - this.inputMethodController?.off('getRightTextOfCursor', this.getRightTextOfCursorCallback); - this.inputMethodController?.off('getTextIndexAtCursor', this.getTextIndexAtCursorCallback); - this.imcFlag = false; - } - - /** - * Clears the text input client. - */ - public clearTextInputClient(): void { - if (this.inputTarget.type == Type.VIRTUAL_DISPLAY_PLATFORM_VIEW) { - return; - } - this.mEditable.removeEditingStateListener(this.plugin); - this.configuration = null; - this.inputTarget = new InputTarget(Type.NO_TARGET, 0); - } -} - -/** - * Enumeration of input target types. - */ -enum Type { - /** No input target */ - NO_TARGET, - /** InputConnection is managed by the TextInputPlugin, and events are forwarded to the Flutter framework. */ - FRAMEWORK_CLIENT, - /** InputConnection is managed by a platform view that is presented on a virtual display. */ - VIRTUAL_DISPLAY_PLATFORM_VIEW, - /** InputConnection is managed by a platform view that is presented on a physical display. */ - PHYSICAL_DISPLAY_PLATFORM_VIEW, -} - -/** - * Represents a target for text input operations. - */ -export class InputTarget { - /** The type of input target. */ - type: Type; - /** The unique identifier for this input target. */ - id: number; - - /** - * Constructs a new InputTarget instance. - * @param type - The type of input target - * @param id - The target ID - */ - constructor(type: Type, id: number) { - this.type = type; - this.id = id; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextUtils.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextUtils.ets deleted file mode 100644 index 3e0ae4c..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextUtils.ets +++ /dev/null @@ -1,440 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on FlutterTextUtils.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ -import FlutterNapi from '../../embedding/engine/FlutterNapi'; -import Log from '../../util/Log'; - -const LINE_FEED: number = 0x0A; -const CARRIAGE_RETURN: number = 0x0D; -const COMBINING_ENCLOSING_KEYCAP: number = 0x20E3; -const CANCEL_TAG: number = 0xE007F; -const ZERO_WIDTH_JOINER: number = 0x200D; - -const TAG = "TextUtils"; - -/** - * Utility class for text processing operations, including Unicode code point handling, - * emoji detection, and text offset calculations. - */ -export class FlutterTextUtils { - - /** - * Checks if a Unicode code point represents an emoji. - * @param code - The Unicode code point to check - * @returns True if the code point is an emoji, false otherwise - */ - static isEmoji(code: number): boolean { - return FlutterNapi.unicodeIsEmoji(code); - } - - /** - * Checks if a Unicode code point represents an emoji modifier. - * @param code - The Unicode code point to check - * @returns True if the code point is an emoji modifier, false otherwise - */ - static isEmojiModifier(code: number): boolean { - return FlutterNapi.unicodeIsEmojiModifier(code); - } - - /** - * Checks if a Unicode code point represents an emoji modifier base. - * @param code - The Unicode code point to check - * @returns True if the code point is an emoji modifier base, false otherwise - */ - static isEmojiModifierBase(code: number): boolean { - return FlutterNapi.unicodeIsEmojiModifierBase(code); - } - - /** - * Checks if a Unicode code point represents a variation selector. - * @param code - The Unicode code point to check - * @returns True if the code point is a variation selector, false otherwise - */ - static isVariationSelector(code: number): boolean { - return FlutterNapi.unicodeIsVariationSelector(code); - } - - /** - * Checks if a Unicode code point represents a regional indicator symbol. - * @param code - The Unicode code point to check - * @returns True if the code point is a regional indicator symbol, false otherwise - */ - static isRegionalIndicatorSymbol(code: number): boolean { - return FlutterNapi.unicodeIsRegionalIndicatorSymbol(code); - } - - /** - * Checks if a Unicode code point is a tag specification character. - * @param code - The Unicode code point to check - * @returns True if the code point is a tag specification character, false otherwise - */ - static isTagSpecChar(code: number): boolean { - return 0xE0020 <= code && code <= 0xE007E; - } - - /** - * Checks if a Unicode code point is a keycap base character (0-9, #, *). - * @param code - The Unicode code point to check - * @returns True if the code point is a keycap base, false otherwise - */ - static isKeycapBase(code: number): boolean { - return ('0'.charCodeAt(0) <= code && code <= '9'.charCodeAt(0)) || code == '#'.charCodeAt(0) || code == '*'.charCodeAt(0); - } - - /** - * Gets the Unicode code point before the specified offset in the text. - * Handles surrogate pairs correctly. - * @param text - The text to examine - * @param offset - The offset position - * @returns The Unicode code point before the offset - * @throws RangeError if the offset is out of range - */ - static codePointBefore(text: string, offset: number): number { - if (offset <= 0 || offset > text.length) { - throw new RangeError('Offset out of range'); - } - - // Get the character before the offset - const char = text[offset - 1]; - - // Check if it is a low surrogate (part of a surrogate pair) - if (offset > 1 && char >= '\uDC00' && char <= '\uDFFF') { - const prevChar = text[offset - 2]; - // Check if the previous character is a high surrogate - if (prevChar >= '\uD800' && prevChar <= '\uDBFF') { - // If it is, combine the surrogate pair into a full Unicode code point - return (prevChar.charCodeAt(0) - 0xD800) * 0x400 + (char.charCodeAt(0) - 0xDC00) + 0x10000; - } - } - - // Return the code point of the single character (if it's not a surrogate pair) - return char.charCodeAt(0); - } - - /** - * Gets the Unicode code point at the specified offset in the text. - * Handles surrogate pairs correctly. - * @param text - The text to examine - * @param offset - The offset position - * @returns The Unicode code point at the offset - * @throws RangeError if the offset is out of range - */ - static codePointAt(text: string, offset: number): number { - if (offset >= text.length) { - throw new RangeError('Offset out of range'); - } - let char = text[offset]; - - // Check if it is a high surrogate (part of a surrogate pair) - if (char >= '\uD800' && char <= '\uDBFF' && offset + 1 < text.length) { - const nextChar = text[offset + 1]; - // Check if the previous character is a low surrogate - if (nextChar >= '\uDC00' && nextChar <= '\uDFFF') { - // If it is, combine the surrogate pair into a full Unicode code point - return (char.charCodeAt(0) - 0xD800) * 0x400 + (nextChar.charCodeAt(0) - 0xDC00) + 0x10000; - } - } - return char.charCodeAt(0); - } - - /** - * Gets the number of UTF-16 code units required to represent a Unicode code point. - * @param codePoint - The Unicode code point - * @returns 1 for BMP characters (0x0000-0xFFFF), 2 for supplementary characters (0x10000-0x10FFFF) - */ - static charCount(codePoint: number): number { - // If the code point is in the BMP range (0x0000 - 0xFFFF), it needs 1 UTF-16 code unit - if (codePoint <= 0xFFFF) { - return 1; - } - // If the code point is in the supplementary range (0x10000 - 0x10FFFF), it needs 2 UTF-16 code units - return 2; - } - - /** - * Gets the offset before the current position, handling complex Unicode sequences - * such as emojis, regional indicators, keycaps, and variation selectors. - * @param text - The text to examine - * @param offset - The current offset position - * @returns The offset before the current position, accounting for Unicode sequences - */ - static getOffsetBefore(text: string, offset: number): number { - if (offset <= 1) { - return 0; - } - - let codePoint: number = FlutterTextUtils.codePointBefore(text, offset); - let deleteCharCount: number = FlutterTextUtils.charCount(codePoint); - let lastOffset: number = offset - deleteCharCount; - - if (lastOffset == 0) { - return 0; - } - - // Line Feed - if (codePoint == LINE_FEED) { - codePoint = FlutterTextUtils.codePointBefore(text, lastOffset); - if (codePoint == CARRIAGE_RETURN) { - ++deleteCharCount; - } - return offset - deleteCharCount; - } - - // Flags - if (FlutterTextUtils.isRegionalIndicatorSymbol(codePoint)) { - codePoint = FlutterTextUtils.codePointBefore(text, lastOffset); - lastOffset -= FlutterTextUtils.charCount(codePoint); - let regionalIndicatorSymbolCount: number = 1; - while (lastOffset > 0 && FlutterTextUtils.isRegionalIndicatorSymbol(codePoint)) { - codePoint = FlutterTextUtils.codePointBefore(text, lastOffset); - lastOffset -= FlutterTextUtils.charCount(codePoint); - regionalIndicatorSymbolCount++; - } - if (FlutterTextUtils.isRegionalIndicatorSymbol(codePoint)) { - regionalIndicatorSymbolCount++; - } - if (regionalIndicatorSymbolCount % 2 == 0) { - deleteCharCount += 2; - } - return offset - deleteCharCount; - } - - // Keycaps - if (codePoint == COMBINING_ENCLOSING_KEYCAP) { - codePoint = FlutterTextUtils.codePointBefore(text, lastOffset); - lastOffset -= FlutterTextUtils.charCount(codePoint); - if (lastOffset > 0 && FlutterTextUtils.isVariationSelector(codePoint)) { - let tmpCodePoint: number = FlutterTextUtils.codePointBefore(text, lastOffset); - if (FlutterTextUtils.isKeycapBase(tmpCodePoint)) { - deleteCharCount += FlutterTextUtils.charCount(codePoint) + FlutterTextUtils.charCount(tmpCodePoint); - } - } else if (FlutterTextUtils.isKeycapBase(codePoint)) { - deleteCharCount += FlutterTextUtils.charCount(codePoint); - } - return offset - deleteCharCount; - } - - /** - * Following if statements for Emoji tag sequence and Variation selector are skipping these - * modifiers for going through the last statement that is for handling emojis. They return the - * offset if they don't find proper base characters - */ - // Emoji Tag Sequence - if (codePoint == CANCEL_TAG) { // tag_end - codePoint = FlutterTextUtils.codePointBefore(text, lastOffset); - lastOffset -= FlutterTextUtils.charCount(codePoint); - while (lastOffset > 0 && FlutterTextUtils.isTagSpecChar(codePoint)) { // tag_spec - deleteCharCount += FlutterTextUtils.charCount(codePoint); - codePoint = FlutterTextUtils.codePointBefore(text, lastOffset); - lastOffset -= FlutterTextUtils.charCount(codePoint); - } - if (!FlutterTextUtils.isEmoji(codePoint)) { // tag_base not found. Just delete the end. - return offset - 2; - } - deleteCharCount += FlutterTextUtils.charCount(codePoint); - } - - if (FlutterTextUtils.isVariationSelector(codePoint)) { - codePoint = FlutterTextUtils.codePointBefore(text, lastOffset); - if (!FlutterTextUtils.isEmoji(codePoint)) { - return offset - deleteCharCount; - } - deleteCharCount += FlutterTextUtils.charCount(codePoint); - - lastOffset -= FlutterTextUtils.charCount(codePoint); - } - - if (FlutterTextUtils.isEmoji(codePoint)) { - let isZwj: boolean = false; - let lastSeenVariantSelectorCharCount: number = 0; - do { - if (isZwj) { - deleteCharCount += FlutterTextUtils.charCount(codePoint) + lastSeenVariantSelectorCharCount + 1; - isZwj = false; - } - lastSeenVariantSelectorCharCount = 0; - if (FlutterTextUtils.isEmojiModifier(codePoint)) { - codePoint = FlutterTextUtils.codePointBefore(text, lastOffset); - lastOffset -= FlutterTextUtils.charCount(codePoint); - if (lastOffset > 0 && FlutterTextUtils.isVariationSelector(codePoint)) { - codePoint = FlutterTextUtils.codePointBefore(text, lastOffset); - if (!FlutterTextUtils.isEmoji(codePoint)) { - return offset - deleteCharCount; - } - lastSeenVariantSelectorCharCount = FlutterTextUtils.charCount(codePoint); - lastOffset -= FlutterTextUtils.charCount(codePoint); - } - if (FlutterTextUtils.isEmojiModifierBase(codePoint)) { - deleteCharCount += lastSeenVariantSelectorCharCount + FlutterTextUtils.charCount(codePoint); - } - break; - } - - if (lastOffset > 0) { - codePoint = FlutterTextUtils.codePointBefore(text, lastOffset); - lastOffset -= FlutterTextUtils.charCount(codePoint); - if (codePoint == ZERO_WIDTH_JOINER) { - isZwj = true; - codePoint = FlutterTextUtils.codePointBefore(text, lastOffset); - lastOffset -= FlutterTextUtils.charCount(codePoint); - if (lastOffset > 0 && FlutterTextUtils.isVariationSelector(codePoint)) { - codePoint = FlutterTextUtils.codePointBefore(text, lastOffset); - lastSeenVariantSelectorCharCount = FlutterTextUtils.charCount(codePoint); - lastOffset -= FlutterTextUtils.charCount(codePoint); - } - } - } - - if (lastOffset == 0) { - break; - } - } while (isZwj && FlutterTextUtils.isEmoji(codePoint)); - - if (isZwj && lastOffset == 0) { - deleteCharCount += FlutterTextUtils.charCount(codePoint) + lastSeenVariantSelectorCharCount + 1; - isZwj = false; - } - } - - return offset - deleteCharCount; - } - - /** - * Gets the offset after the current position, handling complex Unicode sequences - * such as emojis, regional indicators, keycaps, and variation selectors. - * @param text - The text to examine - * @param offset - The current offset position - * @returns The offset after the current position, accounting for Unicode sequences - */ - static getOffsetAfter(text: string, offset: number): number { - const len = text.length; - if (offset >= len - 1) { - return len; - } - - let codePoint: number = FlutterTextUtils.codePointAt(text, offset); - let nextCharCount: number = FlutterTextUtils.charCount(codePoint); - let nextOffset: number = offset + nextCharCount; - - if (nextOffset == 0) { - return 0; - } - // Line Feed - if (codePoint == LINE_FEED) { - codePoint = FlutterTextUtils.codePointAt(text, nextOffset); - if (codePoint == CARRIAGE_RETURN) { - ++nextCharCount; - } - return offset + nextCharCount; - } - - // Flags - if (FlutterTextUtils.isRegionalIndicatorSymbol(codePoint)) { - if (nextOffset >= len - 1 - || !FlutterTextUtils.isRegionalIndicatorSymbol(FlutterTextUtils.codePointAt(text, nextOffset))) { - return offset + nextCharCount; - } - // In this case there are at least two regional indicator symbols ahead of - // offset. If those two regional indicator symbols are a pair that - // represent a region together, the next offset should be after both of - // them. - let regionalIndicatorSymbolCount: number = 0; - let regionOffset: number = offset; - while (regionOffset > 0 - && FlutterTextUtils.isRegionalIndicatorSymbol(FlutterTextUtils.codePointBefore(text, regionOffset))) { - regionOffset -= FlutterTextUtils.charCount(FlutterTextUtils.codePointBefore(text, regionOffset)); - regionalIndicatorSymbolCount++; - } - if (regionalIndicatorSymbolCount % 2 == 0) { - nextCharCount += 2; - } - return offset + nextCharCount; - } - - // Keycaps - if (FlutterTextUtils.isKeycapBase(codePoint)) { - nextCharCount += FlutterTextUtils.charCount(codePoint); - } - if (codePoint == COMBINING_ENCLOSING_KEYCAP) { - codePoint = FlutterTextUtils.codePointBefore(text, nextOffset); - nextOffset += FlutterTextUtils.charCount(codePoint); - if (nextOffset < len && FlutterTextUtils.isVariationSelector(codePoint)) { - let tmpCodePoint: number = FlutterTextUtils.codePointAt(text, nextOffset); - if (FlutterTextUtils.isKeycapBase(tmpCodePoint)) { - nextCharCount += FlutterTextUtils.charCount(codePoint) + FlutterTextUtils.charCount(tmpCodePoint); - } - } else if (FlutterTextUtils.isKeycapBase(codePoint)) { - nextCharCount += FlutterTextUtils.charCount(codePoint); - } - return offset + nextCharCount; - } - - if (FlutterTextUtils.isEmoji(codePoint)) { - let isZwj: boolean = false; - let lastSeenVariantSelectorCharCount: number = 0; - do { - if (isZwj) { - nextCharCount += FlutterTextUtils.charCount(codePoint) + lastSeenVariantSelectorCharCount + 1; - isZwj = false; - } - lastSeenVariantSelectorCharCount = 0; - if (FlutterTextUtils.isEmojiModifier(codePoint)) { - break; - } - - if (nextOffset < len) { - codePoint = FlutterTextUtils.codePointAt(text, nextOffset); - nextOffset += FlutterTextUtils.charCount(codePoint); - if (codePoint == COMBINING_ENCLOSING_KEYCAP) { - codePoint = FlutterTextUtils.codePointBefore(text, nextOffset); - nextOffset += FlutterTextUtils.charCount(codePoint); - if (nextOffset < len && FlutterTextUtils.isVariationSelector(codePoint)) { - let tmpCodePoint: number = FlutterTextUtils.codePointAt(text, nextOffset); - if (FlutterTextUtils.isKeycapBase(tmpCodePoint)) { - nextCharCount += FlutterTextUtils.charCount(codePoint) + FlutterTextUtils.charCount(tmpCodePoint); - } - } else if (FlutterTextUtils.isKeycapBase(codePoint)) { - nextCharCount += FlutterTextUtils.charCount(codePoint); - } - return offset + nextCharCount; - } - if (FlutterTextUtils.isEmojiModifier(codePoint)) { - nextCharCount += lastSeenVariantSelectorCharCount + FlutterTextUtils.charCount(codePoint); - break; - } - if (FlutterTextUtils.isVariationSelector(codePoint)) { - nextCharCount += lastSeenVariantSelectorCharCount + FlutterTextUtils.charCount(codePoint); - break; - } - if (codePoint == ZERO_WIDTH_JOINER) { - isZwj = true; - codePoint = FlutterTextUtils.codePointAt(text, nextOffset); - nextOffset += FlutterTextUtils.charCount(codePoint); - if (nextOffset < len && FlutterTextUtils.isVariationSelector(codePoint)) { - codePoint = FlutterTextUtils.codePointAt(text, nextOffset); - lastSeenVariantSelectorCharCount = FlutterTextUtils.charCount(codePoint); - nextOffset += FlutterTextUtils.charCount(codePoint); - } - } - } - - if (nextOffset >= len) { - break; - } - } while (isZwj && FlutterTextUtils.isEmoji(codePoint)); - - if (isZwj && nextOffset >= len) { - nextCharCount += FlutterTextUtils.charCount(codePoint) + lastSeenVariantSelectorCharCount + 1; - isZwj = false; - } - } - - return offset + nextCharCount; - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/localization/LocalizationPlugin.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/localization/LocalizationPlugin.ets deleted file mode 100644 index cf50893..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/localization/LocalizationPlugin.ets +++ /dev/null @@ -1,123 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on LocalizationPlugin.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import LocalizationChannel, { - LocalizationMessageHandler -} from '../../embedding/engine/systemchannels/LocalizationChannel' -import common from '@ohos.app.ability.common'; -import intl from '@ohos.intl'; -import Log from '../../util/Log'; -import i18n from '@ohos.i18n'; - -const TAG = "LocalizationPlugin"; - -/** - * Plugin for handling localization in Flutter applications. - * This class manages the interaction between Flutter's localization system - * and the OpenHarmony resource management system. - */ -export default class LocalizationPlugin { - private localizationChannel: LocalizationChannel; - private context: common.Context; - - /** - * Converts a locale string to an intl.Locale object. - * @param localeString - The locale string (e.g., "en_US" or "zh-CN") - * @returns The corresponding intl.Locale object - */ - localeFromString(localeString: string): intl.Locale { - localeString = localeString.replace('_', '-'); - let parts: string[] = localeString.split('-', -1); - let languageCode = parts[0]; - let scriptCode = ""; - let countryCode = ""; - let index: number = 1; - - if (parts.length > index && parts[index].length == 4) { - scriptCode = parts[index]; - index++; - } - - if (parts.length > index && parts[index].length >= 2 && parts[index].length <= 3) { - countryCode = parts[index]; - index++; - } - return new intl.Locale(languageCode + '-' + countryCode + '-' + scriptCode); - } - - private localizationMessageHandler: LocalizationMessageHandler = - new enterGetStringResource((key: string, localeString: string | null) => { - - Log.i(TAG, "getStringResource,key: " + key + ",localeString: " + localeString); - let localContext: common.Context = this.context; - let stringToReturn: string | null = null; - // 获取资源管理器 - let resMgr = localContext.resourceManager; - - try { - // 如果localeString不为空,则更新为指定地区的资源管理器 - if (localeString) { - let overrideConfig = resMgr.getOverrideConfiguration(); - overrideConfig.locale = localeString; - let overrideResMgr = resMgr.getOverrideResourceManager(overrideConfig); - stringToReturn = overrideResMgr.getStringByNameSync(key); - } else { - stringToReturn = resMgr.getStringByNameSync(key); - } - } catch (e) { - Log.e(TAG, e); - return null; - } - - return stringToReturn; - }) - - /** - * Constructs a new LocalizationPlugin instance. - * @param context - The application context - * @param localizationChannel - The LocalizationChannel for communication with Flutter - */ - constructor(context: common.Context, localizationChannel: LocalizationChannel) { - this.context = context; - this.localizationChannel = localizationChannel; - this.localizationChannel.setLocalizationMessageHandler(this.localizationMessageHandler); - } - - /** - * Sends the system locale to Flutter. - */ - sendLocaleToFlutter(): void { - let systemLocale: string = i18n.System.getSystemLocale(); - let data: Array = []; - data.push(systemLocale); - this.localizationChannel.sendLocales(data); - } -} - -/** - * Implementation of LocalizationMessageHandler for getting string resources. - */ -class enterGetStringResource { - /** - * The function to get string resources. - * @param key - The resource key - * @param localeString - The locale string, or null to use the default locale - * @returns The localized string, or null if not found - */ - getStringResource: (key: string, localeString: string | null) => string | null - - /** - * Constructs a new enterGetStringResource instance. - * @param getStringResource - The function to get string resources - */ - constructor(getStringResource: (key: string, localeString: string | null) => string | null) { - this.getStringResource = getStringResource - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/mouse/MouseCursorPlugin.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/mouse/MouseCursorPlugin.ets deleted file mode 100644 index 21689d3..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/mouse/MouseCursorPlugin.ets +++ /dev/null @@ -1,135 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on MouseCursorPlugin.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import MouseCursorChannel, { MouseCursorMethodHandler } from '../../embedding/engine/systemchannels/MouseCursorChannel'; -import pointer from '@ohos.multimodalInput.pointer'; -import HashMap from '@ohos.util.HashMap'; -import Log from '../../util/Log'; -import Any from '../common/Any'; - -const TAG: string = "MouseCursorPlugin"; - -/** - * Plugin for handling mouse cursor changes in Flutter applications. - * This class manages the interaction between Flutter's cursor system - * and the OpenHarmony pointer style system. - */ -export default class MouseCursorPlugin implements MouseCursorMethodHandler { - private mouseCursorChannel: MouseCursorChannel; - private systemCursorConstants: HashMap | null = null; - private windowId: number; - - /** - * Constructs a new MouseCursorPlugin instance. - * @param windowId - The window ID for setting pointer styles - * @param mouseCursorChannel - The MouseCursorChannel for communication with Flutter - */ - constructor(windowId: number, mouseCursorChannel: MouseCursorChannel) { - this.windowId = windowId; - this.mouseCursorChannel = mouseCursorChannel; - this.mouseCursorChannel.setMethodHandler(this); - } - - /** - * Activates a system cursor for the specified kind. - * @param kind - The cursor kind (e.g., "click", "text", "move") - */ - activateSystemCursor(kind: string): void { - if (this.windowId < 0) { - Log.e(TAG, "setPointerStyle failed: windowId is invalid: " + this.windowId); - return; - } - let pointStyle: pointer.PointerStyle = this.resolveSystemCursor(kind); - try { - pointer.setPointerStyle(this.windowId, pointStyle, (err: Any) => { - if (err) { - Log.e(TAG, "setPointerStyle callback error: kind=" + kind + ", err=" + JSON.stringify(err)); - } else { - Log.i(TAG, "setPointerStyle success: kind=" + kind); - } - }) - } catch (e) { - Log.e(TAG, "setPointerStyle exception: kind=" + kind + ", error=" + JSON.stringify(e)); - } - } - - private resolveSystemCursor(kind: string): pointer.PointerStyle { - if (this.systemCursorConstants == null) { - this.systemCursorConstants = new HashMap(); - this.systemCursorConstants.set("alias", pointer.PointerStyle.DEFAULT); - this.systemCursorConstants.set("allScroll", pointer.PointerStyle.MOVE); - this.systemCursorConstants.set("basic", pointer.PointerStyle.DEFAULT); - this.systemCursorConstants.set("cell", pointer.PointerStyle.DEFAULT); - this.systemCursorConstants.set("click", pointer.PointerStyle.HAND_POINTING); - this.systemCursorConstants.set("contextMenu", pointer.PointerStyle.DEFAULT); - this.systemCursorConstants.set("copy", pointer.PointerStyle.CURSOR_COPY); - this.systemCursorConstants.set("forbidden", pointer.PointerStyle.CURSOR_FORBID); - this.systemCursorConstants.set("grab", pointer.PointerStyle.HAND_OPEN); - this.systemCursorConstants.set("grabbing", pointer.PointerStyle.HAND_GRABBING); - this.systemCursorConstants.set("help", pointer.PointerStyle.HELP); - this.systemCursorConstants.set("move", pointer.PointerStyle.MOVE); - this.systemCursorConstants.set("none", pointer.PointerStyle.DEFAULT); - this.systemCursorConstants.set("noDrop", pointer.PointerStyle.DEFAULT); - this.systemCursorConstants.set("precise", pointer.PointerStyle.CROSS); - this.systemCursorConstants.set("text", pointer.PointerStyle.TEXT_CURSOR); - this.systemCursorConstants.set("resizeColum", pointer.PointerStyle.NORTH_SOUTH); - this.systemCursorConstants.set("resizeDown", pointer.PointerStyle.SOUTH); - this.systemCursorConstants.set("resizeDownLeft", pointer.PointerStyle.SOUTH_WEST); - this.systemCursorConstants.set("resizeDownRight", pointer.PointerStyle.SOUTH_EAST); - this.systemCursorConstants.set("resizeLeft", pointer.PointerStyle.WEST); - this.systemCursorConstants.set("resizeLeftRight", pointer.PointerStyle.RESIZE_LEFT_RIGHT); - this.systemCursorConstants.set("resizeRight", pointer.PointerStyle.EAST); - this.systemCursorConstants.set("resizeRow", pointer.PointerStyle.WEST_EAST); - this.systemCursorConstants.set("resizeUp", pointer.PointerStyle.NORTH); - this.systemCursorConstants.set("resizeUpDown", pointer.PointerStyle.RESIZE_UP_DOWN); - this.systemCursorConstants.set("resizeUpLeft", pointer.PointerStyle.NORTH_WEST); - this.systemCursorConstants.set("resizeUpRight", pointer.PointerStyle.NORTH_EAST); - this.systemCursorConstants.set("resizeUpLeftDownRight", pointer.PointerStyle.NORTH_WEST_SOUTH_EAST); - this.systemCursorConstants.set("resizeUpRightDownLeft", pointer.PointerStyle.NORTH_EAST_SOUTH_WEST); - this.systemCursorConstants.set("verticalText", pointer.PointerStyle.TEXT_CURSOR); - this.systemCursorConstants.set("wait", pointer.PointerStyle.DEFAULT); - this.systemCursorConstants.set("zoomIn", pointer.PointerStyle.ZOOM_IN); - this.systemCursorConstants.set("zoomOut", pointer.PointerStyle.ZOOM_OUT); - this.systemCursorConstants.set("middleBtnEast", pointer.PointerStyle.MIDDLE_BTN_EAST); - this.systemCursorConstants.set("middleBtnWest", pointer.PointerStyle.MIDDLE_BTN_WEST); - this.systemCursorConstants.set("middleBtnSouth", pointer.PointerStyle.MIDDLE_BTN_SOUTH); - this.systemCursorConstants.set("middleBtnNorth", pointer.PointerStyle.MIDDLE_BTN_NORTH); - this.systemCursorConstants.set("middleBtnNorthSouth", pointer.PointerStyle.MIDDLE_BTN_NORTH_SOUTH); - this.systemCursorConstants.set("middleBtnNorthEast", pointer.PointerStyle.MIDDLE_BTN_NORTH_EAST); - this.systemCursorConstants.set("middleBtnNorthWest", pointer.PointerStyle.MIDDLE_BTN_NORTH_WEST); - this.systemCursorConstants.set("middleBtnSouthEast", pointer.PointerStyle.MIDDLE_BTN_SOUTH_EAST); - this.systemCursorConstants.set("middleBtnSouthWest", pointer.PointerStyle.MIDDLE_BTN_SOUTH_WEST); - this.systemCursorConstants.set("middleBtnNorthSouthWestEast", - pointer.PointerStyle.MIDDLE_BTN_NORTH_SOUTH_WEST_EAST); - this.systemCursorConstants.set("horizontalTextCursor", pointer.PointerStyle.HORIZONTAL_TEXT_CURSOR); - this.systemCursorConstants.set("cursorCross", pointer.PointerStyle.CURSOR_CROSS); - this.systemCursorConstants.set("cursorCircle", pointer.PointerStyle.CURSOR_CIRCLE); - this.systemCursorConstants.set("loading", pointer.PointerStyle.LOADING); - this.systemCursorConstants.set("running", pointer.PointerStyle.RUNNING); - this.systemCursorConstants.set("colorSucker", pointer.PointerStyle.COLOR_SUCKER); - this.systemCursorConstants.set("screenshotChoose", pointer.PointerStyle.SCREENSHOT_CHOOSE); - this.systemCursorConstants.set("screenshotCursor", pointer.PointerStyle.SCREENSHOT_CURSOR); - } - let pointStyle: pointer.PointerStyle = this.systemCursorConstants.get(kind); - if (pointStyle === null) { - return pointer.PointerStyle.DEFAULT; - } - return pointStyle; - } - - /** - * Destroys the mouse cursor plugin and cleans up resources. - * The MouseCursorPlugin instance should not be used after calling this. - */ - destroy(): void { - this.mouseCursorChannel.setMethodHandler(null); - } -} - diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/CustomTouchEvent.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/CustomTouchEvent.ets deleted file mode 100644 index 6475db4..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/CustomTouchEvent.ets +++ /dev/null @@ -1,184 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -*/ - -/** - * Custom implementation of TouchEvent for platform views. - * This class wraps touch event data for communication between Flutter and native views. - */ -export class CustomTouchEvent implements TouchEvent { - /** The type of touch event. */ - type: TouchType = 0; - /** Array of all touch points in this event. */ - touches: CustomTouchObject[]; - /** Array of touch points that changed in this event. */ - changedTouches: CustomTouchObject[]; - /** Function to stop event propagation. */ - stopPropagation: () => void = () => { - }; - /** The timestamp when the event occurred. */ - timestamp: number; - /** The source type of the touch event. */ - source: SourceType; - /** The pressure value of the touch. */ - pressure: number; - /** The X-axis tilt value of the touch. */ - tiltX: number; - /** The Y-axis tilt value of the touch. */ - tiltY: number; - /** The source tool type for the touch. */ - sourceTool: SourceTool; - - /** - * Constructs a new CustomTouchEvent instance. - * @param type - The touch event type - * @param touches - Array of all touch points - * @param changedTouches - Array of touch points that changed - * @param timestamp - The event timestamp - * @param source - The source type of the touch - * @param pressure - The pressure value - * @param tiltX - The X-axis tilt value - * @param tiltY - The Y-axis tilt value - * @param sourceTool - The source tool type - */ - constructor(type: TouchType, touches: CustomTouchObject[], changedTouches: CustomTouchObject[], timestamp: number, - source: SourceType, pressure: number, tiltX: number, tiltY: number, sourceTool: SourceTool) { - this.type = type; - this.touches = touches; - this.changedTouches = changedTouches; - this.timestamp = timestamp; - this.source = source; - this.pressure = pressure; - this.tiltX = tiltX; - this.tiltY = tiltY; - this.sourceTool = sourceTool; - } - - /** Function to prevent the default action. */ - preventDefault: () => void = () => { - }; - - /** - * Gets the modifier key state. - * @param keys - Array of key names to check - * @returns True if any of the keys are pressed - * @throws Error as this method is not implemented - */ - getModifierKeyState(keys: string[]): boolean { - throw new Error('Method not implemented.'); - } - - /** The event target for this touch event. */ - target: EventTarget = new CustomEventTarget(new CustomArea(0, 0, { x: 0, y: 0 }, { x: 0, y: 0 })); - - /** - * Gets historical touch points. - * @returns Array of historical points - * @throws Error as this method is not implemented - */ - getHistoricalPoints(): HistoricalPoint[] { - throw new Error('Method not implemented.'); - } -} - -/** - * Custom implementation of EventTarget for touch events. - * This class provides a target for touch events in platform views. - */ -class CustomEventTarget implements EventTarget { - /** The area associated with this event target */ - area: Area = new CustomArea(0, 0, { x: 0, y: 0 }, { x: 0, y: 0 }); - - /** - * Constructs a new CustomEventTarget instance. - * @param area - The area associated with this event target - */ - constructor(area: Area) { - this.area = area; - } -} - -/** - * Custom implementation of Area for touch events. - * This class represents a rectangular area with position and size information. - */ -class CustomArea implements Area { - /** The width of the area. */ - width: Length = 0; - /** The height of the area. */ - height: Length = 0; - /** The local position of the area. */ - position: Position = { x: 0, y: 0 }; - /** The global position of the area. */ - globalPosition: Position = { x: 0, y: 0 }; - - /** - * Constructs a new CustomArea instance. - * @param width - The width of the area - * @param height - The height of the area - * @param position - The local position - * @param globalPosition - The global position - */ - constructor(width: Length, height: Length, position: Position, globalPosition: Position) { - this.width = width; - this.height = height; - this.position = position; - this.globalPosition = globalPosition; - } -} - -/** - * Custom implementation of TouchObject for platform views. - */ -export class CustomTouchObject implements TouchObject { - /** The type of touch. */ - type: TouchType; - /** The unique identifier for this touch point. */ - id: number; - /** The X coordinate in display space. */ - displayX: number; - /** The Y coordinate in display space. */ - displayY: number; - /** The X coordinate in window space. */ - windowX: number; - /** The Y coordinate in window space. */ - windowY: number; - /** The X coordinate in screen space. */ - screenX: number; - /** The Y coordinate in screen space. */ - screenY: number; - /** The X coordinate in local space. */ - x: number; - /** The Y coordinate in local space. */ - y: number; - - /** - * Constructs a new CustomTouchObject instance. - * @param type - The touch type - * @param id - The touch point ID - * @param displayX - The X coordinate in display space - * @param displayY - The Y coordinate in display space - * @param windowX - The X coordinate in window space - * @param windowY - The Y coordinate in window space - * @param screenX - The X coordinate in screen space - * @param screenY - The Y coordinate in screen space - * @param x - The X coordinate in local space - * @param y - The Y coordinate in local space - */ - constructor(type: TouchType, id: number, displayX: number, displayY: number, windowX: number, windowY: number, - screenX: number, screenY: number, x: number, y: number) { - this.type = type; - this.id = id; - this.displayX = displayX; - this.displayY = displayY; - this.windowX = windowX; - this.windowY = windowY; - this.screenX = screenX; - this.screenY = screenY; - this.x = x; - this.y = y; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView.ets deleted file mode 100644 index 0a80743..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView.ets +++ /dev/null @@ -1,127 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on PlatformView.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import { DVModel, DynamicView } from '../../view/DynamicView/dynamicView' - -/** - * Parameters for platform view rendering. - * This class contains the configuration needed to render a platform view. - */ -export declare class Params { - /** The text direction for the platform view */ - direction: Direction - /** The platform view instance to render */ - platformView: PlatformView -} - -export declare class PlatformViewVisibleAreaEventOptions { - enable: boolean // Enable variable area monitoring - ratios: Array // Ratio thresholds for visible area changes, e.g., [0.0, 1.0] means 0% to 100% visible - expectedUpdateInterval: number // Expected interval for visible area updates in milliseconds - onInactiveThreshold: number // Texture continuous production pause operation visible area threshold - onActiveThreshold: number // Texture continuous production activation operation visible area threshold -} - -// unit: ms -const defaultExpectedUpdateInterval: number = 1000; - -/** A handle to an DynamicView to be embedded in the Flutter hierarchy. */ -export default abstract class PlatformView { - - /** - * Gets the type of this platform view. - * @returns The view type string - */ - getType(): string { - return 'default'; - } - - /** Returns the DynamicView to be embedded in the Flutter hierarchy. */ - abstract getView(): WrappedBuilder<[Params]>; - - /** - * Called by the FlutterEngine that owns this PlatformView when the DynamicView responsible - * for rendering a Flutter UI is associated with the FlutterEngine. - * - * This means that our associated FlutterEngine can now render a UI and interact with the user. - * - * Some platform views may have unusual dependencies on the DynamicView that renders Flutter - * UIs, such as unique keyboard interactions. That DynamicView is provided here for those - * purposes. Use of this DynamicView should be avoided if it is not absolutely necessary, because - * depending on this DynamicView will tend to make platform view code more brittle to future - * changes. - * @param dvModel - The DynamicView model associated with the Flutter view - */ - onFlutterViewAttached(dvModel: DVModel): void { - } - - /** - * Called by the FlutterEngine that owns this PlatformView when the DynamicView responsible - * for rendering a Flutter UI is detached and disassociated from the FlutterEngine. - * - * This means that our associated FlutterEngine no longer has a rendering surface, or a user - * interaction surface of any kind. - * - * This platform view must release any references related to the DynamicView that was - * provided in onFlutterViewAttached. - */ - onFlutterViewDetached(): void { - } - - /** - * Disposes this platform view. - * - * The PlatformView object is unusable after this method is called. - * - * Plugins implementing PlatformView must clear all references to the DynamicView object and - * the PlatformView after this method is called. Failing to do so will result in a memory leak. - * - * References related to the DynamicView attached in onFlutterViewAttached - * must be released in dispose() to avoid memory leaks. - */ - abstract dispose(): void; - - /** - * Callback fired when the platform's input connection is locked, or should be used. - * - * This hook only exists for rare cases where the plugin relies on the state of the input - * connection. This probably doesn't need to be implemented. - */ - onInputConnectionLocked(): void { - } - - /** - * Callback fired when the platform input connection has been unlocked. - * - * This hook only exists for rare cases where the plugin relies on the state of the input - * connection. This probably doesn't need to be implemented. - */ - onInputConnectionUnlocked(): void { - } - - // Obtain the parameters related to the changes in the visible area of the external texture - getPlatformViewVisibleAreaEventOptions(): PlatformViewVisibleAreaEventOptions { - return { - enable: false, - ratios: [0.0, 1.0], - expectedUpdateInterval: defaultExpectedUpdateInterval, - onInactiveThreshold : 0.0, - onActiveThreshold : 1.0 - } as PlatformViewVisibleAreaEventOptions; - } - - // The operation to pause the continuous production of external textures, including animations and videos - onInactive(): void { - } - - // The operation to resume the continuous production of external textures, including animations and videos - onActive(): void { - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewFactory.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewFactory.ets deleted file mode 100644 index 74562f9..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewFactory.ets +++ /dev/null @@ -1,51 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on PlatformViewFactory.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import MessageCodec from '../common/MessageCodec'; -import PlatformView from './PlatformView' -import common from '@ohos.app.ability.common'; -import Any from '../common/Any'; - -/** - * Factory for creating platform views. - * Subclasses must implement the create method to instantiate platform views. - */ -export default abstract class PlatformViewFactory { - private createArgsCodec: MessageCodec; - - /** - * Constructs a new PlatformViewFactory instance. - * @param createArgsCodec - The codec used to decode the args parameter of create - */ - constructor(createArgsCodec: MessageCodec) { - this.createArgsCodec = createArgsCodec; - } - - /** - * Creates a new platform view to be embedded in the Flutter hierarchy. - * - * @param context - The context to be used when creating the view, this is different than - * FlutterView's context - * @param viewId - Unique identifier for the created instance, this value is known on the Dart side - * @param args - Arguments sent from the Flutter app. The bytes for this value are decoded using the - * createArgsCodec argument passed to the constructor. This is null if createArgsCodec was - * null, or no arguments were sent from the Flutter app - * @returns A new PlatformView instance - */ - public abstract create(context: common.Context, viewId: number, args: Any): PlatformView; - - /** - * Returns the codec to be used for decoding the args parameter of create. - * @returns The MessageCodec instance - */ - getCreateArgsCodec(): MessageCodec { - return this.createArgsCodec; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistry.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistry.ets deleted file mode 100644 index 53860e8..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistry.ets +++ /dev/null @@ -1,27 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on PlatformViewRegistry.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import PlatformViewFactory from './PlatformViewFactory' - -/** - * Registry for platform view factories. - * - * Plugins can register factories for specific view types. - */ -export default interface PlatformViewRegistry { - /** - * Registers a factory for a platform view. - * - * @param viewTypeId - Unique identifier for the platform view's type - * @param factory - Factory for creating platform views of the specified type - * @returns True if succeeded, false if a factory is already registered for viewTypeId - */ - registerViewFactory(viewTypeId: string, factory: PlatformViewFactory): boolean; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistryImpl.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistryImpl.ets deleted file mode 100644 index 39f34f4..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistryImpl.ets +++ /dev/null @@ -1,52 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on PlatformViewRegistryImpl.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import HashMap from '@ohos.util.HashMap'; -import PlatformViewFactory from './PlatformViewFactory' -import PlatformViewRegistry from './PlatformViewRegistry' - -/** - * Implementation of PlatformViewRegistry for managing platform view factories. - */ -export default class PlatformViewRegistryImpl implements PlatformViewRegistry { - /** Maps a platform view type id to its factory. */ - private viewFactories: HashMap; - - /** - * Constructs a new PlatformViewRegistryImpl instance. - */ - constructor() { - this.viewFactories = new HashMap(); - } - - /** - * Registers a factory for a platform view. - * @param viewTypeId - Unique identifier for the platform view's type - * @param factory - Factory for creating platform views of the specified type - * @returns True if succeeded, false if a factory is already registered for viewTypeId - */ - registerViewFactory(viewTypeId: string, factory: PlatformViewFactory): boolean { - if (this.viewFactories.hasKey(viewTypeId)) { - return false; - } - - this.viewFactories.set(viewTypeId, factory); - return true; - } - - /** - * Gets the factory for a specific view type. - * @param viewTypeId - The view type ID - * @returns The PlatformViewFactory for the view type, or undefined if not found - */ - getFactory(viewTypeId: string): PlatformViewFactory { - return this.viewFactories.get(viewTypeId); - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewWrapper.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewWrapper.ets deleted file mode 100644 index ac3858a..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewWrapper.ets +++ /dev/null @@ -1,131 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import OhosTouchProcessor from '../../embedding/ohos/OhosTouchProcessor'; -import { DVModel, DVModelParameters } from '../../view/DynamicView/dynamicView'; -import { createDVModelFromJson } from '../../view/DynamicView/dynamicViewJson'; -import { RootDvModeManager } from './RootDvModelManager'; -import matrix4 from '@ohos.matrix4' -import Log from '../../util/Log'; -import Any from '../common/Any'; - -const TAG: string = "PlatformViewWrapper"; - -/** - * Wraps a platform view to intercept gestures and project this view onto a rendering target. - * - * An OpenHarmony platform view is composed by the engine using a TextureLayer. The view is embedded - * in the OpenHarmony view hierarchy like a normal DynamicView, but it's projected onto a rendering - * target, so it can be efficiently composed by the engine. - * - * Since the view is in the OpenHarmony view hierarchy, keyboard and accessibility interactions - * behave normally. - */ -export class PlatformViewWrapper { - private prevLeft: number = 0; - private prevTop: number = 0; - private left: number = 0; - private top: number = 0; - private bufferWidth: number = 0; - private bufferHeight: number = 0; - private touchProcessor: OhosTouchProcessor | null = null; - private model: DVModel | undefined; - - /** - * Sets the touch processor for handling touch events. - * @param newTouchProcessor - The OhosTouchProcessor instance - */ - public setTouchProcessor(newTouchProcessor: OhosTouchProcessor): void { - this.touchProcessor = newTouchProcessor; - } - - /** - * Constructs a new PlatformViewWrapper instance. - */ - constructor() { - } - - /** - * Gets the DynamicView model associated with this wrapper. - * @returns The DVModel instance - */ - public getDvModel(): DVModel { - return this.model!; - } - - /** - * Sets a parameter value in the DVModelParameters. - * @param params - The parameters object to modify - * @param key - The parameter key - * @param element - The value to set - */ - setParams: (params: DVModelParameters, key: string, element: Any) => void = - (params: DVModelParameters, key: string, element: Any): void => { - let params2 = params as Record; - params2[key] = element; - } - - /** - * Gets a parameter value from the DVModelParameters. - * @param params - The parameters object to read from - * @param element - The parameter key - * @returns The parameter value, or undefined if not found - */ - getParams: (params: DVModelParameters, element: string) => string | Any = - (params: DVModelParameters, element: string): string | Any => { - let params2 = params as Record; - return params2[element]; - } - - /** - * Sets the layout parameters for the platform view. - * @param parameters - The layout parameters to apply - */ - public setLayoutParams(parameters: DVModelParameters): void { - if (!this.model) { - return; - } - if (this.model.params == null) { - this.model.params = new DVModelParameters(); - } - this.setParams(this.model.params, "marginLeft", this.getParams(parameters, "marginLeft")); - this.setParams(this.model.params, "marginTop", this.getParams(parameters, "marginTop")); - this.left = this.getParams(parameters, "marginLeft"); - this.top = this.getParams(parameters, "marginTop"); - - this.setParams(this.model.params, "width", this.getParams(parameters, "width")); - this.setParams(this.model.params, "height", this.getParams(parameters, "height")); - } - - /** - * Adds a DynamicView model to this wrapper. - * @param model - The DVModel to add - */ - public addDvModel(model: DVModel): void { - this.model = model - } -} - -/** - * Parameters for DynamicView model creation. - * This class holds the basic structure for creating a DynamicView model. - */ -class DVModelParam { - /** The component type */ - compType: string - /** Array of child components */ - children: [] - - /** - * Constructs a new DVModelParam instance. - * @param compType - The component type - * @param children - Array of child components - */ - constructor(compType: string, children: []) { - this.compType = compType; - this.children = children; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsController.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsController.ets deleted file mode 100644 index 8c2e578..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsController.ets +++ /dev/null @@ -1,767 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on PlatformViewsController.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import PlatformViewsChannel, { - PlatformViewBufferResized, - PlatformViewCreationRequest, - PlatformViewResizeRequest, - PlatformViewsHandler, - PlatformViewTouch, - PlatformViewBufferSize -} from '../../../ets/embedding/engine/systemchannels/PlatformViewsChannel'; -import PlatformView, { Params } from './PlatformView'; -import { DVModelParameters, } from '../../view/DynamicView/dynamicView'; -import { createDVModelFromJson } from '../../view/DynamicView/dynamicViewJson'; -import display from '@ohos.display'; -import { FlutterView } from '../../view/FlutterView'; -import { TextureRegistry } from '../../view/TextureRegistry'; -import TextInputPlugin from '../editing/TextInputPlugin'; -import { PlatformViewWrapper } from './PlatformViewWrapper'; -import { FlutterOverlaySurface } from '../../embedding/engine/FlutterOverlaySurface'; -import HashSet from '@ohos.util.HashSet'; -import PlatformViewRegistry from './PlatformViewRegistry'; -import PlatformViewRegistryImpl from './PlatformViewRegistryImpl'; -import DartExecutor from '../../embedding/engine/dart/DartExecutor'; -import { FlutterMutatorView } from '../../embedding/engine/mutatorsstack/FlutterMutatorView'; -import Log from '../../util/Log' -import PlatformViewFactory from './PlatformViewFactory' -import { ByteBuffer } from '../../util/ByteBuffer'; -import Any from '../common/Any'; -import { ArrayList, Stack } from '@kit.ArkTS'; -import { CustomTouchEvent, CustomTouchObject } from './CustomTouchEvent'; -import { NodeRenderType } from '@kit.ArkUI'; -import { PlatformViewInfo } from '../../embedding/ohos/PlatformViewInfo'; -import { EmbeddingNodeController } from '../../embedding/ohos/EmbeddingNodeController'; - -/** - * JSON representation of a DynamicView model. - */ -class DVModelJson { - /** The component type. */ - compType: string - /** Array of child components. */ - children: Array - /** Component attributes. */ - attributes: Any - /** Component events. */ - events: Any - /** Optional build function. */ - build: Any - - /** - * Constructs a new DVModelJson instance. - * @param compType - The component type - * @param children - Array of child components - * @param attributes - Component attributes - * @param events - Component events - * @param build - Optional build function - */ - constructor(compType: string, children: Array, attributes: Any, events: Any, build?: Any) { - this.compType = compType - this.children = children - this.attributes = attributes - this.events = events; - this.build = build; - } -} -/** - * Enumeration of touch event types. - */ -enum TouchEventType { - /** Action code for when a primary pointer touched the screen. */ - ACTION_DOWN = 0, - /** Action code for when a primary pointer stopped touching the screen. */ - ACTION_UP = 1, - /** Action code for when the event only includes information about pointer movement. */ - ACTION_MOVE = 2, - /** Action code for when a motion event has been canceled. */ - ACTION_CANCEL = 3, - /** Action code for when a secondary pointer touched the screen. */ - ACTION_POINTER_DOWN = 5, - /** Action code for when a secondary pointer stopped touching the screen. */ - ACTION_POINTER_UP = 6, -} - -const TAG = "PlatformViewsController" - -/** - * Controller for managing platform views in Flutter applications. - * This class handles the creation, lifecycle, and interaction of native views embedded in Flutter. - */ -export default class PlatformViewsController implements PlatformViewsHandler { - private registry: PlatformViewRegistryImpl; - private context: Context | null = null; - private flutterView: FlutterView | null = null; - private textureRegistry: TextureRegistry | null = null; - private textInputPlugin: TextInputPlugin | null = null; - private platformViewsChannel: PlatformViewsChannel | null = null; - private nextOverlayLayerId: number = 0; - private focusViewId: number = -1; - private platformViews: Map; - private viewIdWithTextureId: Map; - private viewIdWithNodeController: Map; - private viewWrappers: Map; - private currentFrameUsedOverlayLayerIds: HashSet; - private currentFrameUsedPlatformViewIds: HashSet; - - /** - * Constructs a new PlatformViewsController instance. - */ - constructor() { - this.registry = new PlatformViewRegistryImpl(); - this.currentFrameUsedOverlayLayerIds = new HashSet(); - this.currentFrameUsedPlatformViewIds = new HashSet(); - this.viewWrappers = new Map(); - this.platformViews = new Map(); - this.viewIdWithTextureId = new Map(); - this.viewIdWithNodeController = new Map(); - } - - /** - * Creates a platform view for hybrid composition mode. - * @param request - The platform view creation request - */ - createForPlatformViewLayer(request: PlatformViewCreationRequest): void { - Log.i(TAG, "Enter createForPlatformViewLayer"); - this.ensureValidRequest(request); - - let platformView: PlatformView = this.createPlatformView(request); - - this.configureForHybridComposition(platformView, request); - } - - /** - * Disposes a platform view and releases all associated resources. - * @param viewId - The ID of the platform view to dispose - */ - dispose(viewId: number): void { - let platformView: PlatformView | null = this.platformViews.get(viewId) || null; - if (platformView == null) { - Log.e(TAG, "Disposing unknown platform view with id: " + viewId); - return; - } - if (this.focusViewId == viewId) { - this.clearFocus(viewId); - this.focusViewId = -1; - } - this.platformViews.delete(viewId); - let textureId = this.viewIdWithTextureId.get(viewId); - - if (textureId != undefined) { - this.textureRegistry!.unregisterTexture(textureId); - } - - this.viewIdWithNodeController.get(viewId)?.disposeFrameNode() - this.viewIdWithNodeController.delete(viewId); - - let viewWrapper: PlatformViewWrapper | null = this.viewWrappers.get(viewId) || null; - if (viewWrapper != null && this.flutterView) { - let index = this.flutterView.getDVModel().children.indexOf(viewWrapper.getDvModel()!); - if (index > -1) { - this.flutterView.getDVModel().children.splice(index, 1); - platformView.onFlutterViewDetached(); - } - } - this.viewWrappers.delete(viewId); - - try { - platformView.dispose(); - } catch (err) { - Log.e(TAG, "Disposing platform view threw an exception", err); - } - } - - /** - * Sets a parameter value in the DVModelParameters. - * @param params - The parameters object to modify - * @param key - The parameter key - * @param element - The value to set - */ - setParams: (params: DVModelParameters, key: string, element: Any) => void = - (params: DVModelParameters, key: string, element: Any): void => { - let params2 = params as Record; - params2[key] = element; - } - - /** - * Gets a parameter value from the DVModelParameters. - * @param params - The parameters object to read from - * @param key - The parameter key - * @returns The parameter value as a number - */ - getParams: (params: DVModelParameters, key: string) => number = (params: DVModelParameters, key: string): number => { - let params2 = params as Record; - return params2[key]; - } - - /** - * Resizes a platform view. - * @param request - The resize request containing new dimensions - * @param onComplete - Callback to invoke when resize is complete - */ - resize(request: PlatformViewResizeRequest, onComplete: PlatformViewBufferResized): void { - let physicalWidth: number = this.toPhysicalPixels(request.newLogicalWidth); - let physicalHeight: number = this.toPhysicalPixels(request.newLogicalHeight); - let viewId: number = request.viewId; - Log.i(TAG, - `Resize viewId ${viewId}, pw:${physicalWidth}, ph:${physicalHeight},lw:${request.newLogicalWidth}, lh:${request.newLogicalHeight}`); - - let viewWrapper = this.viewWrappers.get(request.viewId) - let params: DVModelParameters | undefined = viewWrapper?.getDvModel()!.params - - this.setParams(params!, "width", physicalWidth); - this.setParams(params!, "height", physicalHeight); - - let textureId = this.viewIdWithTextureId.get(viewId); - if (textureId != undefined) { - let density = this.getDisplayDensity(); - this.textureRegistry?.notifyTextureResizing(textureId, request.newLogicalWidth * density, request.newLogicalHeight * density); - } - - onComplete.run(new PlatformViewBufferSize(physicalWidth, physicalHeight)); - } - - /** - * Updates the offset position of a platform view. - * @param viewId - The ID of the platform view - * @param top - The top offset - * @param left - The left offset - */ - offset(viewId: number, top: number, left: number): void { - Log.i(TAG, `Offset is id${viewId}, t:${top}, l:${left}`); - - let viewWrapper = this.viewWrappers.get(viewId) - if (viewWrapper === undefined) { - return; - } - - let params: DVModelParameters | undefined = viewWrapper?.getDvModel()!.params; - if (!params) { - return; - } - // When the current value is NaN and the previous value is a normal value, - // the platformView is considered to have transitioned from visible to invisible. - // Use Number.isNaN; the page is considered invisible in the background - // only when both top and left values equal NaN. - if (Number.isNaN(top) && Number.isNaN(left)) { - let leftPre: number | undefined = this.getParams(params!, "left"); - let topPre: number | undefined = this.getParams(params!, "top"); - let compType: string | undefined = viewWrapper?.getDvModel().compType; - if ((leftPre !== undefined && !Number.isNaN(leftPre)) && - (topPre !== undefined && !Number.isNaN(topPre)) && - (compType === "NodeContainer")) { - const nodeController = (params as Record)?.nodeController; - if (nodeController instanceof EmbeddingNodeController) { - nodeController.notifyPlatformViewInvisible(); - } - } - } - this.setParams(params!, "left", left); - this.setParams(params!, "top", top); - } - - /** - * Sets the hover state for platform views. - * @param viewId - The ID of the platform view to set hover state for - */ - hover(viewId: number) { - for (let key of this.viewWrappers.keys()) { - let viewWrapper: undefined | PlatformViewWrapper = this.viewWrappers.get(key); - let dvModel = viewWrapper?.getDvModel(); - let params = dvModel?.getLayoutParams() as Record; - if (key == viewId) { - params["hover"] = true; - } else { - params["hover"] = false; - } - } - } - - /** - * Handles touch events for platform views. - * @param touch - The touch event information - */ - onTouch(touch: PlatformViewTouch): void { - let viewWrapper: undefined | PlatformViewWrapper = this.viewWrappers.get(touch.viewId) - this.focusViewId = touch.viewId; - if (viewWrapper != undefined) { - let dvModel = viewWrapper.getDvModel() - let params = dvModel.getLayoutParams() as Record; - // When receiving a DOWN action - if (touch.action === TouchEventType.ACTION_DOWN) { - // Set the current touch state to true - params['down'] = true - // When first receiving a touch DOWN event, dispatch all events stored in the list - let touchEventArray: Array | undefined = params['touchEvent'] as Array - if (touchEventArray !== undefined) { - let nodeController = params['nodeController'] as EmbeddingNodeController; - for (let it of touchEventArray) { - nodeController.postEvent(it) - } - // Clear the list after first dispatch - params['touchEvent'] = undefined - } - - // When first receiving a mouse PRESS event, dispatch all events stored in the list - let mouseEventArray: Array | undefined = params['mouseEvent'] as Array - if (mouseEventArray !== undefined) { - let nodeController = params['nodeController'] as EmbeddingNodeController; - for (let it of mouseEventArray) { - nodeController.postMouseEvent(it) - } - // Clear the list after first dispatch - params['mouseEvent'] = undefined - } - // When receiving an UP action - } else if (touch.action === TouchEventType.ACTION_UP || touch.action === TouchEventType.ACTION_CANCEL) { - // Set the touch state to false after finger is lifted. When multiple fingers are lifted suddenly, - // the final state returned is also ACTION_UP, so we use the UP state to indicate the user - // is no longer touching the platform view - params['down'] = false - } - } - } - - /** - * Sets the text direction for a platform view. - * @param viewId - The ID of the platform view - * @param direction - The text direction to set - */ - setDirection(viewId: number, direction: Direction): void { - let nodeController = this.viewIdWithNodeController.get(viewId) - if (nodeController != undefined) { - nodeController?.setRenderOption(this.flutterView!.getPlatformView()!, this.flutterView!.getSurfaceId(), - NodeRenderType.RENDER_TYPE_TEXTURE, direction) - nodeController?.rebuild() - } - } - - /** - * Validates if a direction value is valid. - * @param direction - The direction value to validate - * @returns True if the direction is valid, false otherwise - */ - validateDirection(direction: number): boolean { - return direction == Direction.Ltr || direction == Direction.Rtl || direction == Direction.Auto; - } - - /** - * Clears focus from a platform view. - * @param viewId - The ID of the platform view - */ - clearFocus(viewId: number): void { - const platformView = this.platformViews.get(viewId); - if (platformView == null) { - Log.e(TAG, "Setting direction to an unknown view with id: " + viewId); - return; - } - const embeddedView = platformView.getView(); - if (embeddedView == null) { - Log.e(TAG, "Setting direction to a null view with id: " + viewId); - return; - } - // Make the Xcomponent gain focus. - focusControl.requestFocus("unfocus-xcomponent-node"); - } - - /** - * Synchronizes the native view hierarchy. - * @param yes - Whether to synchronize - * @throws Error as this method is not implemented - */ - synchronizeToNativeViewHierarchy(yes: boolean): void { - throw new Error('Method not implemented.'); - } - - /** - * Creates a platform view for texture layer composition mode. - * @param request - The platform view creation request - * @returns The texture ID for the created view - */ - public createForTextureLayer(request: PlatformViewCreationRequest): number { - Log.i(TAG, "Enter createForTextureLayer"); - this.ensureValidRequest(request); - - let platformView: PlatformView = this.createPlatformView(request); - let textureId = this.configureForTextureLayerComposition(platformView, request); - this.viewIdWithTextureId.set(request.viewId, textureId); - return textureId; - } - - /** - * Ensures that a platform view creation request is valid. - * @param request - The request to validate - * @throws Error if the request is invalid - * @private - */ - private ensureValidRequest(request: PlatformViewCreationRequest): void { - if (!this.validateDirection(request.direction)) { - throw new Error("Trying to create a view with unknown direction value: " - + request.direction - + "(view id: " - + request.viewId - + ")") - } - } - - /** - * Creates a platform view instance from a factory. - * @param request - The platform view creation request - * @returns The created PlatformView instance - * @throws Error if the factory is not found or creation fails - * @private - */ - private createPlatformView(request: PlatformViewCreationRequest): PlatformView { - Log.i(TAG, "begin createPlatformView"); - const viewFactory: PlatformViewFactory = this.registry.getFactory(request.viewType); - if (viewFactory == null) { - throw new Error("Trying to create a platform view of unregistered type: " + request.viewType) - } - - let createParams: Any = null; - if (request.params != null) { - let byteParas: ByteBuffer = request.params as ByteBuffer; - createParams = viewFactory.getCreateArgsCodec().decodeMessage(byteParas.buffer); - } - - if (this.context == null) { - throw new Error('PlatformView#context is null.'); - } - let platformView = viewFactory.create(this.context, request.viewId, createParams); - - let embeddedView: WrappedBuilder<[Params]> = platformView.getView(); - if (embeddedView == null) { - throw new Error("PlatformView#getView() returned null, but an WrappedBuilder reference was expected."); - } - - this.platformViews.set(request.viewId, platformView); - return platformView; - } - - /** - * Configures the view for Hybrid Composition mode. - * @param platformView - The platform view to configure - * @param request - The creation request - * @private - */ - private configureForHybridComposition(platformView: PlatformView, request: PlatformViewCreationRequest): void { - Log.i(TAG, "Using hybrid composition for platform view: " + request.viewId); - } - - /** - * Configures the view for Texture Layer Composition mode. - * @param platformView - The platform view to configure - * @param request - The creation request - * @returns The texture ID for the view - * @private - */ - private configureForTextureLayerComposition(platformView: PlatformView, - request: PlatformViewCreationRequest): number { - Log.i(TAG, "Hosting view in view hierarchy for platform view: " + request.viewId); - let surfaceId: string = '0'; - let textureId: number = 0; - if (this.textureRegistry != null) { - textureId = this.textureRegistry!.getTextureId(); - surfaceId = this.textureRegistry!.registerTexture(textureId).getSurfaceId().toString(); - Log.i(TAG, "nodeController getSurfaceId: " + surfaceId); - this.flutterView!.setSurfaceId(surfaceId); - } - - let wrappedBuilder: WrappedBuilder<[Params]> = platformView.getView(); - this.flutterView?.setWrappedBuilder(wrappedBuilder); - this.flutterView?.setPlatformView(platformView); - let physicalWidth: number = this.toPhysicalPixels(request.logicalWidth); - let physicalHeight: number = this.toPhysicalPixels(request.logicalHeight); - - let nodeController = new EmbeddingNodeController(); - nodeController.setRenderOption(platformView, surfaceId, NodeRenderType.RENDER_TYPE_TEXTURE, request.direction); - this.viewIdWithNodeController.set(request.viewId, nodeController); - - let dvModel = createDVModelFromJson(new DVModelJson("NodeContainer", - [], - { - "width": physicalWidth, - "height": physicalHeight, - "nodeController": nodeController, - "left": request.logicalLeft, - "top": request.logicalTop - }, - {}, - undefined)); - let viewWrapper: PlatformViewWrapper = new PlatformViewWrapper(); - viewWrapper.addDvModel(dvModel); - this.viewWrappers.set(request.viewId, viewWrapper); - this.flutterView?.getDVModel().children.push(viewWrapper.getDvModel()) - platformView.onFlutterViewAttached(this.flutterView!.getDVModel()); - Log.i(TAG, "Create platform view success"); - return textureId; - } - - /** - * Attaches the controller to a context, texture registry, and Dart executor. - * @param context - The application context - * @param textureRegistry - The texture registry for managing textures - * @param dartExecutor - The Dart executor for communication - */ - public attach(context: Context, textureRegistry: TextureRegistry | null, dartExecutor: DartExecutor): void { - this.context = context; - this.textureRegistry = textureRegistry; - this.platformViewsChannel = new PlatformViewsChannel(dartExecutor); - this.platformViewsChannel.setPlatformViewsHandler(this); - } - - /** - * Detaches the controller and cleans up resources. - */ - public detach(): void { - if (this.platformViewsChannel != null) { - this.platformViewsChannel.setPlatformViewsHandler(null); - } - this.destroyOverlaySurfaces(); - this.platformViewsChannel = null; - this.context = null; - this.textureRegistry = null; - } - - /** - * Attaches the controller to a FlutterView. - * @param newFlutterView - The FlutterView to attach to - */ - public attachToView(newFlutterView: FlutterView) { - this.flutterView = newFlutterView; - } - - /** - * Detaches the controller from the FlutterView. - */ - public detachFromView(): void { - this.destroyOverlaySurfaces(); - this.removeOverlaySurfaces(); - this.flutterView = null; - } - - /** - * Gets the current FlutterView. - * @returns The FlutterView instance, or null if not attached - */ - public getFlutterView(): FlutterView | null { - return this.flutterView; - } - - /** - * Attaches a text input plugin to this controller. - * @param textInputPlugin - The TextInputPlugin instance - */ - public attachTextInputPlugin(textInputPlugin: TextInputPlugin): void { - this.textInputPlugin = textInputPlugin; - } - - /** - * Detaches the text input plugin from this controller. - */ - public detachTextInputPlugin(): void { - this.textInputPlugin = null; - } - - /** - * Gets the platform view registry. - * @returns The PlatformViewRegistry instance - */ - public getRegistry(): PlatformViewRegistry { - return this.registry; - } - - /** - * Called when the controller is detached from NAPI. - * Disposes all platform views. - */ - public onDetachedFromNapi(): void { - this.diposeAllViews(); - } - - /** - * Called before the Flutter engine restarts. - * Disposes all platform views. - */ - public onPreEngineRestart(): void { - this.diposeAllViews(); - } - - /** - * Gets the display density. - * @returns The display density value - * @private - */ - private getDisplayDensity(): number { - return display.getDefaultDisplaySync().densityPixels; - } - - /** - * Converts logical pixels to physical pixels. - * @param logicalPixels - The logical pixel value - * @returns The physical pixel value - * @private - */ - private toPhysicalPixels(logicalPixels: number): number { - return Math.round(px2vp(logicalPixels * this.getDisplayDensity())); - } - - /** - * Converts physical pixels to logical pixels using a specific density. - * @param physicalPixels - The physical pixel value - * @param displayDensity - The display density to use - * @returns The logical pixel value - * @private - */ - private toLogicalPixelsByDensity(physicalPixels: number, displayDensity: number): number { - return Math.round(physicalPixels / displayDensity); - } - - /** - * Converts physical pixels to logical pixels using the current display density. - * @param physicalPixels - The physical pixel value - * @returns The logical pixel value - * @private - */ - private toLogicalPixels(physicalPixels: number): number { - return this.toLogicalPixelsByDensity(physicalPixels, this.getDisplayDensity()); - } - - /** - * Disposes all platform views. - * @private - */ - private diposeAllViews(): void { - let viewKeys = this.platformViews.keys(); - for (let viewId of viewKeys) { - this.dispose(viewId); - } - } - - /** - * Initializes the root image view if needed. - * @private - */ - private initializeRootImageViewIfNeeded(): void { - } - - /** - * Called when an overlay surface should be displayed. - * @param id - The overlay surface ID - * @param x - The X position - * @param y - The Y position - * @param width - The width - * @param height - The height - */ - public onDisplayOverlaySurface(id: number, x: number, y: number, width: number, height: number): void { - } - - /** - * Called at the beginning of each frame. - * Clears the sets of used overlay layers and platform views. - */ - public onBeginFrame(): void { - this.currentFrameUsedOverlayLayerIds.clear(); - this.currentFrameUsedPlatformViewIds.clear(); - } - - /** - * Called at the end of each frame. - */ - public onEndFrame(): void { - } - - /** - * Finishes frame rendering. - * @param isFrameRenderedUsingImageReaders - Whether the frame was rendered using image readers - * @private - */ - private finishFrame(isFrameRenderedUsingImageReaders: boolean): void { - } - - /** - * Creates a new overlay surface. - * @returns A new FlutterOverlaySurface instance - */ - public createOverlaySurface(): FlutterOverlaySurface { - return new FlutterOverlaySurface(this.nextOverlayLayerId++); - } - - /** - * Destroys all overlay surfaces. - * @private - */ - private destroyOverlaySurfaces(): void { - } - - /** - * Removes overlay surfaces from the view hierarchy. - * @private - */ - private removeOverlaySurfaces(): void { - if (!(this.flutterView instanceof FlutterView)) { - return; - } - } - - /** - * Renders a platform view with the specified dimensions and position. - * @param surfaceId - The surface ID - * @param platformView - The platform view to render - * @param width - The width in pixels - * @param height - The height in pixels - * @param left - The left position in pixels - * @param top - The top position in pixels - */ - public render(surfaceId: number, platformView: PlatformView, - width: number, height: number, left: number, top: number) { - - let wrapper = this.viewWrappers.get(surfaceId); - if (wrapper != null) { - let params: DVModelParameters | undefined = wrapper?.getDvModel()!.params - - this.setParams(params!, "width", width); - this.setParams(params!, "height", height); - this.setParams(params!, "left", left); - this.setParams(params!, "top", top); - return; - } - - this.flutterView!.setSurfaceId(surfaceId.toString()); - let wrappedBuilder: WrappedBuilder<[Params]> = platformView.getView(); - this.flutterView?.setWrappedBuilder(wrappedBuilder); - this.flutterView?.setPlatformView(platformView); - - let nodeController = new EmbeddingNodeController(); - - nodeController.setRenderOption(platformView, surfaceId.toString(), NodeRenderType.RENDER_TYPE_TEXTURE, - Direction.Auto); - this.viewIdWithNodeController.set(surfaceId, nodeController); - - let dvModel = createDVModelFromJson(new DVModelJson("NodeContainer", - [], - { - "width": width, - "height": height, - "nodeController": nodeController, - "left": left, - "top": top - }, - {}, - undefined)); - - let viewWrapper: PlatformViewWrapper = new PlatformViewWrapper(); - viewWrapper.addDvModel(dvModel); - this.viewWrappers.set(surfaceId, viewWrapper); - this.flutterView?.getDVModel().children.push(viewWrapper.getDvModel()); - platformView.onFlutterViewAttached(this.flutterView!.getDVModel()); - this.platformViews.set(surfaceId, platformView!); - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/RawPointerCoord.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/RawPointerCoord.ets deleted file mode 100644 index bad2804..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/RawPointerCoord.ets +++ /dev/null @@ -1,63 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -*/ - -/** - * Represents raw pointer coordinates with additional touch information. - * This class holds detailed information about a pointer event. - */ -export class RawPointerCoords { - private orientation: number = 0; - private pressure: number = 0; - private size: number = 0; - private toolMajor: number = 0; - private toolMinor: number = 0; - private touchMajor: number = 0; - private touchMinor: number = 0; - private x: number = 0; - private y: number = 0; - - /** - * Constructs a new RawPointerCoords instance. - * @param orientation - The orientation angle in radians - * @param pressure - The pressure value (0.0 to 1.0) - * @param size - The size value - * @param toolMajor - The major axis of the tool ellipse - * @param toolMinor - The minor axis of the tool ellipse - * @param touchMajor - The major axis of the touch ellipse - * @param touchMinor - The minor axis of the touch ellipse - * @param x - The X coordinate - * @param y - The Y coordinate - */ - constructor(orientation: number, pressure: number, size: number, toolMajor: number, toolMinor: number, - touchMajor: number, touchMinor: number, x: number, y: number) { - this.orientation = orientation; - this.pressure = pressure; - this.size = size; - this.toolMajor = toolMajor; - this.toolMinor = toolMinor; - this.touchMajor = touchMajor; - this.touchMinor = touchMinor; - this.x = x; - this.y = y; - } - - /** - * Gets the X coordinate. - * @returns The X coordinate value - */ - getX(): number { - return this.x; - } - - /** - * Gets the Y coordinate. - * @returns The Y coordinate value - */ - getY(): number { - return this.y; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/RootDvModelManager.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/RootDvModelManager.ets deleted file mode 100644 index df11ae0..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/RootDvModelManager.ets +++ /dev/null @@ -1,42 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import { - DVModel, - DVModelChildren, - DVModelContainer, - DVModelEvents, - DVModelParameters -} from '../../view/DynamicView/dynamicView'; -import Log from '../../util/Log'; - -/** - * Manager for the root DynamicView model container. - * This class provides a singleton root container for all platform views. - */ -export class RootDvModeManager { - private static model: DVModel = - new DVModel("Stack", new DVModelParameters(), new DVModelEvents(), new DVModelChildren(), null); - private static container: DVModelContainer = new DVModelContainer(RootDvModeManager.model); - - /** - * Gets the root DynamicView model container. - * @returns The root DVModelContainer instance - */ - public static getRootDvMode(): DVModelContainer { - return RootDvModeManager.container; - } - - /** - * Adds a DynamicView model to the root container. - * @param model - The DVModel to add - */ - public static addDvModel(model: DVModel): void { - RootDvModeManager.container.model.children.push(model); - Log.i("flutter RootDvModeManager", 'DVModel: %{public}s', - JSON.stringify(RootDvModeManager.container.model.children) ?? ''); - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/view/SensitiveContentPlugin.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/view/SensitiveContentPlugin.ets deleted file mode 100644 index 309582a..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/view/SensitiveContentPlugin.ets +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2026 Huawei Device Co., Ltd. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE_HW file. - */ - -import SensitiveContentChannel, { SensitiveContentMethodHandler } from '../../embedding/engine/systemchannels/SensitiveContentChannel'; -import Log from '../../util/Log'; -import { BusinessError } from '@kit.BasicServicesKit'; -import window from '@ohos.window'; - -import { - SENSITIVE_CONTENT_SENSITIVITY, - NOT_SENSITIVE_CONTENT_SENSITIVITY, -} from '../../embedding/engine/systemchannels/SensitiveContentChannel'; -const TAG = "SensitiveContentChannel"; -export default class SensitiveContentPlugin implements SensitiveContentMethodHandler { - private readonly sensitiveContentChannel: SensitiveContentChannel; - private currentContentSensitivity: number = NOT_SENSITIVE_CONTENT_SENSITIVITY; - - constructor( - sensitiveContentChannel: SensitiveContentChannel - ) { - this.sensitiveContentChannel = sensitiveContentChannel; - this.sensitiveContentChannel.setSensitiveContentMethodHandler(this); - } - - setContentSensitivity(requestedContentSensitivity: number): void { - let isPrivacyMode: boolean; - switch (requestedContentSensitivity) { - case SENSITIVE_CONTENT_SENSITIVITY: - isPrivacyMode = true; - break; - case NOT_SENSITIVE_CONTENT_SENSITIVITY: - isPrivacyMode = false; - break; - default: - isPrivacyMode = false; - requestedContentSensitivity = NOT_SENSITIVE_CONTENT_SENSITIVITY; - break; - } - if (this.currentContentSensitivity === requestedContentSensitivity) { - // Content sensitivity for the requested View already set to requestedContentSensitivity. - return; - } - try { - window.getLastWindow(getContext(), (err: BusinessError, data) => { - const errCode = err.code; - if (errCode) { - return; - } - // Set requestedContentSensitivity on the View. - let promise = data.setWindowPrivacyMode(isPrivacyMode); - promise.then(() => { - Log.d(TAG, "success to set the window to privacy mode."); - this.currentContentSensitivity = requestedContentSensitivity; - }).catch((err: BusinessError) => { - Log.e(TAG, "Failed to set the window to privacy mode. Cause: " + JSON.stringify(err)); - }); - }) - } catch (exception) { - Log.e(TAG, "Exception when setting window privacy mode: " + JSON.stringify(exception)); - } - } - - getContentSensitivity(): number { - return this.currentContentSensitivity; - } - - isSupported(): boolean { - return true; - } - - destroy(): void { - this.sensitiveContentChannel.setSensitiveContentMethodHandler(null); - } -} - diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ByteBuffer.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ByteBuffer.ets deleted file mode 100644 index 0b644ba..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ByteBuffer.ets +++ /dev/null @@ -1,809 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import util from '@ohos.util' -import StringUtils from './StringUtils' - -/** - * A byte buffer. - * - * Supports the following data types: - * - Bool - * - Int (8, 16, 32, 64) - * - Uint (8, 16, 32, 64) - * - BigInt (64) - * - String (utf8, utf16, and delimited) - * - TypedArray - * - */ -export class ByteBuffer { - /** - * Creates a byte buffer. - * @param source - The data source - * @param byteOffset - The byte offset - * @param byteLength - The byte length - * @returns A byte buffer - */ - static from(source: ArrayBuffer, byteOffset?: number, byteLength?: number): ByteBuffer { - const byteBuffer = new ByteBuffer() - byteBuffer.dataView = byteLength === undefined ? new DataView(source, byteOffset) : - new DataView(source, byteOffset, Math.min(source.byteLength, byteLength)) - byteBuffer.mByteOffset = byteBuffer.dataView.byteOffset - return byteBuffer - } - - private dataView?: DataView - /** The byte offset. */ - mByteOffset: number = 0 - - /** - * The byte offset. - * @returns The byte offset. - */ - get byteOffset(): number { - return this.mByteOffset - } - - /** - * Gets the byte length of the buffer. - * @returns The byte length - */ - get byteLength(): number { - return this.dataView?.byteLength ?? 0 - } - - /** - * The number of remaining bytes. - * @returns The number of bytes remaining. - */ - get bytesRemaining(): number { - return this.dataView ? this.dataView.byteLength - this.mByteOffset : 0; - } - - /** - * Checks if there are remaining bytes to read. - * @returns True if there are remaining bytes, false otherwise - */ - hasRemaining(): boolean { - return this.dataView != undefined && this.mByteOffset < this.dataView.byteLength; - } - - /** - * Gets the underlying ArrayBuffer up to the current offset. - * @returns The ArrayBuffer slice - */ - get buffer(): ArrayBuffer { - return this.dataView!.buffer.slice(0, this.mByteOffset) - } - - /** - * Skips the specified number of bytes. - * @param byteLength - The number of bytes to skip - */ - skip(byteLength: number): void { - this.mByteOffset += byteLength - } - - /** - * Resets the byte offset. - */ - reset(): void { - this.mByteOffset = this.dataView?.byteOffset ?? 0 - } - - /** - * Clears the byte buffer. - */ - clear(): void { - this.getUint8Array(0).fill(0) - } - - /** - * check buffer capacity. - */ - checkWriteCapacity(slen: number): void { - if (this.mByteOffset + slen > this.dataView!.byteLength) { - let newCapacity = this.dataView!.byteLength + (this.dataView!.byteLength >> 1); - if (newCapacity < this.dataView!.byteLength + slen + 512) { - newCapacity = this.dataView!.byteLength + slen + 512; - } - let newBuffer = new ArrayBuffer(newCapacity); - let newDataView = new DataView(newBuffer); - let oldUint8Array = new Uint8Array(this.dataView!.buffer); - let newUint8Array = new Uint8Array(newBuffer); - newUint8Array.set(oldUint8Array); - this.dataView = newDataView; - } - } - - /** - * Gets a boolean. - * @param byteOffset - The byte offset - */ - getBool(byteOffset: number): boolean { - return this.getInt8(byteOffset) !== 0 - } - - /** - * Reads the next boolean. - */ - readBool(): boolean { - return this.getInt8(this.mByteOffset++) !== 0 - } - - /** - * Sets a boolean. - * @param byteOffset - The byte offset - * @param value - The value - */ - setBool(byteOffset: number, value: boolean): void { - this.dataView?.setInt8(byteOffset, value ? 1 : 0) - } - - /** - * Writes the next boolean. - * @param value - The value - */ - writeBool(value: boolean): void { - this.checkWriteCapacity(1) - this.setInt8(this.mByteOffset++, value ? 1 : 0) - } - - /** - * Gets an signed byte. - * @param byteOffset - The byte offset - * @returns The value. - */ - getInt8(byteOffset: number): number { - return this.dataView?.getInt8(byteOffset) || 0 - } - - /** - * Reads the next signed byte. - * @returns The value. - */ - readInt8(): number { - return this.getInt8(this.mByteOffset++) - } - - /** - * Sets a signed byte. - * @param byteOffset - The byte offset - * @param value - The value - */ - setInt8(byteOffset: number, value: number): void { - this.dataView?.setInt8(byteOffset, value) - } - - /** - * Writes the next signed byte. - * @param value - The value - */ - writeInt8(value: number): void { - this.checkWriteCapacity(1) - this.setInt8(this.mByteOffset++, value) - } - - /** - * Gets an unsigned byte. - * @param byteOffset - The byte offset - * @returns The value. - */ - getUint8(byteOffset: number): number { - return this.dataView?.getUint8(byteOffset) || 0 - } - - /** - * Reads the next unsigned byte. - * @returns The value. - */ - readUint8(): number { - return this.getUint8(this.mByteOffset++) - } - - /** - * Sets an unsigned byte. - * @param byteOffset - The byte offset - * @param value - The value - */ - setUint8(byteOffset: number, value: number): void { - this.dataView?.setUint8(byteOffset, value) - } - - /** - * Writes the next signed byte. - * @param value - The value - */ - writeUint8(value: number): void { - this.checkWriteCapacity(1) - this.setUint8(this.mByteOffset++, value) - } - - /** - * Gets an signed short. - * @param byteOffset - The byte offset - * @param littleEndian - Whether the value is little endian - * @returns The value. - */ - getInt16(byteOffset: number, littleEndian?: boolean): number { - return this.dataView?.getInt16(byteOffset, littleEndian) || 0 - } - - /** - * Reads the next signed short. - * @param littleEndian - Whether the value is little endian - * @returns The value. - */ - readInt16(littleEndian?: boolean): number { - const value = this.getInt16(this.mByteOffset, littleEndian) - this.mByteOffset += 2 - return value - } - - /** - * Sets a signed short. - * @param byteOffset - The byte offset - * @param value - The value - * @param littleEndian - Whether the value is little endian - */ - setInt16(byteOffset: number, value: number, littleEndian?: boolean): void { - this.dataView?.setInt16(byteOffset, value, littleEndian) - } - - /** - * Writes the next signed short. - * @param value - The value - * @param littleEndian - Whether the value is little endian - */ - writeInt16(value: number, littleEndian?: boolean): void { - this.checkWriteCapacity(2) - this.setInt16(this.mByteOffset, value, littleEndian) - this.mByteOffset += 2 - } - - /** - * Gets an unsigned short. - * @param byteOffset - The byte offset - * @param littleEndian - Whether the value is little endian - * @returns The value. - */ - getUint16(byteOffset: number, littleEndian?: boolean): number { - return this.dataView?.getUint16(byteOffset, littleEndian) || 0 - } - - /** - * Reads the next unsigned short. - * @param littleEndian - Whether the value is little endian - * @returns The value. - */ - readUint16(littleEndian?: boolean): number { - const value = this.getUint16(this.mByteOffset, littleEndian) - this.mByteOffset += 2 - return value - } - - /** - * Sets an unsigned short. - * @param byteOffset - The byte offset - * @param value - The value - * @param littleEndian - Whether the value is little endian - */ - setUint16(byteOffset: number, value: number, littleEndian?: boolean): void { - this.dataView?.setUint16(byteOffset, value, littleEndian) - } - - /** - * Writes the next signed short. - * @param value - The value - * @param littleEndian - Whether the value is little endian - */ - writeUint16(value: number, littleEndian?: boolean): void { - this.checkWriteCapacity(2) - this.setUint16(this.mByteOffset, value, littleEndian) - this.mByteOffset += 2 - } - - /** - * Gets an signed integer. - * @param byteOffset - The byte offset - * @param littleEndian - Whether the value is little endian - * @returns The value. - */ - getInt32(byteOffset: number, littleEndian?: boolean): number { - return this.dataView?.getInt32(byteOffset, littleEndian) ?? 0 - } - - /** - * Reads the next signed integer. - * @param littleEndian - Whether the value is little endian - * @returns The value. - */ - readInt32(littleEndian?: boolean): number { - const value = this.getInt32(this.mByteOffset, littleEndian) - this.mByteOffset += 4 - return value - } - - /** - * Sets a signed integer. - * @param byteOffset - The byte offset - * @param value - The value - * @param littleEndian - Whether the value is little endian - */ - setInt32(byteOffset: number, value: number, littleEndian?: boolean): void { - this.dataView?.setInt32(byteOffset, value, littleEndian) - } - - /** - * Writes the next signed integer. - * @param value - The value - * @param littleEndian - Whether the value is little endian - */ - writeInt32(value: number, littleEndian?: boolean): void { - this.checkWriteCapacity(4) - this.setInt32(this.mByteOffset, value, littleEndian) - this.mByteOffset += 4 - } - - /** - * Gets an unsigned integer. - * @param byteOffset - The byte offset - * @param littleEndian - Whether the value is little endian - * @returns The value. - */ - getUint32(byteOffset: number, littleEndian?: boolean): number { - return this.dataView?.getUint32(byteOffset, littleEndian) ?? 0 - } - - /** - * Reads the next unsigned integer. - * @param littleEndian - Whether the value is little endian - * @returns The value. - */ - readUint32(littleEndian?: boolean): number { - const value = this.getUint32(this.mByteOffset, littleEndian) - this.mByteOffset += 4 - return value - } - - /** - * Sets an unsigned integer. - * @param byteOffset - The byte offset - * @param value - The value - * @param littleEndian - Whether the value is little endian - */ - setUint32(byteOffset: number, value: number, littleEndian?: boolean): void { - this.dataView?.setUint32(byteOffset, value, littleEndian) - } - - /** - * Writes the next signed integer. - * @param value - The value - * @param littleEndian - Whether the value is little endian - */ - writeUint32(value: number, littleEndian?: boolean): void { - this.checkWriteCapacity(4) - this.setUint32(this.mByteOffset, value, littleEndian) - this.mByteOffset += 4 - } - - /** - * Gets a float. - * @param byteOffset - The byte offset - * @param littleEndian - Whether the value is little endian - * @returns The value. - */ - getFloat32(byteOffset: number, littleEndian?: boolean): number { - return this.dataView?.getFloat32(byteOffset, littleEndian) ?? 0 - } - - /** - * Reads the next float. - * @param littleEndian - Whether the value is little endian - * @returns The value. - */ - readFloat32(littleEndian?: boolean): number { - const value = this.getFloat32(this.mByteOffset, littleEndian) - this.mByteOffset += 4 - return value - } - - /** - * Sets a float. - * @param byteOffset - The byte offset - * @param value - The value - * @param littleEndian - Whether the value is little endian - */ - setFloat32(byteOffset: number, value: number, littleEndian?: boolean): void { - this.dataView?.setFloat32(byteOffset, value, littleEndian) - } - - /** - * Writes the next float. - * @param value - The value - * @param littleEndian - Whether the value is little endian - */ - writeFloat32(value: number, littleEndian?: boolean): void { - this.checkWriteCapacity(4) - this.setFloat32(this.mByteOffset, value, littleEndian) - this.mByteOffset += 4 - } - - /** - * Gets a double. - * @param byteOffset - The byte offset - * @param littleEndian - Whether the value is little endian - * @returns The value. - */ - getFloat64(byteOffset: number, littleEndian?: boolean): number { - return this.dataView?.getFloat64(byteOffset, littleEndian) ?? 0 - } - - /** - * Reads the next double. - * @param littleEndian - Whether the value is little endian - * @returns The value. - */ - readFloat64(littleEndian?: boolean): number { - const value = this.getFloat64(this.mByteOffset, littleEndian) - this.mByteOffset += 8 - return value - } - - /** - * Sets a double. - * @param byteOffset - The byte offset - * @param value - The value - * @param littleEndian - Whether the value is little endian - */ - setFloat64(byteOffset: number, value: number, littleEndian?: boolean): void { - this.dataView?.setFloat64(byteOffset, value, littleEndian) - } - - /** - * Writes the next double. - * @param value - The value - * @param littleEndian - Whether the value is little endian - */ - writeFloat64(value: number, littleEndian?: boolean): void { - this.checkWriteCapacity(8) - this.setFloat64(this.mByteOffset, value, littleEndian) - this.mByteOffset += 8 - } - - /** - * Gets an signed long. - * @param byteOffset - The byte offset - * @param littleEndian - Whether the value is little endian - * @returns The value. - */ - getBigInt64(byteOffset: number, littleEndian?: boolean): bigint { - return this.dataView?.getBigInt64(byteOffset, littleEndian) ?? BigInt(0) - } - - /** - * Reads the next signed long. - * @param littleEndian - Whether the value is little endian - * @returns The value. - */ - readBigInt64(littleEndian?: boolean): bigint { - const value = this.getBigInt64(this.mByteOffset, littleEndian) - this.mByteOffset += 8 - return value - } - - /** - * Sets a signed long. - * @param byteOffset - The byte offset - * @param value - The value - * @param littleEndian - Whether the value is little endian - */ - setBigInt64(byteOffset: number, value: bigint, littleEndian?: boolean): void { - this.dataView?.setBigInt64(byteOffset, value, littleEndian) - } - - /** - * Writes the next signed long. - * @param value - The value - * @param littleEndian - Whether the value is little endian - */ - writeBigInt64(value: bigint, littleEndian?: boolean): void { - this.checkWriteCapacity(8) - this.setBigInt64(this.mByteOffset, value, littleEndian) - this.mByteOffset += 8 - } - - /** - * Gets an unsigned long. - * @param byteOffset - The byte offset - * @param littleEndian - Whether the value is little endian - * @returns The value. - */ - getBigUint64(byteOffset: number, littleEndian?: boolean): bigint { - return this.dataView?.getBigUint64(byteOffset, littleEndian) ?? BigInt(0) - } - - /** - * Reads the next unsigned long. - * @param littleEndian - Whether the value is little endian - * @returns The value. - */ - readBigUint64(littleEndian?: boolean): bigint { - const value = this.getBigUint64(this.mByteOffset, littleEndian) - this.mByteOffset += 8 - return value - } - - /** - * Sets an unsigned long. - * @param byteOffset - The byte offset - * @param value - The value - * @param littleEndian - Whether the value is little endian - */ - setBigUint64(byteOffset: number, value: bigint, littleEndian?: boolean): void { - this.dataView?.setBigUint64(byteOffset, value, littleEndian) - } - - /** - * Writes the next unsigned long. - * @param value - The value - * @param littleEndian - Whether the value is little endian - */ - writeBigUint64(value: bigint, littleEndian?: boolean): void { - this.checkWriteCapacity(8) - this.setBigUint64(this.mByteOffset, value, littleEndian) - this.mByteOffset += 8 - } - - /** - * Gets an signed long. - * @param byteOffset - The byte offset - * @param littleEndian - Whether the value is little endian - * @returns The value. - */ - getInt64(byteOffset: number, littleEndian?: boolean): bigint { - return this.getBigInt64(byteOffset, littleEndian) - } - - /** - * Reads the next signed long. - * @param littleEndian - Whether the value is little endian - * @returns The value. - */ - readInt64(littleEndian?: boolean): bigint { - const value = this.getInt64(this.mByteOffset, littleEndian) - this.mByteOffset += 8 - return value - } - - /** - * Sets a signed long. - * @param byteOffset - The byte offset - * @param value - The value - * @param littleEndian - Whether the value is little endian - */ - setInt64(byteOffset: number, value: number, littleEndian?: boolean): void { - this.setBigInt64(byteOffset, BigInt(value), littleEndian) - } - - /** - * Writes the next signed long. - * @param value - The value - * @param littleEndian - Whether the value is little endian - */ - writeInt64(value: number, littleEndian?: boolean): void { - this.checkWriteCapacity(8) - this.setInt64(this.mByteOffset, value, littleEndian) - this.mByteOffset += 8 - } - - /** - * Gets an unsigned long. - * @param byteOffset - The byte offset - * @param littleEndian - Whether the value is little endian - * @returns The value. - */ - getUint64(byteOffset: number, littleEndian?: boolean): number { - return Number(this.getBigUint64(byteOffset, littleEndian)) - } - - /** - * Reads the next unsigned long. - * @param littleEndian - Whether the value is little endian - * @returns The value. - */ - readUint64(littleEndian?: boolean): number { - const value = this.getUint64(this.mByteOffset, littleEndian) - this.mByteOffset += 8 - return value - } - - /** - * Sets an unsigned long. - * @param byteOffset - The byte offset - * @param value - The value - * @param littleEndian - Whether the value is little endian - */ - setUint64(byteOffset: number, value: number, littleEndian?: boolean): void { - this.setBigUint64(byteOffset, BigInt(value), littleEndian) - } - - /** - * Writes the next signed long. - * @param value - The value - * @param littleEndian - Whether the value is little endian - */ - writeUint64(value: number, littleEndian?: boolean): void { - this.checkWriteCapacity(8) - this.setUint64(this.mByteOffset, value, littleEndian) - this.mByteOffset += 8 - } - - /** - * Gets an array of unsigned bytes. - * @param byteOffset - The byte offset - * @param byteLength - The byte length - * @returns The value. - */ - getUint8Array(byteOffset: number, byteLength?: number): Uint8Array { - return this.dataView == null ? - new Uint8Array(StringUtils.stringToArrayBuffer(""), byteOffset, byteLength) : - new Uint8Array(this.dataView?.buffer, this.dataView?.byteOffset + byteOffset, byteLength) - } - - /** - * Reads the next array of unsigned bytes. - * @param byteLength - The byte length - * @returns The value. - */ - readUint8Array(byteLength?: number): Uint8Array { - const value = this.getUint8Array(this.mByteOffset, byteLength) - this.mByteOffset += value.byteLength - return value - } - - /** - * Sets an array of unsigned bytes. - * @param byteOffset - The byte offset - * @param value - The value - */ - setUint8Array(byteOffset: number, value: Uint8Array): void { - const byteLength = value.byteLength - this.getUint8Array(byteOffset, byteLength).set(value) - } - - /** - * Writes the next array of unsigned bytes. - * @param value - The value - */ - writeUint8Array(value: Uint8Array): void { - this.checkWriteCapacity(value.byteLength) - this.setUint8Array(this.mByteOffset, value) - this.mByteOffset += value.byteLength - } - - /** - * Gets an array of unsigned shorts. - * @param byteOffset - The byte offset - * @param byteLength - The byte length - * @returns The value. - */ - getUint16Array(byteOffset: number, byteLength?: number): Uint16Array { - if (byteLength !== undefined) { - byteLength = Math.floor(byteLength / 2) - } - return this.dataView == null ? - new Uint16Array(StringUtils.stringToArrayBuffer(""), byteOffset, byteLength) : - new Uint16Array(this.dataView.buffer, this.dataView.byteOffset + byteOffset, byteLength) - } - - /** - * Reads the next array of unsigned shorts. - * @param byteLength - The byte length - * @returns The value. - */ - readUint16Array(byteLength?: number): Uint16Array { - const value = this.getUint16Array(this.mByteOffset, byteLength) - this.mByteOffset += value.byteLength - return value - } - - /** - * Sets an array of unsigned bytes. - * @param byteOffset - The byte offset - * @param value - The value - */ - setUint16Array(byteOffset: number, value: Uint16Array): void { - const byteLength = value.byteLength - this.getUint16Array(byteOffset, byteLength).set(value) - } - - /** - * Writes the next array of unsigned bytes. - * @param value - The value - */ - writeUint16Array(value: Uint16Array): void { - this.checkWriteCapacity(value.byteLength) - this.setUint16Array(this.mByteOffset, value) - this.mByteOffset += value.byteLength - } - - /** - * Gets a string. - * @param byteOffset - The byte offset - * @param byteLength - The byte length - * @param byteEncoding - The byte encoding - * @returns The value. - */ - getString(byteOffset: number, byteLength?: number, byteEncoding?: string): string { - const decoder = new util.TextDecoder(byteEncoding || "utf-8") - const encoded = this.getUint8Array(byteOffset, byteLength) - return decoder.decode(encoded) - } - - /** - * Reads the next string. - * @param byteLength - The byte length - * @param byteEncoding - The byte encoding - * @returns The value. - */ - readString(byteLength?: number, byteEncoding?: string): string { - const value = this.getString(this.mByteOffset, byteLength, byteEncoding) - if (byteLength === undefined) { - this.mByteOffset = this.dataView?.byteLength ?? 0 - } else { - this.mByteOffset += byteLength - } - return value - } - - /** - * Sets a string. - * @param byteOffset - The byte offset - * @param value - The string value - * @param byteEncoding - The byte encoding - * @returns The byte length. - */ - setString(byteOffset: number, value: string, byteEncoding?: string, write?: boolean): number { - if (byteEncoding && byteEncoding !== "utf-8") { - throw new TypeError("String encoding '" + byteEncoding + "' is not supported") - } - const encoder = new util.TextEncoder() - const byteLength = Math.min(this.dataView!.byteLength - byteOffset, value.length * 4) - if (write) { - this.checkWriteCapacity(byteLength) - } - const destination = this.getUint8Array(byteOffset, byteLength) - const written = encoder.encodeInto(value, destination).written - return written || 0 - } - - /** - * Writes the next a string. - * @param value - The string value - * @param byteEncoding - The byte encoding - */ - writeString(value: string, byteEncoding?: string): void { - const byteLength = this.setString(this.mByteOffset, value, byteEncoding, true) - this.mByteOffset += byteLength - } - - /** - * Formats to a string. - * @param format - The string format - * @returns The string. - */ - toString(format?: string): string { - return [...this.getUint8Array(0)].map((byte: number) => { - switch (format) { - case "hex": - return ("00" + byte.toString(16)).slice(-2) - default: - return byte.toString(10) - } - }).join(" ") - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/Json5ToJson.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/Json5ToJson.ets deleted file mode 100644 index cb4d79c..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/Json5ToJson.ets +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE_HW file. - */ - - -/** - * Remove JSON5-style comments from text. - * Supports: // line comments, /* block comments *\/ - * Preserves anything inside string literals: "..." (and optionally '...' if present) - */ - -//Pass in a string and remove the comments from it -function stripComments(input: string) { - //Return value - let out = ''; - let i = 0; - - const len = input.length; - let inString = false; - let stringQuote = ''; - //Whether it is in an escape state (the previous character is \), - //used to handle \" or \' etc. - let escaped = false; - - //Loop through each character - while (i < len) { - const ch = input[i]; - const next = i + 1 < len ? input[i + 1] : ''; - - //If currently inside a string, output everything exactly as it is - if (inString) { - out += ch; - //If the previous character is a backslash causing this character to be escaped, - //then clear the escape state - if (escaped) { - escaped = false; - //When encountering a backslash, enter escape mode - } else if (ch === '\\') { - escaped = true; - } else if (ch === stringQuote) { - inString = false; - stringQuote = ''; - } - i++; - continue; - } - //Not inside a string; - //enter string mode when encountering a quotation mark - if (ch === '"' || ch === "'") { - inString = true; - stringQuote = ch; - out += ch; - i++; - continue; - } - //Detect and skip single-line comments - if (ch === '/' && next === '/') { - i += 2; - while (i < len && input[i] !== '\n' && input[i] !== '\r') i++; - continue; - } - //Detect and skip block comments - if (ch === '/' && next === '*') { - i += 2; - while (i < len) { - if (input[i] === '*' && i + 1 < len && input[i + 1] === '/') { - i += 2; - break; - } - i++; - } - continue; - } - out += ch; - i++; - } - return out; -} - - -export function json5Tojson(json5Text: string): string { - const noComments = stripComments(json5Text); - return noComments; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/Log.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/Log.ets deleted file mode 100644 index d8b0dfc..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/Log.ets +++ /dev/null @@ -1,119 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import HiLog from '@ohos.hilog'; -import BuildProfile from '../../../../BuildProfile'; - -const DOMAIN: number = 0x00FF; -const TAG = "Flutter"; -const SYMBOL = " --> "; - -/** - * Basic log class - */ -export default class Log { - private static _logLevel = HiLog.LogLevel.WARN; - - /** - * Sets the log level. - * - * @param level - The log level - */ - public static setLogLevel(level: HiLog.LogLevel) { - Log._logLevel = level; - } - - /** - * Outputs debug-level logs. - * - * @param tag - The log tag - * @param format - The log format string - * @param args - The log parameters - * @since 7 - */ - static d(tag: string, format: string, ...args: Object[]) { - if (Log.isLoggable(HiLog.LogLevel.DEBUG)) { - HiLog.debug(DOMAIN, TAG, tag + SYMBOL + format, args); - } - } - - /** - * Outputs info-level logs. - * - * @param tag - The log tag - * @param format - The log format string - * @param args - The log parameters - * @since 7 - */ - static i(tag: string, format: string, ...args: Object[]) { - if (Log.isLoggable(HiLog.LogLevel.INFO)) { - HiLog.info(DOMAIN, TAG, tag + SYMBOL + format, args); - } - } - - /** - * Outputs warning-level logs. - * - * @param tag - The log tag - * @param format - The log format string - * @param args - The log parameters - * @since 7 - */ - static w(tag: string, format: string, ...args: Object[]) { - if (Log.isLoggable(HiLog.LogLevel.WARN)) { - HiLog.warn(DOMAIN, TAG, tag + SYMBOL + format, args); - } - } - - /** - * Outputs error-level logs. - * - * @param tag - The log tag - * @param format - The log format string - * @param args - The log parameters - * @since 7 - */ - static e(tag: string, format: string, ...args: Object[]) { - if (Log.isLoggable(HiLog.LogLevel.ERROR)) { - args.forEach((item: Object, index: number) => { - if (item instanceof Error) { - args[index] = item.message + item.stack; - } - format += "%{public}s"; - }) - HiLog.error(DOMAIN, TAG, tag + SYMBOL + format, args); - } - } - - /** - * Outputs fatal-level logs. - * - * @param tag - The log tag - * @param format - The log format string - * @param args - The log parameters - * @since 7 - */ - static f(tag: string, format: string, ...args: Object[]) { - if (Log.isLoggable(HiLog.LogLevel.FATAL)) { - HiLog.fatal(DOMAIN, TAG, tag + SYMBOL + format, args); - } - } - - /** - * Checks whether logs of the specified tag and level can be printed. - * - * @param level - The log level - * @returns True if logs can be printed, false otherwise - * @since 7 - */ - private static isLoggable(level: HiLog.LogLevel): boolean { - let buildModeName: string = BuildProfile.BUILD_MODE_NAME.toLowerCase(); - if (buildModeName == 'release' || buildModeName == 'profile') { - return level >= Log._logLevel && HiLog.isLoggable(DOMAIN, TAG, level); - } - return HiLog.isLoggable(DOMAIN, TAG, level); - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/MessageChannelUtils.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/MessageChannelUtils.ets deleted file mode 100644 index f08b175..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/MessageChannelUtils.ets +++ /dev/null @@ -1,25 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import BasicMessageChannel from '../plugin/common/BasicMessageChannel'; -import { BinaryMessenger } from '../plugin/common/BinaryMessenger'; -import StringUtils from './StringUtils'; - -/** - * Utility class for message channel operations. - */ -export default class MessageChannelUtils { - /** - * Resizes a channel buffer. - * @param messenger - The BinaryMessenger to use - * @param channel - The channel name - * @param newSize - The new buffer size - */ - static resizeChannelBuffer(messenger: BinaryMessenger, channel: string, newSize: number) { - const dataStr = `resize\r${channel}\r${newSize}` - messenger.send(BasicMessageChannel.CHANNEL_BUFFERS_CHANNEL, StringUtils.stringToArrayBuffer(dataStr)); - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/PasteboardUtils.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/PasteboardUtils.ets deleted file mode 100644 index cf44eeb..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/PasteboardUtils.ets +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE_HW file. - */ -import { BusinessError, pasteboard } from "@kit.BasicServicesKit"; -import { abilityAccessCtrl } from "@kit.AbilityKit"; -import FlutterManager from "../embedding/ohos/FlutterManager"; -import Log from "./Log"; - -/** - * Utility class for pasteboard operations. - * Provides methods for copying and pasting data to/from the system pasteboard. - */ -export class PasteboardUtils { - private static TAG = "PasteboardUtils"; - - /** - * Copies text data to the OpenHarmony pasteboard. - * @param text - The text to copy - */ - static setCopyData(text: string) { - const pasteData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, text); - const systemPasteboard: pasteboard.SystemPasteboard = pasteboard.getSystemPasteboard(); - try { - systemPasteboard.setDataSync(pasteData); - } catch (err) { - Log.w(PasteboardUtils.TAG, "Failed to set PasteData. Cause: " + JSON.stringify(err)); - } - } - - /** - * Gets paste data from the OpenHarmony pasteboard asynchronously. - * Requests READ_PASTEBOARD permission if needed. - * @returns A Promise that resolves to the pasted text, or empty string if no text is available. - */ - static getPasteDataAsync(): Promise { - return new Promise((resolve) => { - let atManager = abilityAccessCtrl.createAtManager(); - // request the ohos paste operation authority - atManager.requestPermissionsFromUser(FlutterManager.getInstance().getUIAbility().context, - ['ohos.permission.READ_PASTEBOARD']).then((data) => { - enum AuthResultStatus { - NOT_CONFIGURED = -1, - GRANTED = 0, - INVALID_REQ = 2 - } - - const authResult: number = data.authResults[0]; - switch (authResult) { - case AuthResultStatus.GRANTED: { - let systemPasteboard: pasteboard.SystemPasteboard = pasteboard.getSystemPasteboard(); - systemPasteboard.getData().then(async (pasteData: pasteboard.PasteData) => { - let pasteText: string = ''; - const recordCount: number = pasteData.getRecordCount(); - for (let i = 0; i < recordCount; i++) { - const record = pasteData.getRecord(i); - let text: string = ''; - if (typeof record.getValidTypes === 'function') { - // For api14 and above, click here. More formats are supported - text = await PasteboardUtils.getTargetTypesData(record); - } else if (record.mimeType === pasteboard.MIMETYPE_TEXT_HTML) { - const htmlText: StyledString = await StyledString.fromHtml(record.htmlText); - text = htmlText.getString(); - } else if (record.mimeType === pasteboard.MIMETYPE_TEXT_PLAIN) { - text = record.plainText; - } - pasteText += text; - } - resolve(pasteText); - }).catch((err: BusinessError) => { - Log.e(PasteboardUtils.TAG, "Failed to get PasteData. Cause: " + JSON.stringify(err)); - }); - break; - } - case AuthResultStatus.NOT_CONFIGURED: - case AuthResultStatus.INVALID_REQ: - default: { - Log.e(PasteboardUtils.TAG, "error code: " + authResult); - break; - } - } - }).catch((err: BusinessError) => { - Log.e(PasteboardUtils.TAG, "Failed to request permissions from user. Cause: " + JSON.stringify(err)); - }) - }); - } - - static async getTargetTypesData(record: pasteboard.PasteDataRecord): Promise { - let targetTypes: string[] = [ - pasteboard.MIMETYPE_TEXT_PLAIN, - pasteboard.MIMETYPE_TEXT_HTML - ]; - let tmpTypes: string[] = record.getValidTypes(targetTypes); - let str: string = ''; - for (let j = 0; j < tmpTypes.length; j++) { - let value = ''; - try { - value = await record.getData(tmpTypes[j]) as string; - } catch (error) { - Log.e(PasteboardUtils.TAG, "Failed to record.getData: " + JSON.stringify(error)); - } - if (value) { - if (tmpTypes[j] === pasteboard.MIMETYPE_TEXT_HTML) { - try { - const htmlText: StyledString = await StyledString.fromHtml(value); - str = htmlText.getString(); - } catch (error) { - Log.e(PasteboardUtils.TAG, "Failed to record.getData: " + JSON.stringify(error)); - } - } else { - str = value - } - break; - } - } - return str; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/PathUtils.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/PathUtils.ets deleted file mode 100644 index 629ff39..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/PathUtils.ets +++ /dev/null @@ -1,53 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ -import common from '@ohos.app.ability.common'; -import fs from '@ohos.file.fs'; -import Log from './Log'; - -const TAG: string = "PathUtils"; - -/** - * Utility class for path operations in OpenHarmony. - * Provides methods for getting application directories. - */ -export default class PathUtils { - /** - * Gets the files directory for the application. - * @param context - The application context - * @returns The files directory path. - */ - static getFilesDir(context: common.Context): string { - return context.filesDir; - } - - /** - * Gets the cache directory for the application. - * @param context - The application context - * @returns The cache directory path. - */ - static getCacheDirectory(context: common.Context): string { - return context.cacheDir; - } - - /** - * Gets or creates the Flutter data directory. - * @param context - The application context - * @returns The Flutter data directory path, or null if creation fails. - */ - static getDataDirectory(context: common.Context): string | null { - const name = "flutter"; - const flutterDir = context.filesDir + "/" + name; - if (!fs.accessSync(flutterDir)) { - try { - fs.mkdirSync(flutterDir); - } catch (err) { - Log.e(TAG, "mkdirSync failed err:" + err); - return null; - } - } - return flutterDir; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/StringUtils.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/StringUtils.ets deleted file mode 100644 index 9bd3b4d..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/StringUtils.ets +++ /dev/null @@ -1,68 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import flutter from 'libflutter.so' - -/** - * Utility class for string operations. - * Provides methods for converting between strings and ArrayBuffer/Uint8Array. - */ -export default class StringUtils { - - /** - * Converts a string to an ArrayBuffer using UTF-8 encoding. - * @param str - The string to convert. - * @returns The ArrayBuffer containing the UTF-8 encoded string. - */ - static stringToArrayBuffer(str: string): ArrayBuffer { - if (str.length == 0) { - return new ArrayBuffer(0); - } - return flutter.nativeEncodeUtf8(str).buffer; - } - - /** - * Converts an ArrayBuffer to a string using UTF-8 decoding. - * @param buffer - The ArrayBuffer to convert. - * @returns The decoded string, or empty string if buffer is empty. - */ - static arrayBufferToString(buffer: ArrayBuffer): string { - if (buffer.byteLength <= 0) { - return ""; - } - return flutter.nativeDecodeUtf8(new Uint8Array(buffer)); - } - - /** - * Converts a Uint8Array to a string using UTF-8 decoding. - * @param buffer - The Uint8Array to convert. - * @returns The decoded string, or empty string if buffer is empty. - */ - static uint8ArrayToString(buffer: Uint8Array): string { - if (buffer.length <= 0) { - return ""; - } - return flutter.nativeDecodeUtf8(buffer); - } - - /** - * Checks if a string is not empty. - * @param str - The string to check. - * @returns True if the string is not null and has length > 0, false otherwise. - */ - static isNotEmpty(str: string): boolean { - return str != null && str.length > 0; - } - - /** - * Checks if a string is empty. - * @param str - The string to check - * @returns True if the string is null, undefined, or has length 0, false otherwise. - */ - static isEmpty(str: string): boolean { - return (!str) || str.length == 0; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ToolUtils.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ToolUtils.ets deleted file mode 100644 index 292c0aa..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ToolUtils.ets +++ /dev/null @@ -1,30 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ -import Any from '../plugin/common/Any'; - -/** - * Utility class for object operations. - */ -export default class ToolUtils { - /** - * Checks if a value is an object. - * @param object - The value to check - * @returns True if the value is an object, false otherwise. - */ - static isObj(object: Object): boolean { - return object && typeof (object) == 'object'; - } - - /** - * Checks if an object implements a specific method (interface check). - * @param obj - The object to check - * @param method - The method name to check for - * @returns True if the object has the method and it's a function, false otherwise. - */ - static implementsInterface(obj: Any, method: string): boolean { - return Reflect.has(obj, method) && typeof obj[method] === 'function' - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/TraceSection.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/TraceSection.ets deleted file mode 100644 index f7c1f91..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/util/TraceSection.ets +++ /dev/null @@ -1,59 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on TraceSection.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import hiTraceMeter from '@ohos.hiTraceMeter' - -/** - * Utility class for tracing code sections using hiTraceMeter. - * Provides methods to begin and end trace sections with automatic name cropping. - */ -export class TraceSection { - /** The current task ID for trace sections. */ - static taskId: number = 0; - - /** - * Crops a section name to ensure it stays below 124 characters. - * @param sectionName - The section name to crop - * @returns The cropped section name. - * @private - */ - private static cropSectionName(sectionName: string): string { - return sectionName.length < 124 ? sectionName : sectionName.substring(0, 124) + "..."; - } - - /** - * Wraps Trace.beginSection to ensure that the line length stays below 127 code units. - * - * @param sectionName - The string to display as the section name in the trace - * @returns The task ID for this trace section - */ - public static begin(sectionName: string): number { - TraceSection.taskId++; - hiTraceMeter.startTrace(TraceSection.cropSectionName(sectionName), TraceSection.taskId); - return TraceSection.taskId; - } - - /** - * Ends a trace section. - * @param sectionName - The section name to end. - */ - public static end(sectionName: string): void { - hiTraceMeter.finishTrace(TraceSection.cropSectionName(sectionName), TraceSection.taskId); - } - - /** - * Ends a trace section with a specific task ID. - * @param sectionName - The section name to end. - * @param id - The task ID to use. - */ - public static endWithId(sectionName: string, id: number): void { - hiTraceMeter.finishTrace(TraceSection.cropSectionName(sectionName), id); - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicView.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicView.ets deleted file mode 100644 index a757281..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicView.ets +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE_HW file. - */ -import matrix4 from '@ohos.matrix4'; -import Any from '../../plugin/common/Any'; -import Log from '../../util/Log'; - -/** - * Dynamic View creation - * from a recursive data structure - * - * exported @Component: DynamicView - * exported view model classes: - * - DVModelContainer - * - DVModel - * - DVModelParameters - * - DVModelEvents - * - DVModelChildren - * - * The purpose of exporting the DVModel classes - * is to make them available to the converter from - * JD's XML format and the expression parser. These - * components are expected to generate and update the - * DVModel. - * - * An application written by JS should only import - * DynamicView, DVModelContainer to be used in their own ArkUI - * container view. - */ - -/** - * View Model classes - */ - -/** - * Parameters for DynamicView model components. - * This class is observed to enable reactive updates when parameters change. - * It serves as a container for component attributes and properties. - */ -@Observed -export class DVModelParameters extends Object { - /* empty, just get any instance wrapped inside an ObservedObject - with the help of the decoration */ -} - -/** - * Events for DynamicView model components. - * This class is observed to enable reactive updates when events change. - * It serves as a container for component event handlers. - */ -@Observed -export class DVModelEvents extends Object { - /* empty, just get any instance wrapped inside an ObservedObject - with the help of the decoration */ -} - -/** - * Children array for DynamicView model components. - * This class is observed to enable reactive updates when children change. - * It serves as a container for child DVModel instances. - */ -@Observed -export class DVModelChildren extends Array { - /* empty, just get any instance wrapped inside an ObservedObject - with the help of the decoration */ -} - -let nextId: number = 1; - -/** - * Model class representing a dynamic view component. - * This class holds all information needed to render a component dynamically, - * including its type, parameters, events, children, and optional builder. - */ -@Observed -export class DVModel { - /** The unique identifier for this model. */ - id_: number; - /** The component type (e.g., "Column", "Row", "Text", "Image"). */ - compType: string; - /** The component parameters. */ - params: DVModelParameters; - /** The component events. */ - events: DVModelEvents; - /** The child components. */ - children: DVModelChildren; - /** Optional custom builder function. */ - builder: Any; - - /** - * Constructs a new DVModel instance. - * @param compType - The component type (e.g., "Column", "Row", "Text", "Image") - * @param params - The component parameters - * @param events - The component events - * @param children - The child components - * @param builder - Optional custom builder function - */ - constructor(compType: string, params: DVModelParameters, events: DVModelEvents, children: DVModelChildren, - builder?: Any) { - this.id_ = nextId++; - this.compType = compType; - this.params = params ?? new DVModelParameters; - this.events = events; - this.children = children; - this.builder = builder; - } - - /** - * Gets the layout parameters for this model. - * @returns The DVModelParameters instance - */ - public getLayoutParams(): DVModelParameters { - return this.params; - } -} - -/** - * Container for the root DVModel object. - * This class wraps the root model to provide a container structure. - */ -export class DVModelContainer { - /** The root DVModel instance. */ - model: DVModel; - - /** - * Constructs a new DVModelContainer instance. - * @param model - The root DVModel to contain - */ - constructor(model: DVModel) { - this.model = model; - } -} - -/** - DynamicView is the @Component that does all the work: - - The following 4 features are the key solution elements for dynamic View - construction and update: - - 1. The if statement decides which framework component to create. - We can not use a factory function here, because that would requite calling - a regular function inside build() or a @Builder function. - - 2. Take note of the @Builder for Row, Column containers: - These functions create DynamicView Views inside a DynamicView - view. This behaviour is why we talk about DynamicView as a 'recursive' View. - All @Builder functions are member functions of the DynamicView @Component to - retain access ('this.xyz') to its decorated state variables. - - 3. The @Extend functions execute attribute and event handler registration functions - for all attributes and events permissable on the framework component, irrespective - if DVModelParameters or DVModelEvents objects includes a value or not. If not - the attribute or event is set to 'undefined' by intention. This is required to unset - any previously set value. - - 4. The scope ('this') of any lambda registered as an event hander function, e.g. for onClick, - is the @Component, in which the DVModel object is initialized. This said, it is advised to initialize - the DVModel object in the @Component that is parent to outmost DynamicView. Thereby, - any event handler function is able to mutate decorated state variables of that @Component - - */ - -@Component -export struct DynamicView { - @ObjectLink model: DVModel; - @ObjectLink children: DVModelChildren; - @ObjectLink params: DVModelParameters; - @ObjectLink events: DVModelEvents; - @BuilderParam customBuilder?: ($$: BuilderParams) => void; - - /** - * Gets a parameter value from the parameters object. - * @param params - The parameters object - * @param element - The parameter key - * @returns The parameter value, or undefined if not found - */ - getParams: (params: DVModelParameters, element: string) => string | Any = - (params: DVModelParameters, element: string): string | Any => { - let params2 = params as Record; - return params2[element]; - } - - /** - * Gets an event handler from the events object. - * @param events - The events object - * @param element - The event key - * @returns The event handler, or undefined if not found - */ - getEvents: (events: DVModelEvents, element: string) => Any = (events: DVModelEvents, element: string): Any => { - let events2 = events as Record; - return events2[element]; - } - - @Styles - common_attrs() { - .width(this.getParams(this.params, "width")) - .height(this.getParams(this.params, "height")) - .backgroundColor(this.getParams(this.params, "backgroundColor")) - .onClick(this.getEvents(this.events, "onClick")) - .margin({ - left: this.getParams(this.params, "marginLeft"), - right: this.getParams(this.params, "marginRight"), - top: this.getParams(this.params, "marginTop"), - bottom: this.getParams(this.params, "marginBottom") - }) - .onTouch(this.getEvents(this.events, "onTouch")) - .onFocus(this.getEvents(this.events, "onFocus")) - .onBlur(this.getEvents(this.events, "onBlur")) - .translate({ - x: this.getParams(this.params, "translateX"), - y: this.getParams(this.params, "translateY"), - z: this.getParams(this.params, "translateZ") - }) - .transform(this.getParams(this.params, "matrix")) - .direction(this.getParams(this.params, "direction")) - } - - @Styles - clip_attrs() { - .clip(this.getParams(this.params, "rectWidth") ? new Rect({ - width: this.getParams(this.params, "rectWidth"), - height: this.getParams(this.params, "rectHeight"), - radius: this.getParams(this.params, "rectRadius") - }) : null) - .clip(this.getParams(this.params, "pathWidth") ? new Path({ - width: this.getParams(this.params, "pathWidth"), - height: this.getParams(this.params, "pathHeight"), - commands: this.getParams(this.params, "pathCommands") - }) : null) - } - - @Builder - buildChildren() { - ForEach(this.children, - (child: Any) => { - DynamicView({ - model: child as DVModel, - params: child.params, - events: child.events, - children: child.children, - customBuilder: child.builder - }) - }, - (child: Any) => `${child.id_}` - ) - } - - @Builder - buildRow() { - Row() { - this.buildChildren() - } - .common_attrs() - .clip_attrs() - } - - @Builder - buildColumn() { - Column() { - this.buildChildren() - } - .common_attrs() - .clip_attrs() - } - - @Builder - buildStack() { - Stack() { - this.buildChildren() - } - .common_attrs() - .clip_attrs() - .alignContent(this.getParams(this.params, "alignContent")) - } - - @Builder - buildText() { - Text(`${this.getParams(this.params, "value")}`) - .common_attrs() - .fontColor(this.getParams(this.params, "fontColor")) - } - - @Builder - buildImage() { - Image(this.getParams(this.params, "src")) - .common_attrs() - } - - @Builder - buildButton() { - Button(this.getParams(this.params, "value")) - .common_attrs() - } - - @Builder - buildNodeContainer() { - NodeContainer(this.getParams(this.params, "nodeController")) - .common_attrs() - .position({ - x: (this.params as Record)['left'] as number, - y: (this.params as Record)['top'] as number - }) - } - - @Builder - buildCustom() { - if (this.customBuilder) { - this.customBuilder(new BuilderParams(this.params)); - } - } - - build() { - if (this.model.compType == "Column") { - this.buildColumn() - } else if (this.model.compType == "Row") { - this.buildRow() - } else if (this.model.compType == "Stack") { - this.buildStack() - } else if (this.model.compType == "Text") { - this.buildText() - } else if (this.model.compType == "Image") { - this.buildImage() - } else if (this.model.compType == "Button") { - this.buildButton() - } else if (this.model.compType == "NodeContainer") { - this.buildNodeContainer() - } else { - this.buildCustom() - } - } -} - -/** - * Parameters passed to custom builder functions. - * This class wraps DVModelParameters for use in custom builders. - */ -export class BuilderParams { - /** The DVModelParameters to wrap. */ - params: DVModelParameters; - - /** - * Constructs a new BuilderParams instance. - * @param params - The DVModelParameters to wrap - */ - constructor(params: DVModelParameters) { - this.params = params; - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicViewJson.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicViewJson.ets deleted file mode 100644 index afc3412..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicViewJson.ets +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE_HW file. - */ -import Any from '../../plugin/common/Any'; - -import { DVModel, DVModelParameters, DVModelEvents, DVModelChildren } from "./dynamicView"; -import Log from '../../util/Log'; -const TAG = "dynamicViewJson"; - -/** - * Creates a DVModel instance from a JSON object. - * This function recursively parses the JSON structure to build a complete DVModel tree. - * @param json - The JSON object representing the view structure - * @returns A DVModel instance created from the JSON - */ -export function createDVModelFromJson(json: Object): DVModel { - - /** - * Helper function to create children from a JSON array. - * @param children - Array of child JSON objects - * @returns A DVModelChildren instance containing parsed child models - * @private - */ - let createChildrenFrom: (children: Array) => DVModelChildren = (children: Array): DVModelChildren => { - let result = new DVModelChildren(); - if (Array.isArray(children)) { - (children as Array).forEach(child => { - const childView = createDVModelFromJson(child); - if (childView != undefined) { - result.push(childView); - } - }); - } - return result; - } - - /** - * Helper function to set a parameter or event value. - * @param result - The parameters or events object to modify - * @param key - The key to set - * @param element - The source object containing the value - * @private - */ - let setParams: (result: DVModelParameters | DVModelEvents, key: Any, element: Object) => void = - (result: DVModelParameters, key: Any, element: Any): void => { - let newResult = result as Record; - newResult[key] = element[key]; - } - - /** - * Helper function to create parameters from a JSON attributes object. - * @param attributes - The attributes JSON object - * @returns A DVModelParameters instance - * @private - */ - let createAttributesFrom: (attributes: Object) => DVModelParameters = (attributes: Object): DVModelParameters => { - let result = new DVModelParameters(); - if ((typeof attributes == "object") && (!Array.isArray(attributes))) { - Object.keys(attributes).forEach(k => { - setParams(result, k, attributes) - }); - } - return result; - } - - /** - * Helper function to create events from a JSON events object. - * @param events - The events JSON object - * @returns A DVModelEvents instance - * @private - */ - let createEventsFrom: (events: Object) => DVModelEvents = (events: Object): DVModelEvents => { - let result = new DVModelEvents(); - if ((typeof events == "object") && (!Array.isArray(events))) { - Object.keys(events).forEach(k => { - setParams(result, k, events) - }); - } - return result; - } - - if (typeof json !== 'object') { - Log.e(TAG, "createDVModelFromJson: input is not JSON"); - return new DVModel("", "", "", createChildrenFrom([])); - } - - let jsonObject = json as Record; - return new DVModel( - jsonObject["compType"], - createAttributesFrom(jsonObject["attributes"]), - createEventsFrom(jsonObject["events"]), - createChildrenFrom(jsonObject["children"]), - jsonObject["build"] - ); -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterCallbackInformation.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterCallbackInformation.ets deleted file mode 100644 index 9afb0f1..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterCallbackInformation.ets +++ /dev/null @@ -1,60 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on FlutterCallbackInformation.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -import FlutterNapi from '../embedding/engine/FlutterNapi'; - -/** - * A class representing information for a callback registered using `PluginUtilities` from `dart:ui`. - * - * This class holds information about callbacks that can be invoked from native code. - */ -export class FlutterCallbackInformation { - /** The name of the callback function. */ - callbackName?: string; - /** The class name containing the callback. */ - callbackClassName?: string; - /** The library path where the callback is defined. */ - callbackLibraryPath?: string; - - /** - * Gets callback information for a given handle. - * - * @param handle - The handle for the callback, generated by `PluginUtilities.getCallbackHandle` in - * `dart:ui` - * @returns An instance of FlutterCallbackInformation for the provided handle, or null if not found - */ - static lookupCallbackInformation(handle: number): FlutterCallbackInformation | null { - return FlutterNapi.nativeLookupCallbackInformation(handle); - } - - /** - * Constructs a new FlutterCallbackInformation instance. - * @param callbackName - The name of the callback function - * @param callbackClassName - The class name containing the callback - * @param callbackLibraryPath - The library path where the callback is defined - */ - constructor(callbackName?: string, callbackClassName?: string, callbackLibraryPath?: string) { - this.callbackName = callbackName; - this.callbackClassName = callbackClassName; - this.callbackLibraryPath = callbackLibraryPath; - } - - /** - * Initializes the callback information. - * @param callbackName - The name of the callback function - * @param callbackClassName - The class name containing the callback - * @param callbackLibraryPath - The library path where the callback is defined - */ - init(callbackName: string, callbackClassName: string, callbackLibraryPath: string) { - this.callbackName = callbackName; - this.callbackClassName = callbackClassName; - this.callbackLibraryPath = callbackLibraryPath; - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterRunArguments.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterRunArguments.ets deleted file mode 100644 index 7a32ede..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterRunArguments.ets +++ /dev/null @@ -1,34 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on FlutterRunArguments.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ - -/** - * A class containing arguments for entering a FlutterNativeView's isolate for the first time. - * Contains the bundle path, entrypoint, and library path. - */ -export default class FlutterRunArguments { - /** The path to the Flutter bundle. */ - public bundlePath: string; - /** The entrypoint function name. */ - public entrypoint: string; - /** The path to the Dart library. */ - public libraryPath: string; - - /** - * Constructs a new FlutterRunArguments instance. - * @param bundlePath - The path to the Flutter bundle - * @param entrypoint - The entrypoint function name - * @param libraryPath - The path to the Dart library - */ - constructor(bundlePath: string, entrypoint: string, libraryPath: string) { - this.bundlePath = bundlePath; - this.entrypoint = entrypoint; - this.libraryPath = libraryPath; - } -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterView.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterView.ets deleted file mode 100644 index 09fad2b..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterView.ets +++ /dev/null @@ -1,1212 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -*/ - -import FlutterEngine from '../embedding/engine/FlutterEngine'; -import Log from '../util/Log'; -import { DVModel, DVModelChildren, DVModelEvents, DVModelParameters } from './DynamicView/dynamicView'; -import { display } from '@kit.ArkUI' -import FlutterManager from '../embedding/ohos/FlutterManager'; -import window from '@ohos.window'; -import KeyboardManager from '../embedding/ohos/KeyboardManager'; -import MouseCursorPlugin from '../plugin/mouse/MouseCursorPlugin'; -import Settings from '../embedding/ohos/Settings'; -import ArrayList from '@ohos.util.ArrayList'; -import { EmbeddingNodeController } from '../embedding/ohos/EmbeddingNodeController'; -import PlatformView, { Params } from '../plugin/platform/PlatformView'; -import hiTraceMeter from '@ohos.hiTraceMeter' -import { JSON } from '@kit.ArkTS'; -import TextInputPlugin from '../plugin/editing/TextInputPlugin'; -import { accessibility } from '@kit.AccessibilityKit'; -import { uiObserver } from '@kit.ArkUI'; -import { common } from '@kit.AbilityKit'; -import { deviceInfo } from '@kit.BasicServicesKit'; -import KeyEventChannel from '../embedding/engine/systemchannels/KeyEventChannel'; -import StatusBarClickChannel from '../embedding/engine/systemchannels/StatusBarClickChannel'; -import { commonEventManager, BusinessError } from '@kit.BasicServicesKit'; - -const TAG = "FlutterViewTag"; -const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS'; -const DPI_SCALE_RESET: number = -1; - -/** - * Metrics describing the viewport dimensions and insets. - * This class holds information about the physical dimensions, padding, insets, and display features. - */ -export class ViewportMetrics { - /** Device pixel ratio for converting logical to physical pixels. */ - devicePixelRatio: number = 1.0; - /** Physical width of the viewport in pixels. */ - physicalWidth: number = 0; - /** Physical height of the viewport in pixels. */ - physicalHeight: number = 0; - /** Top padding of the viewport in physical pixels. */ - physicalViewPaddingTop: number = 0; - /** Right padding of the viewport in physical pixels. */ - physicalViewPaddingRight: number = 0; - /** Bottom padding of the viewport in physical pixels. */ - physicalViewPaddingBottom: number = 0; - /** Left padding of the viewport in physical pixels. */ - physicalViewPaddingLeft: number = 0; - /** Top inset of the viewport in physical pixels. */ - physicalViewInsetTop: number = 0; - /** Right inset of the viewport in physical pixels. */ - physicalViewInsetRight: number = 0; - /** Bottom inset of the viewport in physical pixels. */ - physicalViewInsetBottom: number = 0; - /** Left inset of the viewport in physical pixels. */ - physicalViewInsetLeft: number = 0; - /** Top system gesture inset in physical pixels. */ - systemGestureInsetTop: number = 0; - /** Right system gesture inset in physical pixels. */ - systemGestureInsetRight: number = 0; - /** Bottom system gesture inset in physical pixels. */ - systemGestureInsetBottom: number = 0; - /** Left system gesture inset in physical pixels. */ - systemGestureInsetLeft: number = 0; - /** Physical touch slop value, or -1 if not set. */ - physicalTouchSlop: number = -1; - /** List of display features such as folds, hinges, or cutouts. */ - displayFeatures: ArrayList = new ArrayList(); - - /** - * Creates a deep copy of this ViewportMetrics instance. - * @returns A new ViewportMetrics instance with copied values - */ - clone(): ViewportMetrics { - const copy = new ViewportMetrics(); - copy.devicePixelRatio = this.devicePixelRatio; - copy.physicalWidth = this.physicalWidth; - copy.physicalHeight = this.physicalHeight; - copy.physicalViewPaddingTop = this.physicalViewPaddingTop; - copy.physicalViewPaddingRight = this.physicalViewPaddingRight; - copy.physicalViewPaddingBottom = this.physicalViewPaddingBottom; - copy.physicalViewPaddingLeft = this.physicalViewPaddingLeft; - copy.physicalViewInsetTop = this.physicalViewInsetTop; - copy.physicalViewInsetRight = this.physicalViewInsetRight; - copy.physicalViewInsetBottom = this.physicalViewInsetBottom; - copy.physicalViewInsetLeft = this.physicalViewInsetLeft; - copy.systemGestureInsetTop = this.systemGestureInsetTop; - copy.systemGestureInsetRight = this.systemGestureInsetRight; - copy.systemGestureInsetBottom = this.systemGestureInsetBottom; - copy.systemGestureInsetLeft = this.systemGestureInsetLeft; - copy.physicalTouchSlop = this.physicalTouchSlop; - copy.displayFeatures = this.displayFeatures; - return copy; - } - - /** - * Checks if this ViewportMetrics is equal to another. - * @param other - The other ViewportMetrics to compare with - * @returns True if all metrics are equal, false otherwise - */ - isEqual(other: ViewportMetrics): boolean { - return this.devicePixelRatio === other.devicePixelRatio && - this.physicalWidth === other.physicalWidth && - this.physicalHeight === other.physicalHeight && - this.physicalViewPaddingTop === other.physicalViewPaddingTop && - this.physicalViewPaddingRight === other.physicalViewPaddingRight && - this.physicalViewPaddingBottom === other.physicalViewPaddingBottom && - this.physicalViewPaddingLeft === other.physicalViewPaddingLeft && - this.physicalViewInsetTop === other.physicalViewInsetTop && - this.physicalViewInsetRight === other.physicalViewInsetRight && - this.physicalViewInsetBottom === other.physicalViewInsetBottom && - this.physicalViewInsetLeft === other.physicalViewInsetLeft && - this.systemGestureInsetTop === other.systemGestureInsetTop && - this.systemGestureInsetRight === other.systemGestureInsetRight && - this.systemGestureInsetBottom === other.systemGestureInsetBottom && - this.systemGestureInsetLeft === other.systemGestureInsetLeft && - this.physicalTouchSlop === other.physicalTouchSlop && - this.displayFeatures === other.displayFeatures; - } -} - -/** - * Represents a display feature such as a fold, hinge, or cutout. - */ -export class DisplayFeature { - /** Bounding rectangle of the display feature. */ - bound: display.Rect; - /** Type of the display feature (fold, hinge, cutout, etc.). */ - type: DisplayFeatureType; - /** State of the display feature. */ - state: DisplayFeatureState; - - /** - * Constructs a new DisplayFeature instance. - * @param bound - The bounding rectangle of the feature - * @param type - The type of display feature - * @param state - The state of the display feature - */ - constructor(bound: display.Rect, type: DisplayFeatureType, state: DisplayFeatureState) { - this.bound = bound; - this.type = type; - this.state = state; - } - - /** - * Gets the bounding rectangle of the display feature. - * @returns The bounding rectangle - */ - getBound(): display.Rect { - return this.bound; - } - - /** - * Gets the type of the display feature. - * @returns The display feature type - */ - getType(): DisplayFeatureType { - return this.type; - } - - /** - * Gets the state of the display feature. - * @returns The display feature state - */ - getState(): DisplayFeatureState { - return this.state - } - - /** - * Sets the bounding rectangle of the display feature. - * @param bound - The bounding rectangle to set - */ - setBound(bound: display.Rect): void { - this.bound = bound; - } - - /** - * Sets the type of the display feature. - * @param type - The display feature type to set - */ - setType(type: DisplayFeatureType): void { - this.type = type; - } - - /** - * Sets the state of the display feature. - * @param state - The display feature state to set - */ - setState(state: DisplayFeatureState): void { - this.state = state; - } -} - -/** - * Enumeration of display feature types. - */ -export enum DisplayFeatureType { - /** Unknown display feature type */ - UNKNOWN = 0, - /** Fold display feature */ - FOLD = 1, - /** Hinge display feature */ - HINGE = 2, - /** Cutout display feature */ - CUTOUT = 3 -} - -/** - * Enumeration of display feature states. - */ -export enum DisplayFeatureState { - /** Unknown state */ - UNKNOWN = 0, - /** Flat posture */ - POSTURE_FLAT = 1, - /** Half-opened posture */ - POSTURE_HALF_OPENED = 2, -} - -/** - * Enumeration of display fold status. - */ -export enum DisplayFoldStatus { - /** Unknown fold status */ - FOLD_STATUS_UNKNOWN = 0, - /** Display is expanded */ - FOLD_STATUS_EXPANDED = 1, - /** Display is folded */ - FOLD_STATUS_FOLDED = 2, - /** Display is half-folded */ - FOLD_STATUS_HALF_FOLDED = 3 -} - -type callbackNumber = () => number - -/** - * Parameters for platform view layout. - * @deprecated since 3.7 - */ -export class PlatformViewParas { - /** The width of the platform view. */ - width: number = 0.0; - /** The height of the platform view. */ - height: number = 0.0; - /** The top position of the platform view. */ - top: number = 0.0; - /** The left position of the platform view. */ - left: number = 0.0; - /** The layout direction for the platform view. */ - direction: Direction = Direction.Auto; - - /** - * Sets the layout values. - * @param width - The width - * @param height - The height - * @param top - The top position - * @param left - The left position - */ - setValue(width: number, height: number, top: number, left: number): void { - this.width = width; - this.height = height; - this.top = top; - this.left = left; - } - - /** - * Sets the offset position. - * @param top - The top offset - * @param left - The left offset - */ - setOffset(top: number, left: number): void { - this.top = top; - this.left = left; - } -} - -/** - * Main view class for rendering Flutter content in OpenHarmony applications. - * This class manages the Flutter engine, viewport metrics, keyboard handling, - * and all interactions between Flutter and the native platform. - */ -export class FlutterView { - private flutterEngine: FlutterEngine | null = null - private id: string = "" - private isActive: boolean = true - private dVModel: DVModel = - new DVModel("Stack", new DVModelParameters(), new DVModelEvents(), new DVModelChildren(), null); - /** The wrapped builder for creating the view, or undefined if not set. */ - private wrapBuilder: WrappedBuilder<[Params]> | undefined = undefined; - private platformView: PlatformView | undefined = undefined; - private isSurfaceAvailableForRendering: boolean = false - private viewportMetrics = new ViewportMetrics(); - private displayInfo?: display.Display; - private keyboardManager: KeyboardManager | null = null; - private statusBarClickChannel: StatusBarClickChannel|null = null; - private mainWindow: window.Window | null = null; - private mouseCursorPlugin?: MouseCursorPlugin; - private textInputPlugin?: TextInputPlugin; - private uiContext?: UIContext | undefined; - private context: Context; - private settings?: Settings; - private mFirstFrameListeners: ArrayList; - private mFirstPreloadFrameListeners: ArrayList; - private isFlutterUiDisplayed: boolean = false; - private isFlutterUiPreload: boolean = false; - private surfaceId: string = "0"; - private nodeController: EmbeddingNodeController = new EmbeddingNodeController(); - private platformViewSize: PlatformViewParas = new PlatformViewParas(); - private checkFullScreen: boolean = true; - private checkKeyboard: boolean = true; - private checkGesture: boolean = true; - private checkAiBar: boolean = true; - private frameCache: boolean = true; - private paddingTop?: number; - private paddingBottom?: number; - private systemAvoidArea: window.AvoidArea; - private navigationAvoidArea: window.AvoidArea; - private gestureAvoidArea: window.AvoidArea; - private keyboardAvoidArea: window.AvoidArea; - private needSetViewport: boolean = false; - private windowPosition: window.Rect | null = null; - // 默认值5,参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-gestures-pangesture - private callbackValue: callbackNumber = () => 5; - // DPI update flag to distinguish between system DPI updates and custom DPI updates - private isDevicePixelRatioAdaptive: boolean = false; - private lastHeight: number = 0; - private statusBarClickSubscriber: commonEventManager.CommonEventSubscriber | null = null; - - /** - * Constructs a new FlutterView instance. - * @param viewId - The unique identifier for this view - * @param context - The application context - */ - constructor(viewId: string, context: Context) { - this.id = viewId; - this.context = context; - this.displayInfo = display.getDefaultDisplaySync(); - this.viewportMetrics.devicePixelRatio = this.displayInfo?.densityPixels; - this.buildDisplayFeatures(display.getFoldStatus()); - - this.mainWindow = FlutterManager.getInstance() - .getWindowStage(FlutterManager.getInstance().getUIAbility(context)) - ?.getMainWindowSync(); - this.mFirstFrameListeners = new ArrayList(); - this.mFirstPreloadFrameListeners = new ArrayList(); - - this.mainWindow?.on('windowSizeChange', this.windowSizeChangeCallback); - this.mainWindow?.on('avoidAreaChange', this.avoidAreaChangeCallback); - this.mainWindow?.on('windowStatusChange', this.windowStatusChangeCallback); - this.mainWindow?.on('keyboardHeightChange', this.keyboardHeightChangeCallback); - this.mainWindow?.on('windowRectChange', this.windowRectChangeCallback); - //监听系统无障碍服务状态改变 - accessibility.on('accessibilityStateChange', this.accessibilityStateChangeCallback); - - this.systemAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); - this.navigationAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR); - this.gestureAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM_GESTURE); - this.keyboardAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_KEYBOARD); - commonEventManager.createSubscriber( - { events: ["usual.event.CLICK_STATUSBAR"] }, this.onStatusBarClick); - - // 监听折叠状态的改变 - display?.on('foldStatusChange', this.foldStatusChangeCallback); - - // Subscribes to display changes. Example: event that the display size is changed. - try { - display.on("change", this.displayChangeCallback); - } catch (e) { - Log.e(TAG, "displayInfo error" + JSON.stringify(e)); - } - this.context.eventHub.on('changeDevicePixelRatio', this.onDevicePixelRatioChange); - } - - onDevicePixelRatioChange = (dpiScaleFactor: number) => { - try { - // Get display information - this.displayInfo = display.getDefaultDisplaySync(); - - // Set DPI for text input channel - this.flutterEngine?.getTextInputChannel()?.setDevicePixelRatio(this.displayInfo.densityPixels); - - // Calculate device pixel ratio - // When dpiScaleFactor is DPI_SCALE_RESET, reset DPI to system default - let newDevicePixelRatio: number; - if (dpiScaleFactor === DPI_SCALE_RESET) { - newDevicePixelRatio = this.displayInfo.densityPixels; - Log.d(TAG, "Resetting device pixel ratio to system default: " + newDevicePixelRatio); - // When resetting DPI, set the flag to false - this.isDevicePixelRatioAdaptive = false; - } else { - newDevicePixelRatio = this.displayInfo.densityPixels * dpiScaleFactor; - Log.d(TAG, "Scaling device pixel ratio by factor " + dpiScaleFactor + ": " + newDevicePixelRatio); - // When customizing DPI, set the flag to true - this.isDevicePixelRatioAdaptive = true; - } - - // Only update when DPI actually changes - if (newDevicePixelRatio !== this.viewportMetrics.devicePixelRatio) { - this.viewportMetrics.devicePixelRatio = newDevicePixelRatio; - Log.i(TAG, "Device pixel ratio updated: " + newDevicePixelRatio + - " (scale factor: " + dpiScaleFactor + ", system DPI: " + this.displayInfo.densityPixels + ")"); - this.needSetViewport = true; - this.onAreaChange(null); - } - } catch (e) { - Log.e(TAG, "Error updating device pixel ratio: " + JSON.stringify(e)); - } - } - - /** - * Sets the callback for getting touch slop value. - * @param callback - The callback function that returns the touch slop value - */ - setTouchSlopCallbackValue(callback: callbackNumber) { - this.callbackValue = callback; - } - - private async buildDisplayFeatures(foldStatus: display.FoldStatus) { - let displayFeatures: ArrayList = new ArrayList(); - const displayInfo = display.getDefaultDisplaySync(); - /* - There are some bugs about getCurrentFoldCreaseRegion: - * 1. the crease region area is inaccurate - * 2. the creaseRegion.displayId and displayInfo.id are always both 0, in which case it is unable to - * distinguish whether the crease region is on the current screen. - * So do not add FOLD feature until the bugs are fixed. - */ - // if (display.isFoldable()) { - // let state: DisplayFeatureState = DisplayFeatureState.UNKNOWN; - // if (foldStatus == display.FoldStatus.FOLD_STATUS_EXPANDED) { - // state = DisplayFeatureState.POSTURE_FLAT; - // } else if (foldStatus == display.FoldStatus.FOLD_STATUS_HALF_FOLDED) { - // state = DisplayFeatureState.POSTURE_HALF_OPENED; - // } else { - // state = DisplayFeatureState.UNKNOWN; - // } - // let creaseRegion: display.FoldCreaseRegion = display.getCurrentFoldCreaseRegion(); - // if (creaseRegion.displayId == displayInfo.id) { - // for (let bound of creaseRegion.creaseRects) { - // displayFeatures.add(new DisplayFeature(bound, DisplayFeatureType.FOLD, state)); - // } - // } - // } - - let cutoutInfos = await displayInfo?.getCutoutInfo(); - for (let bound of cutoutInfos.boundingRects) { - displayFeatures.add(new DisplayFeature(bound, DisplayFeatureType.CUTOUT, DisplayFeatureState.UNKNOWN)); - } - Log.d(TAG, `device displayFeatures is : ${JSON.stringify(displayFeatures)}`); - this.viewportMetrics.displayFeatures = displayFeatures; - this.updateViewportMetrics(); - } - - private routerPageUpdateCallback = (info: uiObserver.RouterPageInfo) => { - if (this.getKeyboardHeight() !== 0 && info.state === uiObserver.RouterPageState.ON_PAGE_SHOW) { - this.flutterEngine?.getTextInputChannel()?.textInputMethodHandler?.hide(); - } - } - - private densityUpdateCallback = (info: uiObserver.DensityInfo) => { - try { - const sysDensity = display.getDefaultDisplaySync().densityPixels; - const customDensity = info.density; - if (sysDensity > 0 && customDensity > 0 && Number.isFinite(customDensity)) { - const scale = customDensity / sysDensity; - Log.i(TAG, "densityUpdateCallback: customDensity=" + customDensity + ", sysDensity=" + - sysDensity + ", scale=" + scale); - this.onDevicePixelRatioChange(scale); - } - } catch (e) { - Log.e(TAG, "densityUpdateCallback error: " + JSON.stringify(e)); - } - } - - private avoidAreaChangeCallback = (data: window.AvoidAreaOptions) => { - Log.i(TAG, "avoidAreaChangeCallback, type=" + data.type + ", area=" + JSON.stringify(data.area)); - - switch (data.type) { - case window.AvoidAreaType.TYPE_SYSTEM: - this.systemAvoidArea = data.area; - break; - case window.AvoidAreaType.TYPE_SYSTEM_GESTURE: - this.gestureAvoidArea = data.area; - break; - case window.AvoidAreaType.TYPE_KEYBOARD: - if (this.getKeyboardHeight() > 0) { - this.keyboardAvoidArea = data.area; - } else { - this.keyboardAvoidArea.bottomRect = { left: 0, top: 0, width: 0, height: 0 }; - } - break; - case window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR: - this.navigationAvoidArea = data.area; - break; - default: - break; - } - if (this.isAttachedToFlutterEngine()) { - this.onAreaChange(null); - } - } - private windowSizeChangeCallback = (data: window.Size) => { - Log.i(TAG, `windowSizeChangeCallback: width=${data.width}, height=${data.height}, lastHeight=${this.lastHeight}`); - - // Only handle when height changes - if (this.lastHeight !== data.height) { - try { - // If DPI has been customized, do not process system DPI changes - this.displayInfo = display.getDefaultDisplaySync(); - this.flutterEngine?.getTextInputChannel()?.setDevicePixelRatio(this.displayInfo.densityPixels); - - let devicePixelRatio: number = this.displayInfo.densityPixels; - Log.i(TAG, `windowSizeChangeCallback devicePixelRatio: ${devicePixelRatio}, viewportMetrics.devicePixelRatio: ${this.viewportMetrics.devicePixelRatio}`); - - if (devicePixelRatio !== this.viewportMetrics.devicePixelRatio) { - this.viewportMetrics.devicePixelRatio = devicePixelRatio; - Log.i(TAG, `windowSizeChangeCallback: Updated devicePixelRatio to ${devicePixelRatio}`); - this.needSetViewport = true; - } - } catch (e) { - Log.e(TAG, `windowSizeChangeCallback error: ${JSON.stringify(e)}`); - } - } - - // Update lastHeight - this.lastHeight = data.height; - - // Notify area change, this method handles all necessary view updates - if (this.isAttachedToFlutterEngine()) { - this.onAreaChange(null); - } - } - private windowStatusChangeCallback = (data: window.WindowStatusType) => { - Log.i(TAG, "windowStatusChangeCallback " + data); - if (this.isAttachedToFlutterEngine()) { - FlutterManager.getInstance().getFullScreenListener().onScreenStateChanged(data); - } - }; - private displayChangeCallback = (data: number) => { - // If DPI has been customized, do not process system DPI changes - if (this.isDevicePixelRatioAdaptive) { - Log.d(TAG, "Skipping display change callback due to custom DPI setting"); - return; - } - - this.displayInfo = display.getDefaultDisplaySync(); - this.flutterEngine?.getTextInputChannel()?.setDevicePixelRatio(this.displayInfo.densityPixels); - let devicePixelRatio: number = this.displayInfo?.densityPixels; - Log.i(TAG, "Display on: " + JSON.stringify(this.displayInfo) + ". Display id:" + JSON.stringify(data)) - if (devicePixelRatio != this.viewportMetrics.devicePixelRatio) { - this.viewportMetrics.devicePixelRatio = devicePixelRatio; - this.needSetViewport = true; - this.onAreaChange(null); - } - this.flutterEngine?.getFlutterNapi()?.updateRefreshRate(this.displayInfo?.refreshRate); - } - private keyboardHeightChangeCallback = (data: number) => { - Log.i(TAG, "keyboardHeightChangeCallback " + data); - if (this.keyboardAvoidArea) { - this.keyboardAvoidArea.bottomRect.height = data; - } - this.onAreaChange(null); - }; - private windowRectChangeCallback = (data: window.RectChangeOptions) => { - Log.i(TAG, "windowRectChangeCallback " + data); - this.windowPosition = data.rect as window.Rect; - this.flutterEngine?.getTextInputChannel()?.setWindowPosition(this.windowPosition); - } - private accessibilityStateChangeCallback = (data: boolean) => { - Log.i(TAG, `subscribe accessibility state change, result: ${JSON.stringify(data)}`); - this.flutterEngine?.getFlutterNapi()?.accessibilityStateChange(data); - } - private foldStatusChangeCallback = (data: display.FoldStatus) => { - Log.d(TAG, `Fold status change to ${JSON.stringify(data)}`) - this.buildDisplayFeatures(data); - } - private windowTitleButtonRectChangeCallback = (data: window.TitleButtonRect) => { - Log.i(TAG, "windowTitleButtonRectChangeCallback " + JSON.stringify(data)); - FlutterManager.getInstance().handleWindowDecorSafeArea(this.id, this.context); - } - - /** - * Gets the view ID. - * @returns The view ID - */ - getId(): string { - return this.id; - } - - /** - * Sets the active state of the view. - * @param value - True to activate, false to deactivate - */ - setActive(value: boolean): void { - this.isActive = value; - } - - /** - * Gets the active state of the view. - * @returns True if active, false otherwise - */ - getActive(): boolean { - return this.isActive; - } - - /** - * Sets the surface ID for rendering. - * @param surfaceId - The surface ID - */ - setSurfaceId(surfaceId: string): void { - this.surfaceId = surfaceId; - } - - /** - * Gets the surface ID. - * @returns The surface ID - */ - getSurfaceId(): string { - return this.surfaceId; - } - - /** - * Gets the embedding node controller. - * @deprecated since 3.7 - * @returns The EmbeddingNodeController instance - */ - getEmbeddingNodeController(): EmbeddingNodeController { - return this.nodeController; - } - - /** - * Sets the wrapped builder for platform views. - * @param wrappedBuilder - The WrappedBuilder instance - */ - setWrappedBuilder(wrappedBuilder: WrappedBuilder<[Params]>) { - this.wrapBuilder = wrappedBuilder; - } - - /** - * Gets the wrapped builder. - * @returns The WrappedBuilder instance, or undefined if not set - */ - getWrappedBuilder(): WrappedBuilder<[Params]> | undefined { - return this.wrapBuilder; - } - - /** - * Sets the platform view. - * @param platformView - The PlatformView instance - */ - setPlatformView(platformView: PlatformView) { - this.platformView = platformView; - } - - /** - * Gets the platform view. - * @returns The PlatformView instance, or undefined if not set - */ - getPlatformView(): PlatformView | undefined { - return this.platformView; - } - - /** - * Gets the platform view size. - * @deprecated since 3.7 - * @returns The PlatformViewParas instance - */ - getPlatformViewSize(): PlatformViewParas { - return this.platformViewSize; - } - - /** - * Gets the DynamicView model. - * @returns The DVModel instance - */ - getDVModel() { - return this.dVModel; - } - - /** - * Gets the current keyboard height. - * @returns The keyboard height in pixels, or 0 if keyboard is not visible - */ - getKeyboardHeight() { - return this.keyboardAvoidArea?.bottomRect.height - } - - /** - * Called when the view is being destroyed. - * Cleans up all event listeners and resources. - */ - onDestroy() { - try { - uiObserver.off('routerPageUpdate', this.uiContext as UIContext, this.routerPageUpdateCallback); - uiObserver.off('densityUpdate', this.uiContext as UIContext, this.densityUpdateCallback); - this.mainWindow?.off('windowSizeChange', this.windowSizeChangeCallback); - this.mainWindow?.off('avoidAreaChange', this.avoidAreaChangeCallback); - this.mainWindow?.off('windowStatusChange', this.windowStatusChangeCallback); - this.mainWindow?.off('keyboardHeightChange', this.keyboardHeightChangeCallback); - this.mainWindow?.off('windowRectChange', this.windowRectChangeCallback); - this.mainWindow?.off('windowTitleButtonRectChange', this.windowTitleButtonRectChangeCallback); - accessibility.off('accessibilityStateChange', this.accessibilityStateChangeCallback); - display.off('foldStatusChange', this.foldStatusChangeCallback); - this.context.eventHub.off('changeDevicePixelRatio', this.onDevicePixelRatioChange); - } catch (e) { - Log.e(TAG, "mainWindow off error: " + JSON.stringify(e)); - } - this.mainWindow = null; - - try { - display.off("change", this.displayChangeCallback); - } catch (e) { - Log.e(TAG, "displayInfo off error" + JSON.stringify(e)); - } - FlutterManager.getInstance().deleteFlutterView(this.id, this); - - this.nodeController.disposeFrameNode(); - } - - /** - * Attaches this view to a Flutter engine. - * @param flutterEngine - The FlutterEngine to attach to - */ - attachToFlutterEngine(flutterEngine: FlutterEngine): void { - hiTraceMeter.startTrace("attachToFlutterEngine", 0); - if (this.isAttachedToFlutterEngine()) { - if (flutterEngine == this.flutterEngine) { - Log.i(TAG, "Already attached to this engine. Doing nothing."); - return; - } - // Detach from a previous FlutterEngine so we can attach to this new one.f - Log.i( - TAG, - "Currently attached to a different engine. Detaching and then attaching" - + " to new engine."); - this.detachFromFlutterEngine(); - } - Log.i(TAG, "attachToFlutterEngine"); - this.flutterEngine = flutterEngine; - this.flutterEngine?.getFlutterNapi().xComponentAttachFlutterEngine(this.id) - this.flutterEngine?.getFlutterNapi()?.updateRefreshRate(this.displayInfo!.refreshRate) - this.flutterEngine?.getFlutterNapi()?.updateSize(this.displayInfo!.width, this.displayInfo!.height) - this.flutterEngine?.getFlutterNapi()?.updateDensity(this.displayInfo!.densityPixels) - this.flutterEngine?.getFlutterNapi().enableFrameCache(this.frameCache); - if (accessibility.isOpenAccessibilitySync()) { - this.flutterEngine?.getFlutterNapi()?.accessibilityStateChange(true); - } - flutterEngine.getPlatformViewsController()?.attachToView(this); - - let newArea: Area | null = { - width: px2vp(this.displayInfo!.width), - height: px2vp(this.displayInfo!.height), - position: { x: 0, y: 0 }, - globalPosition: { x: 0, y: 0 } - }; - if (this.viewportMetrics.physicalWidth != 0 || this.viewportMetrics.physicalHeight != 0) { - newArea = null; - } - this.onAreaChange(newArea, true); - - this.context.eventHub.on(EVENT_BACK_PRESS, () => { - if (this?.getKeyboardHeight() == 0) { - this.flutterEngine?.getNavigationChannel()?.popRoute(); - } else { - this.flutterEngine?.getTextInputChannel()?.textInputMethodHandler?.hide(); - } - }); - - let windowId = this.mainWindow?.getWindowProperties()?.id ?? 0 - this.mouseCursorPlugin = new MouseCursorPlugin(windowId, this.flutterEngine?.getMouseCursorChannel()!); - this.textInputPlugin = new TextInputPlugin(this.flutterEngine?.getTextInputChannel()!, this.id, - new KeyEventChannel(this.flutterEngine.dartExecutor)); - this.statusBarClickChannel = new StatusBarClickChannel(flutterEngine.dartExecutor) - this.keyboardManager = new KeyboardManager(flutterEngine, this.textInputPlugin!); - this.settings = new Settings(this.flutterEngine.getSettingsChannel()!); - this.sendSettings(); - this.isFlutterUiDisplayed = this.flutterEngine.getFlutterNapi().isDisplayingFlutterUi; - this.isFlutterUiPreload = this.flutterEngine.getFlutterNapi().isPreloadedFlutterUi; - if (this.isFlutterUiPreload) { - this.onFirstFrame(1); - } - if (this.isFlutterUiDisplayed) { - this.onFirstFrame(); - } - if (this.isSurfaceAvailableForRendering) { - this.flutterEngine?.processPendingMessages(); - } - hiTraceMeter.finishTrace("attachToFlutterEngine", 0); - } - - /** - * Called before drawing a frame. - * @param width - The width of the drawing area, defaults to display width - * @param height - The height of the drawing area, defaults to display height - */ - preDraw(width: number = 0, height: number = 0): void { - if (this.isAttachedToFlutterEngine()) { - if (width == 0 || height == 0) { - width = this.displayInfo!.width; - height = this.displayInfo!.height; - } - this.flutterEngine?.getFlutterNapi().xComponentPreDraw(this.id, width, height); - } - } - - /** - * Detaches this view from the Flutter engine. - * Cleans up all engine-related resources. - */ - detachFromFlutterEngine(): void { - Log.i(TAG, "detachFromFlutterEngine"); - if (!this.isAttachedToFlutterEngine()) { - Log.d(TAG, "FlutterView not attached to an engine. Not detaching."); - return; - } - if (this.isSurfaceAvailableForRendering) { - this.flutterEngine!!.getFlutterNapi().xComponentDetachFlutterEngine(this.id) - } - this.flutterEngine?.getPlatformViewsController()?.detachFromView(); - this.flutterEngine = null; - this.keyboardManager = null; - this.textInputPlugin?.destroy(); - this.context?.eventHub.off(EVENT_BACK_PRESS); - } - - /** - * Called when the window is created. - * Initializes the UIContext and sends settings to Flutter. - */ - onWindowCreated() { - Log.d(TAG, "received onwindowCreated."); - let _UIContext = this.mainWindow?.getUIContext(); - this.uiContext = _UIContext; - // Listen to route navigation (Flutter navigating to HarmonyOS native), soft keyboard management - uiObserver.on('routerPageUpdate', this.uiContext as UIContext, this.routerPageUpdateCallback); - uiObserver.on('densityUpdate', this.uiContext as UIContext, this.densityUpdateCallback); - this.sendSettings(); - this.mainWindow?.on('windowTitleButtonRectChange', this.windowTitleButtonRectChangeCallback); - Log.d(TAG, "uiContext init and sendSettings finished."); - } - - /** - * Sends system settings to Flutter. - */ - sendSettings(): void { - if (this.uiContext != undefined && this.isAttachedToFlutterEngine()) { - this.settings?.sendSettings(this.uiContext.getMediaQuery()); - } else { - Log.e(TAG, "UIContext is null, cannot send Settings!"); - } - } - - /** - * Called when the rendering surface is created. - * Marks the surface as available and processes pending messages. - */ - onSurfaceCreated() { - this.isSurfaceAvailableForRendering = true; - this.flutterEngine?.processPendingMessages(); - } - - /** - * Called when the rendering surface is destroyed. - * Marks the surface as unavailable and detaches from the engine. - */ - onSurfaceDestroyed() { - this.isSurfaceAvailableForRendering = false; - if (this.isAttachedToFlutterEngine()) { - this.flutterEngine!!.getFlutterNapi().xComponentDetachFlutterEngine(this.id) - } - } - - /** - * Called when the view area changes. - * Updates viewport metrics based on the new area and avoid areas. - * @param newArea - The new area, or null to use current display dimensions - * @param setFullScreen - Whether to set fullscreen mode - */ - onAreaChange(newArea: Area | null, setFullScreen: boolean = false) { - const originalMetrics = this.viewportMetrics.clone(); - if (newArea != null) { - this.viewportMetrics.physicalWidth = vp2px(newArea.width as number); - this.viewportMetrics.physicalHeight = vp2px(newArea.height as number); - } - let fullScreen = false - // 根据是否全屏显示,设置标题栏高度 - if (this.checkFullScreen && - (setFullScreen || FlutterManager.getInstance().getFullScreenListener().useFullScreen())) { // 全屏显示 - fullScreen = true - if (this.paddingTop != undefined) { - this.viewportMetrics.physicalViewPaddingTop = this.paddingTop; - } else { - this.viewportMetrics.physicalViewPaddingTop = - this.systemAvoidArea?.topRect.height ?? this.viewportMetrics.physicalViewPaddingTop; - } - if (this.paddingBottom != undefined) { - this.viewportMetrics.physicalViewPaddingBottom = this.paddingBottom; - } else { - this.viewportMetrics.physicalViewPaddingBottom = - this.systemAvoidArea?.bottomRect.height ?? this.viewportMetrics.physicalViewPaddingBottom; - } - } else { // 非全屏显示 - this.viewportMetrics.physicalViewPaddingTop = this.paddingTop ?? 0; - this.viewportMetrics.physicalViewPaddingBottom = this.paddingBottom ?? 0; - } - - this.viewportMetrics.physicalViewPaddingLeft = - this.systemAvoidArea?.leftRect.width ?? this.viewportMetrics.physicalViewPaddingLeft; - this.viewportMetrics.physicalViewPaddingRight = - this.systemAvoidArea?.rightRect.width ?? this.viewportMetrics.physicalViewPaddingRight; - - this.onKeyboardAreaChange(fullScreen) - this.onAiBarAreaChange(fullScreen) - this.onGestureAreaChange(fullScreen) - if (!this.viewportMetrics.isEqual(originalMetrics) || this.needSetViewport) { - if (!this.updateViewportMetrics()) { - this.needSetViewport = true; - } else { - this.needSetViewport = false; - } - } - } - - private onAiBarAreaChange(fullScreen: boolean = false) { - if (this.checkAiBar && this.navigationAvoidArea != null && fullScreen) { - this.viewportMetrics.physicalViewPaddingBottom = - Math.max(this.navigationAvoidArea?.bottomRect.height, this.viewportMetrics.physicalViewPaddingBottom) - } - } - - private onKeyboardAreaChange(fullScreen: boolean = false) { - if (this.checkKeyboard && fullScreen) { - this.viewportMetrics.physicalViewInsetTop = - this.keyboardAvoidArea?.topRect.height ?? this.viewportMetrics.physicalViewInsetTop - this.viewportMetrics.physicalViewInsetLeft = - this.keyboardAvoidArea?.leftRect.width ?? this.viewportMetrics.physicalViewInsetLeft - this.viewportMetrics.physicalViewInsetBottom = - this.keyboardAvoidArea?.bottomRect.height ?? this.viewportMetrics.physicalViewInsetBottom - this.viewportMetrics.physicalViewInsetRight = - this.keyboardAvoidArea?.rightRect.width ?? this.viewportMetrics.physicalViewInsetRight - } else { - this.viewportMetrics.physicalViewInsetTop = 0 - this.viewportMetrics.physicalViewInsetLeft = 0 - this.viewportMetrics.physicalViewInsetBottom = 0 - this.viewportMetrics.physicalViewInsetRight = 0 - } - } - - private onGestureAreaChange(fullScreen: boolean = false) { - if (this.checkGesture && fullScreen) { - this.viewportMetrics.systemGestureInsetTop = - this.gestureAvoidArea?.topRect.height ?? this.viewportMetrics.systemGestureInsetTop - this.viewportMetrics.systemGestureInsetLeft = - this.gestureAvoidArea?.leftRect.width ?? this.viewportMetrics.systemGestureInsetLeft - this.viewportMetrics.systemGestureInsetBottom = - Math.max(this.navigationAvoidArea?.bottomRect.height, this.gestureAvoidArea?.bottomRect.height) - this.viewportMetrics.systemGestureInsetRight = - this.gestureAvoidArea?.rightRect.width ?? this.viewportMetrics.systemGestureInsetRight - } else { - this.viewportMetrics.systemGestureInsetTop = 0 - this.viewportMetrics.systemGestureInsetLeft = 0 - this.viewportMetrics.systemGestureInsetBottom = 0 - this.viewportMetrics.systemGestureInsetRight = 0 - } - } - - /** - * Checks if this view is attached to a Flutter engine. - * @returns True if attached, false otherwise - */ - public isAttachedToFlutterEngine(): boolean { - return this.flutterEngine != null - } - - /** - * Checks if this view is attached to an engine with the specified shell holder ID. - * @param id - The shell holder ID to check - * @returns True if attached to an engine with the specified ID, false otherwise - */ - public isSameEngineShellHolderId(id: number): boolean { - if (this.flutterEngine) { - let flutterNapi = this.flutterEngine.getFlutterNapi(); - if (flutterNapi.nativeShellHolderId == id && id != 0) { - return true; - } - } - return false; - } - - private updateViewportMetrics(): boolean { - if (this.isAttachedToFlutterEngine()) { - const displayFeatures = this.viewportMetrics.displayFeatures; - let displayFeatureBound: number[] = new Array(displayFeatures.length * 4); - let displayFeatureType: number[] = new Array(displayFeatures.length); - let displayFeatureStatus: number[] = new Array(displayFeatures.length); - for (let i = 0; i < displayFeatures.length; i++) { - let singleFeatureBound = displayFeatures[i].getBound(); - displayFeatureBound[4 * i] = singleFeatureBound.left; - displayFeatureBound[4 * i + 1] = singleFeatureBound.top - displayFeatureBound[4 * i + 2] = singleFeatureBound.left + singleFeatureBound.width; - displayFeatureBound[4 * i + 3] = singleFeatureBound.top + singleFeatureBound.height; - displayFeatureType[i] = displayFeatures[i].getType(); - displayFeatureStatus[i] = displayFeatures[i].getState(); - } - - this.viewportMetrics.physicalTouchSlop = this.callbackValue(); - this?.flutterEngine?.getFlutterNapi()?.setViewportMetrics(this.viewportMetrics.devicePixelRatio, - this.viewportMetrics.physicalWidth, - this.viewportMetrics.physicalHeight, - this.viewportMetrics.physicalViewPaddingTop, - this.viewportMetrics.physicalViewPaddingRight, - this.viewportMetrics.physicalViewPaddingBottom, - this.viewportMetrics.physicalViewPaddingLeft, - this.viewportMetrics.physicalViewInsetTop, - this.viewportMetrics.physicalViewInsetRight, - this.viewportMetrics.physicalViewInsetBottom, - this.viewportMetrics.physicalViewInsetLeft, - this.viewportMetrics.systemGestureInsetTop, - this.viewportMetrics.systemGestureInsetRight, - this.viewportMetrics.systemGestureInsetBottom, - this.viewportMetrics.systemGestureInsetLeft, - this.viewportMetrics.physicalTouchSlop, - displayFeatureBound, - displayFeatureType, - displayFeatureStatus) - return true - } - return false - } - - onStatusBarClick = (err: BusinessError, subscriber: commonEventManager.CommonEventSubscriber) => { - this.statusBarClickSubscriber = subscriber - if(subscriber !== null) { - commonEventManager.subscribe(subscriber, (err, data) => { - this.statusBarClickChannel?.sendClick() - }) - } - } - - /** - * Handles key events before they reach the input method editor. - * @param event - The key event - * @returns True if the event was handled, false otherwise - */ - onKeyPreIme(event: KeyEvent): boolean { - return this.keyboardManager?.onKeyPreIme(event) ?? false; - } - - /** - * Handles key events. - * @param event - The key event - * @returns True if the event was handled, false otherwise - */ - onKeyEvent(event: KeyEvent): boolean { - return this.keyboardManager?.onKeyEvent(event) ?? false; - } - - /** - * Handles mouse wheel events. - * @param eventType - The event type - * @param event - The pan gesture event - */ - onMouseWheel(eventType: string, event: PanGestureEvent) { - if (deviceInfo.sdkApiVersion < 15) { // API15 及以后通过轴事件处理滚动 - this.flutterEngine?.getFlutterNapi()?.xComponentDisPatchMouseWheel(this.id, eventType, event); - } - } - - /** - * Adds a listener for the first frame event. - * @param listener - The listener to add - */ - addFirstFrameListener(listener: FirstFrameListener) { - this.mFirstFrameListeners.add(listener); - } - - /** - * Removes a first frame listener. - * @param listener - The listener to remove - */ - removeFirstFrameListener(listener: FirstFrameListener) { - this.mFirstFrameListeners.remove(listener); - } - - /** - * Adds a listener for the first preload frame event. - * @param listener - The listener to add - */ - addFirstPreloadFrameListener(listener: FirstPreloadFrameListener) { - this.mFirstPreloadFrameListeners.add(listener); - } - - /** - * Removes a first preload frame listener. - * @param listener - The listener to remove - */ - removeFirstPreloadFrameListener(listener: FirstPreloadFrameListener) { - this.mFirstPreloadFrameListeners.remove(listener); - } - - /** - * Checks if the first frame has been rendered. - * @returns True if the first frame has been rendered, false otherwise - */ - hasRenderedFirstFrame(): boolean { - return this.isFlutterUiDisplayed; - } - - /** - * Called when the first frame is rendered. - * Notifies all registered listeners. - * @param isPreload - 1 for preload frame, 0 for normal first frame - */ - onFirstFrame(isPreload: number = 0) { - if (isPreload) { - let listeners = this.mFirstPreloadFrameListeners.clone(); - listeners.forEach((listener) => { - listener.onFirstPreloadFrame(); - }) - } else { - let listeners = this.mFirstFrameListeners.clone(); - listeners.forEach((listener) => { - listener.onFirstFrame(); - }) - } - } - - /** - * Sets whether to check fullscreen mode. - * @param check - True to check fullscreen, false otherwise - */ - setCheckFullScreen(check: boolean) { - this.checkFullScreen = check; - } - - /** - * Sets whether to check keyboard area. - * @param check - True to check keyboard area, false otherwise - */ - setCheckKeyboard(check: boolean) { - this.checkKeyboard = check - } - - /** - * Sets whether to check gesture area. - * @param check - True to check gesture area, false otherwise - */ - setCheckGesture(check: boolean) { - this.checkGesture = check - } - - /** - * Sets whether to check AI bar area. - * @param check - True to check AI bar area, false otherwise - */ - setCheckAiBar(check: boolean) { - this.checkAiBar = check - } - - /** - * Sets the top padding value. - * @param paddingTop - The top padding value, or undefined to use default - */ - setPaddingTop(paddingTop?: number) { - this.paddingTop = paddingTop; - this.onAreaChange(null); - } - - /** - * Sets the bottom padding value. - * @param paddingBottom - The bottom padding value, or undefined to use default - */ - setPaddingBottom(paddingBottom?: number) { - this.paddingBottom = paddingBottom; - this.onAreaChange(null); - } - - /** - * Enables or disables frame caching. - * @param cacheEnable - True to enable frame cache, false to disable - */ - enableFrameCache(cacheEnable: boolean) { - this.frameCache = cacheEnable; - if (this.isAttachedToFlutterEngine()) { - this.flutterEngine?.getFlutterNapi().enableFrameCache(cacheEnable); - } - } -} - -/** - * Listener interface for first frame events. - */ -export interface FirstFrameListener { - /** - * Called when the first frame is rendered. - */ - onFirstFrame(): void; -} - -/** - * Listener interface for first preload frame events. - */ -export interface FirstPreloadFrameListener { - /** - * Called when the first preload frame is rendered. - */ - onFirstPreloadFrame(): void; -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/view/TextureRegistry.ets b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/view/TextureRegistry.ets deleted file mode 100644 index 6a7382d..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/ets/view/TextureRegistry.ets +++ /dev/null @@ -1,92 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. All rights reserved. -* Use of this source code is governed by a BSD-style license that can be -* found in the LICENSE_KHZG file. -* -* Based on TextureRegistry.java originally written by -* Copyright (C) 2013 The Flutter Authors. -* -*/ -import image from '@ohos.multimedia.image'; - -/** - * Registry of backend textures used with a single FlutterView instance. - * Entries may be embedded into the Flutter view using the Texture widget. - * Textures can be created from surface textures, image receivers, or pixel maps. - */ -export interface TextureRegistry { - - createSurfaceTexture(): SurfaceTextureEntry; - - getTextureId(): number; - - registerTexture(textureId: number): SurfaceTextureEntry; - - registerSurfaceTexture(receiver: image.ImageReceiver): SurfaceTextureEntry; - - registerPixelMap(pixelMap: PixelMap): number; - - setTextureBackGroundPixelMap(textureId: number, pixelMap: PixelMap): void; - - /** - * @deprecated since 3.7 - */ - setTextureBackGroundColor(textureId: number, color: number): void; - - setTextureBufferSize(textureId: number, width: number, height: number): void; - - notifyTextureResizing(textureId: number, width: number, height: number): void; - - /** - * @deprecated since 3.22 - * @useinstead TextureRegistry#setExternalNativeImagePtr - */ - setExternalNativeImage(textureId: number, native_image: number): boolean; - - setExternalNativeImagePtr(textureId: number, native_image: bigint): boolean; - - resetExternalTexture(textureId: number, need_surfaceId: boolean): number; - - unregisterTexture(textureId: number): void; - - onTrimMemory(level: number): void; -} - -/** - * Entry representing a surface texture registered with the texture registry. - */ -export interface SurfaceTextureEntry { - getTextureId(): number; - - getSurfaceId(): number; - - /* - * This return value is OHNativeWindow* in native code. - * Once converted to OHNativeWindow*, it can be used to create an EGLSurface or VkSurface for rendering. - * This OHNativeWindow* needn't be released when invoking unregisterTexture. - */ - getNativeWindowId(): number; - - release(): void; -} - -/** - * Listener for frame consumption events. - */ -export interface OnFrameConsumedListener { - /** - * Called when a frame has been consumed. - */ - onFrameConsumed(): void; -} - -/** - * Listener for memory trim events. - */ -export interface OnTrimMemoryListener { - /** - * Called when memory should be trimmed. - * @param level - The memory trim level - */ - onTrimMemory(level: number): void; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/module.json b/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/module.json deleted file mode 100644 index a3a1dfa..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/@ohos/flutter_ohos/src/main/module.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "app": { - "bundleName": "com.example.config", - "debug": false, - "versionCode": 1000000, - "versionName": "1.0.0", - "minAPIVersion": 50000012, - "targetAPIVersion": 60001021, - "apiReleaseType": "Release", - "targetMinorAPIVersion": 0, - "targetPatchAPIVersion": 0, - "compileSdkVersion": "6.0.1.112", - "compileSdkType": "HarmonyOS", - "appEnvironments": [], - "bundleType": "app", - "buildMode": "release" - }, - "module": { - "name": "flutter", - "type": "har", - "deviceTypes": [ - "default" - ], - "packageName": "@ohos/flutter_ohos", - "installationFree": false, - "virtualMachine": "ark", - "compileMode": "esmodule", - "dependencies": [] - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/BuildProfile.ets b/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/BuildProfile.ets deleted file mode 100644 index e599d28..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/BuildProfile.ets +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Use these variables when you tailor your ArkTS code. They must be of the const type. - */ -export const HAR_VERSION = '1.0.0-e34a685f4b'; -export const BUILD_MODE_NAME = 'release'; -export const DEBUG = false; -export const TARGET_NAME = 'default'; - -/** - * BuildProfile Class is used only for compatibility purposes. - */ -export default class BuildProfile { - static readonly HAR_VERSION = HAR_VERSION; - static readonly BUILD_MODE_NAME = BUILD_MODE_NAME; - static readonly DEBUG = DEBUG; - static readonly TARGET_NAME = TARGET_NAME; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/Index.ets b/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/Index.ets deleted file mode 100644 index e69de29..0000000 diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/build-profile.json5 b/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/build-profile.json5 deleted file mode 100644 index e3fb899..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/build-profile.json5 +++ /dev/null @@ -1,34 +0,0 @@ -{ - "apiType": "stageMode", - "buildOption": { - "nativeLib": { - "debugSymbol": { - "strip": false, - "exclude": [] - } - } - }, - "buildOptionSet": [ - { - "name": "release", - "arkOptions": { - "obfuscation": { - "ruleOptions": { - "enable": false, - "files": [ - "./obfuscation-rules.txt" - ] - }, - "consumerFiles": [ - "./consumer-rules.txt" - ] - } - }, - }, - ], - "targets": [ - { - "name": "default" - } - ] -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/consumer-rules.txt b/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/consumer-rules.txt deleted file mode 100644 index e69de29..0000000 diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/hvigorfile.ts b/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/hvigorfile.ts deleted file mode 100644 index 4218707..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/hvigorfile.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { harTasks } from '@ohos/hvigor-ohos-plugin'; - -export default { - system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ - plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/libs/arm64-v8a/libflutter.so b/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/libs/arm64-v8a/libflutter.so deleted file mode 100644 index 901632c..0000000 Binary files a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/libs/arm64-v8a/libflutter.so and /dev/null differ diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/obfuscation-rules.txt b/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/obfuscation-rules.txt deleted file mode 100644 index 272efb6..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/obfuscation-rules.txt +++ /dev/null @@ -1,23 +0,0 @@ -# Define project specific obfuscation rules here. -# You can include the obfuscation configuration files in the current module's build-profile.json5. -# -# For more details, see -# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 - -# Obfuscation options: -# -disable-obfuscation: disable all obfuscations -# -enable-property-obfuscation: obfuscate the property names -# -enable-toplevel-obfuscation: obfuscate the names in the global scope -# -compact: remove unnecessary blank spaces and all line feeds -# -remove-log: remove all console.* statements -# -print-namecache: print the name cache that contains the mapping from the old names to new names -# -apply-namecache: reuse the given cache file - -# Keep options: -# -keep-property-name: specifies property names that you want to keep -# -keep-global-name: specifies names that you want to keep in the global scope - --enable-property-obfuscation --enable-toplevel-obfuscation --enable-filename-obfuscation --enable-export-obfuscation \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/obfuscation.txt b/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/obfuscation.txt deleted file mode 100644 index e69de29..0000000 diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/oh-package.json5 b/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/oh-package.json5 deleted file mode 100644 index 739d5e1..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/oh-package.json5 +++ /dev/null @@ -1 +0,0 @@ -{"name":"flutter_native_arm64_v8a","version":"1.0.0-e34a685f4b","description":"Place so files for flutter on ohos.","main":"Index.ets","author":"","license":"Apache-2.0","dependencies":{},"metadata":{"sourceRoots":["./src/main"],"debug":false,"nativeDebugSymbol":false},"compatibleSdkVersionStage":"beta1","compatibleSdkVersion":12,"compatibleSdkType":"HarmonyOS","obfuscated":false} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/src/main/module.json b/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/src/main/module.json deleted file mode 100644 index c09f8ef..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_arm64_v8a/src/main/module.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "app": { - "bundleName": "com.example.config", - "debug": false, - "versionCode": 1000000, - "versionName": "1.0.0", - "minAPIVersion": 50000012, - "targetAPIVersion": 60001021, - "apiReleaseType": "Release", - "targetMinorAPIVersion": 0, - "targetPatchAPIVersion": 0, - "compileSdkVersion": "6.0.1.112", - "compileSdkType": "HarmonyOS", - "appEnvironments": [], - "bundleType": "app", - "buildMode": "release" - }, - "module": { - "name": "flutter_native", - "type": "har", - "deviceTypes": [ - "default" - ], - "packageName": "flutter_native_arm64_v8a", - "installationFree": false, - "virtualMachine": "ark", - "compileMode": "esmodule", - "dependencies": [] - } -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/BuildProfile.ets b/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/BuildProfile.ets deleted file mode 100644 index e599d28..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/BuildProfile.ets +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Use these variables when you tailor your ArkTS code. They must be of the const type. - */ -export const HAR_VERSION = '1.0.0-e34a685f4b'; -export const BUILD_MODE_NAME = 'release'; -export const DEBUG = false; -export const TARGET_NAME = 'default'; - -/** - * BuildProfile Class is used only for compatibility purposes. - */ -export default class BuildProfile { - static readonly HAR_VERSION = HAR_VERSION; - static readonly BUILD_MODE_NAME = BUILD_MODE_NAME; - static readonly DEBUG = DEBUG; - static readonly TARGET_NAME = TARGET_NAME; -} \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/Index.ets b/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/Index.ets deleted file mode 100644 index e69de29..0000000 diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/build-profile.json5 b/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/build-profile.json5 deleted file mode 100644 index e3fb899..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/build-profile.json5 +++ /dev/null @@ -1,34 +0,0 @@ -{ - "apiType": "stageMode", - "buildOption": { - "nativeLib": { - "debugSymbol": { - "strip": false, - "exclude": [] - } - } - }, - "buildOptionSet": [ - { - "name": "release", - "arkOptions": { - "obfuscation": { - "ruleOptions": { - "enable": false, - "files": [ - "./obfuscation-rules.txt" - ] - }, - "consumerFiles": [ - "./consumer-rules.txt" - ] - } - }, - }, - ], - "targets": [ - { - "name": "default" - } - ] -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/consumer-rules.txt b/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/consumer-rules.txt deleted file mode 100644 index e69de29..0000000 diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/hvigorfile.ts b/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/hvigorfile.ts deleted file mode 100644 index 4218707..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/hvigorfile.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { harTasks } from '@ohos/hvigor-ohos-plugin'; - -export default { - system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ - plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ -} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/libs/x86_64/libflutter.so b/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/libs/x86_64/libflutter.so deleted file mode 100644 index 6a1ed1f..0000000 Binary files a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/libs/x86_64/libflutter.so and /dev/null differ diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/obfuscation-rules.txt b/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/obfuscation-rules.txt deleted file mode 100644 index 272efb6..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/obfuscation-rules.txt +++ /dev/null @@ -1,23 +0,0 @@ -# Define project specific obfuscation rules here. -# You can include the obfuscation configuration files in the current module's build-profile.json5. -# -# For more details, see -# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 - -# Obfuscation options: -# -disable-obfuscation: disable all obfuscations -# -enable-property-obfuscation: obfuscate the property names -# -enable-toplevel-obfuscation: obfuscate the names in the global scope -# -compact: remove unnecessary blank spaces and all line feeds -# -remove-log: remove all console.* statements -# -print-namecache: print the name cache that contains the mapping from the old names to new names -# -apply-namecache: reuse the given cache file - -# Keep options: -# -keep-property-name: specifies property names that you want to keep -# -keep-global-name: specifies names that you want to keep in the global scope - --enable-property-obfuscation --enable-toplevel-obfuscation --enable-filename-obfuscation --enable-export-obfuscation \ No newline at end of file diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/obfuscation.txt b/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/obfuscation.txt deleted file mode 100644 index e69de29..0000000 diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/oh-package.json5 b/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/oh-package.json5 deleted file mode 100644 index d375780..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/oh-package.json5 +++ /dev/null @@ -1 +0,0 @@ -{"name":"flutter_native_x86_64","version":"1.0.0-e34a685f4b","description":"Place so files for flutter on ohos.","main":"Index.ets","author":"","license":"Apache-2.0","dependencies":{},"metadata":{"sourceRoots":["./src/main"],"debug":false,"nativeDebugSymbol":false},"compatibleSdkVersionStage":"beta1","compatibleSdkVersion":12,"compatibleSdkType":"HarmonyOS","obfuscated":false} diff --git a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/src/main/module.json b/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/src/main/module.json deleted file mode 100644 index 3f478ff..0000000 --- a/packages/fluttertoast_ohos/ohos/oh_modules/flutter_native_x86_64/src/main/module.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "app": { - "bundleName": "com.example.config", - "debug": false, - "versionCode": 1000000, - "versionName": "1.0.0", - "minAPIVersion": 50000012, - "targetAPIVersion": 60001021, - "apiReleaseType": "Release", - "targetMinorAPIVersion": 0, - "targetPatchAPIVersion": 0, - "compileSdkVersion": "6.0.1.112", - "compileSdkType": "HarmonyOS", - "appEnvironments": [], - "bundleType": "app", - "buildMode": "release" - }, - "module": { - "name": "flutter_native", - "type": "har", - "deviceTypes": [ - "default" - ], - "packageName": "flutter_native_x86_64", - "installationFree": false, - "virtualMachine": "ark", - "compileMode": "esmodule", - "dependencies": [] - } -} diff --git a/packages/fluttertoast_ohos/pubspec.lock b/packages/fluttertoast_ohos/pubspec.lock index f9af0ca..3c85d11 100644 --- a/packages/fluttertoast_ohos/pubspec.lock +++ b/packages/fluttertoast_ohos/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b url: "https://pub.flutter-io.cn" source: hosted - version: "1.4.0" + version: "1.4.1" collection: dependency: transitive description: @@ -26,18 +26,18 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" url: "https://pub.flutter-io.cn" source: hosted - version: "0.11.1" + version: "0.13.0" meta: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" url: "https://pub.flutter-io.cn" source: hosted - version: "1.16.0" + version: "1.17.0" sky_engine: dependency: transitive description: flutter @@ -52,5 +52,5 @@ packages: source: hosted version: "2.2.0" sdks: - dart: ">=3.8.0-0 <4.0.0" - flutter: ">=1.10.0" + dart: ">=3.11.0 <4.0.0" + flutter: ">=3.41.0" diff --git a/packages/fluttertoast_ohos/pubspec.yaml b/packages/fluttertoast_ohos/pubspec.yaml index 0130cf8..9a07b10 100644 --- a/packages/fluttertoast_ohos/pubspec.yaml +++ b/packages/fluttertoast_ohos/pubspec.yaml @@ -4,8 +4,8 @@ version: 1.0.0 homepage: https://github.com/PonnamKarthik/FlutterToast environment: - sdk: '>=2.12.0 <4.0.0' - flutter: ">=1.10.0" + sdk: ">=3.11.0 <4.0.0" + flutter: ">=3.41.0" dependencies: flutter: diff --git a/pubspec.lock b/pubspec.lock index 8cfa346..0d6a625 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a + sha256: "5b7468c326d2f8a4f630056404ca0d291ade42918f4a3c6233618e724f39da8e" url: "https://pub.flutter-io.cn" source: hosted - version: "61.0.0" + version: "92.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 + sha256: "70e4b1ef8003c64793a9e268a551a82869a8a96f39deb73dea28084b0e8bf75e" url: "https://pub.flutter-io.cn" source: hosted - version: "5.13.0" + version: "9.0.0" animations: dependency: "direct main" description: @@ -85,18 +85,18 @@ packages: dependency: transitive description: name: build - sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" + sha256: a156715e7cd728130c592f30552575908aae5b100005fbc1f0fb16b3c03a3d10 url: "https://pub.flutter-io.cn" source: hosted - version: "2.4.1" + version: "4.0.6" build_config: dependency: transitive description: name: build_config - sha256: "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33" + sha256: "4070d2a59f8eec34c97c86ceb44403834899075f66e8a9d59706f8e7834f6f71" url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.2" + version: "1.3.0" build_daemon: dependency: transitive description: @@ -105,30 +105,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "4.1.1" - build_resolvers: - dependency: transitive - description: - name: build_resolvers - sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" - url: "https://pub.flutter-io.cn" - source: hosted - version: "2.4.2" build_runner: dependency: "direct dev" description: name: build_runner - sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d" + sha256: "1523ce62448ebac2c15a8ba5fbad8acac169788658a7dd2a1c2d9c2a9318b9a6" url: "https://pub.flutter-io.cn" source: hosted - version: "2.4.13" - build_runner_core: - dependency: transitive - description: - name: build_runner_core - sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0 - url: "https://pub.flutter-io.cn" - source: hosted - version: "7.3.2" + version: "2.15.0" built_collection: dependency: transitive description: @@ -180,10 +164,10 @@ packages: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b url: "https://pub.flutter-io.cn" source: hosted - version: "1.4.0" + version: "1.4.1" checked_yaml: dependency: transitive description: @@ -220,19 +204,19 @@ packages: dependency: "direct main" description: path: "packages/connectivity_plus/connectivity_plus" - ref: HEAD - resolved-ref: "33d37b3ab716467ac77366c184b3a3c3650d9eff" + ref: "br_connectivity_plus-v6.1.0_ohos" + resolved-ref: "4ca461ac6e42c2b6e856897a8612041bef2a5a8e" url: "https://gitcode.com/openharmony-sig/flutter_plus_plugins.git" source: git - version: "5.0.1" + version: "6.1.0" connectivity_plus_platform_interface: dependency: transitive description: name: connectivity_plus_platform_interface - sha256: cf1d1c28f4416f8c654d7dc3cd638ec586076255d407cef3ddbdaf178272a71a + sha256: "3c09627c536d22fd24691a905cdd8b14520de69da52c7a97499c8be5284a32ed" url: "https://pub.flutter-io.cn" source: hosted - version: "1.2.4" + version: "2.1.0" convert: dependency: transitive description: @@ -269,10 +253,10 @@ packages: dependency: transitive description: name: dart_style - sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55" + sha256: a9c30492da18ff84efe2422ba2d319a89942d93e58eb0b73d32abe822ef54b7b url: "https://pub.flutter-io.cn" source: hosted - version: "2.3.2" + version: "3.1.3" dbus: dependency: transitive description: @@ -285,8 +269,8 @@ packages: dependency: "direct main" description: path: "packages/device_info_plus/device_info_plus" - ref: HEAD - resolved-ref: "33d37b3ab716467ac77366c184b3a3c3650d9eff" + ref: "br_device_info_plus_v11.4.0_ohos" + resolved-ref: "9f8cc41353907c392eed2dcc502e2056f21b407e" url: "https://gitcode.com/openharmony-sig/flutter_plus_plugins.git" source: git version: "9.1.0" @@ -438,7 +422,7 @@ packages: source: git version: "0.1.7+1" flutter_cache_manager: - dependency: transitive + dependency: "direct main" description: name: flutter_cache_manager sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386" @@ -519,14 +503,6 @@ packages: relative: true source: path version: "1.0.0" - frontend_server_client: - dependency: transitive - description: - name: frontend_server_client - sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 - url: "https://pub.flutter-io.cn" - source: hosted - version: "4.0.0" get: dependency: "direct main" description: @@ -559,7 +535,7 @@ packages: source: hosted version: "2.19.3" http: - dependency: transitive + dependency: "direct main" description: name: http sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" @@ -694,14 +670,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.0.1" - js: - dependency: transitive - description: - name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.6.7" json_annotation: dependency: transitive description: @@ -777,26 +745,26 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 url: "https://pub.flutter-io.cn" source: hosted - version: "0.12.17" + version: "0.12.19" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" url: "https://pub.flutter-io.cn" source: hosted - version: "0.11.1" + version: "0.13.0" meta: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" url: "https://pub.flutter-io.cn" source: hosted - version: "1.16.0" + version: "1.17.0" mime: dependency: transitive description: @@ -873,11 +841,11 @@ packages: dependency: "direct main" description: path: "packages/path_provider/path_provider" - ref: master - resolved-ref: "9d463c2acb74079d6892bb04ae9ad37b37c1b597" - url: "https://gitcode.com/openharmony-sig/flutter_packages.git" + ref: "br_path_provider-v2.1.5_ohos" + resolved-ref: a32bc5c0d1be4411cd026bcf8bc0d9d85a491592 + url: "https://gitcode.com/openharmony-tpc/flutter_packages.git" source: git - version: "2.1.0" + version: "2.1.5" path_provider_android: dependency: transitive description: @@ -906,11 +874,11 @@ packages: dependency: transitive description: path: "packages/path_provider/path_provider_ohos" - ref: HEAD - resolved-ref: "9d463c2acb74079d6892bb04ae9ad37b37c1b597" - url: "https://gitcode.com/openharmony-tpc/flutter_packages.git" + ref: "br_path_provider-v2.1.5_ohos" + resolved-ref: a32bc5c0d1be4411cd026bcf8bc0d9d85a491592 + url: "https://gitcode.com/openharmony-sig/flutter_packages.git" source: git - version: "2.2.1" + version: "2.2.17" path_provider_platform_interface: dependency: transitive description: @@ -938,19 +906,19 @@ packages: dependency: "direct main" description: path: permission_handler - ref: "br_permission_handler_v11.3.1_ohos" - resolved-ref: "86eae5711f8c561d2a4ef2a11030ff1330175b1b" + ref: "br_v12.0.1_ohos" + resolved-ref: b98df5865d4ab32faf5fe54017d05c61c523511a url: "https://gitcode.com/openharmony-sig/flutter_permission_handler.git" source: git - version: "11.3.1" + version: "12.0.1" permission_handler_android: dependency: transitive description: name: permission_handler_android - sha256: d3971dcdd76182a0c198c096b5db2f0884b0d4196723d21a866fc4cdea057ebc + sha256: "1e3bc410ca1bf84662104b100eb126e066cb55791b7451307f9708d4007350e6" url: "https://pub.flutter-io.cn" source: hosted - version: "12.1.0" + version: "13.0.1" permission_handler_apple: dependency: transitive description: @@ -967,15 +935,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "0.1.3+5" - permission_handler_ohos: - dependency: transitive - description: - path: permission_handler_ohos - ref: "br_permission_handler_v11.3.1_ohos" - resolved-ref: "86eae5711f8c561d2a4ef2a11030ff1330175b1b" - url: "https://gitcode.com/openharmony-sig/flutter_permission_handler.git" - source: git - version: "10.3.2" permission_handler_platform_interface: dependency: transitive description: @@ -1004,11 +963,11 @@ packages: dependency: "direct main" description: path: "packages/pigeon" - ref: HEAD - resolved-ref: "9d463c2acb74079d6892bb04ae9ad37b37c1b597" - url: "https://gitcode.com/openharmony-sig/flutter_packages.git" + ref: "br_pigeon-v26.1.5_ohos" + resolved-ref: a310277e0586bb63dc16c7283cc991d65bd69565 + url: "https://gitcode.com/openharmony-tpc/flutter_packages.git" source: git - version: "11.0.1" + version: "26.1.5" platform: dependency: transitive description: @@ -1108,29 +1067,29 @@ packages: dependency: "direct main" description: path: "packages/share_plus/share_plus" - ref: "br_share_plus-v10.1.1_ohos" - resolved-ref: "46cf97a5decaa48d8b95baee41f9f83d25a313ad" + ref: "br_share_plus-v12.0.1_ohos" + resolved-ref: "5bef4632bccbd428f9a2e56bec96b3e9b6fe3c50" url: "https://gitcode.com/openharmony-sig/flutter_plus_plugins.git" source: git - version: "10.1.1" + version: "12.0.1" share_plus_platform_interface: dependency: transitive description: path: "packages/share_plus/share_plus_platform_interface" - ref: "46cf97a5decaa48d8b95baee41f9f83d25a313ad" - resolved-ref: "46cf97a5decaa48d8b95baee41f9f83d25a313ad" + ref: "5bef4632bccbd428f9a2e56bec96b3e9b6fe3c50" + resolved-ref: "5bef4632bccbd428f9a2e56bec96b3e9b6fe3c50" url: "https://gitcode.com/openharmony-sig/flutter_plus_plugins.git" source: git - version: "5.0.1" + version: "6.1.0" shared_preferences: dependency: "direct main" description: path: "packages/shared_preferences/shared_preferences" - ref: HEAD - resolved-ref: "9d463c2acb74079d6892bb04ae9ad37b37c1b597" + ref: "br_shared_preferences-v2.5.4_ohos" + resolved-ref: baa08b15565efccb870a6484ff6a31e7b7e5af74 url: "https://gitcode.com/openharmony-tpc/flutter_packages.git" source: git - version: "2.2.0" + version: "2.5.4" shared_preferences_android: dependency: transitive description: @@ -1159,11 +1118,11 @@ packages: dependency: transitive description: path: "packages/shared_preferences/shared_preferences_ohos" - ref: HEAD - resolved-ref: "9d463c2acb74079d6892bb04ae9ad37b37c1b597" + ref: "br_shared_preferences-v2.5.4_ohos" + resolved-ref: baa08b15565efccb870a6484ff6a31e7b7e5af74 url: "https://gitcode.com/openharmony-tpc/flutter_packages.git" source: git - version: "2.2.0" + version: "2.5.4" shared_preferences_platform_interface: dependency: transitive description: @@ -1309,18 +1268,10 @@ packages: dependency: transitive description: name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" + sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a" url: "https://pub.flutter-io.cn" source: hosted - version: "0.7.6" - timing: - dependency: transitive - description: - name: timing - sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe" - url: "https://pub.flutter-io.cn" - source: hosted - version: "1.0.2" + version: "0.7.10" typed_data: dependency: transitive description: @@ -1349,11 +1300,11 @@ packages: dependency: "direct main" description: path: "packages/url_launcher/url_launcher" - ref: HEAD - resolved-ref: "9d463c2acb74079d6892bb04ae9ad37b37c1b597" + ref: "br_url_launcher-v6.3.2_ohos" + resolved-ref: b9347f529059a5f6bc0b863e3a459a3db316f127 url: "https://gitcode.com/openharmony-tpc/flutter_packages.git" source: git - version: "6.1.12" + version: "6.3.2" url_launcher_android: dependency: transitive description: @@ -1390,11 +1341,11 @@ packages: dependency: transitive description: path: "packages/url_launcher/url_launcher_ohos" - ref: HEAD - resolved-ref: "9d463c2acb74079d6892bb04ae9ad37b37c1b597" + ref: "br_url_launcher-v6.3.2_ohos" + resolved-ref: b9347f529059a5f6bc0b863e3a459a3db316f127 url: "https://gitcode.com/openharmony-tpc/flutter_packages.git" source: git - version: "6.0.38" + version: "6.3.2" url_launcher_platform_interface: dependency: transitive description: @@ -1516,5 +1467,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.9.2 <4.0.0" - flutter: ">=3.35.6" + dart: ">=3.11.0 <4.0.0" + flutter: ">=3.41.0" diff --git a/pubspec.yaml b/pubspec.yaml index a1964c9..f465268 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,10 +16,10 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.5.1+26050103 +version: 1.6.1+26062103 environment: - sdk: ^3.9.2 + sdk: ^3.11.0 # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions @@ -61,6 +61,7 @@ dependencies: git: url: "https://gitcode.com/openharmony-tpc/flutter_packages.git" path: "packages/shared_preferences/shared_preferences" + ref: br_shared_preferences-v2.5.4_ohos # go_router: # git: @@ -93,18 +94,20 @@ dependencies: pigeon: - git: - url: "https://gitcode.com/openharmony-sig/flutter_packages.git" + git: + url: "https://gitcode.com/openharmony-tpc/flutter_packages.git" path: "packages/pigeon" + ref: br_pigeon-v26.1.5_ohos share_plus: git: url: https://gitcode.com/openharmony-sig/flutter_plus_plugins.git path: packages/share_plus/share_plus - ref: br_share_plus-v10.1.1_ohos + ref: br_share_plus-v12.0.1_ohos connectivity_plus: git: url: https://gitcode.com/openharmony-sig/flutter_plus_plugins.git path: packages/connectivity_plus/connectivity_plus + ref: br_connectivity_plus-v6.1.0_ohos package_info_plus: git: url: https://gitcode.com/openharmony-sig/flutter_plus_plugins.git @@ -114,12 +117,13 @@ dependencies: git: url: https://gitcode.com/openharmony-sig/flutter_permission_handler.git path: permission_handler - ref: br_permission_handler_v11.3.1_ohos + ref: br_v12.0.1_ohos device_info_plus: git: url: https://gitcode.com/openharmony-sig/flutter_plus_plugins.git path: packages/device_info_plus/device_info_plus + ref: br_device_info_plus_v11.4.0_ohos mobile_scanner: path: packages/mobile_scanner @@ -131,6 +135,7 @@ dependencies: path: packages/flutter_staggered_grid_view cached_network_image: path: packages/cached_network_image/cached_network_image + flutter_cache_manager: ^3.4.1 flutter_card_swiper: path: packages/flutter_card_swiper @@ -141,12 +146,13 @@ dependencies: git: url: https://gitcode.com/openharmony-tpc/flutter_packages.git path: "packages/url_launcher/url_launcher" + ref: br_url_launcher-v6.3.2_ohos path_provider: git: - url: "https://gitcode.com/openharmony-sig/flutter_packages.git" + url: "https://gitcode.com/openharmony-tpc/flutter_packages.git" path: "packages/path_provider/path_provider" - ref: master + ref: br_path_provider-v2.1.5_ohos hive_ce: ^2.11.0 @@ -165,6 +171,7 @@ dependencies: flutter_markdown_plus: path: packages/flutter_markdown_plus + http: any dev_dependencies: flutter_test: sdk: flutter @@ -175,9 +182,9 @@ dev_dependencies: dependency_overrides: path_provider: git: - url: "https://gitcode.com/openharmony-sig/flutter_packages.git" + url: "https://gitcode.com/openharmony-tpc/flutter_packages.git" path: "packages/path_provider/path_provider" - ref: master + ref: br_path_provider-v2.1.5_ohos package_info_plus: git: url: https://gitcode.com/openharmony-sig/flutter_plus_plugins.git @@ -187,6 +194,7 @@ dependency_overrides: git: url: https://gitcode.com/openharmony-sig/flutter_plus_plugins.git path: packages/device_info_plus/device_info_plus + ref: br_device_info_plus_v11.4.0_ohos fluttertoast: path: packages/fluttertoast mailer: diff --git a/test/integration/api_integration_test.dart b/test/integration/api_integration_test.dart deleted file mode 100644 index 24b6f9d..0000000 --- a/test/integration/api_integration_test.dart +++ /dev/null @@ -1,89 +0,0 @@ -// 创建时间: 2026-04-09 -// 更新时间: 2026-04-09 -// 名称: API集成测试 -// 作用: 测试关键API接口的集成 -// 上次更新内容: 初始创建 - -import 'package:flutter_test/flutter_test.dart'; -import 'package:cute_kitchen/src/repositories/action_repository.dart'; -import 'package:cute_kitchen/src/repositories/preference_repository.dart'; -import 'package:cute_kitchen/src/services/api/api_service.dart'; -import 'package:cute_kitchen/src/services/api/api_exception.dart'; - -void main() { - group('API 集成测试', () { - late ApiService apiService; - late ActionRepository actionRepository; - late PreferenceRepository preferenceRepository; - - setUp(() { - apiService = ApiService(); - actionRepository = ActionRepository(); - preferenceRepository = PreferenceRepository(); - }); - - test('ApiService 初始化测试', () { - expect(apiService, isNotNull); - }); - - test('ApiException 类型测试', () { - final exception = ApiException( - type: ApiExceptionType.rateLimited, - message: 'Rate limited', - statusCode: 429, - ); - expect(exception.isRateLimited, isTrue); - expect(exception.statusCode, 429); - }); - - test('ActionRepository 初始化测试', () { - expect(actionRepository, isNotNull); - }); - - test('PreferenceRepository 初始化测试', () { - expect(preferenceRepository, isNotNull); - }); - - // 注意:这些测试需要真实的API连接,在CI环境中可能需要mock - // 这里只测试初始化和基本逻辑,不进行实际网络请求 - }); - - group('响应格式适配器测试', () { - test('extractList 测试', () { - final data1 = { - 'list': [1, 2, 3], - }; - final data2 = { - 'items': [4, 5, 6], - }; - final data3 = { - 'candidates': [7, 8, 9], - }; - final data4 = { - 'recipe_view': [10, 11, 12], - }; - - // 由于ResponseAdapter在另一个文件,这里只测试数据结构 - expect(data1['list'], isNotNull); - expect(data2['items'], isNotNull); - expect(data3['candidates'], isNotNull); - expect(data4['recipe_view'], isNotNull); - }); - - test('extractItem 测试', () { - final data1 = { - 'item': {'id': 1}, - }; - final data2 = { - 'recipe': {'id': 2}, - }; - final data3 = { - 'best_match': {'id': 3}, - }; - - expect(data1['item'], isNotNull); - expect(data2['recipe'], isNotNull); - expect(data3['best_match'], isNotNull); - }); - }); -}