Skip to content

Commit 11e08c9

Browse files
loic-sharmagaaclarke
authored andcommitted
[Embedder] Refactor how semantic updates are mapped (flutter#44553)
This refactors how engine semantic updates are mapped to embedder semantic updates. There are no behavioral changes. Part of flutter/flutter#119970, flutter/flutter#98948 Next PR: flutter#44616 ## Background For flutter/flutter#119970, we will need to update the embedder API to add string attributes to semantic nodes' text values. There are multiple kinds of string attributes, and each text value can have multiple string attributes. This requires gnarly mapping code that's best kept out of `embedder.cc`. [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
1 parent 4902f41 commit 11e08c9

File tree

6 files changed

+313
-222
lines changed

6 files changed

+313
-222
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2852,6 +2852,8 @@ ORIGIN: ../../../flutter/shell/platform/embedder/embedder_render_target_impeller
28522852
ORIGIN: ../../../flutter/shell/platform/embedder/embedder_render_target_impeller.h + ../../../flutter/LICENSE
28532853
ORIGIN: ../../../flutter/shell/platform/embedder/embedder_render_target_skia.cc + ../../../flutter/LICENSE
28542854
ORIGIN: ../../../flutter/shell/platform/embedder/embedder_render_target_skia.h + ../../../flutter/LICENSE
2855+
ORIGIN: ../../../flutter/shell/platform/embedder/embedder_semantics_update.cc + ../../../flutter/LICENSE
2856+
ORIGIN: ../../../flutter/shell/platform/embedder/embedder_semantics_update.h + ../../../flutter/LICENSE
28552857
ORIGIN: ../../../flutter/shell/platform/embedder/embedder_struct_macros.h + ../../../flutter/LICENSE
28562858
ORIGIN: ../../../flutter/shell/platform/embedder/embedder_surface.cc + ../../../flutter/LICENSE
28572859
ORIGIN: ../../../flutter/shell/platform/embedder/embedder_surface.h + ../../../flutter/LICENSE
@@ -5597,6 +5599,8 @@ FILE: ../../../flutter/shell/platform/embedder/embedder_render_target_impeller.c
55975599
FILE: ../../../flutter/shell/platform/embedder/embedder_render_target_impeller.h
55985600
FILE: ../../../flutter/shell/platform/embedder/embedder_render_target_skia.cc
55995601
FILE: ../../../flutter/shell/platform/embedder/embedder_render_target_skia.h
5602+
FILE: ../../../flutter/shell/platform/embedder/embedder_semantics_update.cc
5603+
FILE: ../../../flutter/shell/platform/embedder/embedder_semantics_update.h
56005604
FILE: ../../../flutter/shell/platform/embedder/embedder_struct_macros.h
56015605
FILE: ../../../flutter/shell/platform/embedder/embedder_surface.cc
56025606
FILE: ../../../flutter/shell/platform/embedder/embedder_surface.h

shell/platform/embedder/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ template("embedder_source_set") {
7878
"embedder_render_target_cache.h",
7979
"embedder_render_target_skia.cc",
8080
"embedder_render_target_skia.h",
81+
"embedder_semantics_update.cc",
82+
"embedder_semantics_update.h",
8183
"embedder_struct_macros.h",
8284
"embedder_surface.cc",
8385
"embedder_surface.h",

shell/platform/embedder/embedder.cc

Lines changed: 53 additions & 219 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ extern const intptr_t kPlatformStrongDillSize;
5656
#include "flutter/shell/platform/embedder/embedder_platform_message_response.h"
5757
#include "flutter/shell/platform/embedder/embedder_render_target.h"
5858
#include "flutter/shell/platform/embedder/embedder_render_target_skia.h"
59+
#include "flutter/shell/platform/embedder/embedder_semantics_update.h"
5960
#include "flutter/shell/platform/embedder/embedder_struct_macros.h"
6061
#include "flutter/shell/platform/embedder/embedder_task_runner.h"
6162
#include "flutter/shell/platform/embedder/embedder_thread_host.h"
@@ -1494,214 +1495,11 @@ void PopulateAOTSnapshotMappingCallbacks(
14941495
}
14951496
}
14961497

1497-
// Translates engine semantic nodes to embedder semantic nodes.
1498-
FlutterSemanticsNode CreateEmbedderSemanticsNode(
1499-
const flutter::SemanticsNode& node) {
1500-
SkMatrix transform = node.transform.asM33();
1501-
FlutterTransformation flutter_transform{
1502-
transform.get(SkMatrix::kMScaleX), transform.get(SkMatrix::kMSkewX),
1503-
transform.get(SkMatrix::kMTransX), transform.get(SkMatrix::kMSkewY),
1504-
transform.get(SkMatrix::kMScaleY), transform.get(SkMatrix::kMTransY),
1505-
transform.get(SkMatrix::kMPersp0), transform.get(SkMatrix::kMPersp1),
1506-
transform.get(SkMatrix::kMPersp2)};
1507-
1508-
// Do not add new members to FlutterSemanticsNode.
1509-
// This would break the forward compatibility of FlutterSemanticsUpdate.
1510-
// All new members must be added to FlutterSemanticsNode2 instead.
1511-
return {
1512-
sizeof(FlutterSemanticsNode),
1513-
node.id,
1514-
static_cast<FlutterSemanticsFlag>(node.flags),
1515-
static_cast<FlutterSemanticsAction>(node.actions),
1516-
node.textSelectionBase,
1517-
node.textSelectionExtent,
1518-
node.scrollChildren,
1519-
node.scrollIndex,
1520-
node.scrollPosition,
1521-
node.scrollExtentMax,
1522-
node.scrollExtentMin,
1523-
node.elevation,
1524-
node.thickness,
1525-
node.label.c_str(),
1526-
node.hint.c_str(),
1527-
node.value.c_str(),
1528-
node.increasedValue.c_str(),
1529-
node.decreasedValue.c_str(),
1530-
static_cast<FlutterTextDirection>(node.textDirection),
1531-
FlutterRect{node.rect.fLeft, node.rect.fTop, node.rect.fRight,
1532-
node.rect.fBottom},
1533-
flutter_transform,
1534-
node.childrenInTraversalOrder.size(),
1535-
node.childrenInTraversalOrder.data(),
1536-
node.childrenInHitTestOrder.data(),
1537-
node.customAccessibilityActions.size(),
1538-
node.customAccessibilityActions.data(),
1539-
node.platformViewId,
1540-
node.tooltip.c_str(),
1541-
};
1542-
}
1543-
1544-
// Translates engine semantic nodes to embedder semantic nodes.
1545-
FlutterSemanticsNode2 CreateEmbedderSemanticsNode2(
1546-
const flutter::SemanticsNode& node) {
1547-
SkMatrix transform = node.transform.asM33();
1548-
FlutterTransformation flutter_transform{
1549-
transform.get(SkMatrix::kMScaleX), transform.get(SkMatrix::kMSkewX),
1550-
transform.get(SkMatrix::kMTransX), transform.get(SkMatrix::kMSkewY),
1551-
transform.get(SkMatrix::kMScaleY), transform.get(SkMatrix::kMTransY),
1552-
transform.get(SkMatrix::kMPersp0), transform.get(SkMatrix::kMPersp1),
1553-
transform.get(SkMatrix::kMPersp2)};
1554-
return {
1555-
sizeof(FlutterSemanticsNode2),
1556-
node.id,
1557-
static_cast<FlutterSemanticsFlag>(node.flags),
1558-
static_cast<FlutterSemanticsAction>(node.actions),
1559-
node.textSelectionBase,
1560-
node.textSelectionExtent,
1561-
node.scrollChildren,
1562-
node.scrollIndex,
1563-
node.scrollPosition,
1564-
node.scrollExtentMax,
1565-
node.scrollExtentMin,
1566-
node.elevation,
1567-
node.thickness,
1568-
node.label.c_str(),
1569-
node.hint.c_str(),
1570-
node.value.c_str(),
1571-
node.increasedValue.c_str(),
1572-
node.decreasedValue.c_str(),
1573-
static_cast<FlutterTextDirection>(node.textDirection),
1574-
FlutterRect{node.rect.fLeft, node.rect.fTop, node.rect.fRight,
1575-
node.rect.fBottom},
1576-
flutter_transform,
1577-
node.childrenInTraversalOrder.size(),
1578-
node.childrenInTraversalOrder.data(),
1579-
node.childrenInHitTestOrder.data(),
1580-
node.customAccessibilityActions.size(),
1581-
node.customAccessibilityActions.data(),
1582-
node.platformViewId,
1583-
node.tooltip.c_str(),
1584-
};
1585-
}
1586-
1587-
// Translates engine semantic custom actions to embedder semantic custom
1588-
// actions.
1589-
FlutterSemanticsCustomAction CreateEmbedderSemanticsCustomAction(
1590-
const flutter::CustomAccessibilityAction& action) {
1591-
// Do not add new members to FlutterSemanticsCustomAction.
1592-
// This would break the forward compatibility of FlutterSemanticsUpdate.
1593-
// All new members must be added to FlutterSemanticsCustomAction2 instead.
1594-
return {
1595-
sizeof(FlutterSemanticsCustomAction),
1596-
action.id,
1597-
static_cast<FlutterSemanticsAction>(action.overrideId),
1598-
action.label.c_str(),
1599-
action.hint.c_str(),
1600-
};
1601-
}
1602-
1603-
// Translates engine semantic custom actions to embedder semantic custom
1604-
// actions.
1605-
FlutterSemanticsCustomAction2 CreateEmbedderSemanticsCustomAction2(
1606-
const flutter::CustomAccessibilityAction& action) {
1607-
return {
1608-
sizeof(FlutterSemanticsCustomAction2),
1609-
action.id,
1610-
static_cast<FlutterSemanticsAction>(action.overrideId),
1611-
action.label.c_str(),
1612-
action.hint.c_str(),
1613-
};
1614-
}
1615-
1616-
// Create a callback to notify the embedder of semantic updates
1617-
// using the deprecated embedder callback 'update_semantics_callback'.
1618-
flutter::PlatformViewEmbedder::UpdateSemanticsCallback
1619-
CreateNewEmbedderSemanticsUpdateCallback(
1620-
FlutterUpdateSemanticsCallback update_semantics_callback,
1621-
void* user_data) {
1622-
return [update_semantics_callback, user_data](
1623-
const flutter::SemanticsNodeUpdates& nodes,
1624-
const flutter::CustomAccessibilityActionUpdates& actions) {
1625-
std::vector<FlutterSemanticsNode> embedder_nodes;
1626-
for (const auto& value : nodes) {
1627-
embedder_nodes.push_back(CreateEmbedderSemanticsNode(value.second));
1628-
}
1629-
1630-
std::vector<FlutterSemanticsCustomAction> embedder_custom_actions;
1631-
for (const auto& value : actions) {
1632-
embedder_custom_actions.push_back(
1633-
CreateEmbedderSemanticsCustomAction(value.second));
1634-
}
1635-
1636-
FlutterSemanticsUpdate update{
1637-
.struct_size = sizeof(FlutterSemanticsUpdate),
1638-
.nodes_count = embedder_nodes.size(),
1639-
.nodes = embedder_nodes.data(),
1640-
.custom_actions_count = embedder_custom_actions.size(),
1641-
.custom_actions = embedder_custom_actions.data(),
1642-
};
1643-
1644-
update_semantics_callback(&update, user_data);
1645-
};
1646-
}
1647-
1648-
// Create a callback to notify the embedder of semantic updates
1649-
// using the new embedder callback 'update_semantics_callback2'.
1650-
flutter::PlatformViewEmbedder::UpdateSemanticsCallback
1651-
CreateNewEmbedderSemanticsUpdateCallback2(
1652-
FlutterUpdateSemanticsCallback2 update_semantics_callback,
1653-
void* user_data) {
1654-
return [update_semantics_callback, user_data](
1655-
const flutter::SemanticsNodeUpdates& nodes,
1656-
const flutter::CustomAccessibilityActionUpdates& actions) {
1657-
std::vector<FlutterSemanticsNode2> embedder_nodes;
1658-
std::vector<FlutterSemanticsCustomAction2> embedder_custom_actions;
1659-
1660-
embedder_nodes.reserve(nodes.size());
1661-
embedder_custom_actions.reserve(actions.size());
1662-
1663-
for (const auto& value : nodes) {
1664-
embedder_nodes.push_back(CreateEmbedderSemanticsNode2(value.second));
1665-
}
1666-
1667-
for (const auto& value : actions) {
1668-
embedder_custom_actions.push_back(
1669-
CreateEmbedderSemanticsCustomAction2(value.second));
1670-
}
1671-
1672-
// Provide the embedder an array of pointers to maintain full forward and
1673-
// backward compatibility even if new members are added to semantic structs.
1674-
std::vector<FlutterSemanticsNode2*> embedder_node_pointers;
1675-
std::vector<FlutterSemanticsCustomAction2*> embedder_custom_action_pointers;
1676-
1677-
embedder_node_pointers.reserve(embedder_nodes.size());
1678-
embedder_custom_action_pointers.reserve(embedder_custom_actions.size());
1679-
1680-
for (auto& node : embedder_nodes) {
1681-
embedder_node_pointers.push_back(&node);
1682-
}
1683-
1684-
for (auto& action : embedder_custom_actions) {
1685-
embedder_custom_action_pointers.push_back(&action);
1686-
}
1687-
1688-
FlutterSemanticsUpdate2 update{
1689-
.struct_size = sizeof(FlutterSemanticsUpdate2),
1690-
.node_count = embedder_node_pointers.size(),
1691-
.nodes = embedder_node_pointers.data(),
1692-
.custom_action_count = embedder_custom_action_pointers.size(),
1693-
.custom_actions = embedder_custom_action_pointers.data(),
1694-
};
1695-
1696-
update_semantics_callback(&update, user_data);
1697-
};
1698-
}
1699-
17001498
// Create a callback to notify the embedder of semantic updates
17011499
// using the legacy embedder callbacks 'update_semantics_node_callback' and
17021500
// 'update_semantics_custom_action_callback'.
17031501
flutter::PlatformViewEmbedder::UpdateSemanticsCallback
1704-
CreateLegacyEmbedderSemanticsUpdateCallback(
1502+
CreateEmbedderSemanticsUpdateCallbackV1(
17051503
FlutterUpdateSemanticsNodeCallback update_semantics_node_callback,
17061504
FlutterUpdateSemanticsCustomActionCallback
17071505
update_semantics_custom_action_callback,
@@ -1710,20 +1508,20 @@ CreateLegacyEmbedderSemanticsUpdateCallback(
17101508
update_semantics_custom_action_callback,
17111509
user_data](const flutter::SemanticsNodeUpdates& nodes,
17121510
const flutter::CustomAccessibilityActionUpdates& actions) {
1511+
flutter::EmbedderSemanticsUpdate update{nodes, actions};
1512+
FlutterSemanticsUpdate* update_ptr = update.get();
1513+
17131514
// First, queue all node and custom action updates.
17141515
if (update_semantics_node_callback != nullptr) {
1715-
for (const auto& value : nodes) {
1716-
const FlutterSemanticsNode embedder_node =
1717-
CreateEmbedderSemanticsNode(value.second);
1718-
update_semantics_node_callback(&embedder_node, user_data);
1516+
for (size_t i = 0; i < update_ptr->nodes_count; i++) {
1517+
update_semantics_node_callback(&update_ptr->nodes[i], user_data);
17191518
}
17201519
}
17211520

17221521
if (update_semantics_custom_action_callback != nullptr) {
1723-
for (const auto& value : actions) {
1724-
const FlutterSemanticsCustomAction embedder_action =
1725-
CreateEmbedderSemanticsCustomAction(value.second);
1726-
update_semantics_custom_action_callback(&embedder_action, user_data);
1522+
for (size_t i = 0; i < update_ptr->custom_actions_count; i++) {
1523+
update_semantics_custom_action_callback(&update_ptr->custom_actions[i],
1524+
user_data);
17271525
}
17281526
}
17291527

@@ -1747,26 +1545,62 @@ CreateLegacyEmbedderSemanticsUpdateCallback(
17471545
};
17481546
}
17491547

1548+
// Create a callback to notify the embedder of semantic updates
1549+
// using the deprecated embedder callback 'update_semantics_callback'.
1550+
flutter::PlatformViewEmbedder::UpdateSemanticsCallback
1551+
CreateEmbedderSemanticsUpdateCallbackV2(
1552+
FlutterUpdateSemanticsCallback update_semantics_callback,
1553+
void* user_data) {
1554+
return [update_semantics_callback, user_data](
1555+
const flutter::SemanticsNodeUpdates& nodes,
1556+
const flutter::CustomAccessibilityActionUpdates& actions) {
1557+
flutter::EmbedderSemanticsUpdate update{nodes, actions};
1558+
1559+
update_semantics_callback(update.get(), user_data);
1560+
};
1561+
}
1562+
1563+
// Create a callback to notify the embedder of semantic updates
1564+
// using the new embedder callback 'update_semantics_callback2'.
1565+
flutter::PlatformViewEmbedder::UpdateSemanticsCallback
1566+
CreateEmbedderSemanticsUpdateCallbackV3(
1567+
FlutterUpdateSemanticsCallback2 update_semantics_callback,
1568+
void* user_data) {
1569+
return [update_semantics_callback, user_data](
1570+
const flutter::SemanticsNodeUpdates& nodes,
1571+
const flutter::CustomAccessibilityActionUpdates& actions) {
1572+
flutter::EmbedderSemanticsUpdate2 update{nodes, actions};
1573+
1574+
update_semantics_callback(update.get(), user_data);
1575+
};
1576+
}
1577+
17501578
// Creates a callback that receives semantic updates from the engine
17511579
// and notifies the embedder's callback(s). Returns null if the embedder
17521580
// did not register any callbacks.
17531581
flutter::PlatformViewEmbedder::UpdateSemanticsCallback
17541582
CreateEmbedderSemanticsUpdateCallback(const FlutterProjectArgs* args,
17551583
void* user_data) {
1756-
// The embedder can register the new callback, or the legacy callbacks, or
1757-
// nothing at all. Handle the case where the embedder registered the 'new'
1758-
// callback.
1584+
// There are three variants for the embedder API's semantic update callbacks.
1585+
// Create a callback that maps to the embedder's desired semantic update API.
1586+
//
1587+
// Handle the case where the embedder registered the callback
1588+
// 'updated_semantics_callback2'
17591589
if (SAFE_ACCESS(args, update_semantics_callback2, nullptr) != nullptr) {
1760-
return CreateNewEmbedderSemanticsUpdateCallback2(
1590+
return CreateEmbedderSemanticsUpdateCallbackV3(
17611591
args->update_semantics_callback2, user_data);
17621592
}
17631593

1594+
// Handle the case where the embedder registered the deprecated callback
1595+
// 'update_semantics_callback'.
17641596
if (SAFE_ACCESS(args, update_semantics_callback, nullptr) != nullptr) {
1765-
return CreateNewEmbedderSemanticsUpdateCallback(
1597+
return CreateEmbedderSemanticsUpdateCallbackV2(
17661598
args->update_semantics_callback, user_data);
17671599
}
17681600

1769-
// Handle the case where the embedder registered 'legacy' callbacks.
1601+
// Handle the case where the embedder registered the deprecated callbacks
1602+
// 'update_semantics_node_callback' and
1603+
// 'update_semantics_custom_action_callback'.
17701604
FlutterUpdateSemanticsNodeCallback update_semantics_node_callback = nullptr;
17711605
if (SAFE_ACCESS(args, update_semantics_node_callback, nullptr) != nullptr) {
17721606
update_semantics_node_callback = args->update_semantics_node_callback;
@@ -1782,7 +1616,7 @@ CreateEmbedderSemanticsUpdateCallback(const FlutterProjectArgs* args,
17821616

17831617
if (update_semantics_node_callback != nullptr ||
17841618
update_semantics_custom_action_callback != nullptr) {
1785-
return CreateLegacyEmbedderSemanticsUpdateCallback(
1619+
return CreateEmbedderSemanticsUpdateCallbackV1(
17861620
update_semantics_node_callback, update_semantics_custom_action_callback,
17871621
user_data);
17881622
}

0 commit comments

Comments
 (0)