@@ -1253,6 +1253,182 @@ void PopulateAOTSnapshotMappingCallbacks(
1253
1253
}
1254
1254
}
1255
1255
1256
+ // Translates engine semantic nodes to embedder semantic nodes.
1257
+ FlutterSemanticsNode CreateEmbedderSemanticsNode (
1258
+ const flutter::SemanticsNode& node) {
1259
+ SkMatrix transform = node.transform .asM33 ();
1260
+ FlutterTransformation flutter_transform{
1261
+ transform.get (SkMatrix::kMScaleX ), transform.get (SkMatrix::kMSkewX ),
1262
+ transform.get (SkMatrix::kMTransX ), transform.get (SkMatrix::kMSkewY ),
1263
+ transform.get (SkMatrix::kMScaleY ), transform.get (SkMatrix::kMTransY ),
1264
+ transform.get (SkMatrix::kMPersp0 ), transform.get (SkMatrix::kMPersp1 ),
1265
+ transform.get (SkMatrix::kMPersp2 )};
1266
+ return {
1267
+ sizeof (FlutterSemanticsNode),
1268
+ node.id ,
1269
+ static_cast <FlutterSemanticsFlag>(node.flags ),
1270
+ static_cast <FlutterSemanticsAction>(node.actions ),
1271
+ node.textSelectionBase ,
1272
+ node.textSelectionExtent ,
1273
+ node.scrollChildren ,
1274
+ node.scrollIndex ,
1275
+ node.scrollPosition ,
1276
+ node.scrollExtentMax ,
1277
+ node.scrollExtentMin ,
1278
+ node.elevation ,
1279
+ node.thickness ,
1280
+ node.label .c_str (),
1281
+ node.hint .c_str (),
1282
+ node.value .c_str (),
1283
+ node.increasedValue .c_str (),
1284
+ node.decreasedValue .c_str (),
1285
+ static_cast <FlutterTextDirection>(node.textDirection ),
1286
+ FlutterRect{node.rect .fLeft , node.rect .fTop , node.rect .fRight ,
1287
+ node.rect .fBottom },
1288
+ flutter_transform,
1289
+ node.childrenInTraversalOrder .size (),
1290
+ node.childrenInTraversalOrder .data (),
1291
+ node.childrenInHitTestOrder .data (),
1292
+ node.customAccessibilityActions .size (),
1293
+ node.customAccessibilityActions .data (),
1294
+ node.platformViewId ,
1295
+ };
1296
+ }
1297
+
1298
+ // Translates engine semantic custom actions to embedder semantic custom
1299
+ // actions.
1300
+ FlutterSemanticsCustomAction CreateEmbedderSemanticsCustomAction (
1301
+ const flutter::CustomAccessibilityAction& action) {
1302
+ return {
1303
+ sizeof (FlutterSemanticsCustomAction),
1304
+ action.id ,
1305
+ static_cast <FlutterSemanticsAction>(action.overrideId ),
1306
+ action.label .c_str (),
1307
+ action.hint .c_str (),
1308
+ };
1309
+ }
1310
+
1311
+ // Create a callback to notify the embedder of semantic updates
1312
+ // using the new embedder callback 'update_semantics_callback'.
1313
+ flutter::PlatformViewEmbedder::UpdateSemanticsCallback
1314
+ CreateNewEmbedderSemanticsUpdateCallback (
1315
+ FlutterUpdateSemanticsCallback update_semantics_callback,
1316
+ void * user_data) {
1317
+ return [update_semantics_callback, user_data](
1318
+ const flutter::SemanticsNodeUpdates& nodes,
1319
+ const flutter::CustomAccessibilityActionUpdates& actions) {
1320
+ std::vector<FlutterSemanticsNode> embedder_nodes;
1321
+ for (const auto & value : nodes) {
1322
+ embedder_nodes.push_back (CreateEmbedderSemanticsNode (value.second ));
1323
+ }
1324
+
1325
+ std::vector<FlutterSemanticsCustomAction> embedder_custom_actions;
1326
+ for (const auto & value : actions) {
1327
+ embedder_custom_actions.push_back (
1328
+ CreateEmbedderSemanticsCustomAction (value.second ));
1329
+ }
1330
+
1331
+ FlutterSemanticsUpdate update{
1332
+ .struct_size = sizeof (FlutterSemanticsUpdate),
1333
+ .nodes_count = embedder_nodes.size (),
1334
+ .nodes = embedder_nodes.data (),
1335
+ .custom_actions_count = embedder_custom_actions.size (),
1336
+ .custom_actions = embedder_custom_actions.data (),
1337
+ };
1338
+
1339
+ update_semantics_callback (&update, user_data);
1340
+ };
1341
+ }
1342
+
1343
+ // Create a callback to notify the embedder of semantic updates
1344
+ // using the legacy embedder callbacks 'update_semantics_node_callback' and
1345
+ // 'update_semantics_custom_action_callback'.
1346
+ flutter::PlatformViewEmbedder::UpdateSemanticsCallback
1347
+ CreateLegacyEmbedderSemanticsUpdateCallback (
1348
+ FlutterUpdateSemanticsNodeCallback update_semantics_node_callback,
1349
+ FlutterUpdateSemanticsCustomActionCallback
1350
+ update_semantics_custom_action_callback,
1351
+ void * user_data) {
1352
+ return [update_semantics_node_callback,
1353
+ update_semantics_custom_action_callback,
1354
+ user_data](const flutter::SemanticsNodeUpdates& nodes,
1355
+ const flutter::CustomAccessibilityActionUpdates& actions) {
1356
+ // First, queue all node and custom action updates.
1357
+ if (update_semantics_node_callback != nullptr ) {
1358
+ for (const auto & value : nodes) {
1359
+ const FlutterSemanticsNode embedder_node =
1360
+ CreateEmbedderSemanticsNode (value.second );
1361
+ update_semantics_node_callback (&embedder_node, user_data);
1362
+ }
1363
+ }
1364
+
1365
+ if (update_semantics_custom_action_callback != nullptr ) {
1366
+ for (const auto & value : actions) {
1367
+ const FlutterSemanticsCustomAction embedder_action =
1368
+ CreateEmbedderSemanticsCustomAction (value.second );
1369
+ update_semantics_custom_action_callback (&embedder_action, user_data);
1370
+ }
1371
+ }
1372
+
1373
+ // Second, mark node and action batches completed now that all
1374
+ // updates are queued.
1375
+ if (update_semantics_node_callback != nullptr ) {
1376
+ const FlutterSemanticsNode batch_end_sentinel = {
1377
+ sizeof (FlutterSemanticsNode),
1378
+ kFlutterSemanticsNodeIdBatchEnd ,
1379
+ };
1380
+ update_semantics_node_callback (&batch_end_sentinel, user_data);
1381
+ }
1382
+
1383
+ if (update_semantics_custom_action_callback != nullptr ) {
1384
+ const FlutterSemanticsCustomAction batch_end_sentinel = {
1385
+ sizeof (FlutterSemanticsCustomAction),
1386
+ kFlutterSemanticsCustomActionIdBatchEnd ,
1387
+ };
1388
+ update_semantics_custom_action_callback (&batch_end_sentinel, user_data);
1389
+ }
1390
+ };
1391
+ }
1392
+
1393
+ // Creates a callback that receives semantic updates from the engine
1394
+ // and notifies the embedder's callback(s). Returns null if the embedder
1395
+ // did not register any callbacks.
1396
+ flutter::PlatformViewEmbedder::UpdateSemanticsCallback
1397
+ CreateEmbedderSemanticsUpdateCallback (const FlutterProjectArgs* args,
1398
+ void * user_data) {
1399
+ // The embedder can register the new callback, or the legacy callbacks, or
1400
+ // nothing at all. Handle the case where the embedder registered the 'new'
1401
+ // callback.
1402
+ if (SAFE_ACCESS (args, update_semantics_callback, nullptr ) != nullptr ) {
1403
+ return CreateNewEmbedderSemanticsUpdateCallback (
1404
+ args->update_semantics_callback , user_data);
1405
+ }
1406
+
1407
+ // Handle the case where the embedder registered 'legacy' callbacks.
1408
+ FlutterUpdateSemanticsNodeCallback update_semantics_node_callback = nullptr ;
1409
+ if (SAFE_ACCESS (args, update_semantics_node_callback, nullptr ) != nullptr ) {
1410
+ update_semantics_node_callback = args->update_semantics_node_callback ;
1411
+ }
1412
+
1413
+ FlutterUpdateSemanticsCustomActionCallback
1414
+ update_semantics_custom_action_callback = nullptr ;
1415
+ if (SAFE_ACCESS (args, update_semantics_custom_action_callback, nullptr ) !=
1416
+ nullptr ) {
1417
+ update_semantics_custom_action_callback =
1418
+ args->update_semantics_custom_action_callback ;
1419
+ }
1420
+
1421
+ if (update_semantics_node_callback != nullptr ||
1422
+ update_semantics_custom_action_callback != nullptr ) {
1423
+ return CreateLegacyEmbedderSemanticsUpdateCallback (
1424
+ update_semantics_node_callback, update_semantics_custom_action_callback,
1425
+ user_data);
1426
+ }
1427
+
1428
+ // Handle the case where the embedder registered no callbacks.
1429
+ return nullptr ;
1430
+ }
1431
+
1256
1432
FlutterEngineResult FlutterEngineRun (size_t version,
1257
1433
const FlutterRendererConfig* config,
1258
1434
const FlutterProjectArgs* args,
@@ -1400,113 +1576,20 @@ FlutterEngineResult FlutterEngineInitialize(size_t version,
1400
1576
settings.log_tag = SAFE_ACCESS (args, log_tag, nullptr );
1401
1577
}
1402
1578
1403
- FlutterUpdateSemanticsNodeCallback update_semantics_node_callback = nullptr ;
1404
- if (SAFE_ACCESS (args, update_semantics_node_callback, nullptr ) != nullptr ) {
1405
- update_semantics_node_callback = args->update_semantics_node_callback ;
1406
- }
1407
-
1408
- FlutterUpdateSemanticsCustomActionCallback
1409
- update_semantics_custom_action_callback = nullptr ;
1410
- if (SAFE_ACCESS (args, update_semantics_custom_action_callback, nullptr ) !=
1411
- nullptr ) {
1412
- update_semantics_custom_action_callback =
1413
- args->update_semantics_custom_action_callback ;
1579
+ if (args->update_semantics_callback != nullptr &&
1580
+ (args->update_semantics_node_callback != nullptr ||
1581
+ args->update_semantics_custom_action_callback != nullptr )) {
1582
+ return LOG_EMBEDDER_ERROR (
1583
+ kInvalidArguments ,
1584
+ " Multiple semantics update callbacks provided. "
1585
+ " Embedders should provide either `update_semantics_callback` "
1586
+ " or both `update_semantics_nodes_callback` and "
1587
+ " `update_semantics_custom_actions_callback`." );
1414
1588
}
1415
1589
1416
1590
flutter::PlatformViewEmbedder::UpdateSemanticsCallback
1417
- update_semantics_callback = nullptr ;
1418
- if (update_semantics_node_callback != nullptr ||
1419
- update_semantics_custom_action_callback != nullptr ) {
1420
- update_semantics_callback =
1421
- [update_semantics_node_callback,
1422
- update_semantics_custom_action_callback,
1423
- user_data](const flutter::SemanticsNodeUpdates& update,
1424
- const flutter::CustomAccessibilityActionUpdates& actions) {
1425
- // First, queue all node and custom action updates.
1426
- if (update_semantics_node_callback != nullptr ) {
1427
- for (const auto & value : update) {
1428
- const auto & node = value.second ;
1429
- SkMatrix transform = node.transform .asM33 ();
1430
- FlutterTransformation flutter_transform{
1431
- transform.get (SkMatrix::kMScaleX ),
1432
- transform.get (SkMatrix::kMSkewX ),
1433
- transform.get (SkMatrix::kMTransX ),
1434
- transform.get (SkMatrix::kMSkewY ),
1435
- transform.get (SkMatrix::kMScaleY ),
1436
- transform.get (SkMatrix::kMTransY ),
1437
- transform.get (SkMatrix::kMPersp0 ),
1438
- transform.get (SkMatrix::kMPersp1 ),
1439
- transform.get (SkMatrix::kMPersp2 )};
1440
- const FlutterSemanticsNode embedder_node{
1441
- sizeof (FlutterSemanticsNode),
1442
- node.id ,
1443
- static_cast <FlutterSemanticsFlag>(node.flags ),
1444
- static_cast <FlutterSemanticsAction>(node.actions ),
1445
- node.textSelectionBase ,
1446
- node.textSelectionExtent ,
1447
- node.scrollChildren ,
1448
- node.scrollIndex ,
1449
- node.scrollPosition ,
1450
- node.scrollExtentMax ,
1451
- node.scrollExtentMin ,
1452
- node.elevation ,
1453
- node.thickness ,
1454
- node.label .c_str (),
1455
- node.hint .c_str (),
1456
- node.value .c_str (),
1457
- node.increasedValue .c_str (),
1458
- node.decreasedValue .c_str (),
1459
- static_cast <FlutterTextDirection>(node.textDirection ),
1460
- FlutterRect{node.rect .fLeft , node.rect .fTop , node.rect .fRight ,
1461
- node.rect .fBottom },
1462
- flutter_transform,
1463
- node.childrenInTraversalOrder .size (),
1464
- node.childrenInTraversalOrder .data (),
1465
- node.childrenInHitTestOrder .data (),
1466
- node.customAccessibilityActions .size (),
1467
- node.customAccessibilityActions .data (),
1468
- node.platformViewId ,
1469
- node.tooltip .c_str (),
1470
- };
1471
- update_semantics_node_callback (&embedder_node, user_data);
1472
- }
1473
- }
1474
-
1475
- if (update_semantics_custom_action_callback != nullptr ) {
1476
- for (const auto & value : actions) {
1477
- const auto & action = value.second ;
1478
- const FlutterSemanticsCustomAction embedder_action = {
1479
- sizeof (FlutterSemanticsCustomAction),
1480
- action.id ,
1481
- static_cast <FlutterSemanticsAction>(action.overrideId ),
1482
- action.label .c_str (),
1483
- action.hint .c_str (),
1484
- };
1485
- update_semantics_custom_action_callback (&embedder_action,
1486
- user_data);
1487
- }
1488
- }
1489
-
1490
- // Second, mark node and action batches completed now that all
1491
- // updates are queued.
1492
- if (update_semantics_node_callback != nullptr ) {
1493
- const FlutterSemanticsNode batch_end_sentinel = {
1494
- sizeof (FlutterSemanticsNode),
1495
- kFlutterSemanticsNodeIdBatchEnd ,
1496
- };
1497
- update_semantics_node_callback (&batch_end_sentinel, user_data);
1498
- }
1499
-
1500
- if (update_semantics_custom_action_callback != nullptr ) {
1501
- const FlutterSemanticsCustomAction batch_end_sentinel = {
1502
- sizeof (FlutterSemanticsCustomAction),
1503
- kFlutterSemanticsCustomActionIdBatchEnd ,
1504
- };
1505
- update_semantics_custom_action_callback (&batch_end_sentinel,
1506
- user_data);
1507
- }
1508
- };
1509
- }
1591
+ update_semantics_callback =
1592
+ CreateEmbedderSemanticsUpdateCallback (args, user_data);
1510
1593
1511
1594
flutter::PlatformViewEmbedder::PlatformMessageResponseCallback
1512
1595
platform_message_response_callback = nullptr ;
0 commit comments