Move `Shell::Add/RemoveView` to `PlatformView` and refine embedder API doc (#52003)
This PR moves the methods to add or remove views from `Shell` to
`PlatformView`. By design, the `Shell` is supposed to be a messenger
that glues classes together, while `PlatformView` is the operator that
embedders that do not use the embedder API should operate on. The
current design was made due to lack of knowledge to this design.
This also makes `PlatformView` aware of views, which might be a
prerequisite to https://github.com/flutter/engine/pull/51925.
This PR also adds some details to embedder API `AddView` and
`RemoveView`.
## Pre-launch Checklist
- [ ] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [ ] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [ ] I read and followed the [Flutter Style Guide] and the [C++,
Objective-C, Java style guides].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] I added new tests to check the change I am making or feature I am
adding, or the PR is [test-exempt]. See [testing the engine] for
instructions on writing and running engine tests.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [ ] I signed the [CLA].
- [ ] All existing and new tests are passing.
If you need help, consider asking for advice on the #hackers-new channel
on [Discord].
<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#overview
[Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene
[test-exempt]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo
[C++, Objective-C, Java style guides]:
https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
[testing the engine]:
https://github.com/flutter/flutter/wiki/Testing-the-engine
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes
[Discord]: https://github.com/flutter/flutter/wiki/Chat
diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc
index 48439c2..85ad6db 100644
--- a/shell/common/platform_view.cc
+++ b/shell/common/platform_view.cc
@@ -87,6 +87,17 @@
delegate_.OnPlatformViewScheduleFrame();
}
+void PlatformView::AddView(int64_t view_id,
+ const ViewportMetrics& viewport_metrics,
+ AddViewCallback callback) {
+ delegate_.OnPlatformViewAddView(view_id, viewport_metrics,
+ std::move(callback));
+}
+
+void PlatformView::RemoveView(int64_t view_id, RemoveViewCallback callback) {
+ delegate_.OnPlatformViewRemoveView(view_id, std::move(callback));
+}
+
sk_sp<GrDirectContext> PlatformView::CreateResourceContext() const {
FML_DLOG(WARNING) << "This platform does not set up the resource "
"context on the IO thread for async texture uploads.";
diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h
index bfb6489..04f85a5 100644
--- a/shell/common/platform_view.h
+++ b/shell/common/platform_view.h
@@ -51,6 +51,8 @@
///
class PlatformView {
public:
+ using AddViewCallback = std::function<void(bool added)>;
+ using RemoveViewCallback = std::function<void(bool removed)>;
//----------------------------------------------------------------------------
/// @brief Used to forward events from the platform view to interested
/// subsystems. This forwarding is done by the shell which sets
@@ -58,6 +60,8 @@
///
class Delegate {
public:
+ using AddViewCallback = PlatformView::AddViewCallback;
+ using RemoveViewCallback = PlatformView::RemoveViewCallback;
using KeyDataResponse = std::function<void(bool)>;
//--------------------------------------------------------------------------
/// @brief Notifies the delegate that the platform view was created
@@ -84,6 +88,40 @@
///
virtual void OnPlatformViewScheduleFrame() = 0;
+ /// @brief Allocate resources for a new non-implicit view and inform
+ /// Dart about the view, and on success, schedules a new frame.
+ ///
+ /// After the operation, |callback| should be invoked with whether
+ /// the operation is successful.
+ ///
+ /// Adding |kFlutterImplicitViewId| or an existing view ID should
+ /// result in failure.
+ ///
+ /// @param[in] view_id The view ID of the new view.
+ /// @param[in] viewport_metrics The initial viewport metrics for the view.
+ /// @param[in] callback The callback that's invoked once the shell
+ /// has attempted to add the view.
+ ///
+ virtual void OnPlatformViewAddView(int64_t view_id,
+ const ViewportMetrics& viewport_metrics,
+ AddViewCallback callback) = 0;
+
+ /// @brief Deallocate resources for a removed view and inform
+ /// Dart about the removal.
+ ///
+ /// After the operation, |callback| should be invoked with whether
+ /// the operation is successful.
+ ///
+ /// Removing |kFlutterImplicitViewId| or an non-existent view ID
+ /// should result in failure.
+ ///
+ /// @param[in] view_id The view ID of the view to be removed.
+ /// @param[in] callback The callback that's invoked once the shell has
+ /// attempted to remove the view.
+ ///
+ virtual void OnPlatformViewRemoveView(int64_t view_id,
+ RemoveViewCallback callback) = 0;
+
//--------------------------------------------------------------------------
/// @brief Notifies the delegate that the specified callback needs to
/// be invoked after the rasterizer is done rendering the next
@@ -517,6 +555,57 @@
///
void ScheduleFrame();
+ /// @brief Used by embedders to notify the shell of a new non-implicit view.
+ ///
+ /// This method notifies the shell to allocate resources and inform
+ /// Dart about the view, and on success, schedules a new frame.
+ /// Finally, it invokes |callback| with whether the operation is
+ /// successful.
+ ///
+ /// This operation is asynchronous; avoid using the view until
+ /// |callback| returns true. Callers should prepare resources for the
+ /// view (if any) in advance but be ready to clean up on failure.
+ ///
+ /// The callback is called on a different thread.
+ ///
+ /// Do not use for implicit views, which are added internally during
+ /// shell initialization. Adding |kFlutterImplicitViewId| or an
+ /// existing view ID will fail, indicated by |callback| returning
+ /// false.
+ ///
+ /// @param[in] view_id The view ID of the new view.
+ /// @param[in] viewport_metrics The initial viewport metrics for the view.
+ /// @param[in] callback The callback that's invoked once the shell
+ /// has attempted to add the view.
+ ///
+ void AddView(int64_t view_id,
+ const ViewportMetrics& viewport_metrics,
+ AddViewCallback callback);
+
+ /// @brief Used by embedders to notify the shell of a removed non-implicit
+ /// view.
+ ///
+ /// This method notifies the shell to deallocate resources and inform
+ /// Dart about the removal. Finally, it invokes |callback| with
+ /// whether the operation is successful.
+ ///
+ /// This operation is asynchronous. The embedder should not deallocate
+ /// resources until the |callback| is invoked.
+ ///
+ /// The callback is called on a different thread.
+ ///
+ /// Do not use for implicit views, which are never removed throughout
+ /// the lifetime of the app.
+ /// Removing |kFlutterImplicitViewId| or an
+ /// non-existent view ID will fail, indicated by |callback| returning
+ /// false.
+ ///
+ /// @param[in] view_id The view ID of the view to be removed.
+ /// @param[in] callback The callback that's invoked once the shell has
+ /// attempted to remove the view.
+ ///
+ void RemoveView(int64_t view_id, RemoveViewCallback callback);
+
//----------------------------------------------------------------------------
/// @brief Used by the shell to obtain a Skia GPU context that is capable
/// of operating on the IO thread. The context must be in the same
diff --git a/shell/common/shell.cc b/shell/common/shell.cc
index a9a23d3..9cb5735 100644
--- a/shell/common/shell.cc
+++ b/shell/common/shell.cc
@@ -2114,9 +2114,9 @@
return true;
}
-void Shell::AddView(int64_t view_id,
- const ViewportMetrics& viewport_metrics,
- AddViewCallback callback) {
+void Shell::OnPlatformViewAddView(int64_t view_id,
+ const ViewportMetrics& viewport_metrics,
+ AddViewCallback callback) {
TRACE_EVENT0("flutter", "Shell::AddView");
FML_DCHECK(is_set_up_);
FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread());
@@ -2135,7 +2135,8 @@
});
}
-void Shell::RemoveView(int64_t view_id, RemoveViewCallback callback) {
+void Shell::OnPlatformViewRemoveView(int64_t view_id,
+ RemoveViewCallback callback) {
TRACE_EVENT0("flutter", "Shell::RemoveView");
FML_DCHECK(is_set_up_);
FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread());
diff --git a/shell/common/shell.h b/shell/common/shell.h
index a510e14..b724fa0 100644
--- a/shell/common/shell.h
+++ b/shell/common/shell.h
@@ -133,8 +133,6 @@
const std::shared_ptr<fml::SyncSwitch>& gpu_disabled_switch,
impeller::RuntimeStageBackend runtime_stage_type)>
EngineCreateCallback;
- using AddViewCallback = std::function<void(bool added)>;
- using RemoveViewCallback = std::function<void(bool removed)>;
//----------------------------------------------------------------------------
/// @brief Creates a shell instance using the provided settings. The
@@ -304,43 +302,6 @@
///
bool IsSetup() const;
- /// @brief Allocates resources for a new non-implicit view.
- ///
- /// This method returns immediately and does not wait for the task on
- /// the UI thread to finish. This is safe because operations are
- /// either initiated from the UI thread (such as rendering), or are
- /// sent as posted tasks that are queued. In either case, it's ok for
- /// the engine to have views that the Dart VM doesn't.
- ///
- /// The implicit view should never be added with this function.
- /// Instead, it is added internally on Shell initialization. Trying to
- /// add `kFlutterImplicitViewId` triggers an assertion.
- ///
- /// @param[in] view_id The view ID of the new view.
- /// @param[in] viewport_metrics The initial viewport metrics for the view.
- /// @param[in] callback The callback that's invoked once the engine
- /// has attempted to add the view.
- ///
- void AddView(int64_t view_id,
- const ViewportMetrics& viewport_metrics,
- AddViewCallback callback);
-
- /// @brief Deallocates resources for a non-implicit view.
- ///
- /// This method returns immediately and does not wait for the task on
- /// the UI thread to finish. This means that the Dart VM might still
- /// send messages regarding this view ID for a short while, even
- /// though this view ID is already invalid.
- ///
- /// The implicit view should never be removed. Trying to remove
- /// `kFlutterImplicitViewId` triggers an assertion.
- ///
- /// @param[in] view_id The view ID of the view to be removed.
- /// @param[in] callback The callback that's invoked once the engine has
- /// attempted to remove the view.
- ///
- void RemoveView(int64_t view_id, RemoveViewCallback callback);
-
//----------------------------------------------------------------------------
/// @brief Captures a screenshot and optionally Base64 encodes the data
/// of the last layer tree rendered by the rasterizer in this
@@ -601,6 +562,15 @@
void OnPlatformViewScheduleFrame() override;
// |PlatformView::Delegate|
+ void OnPlatformViewAddView(int64_t view_id,
+ const ViewportMetrics& viewport_metrics,
+ AddViewCallback callback) override;
+
+ // |PlatformView::Delegate|
+ void OnPlatformViewRemoveView(int64_t view_id,
+ RemoveViewCallback callback) override;
+
+ // |PlatformView::Delegate|
void OnPlatformViewSetViewportMetrics(
int64_t view_id,
const ViewportMetrics& metrics) override;
diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc
index 7754267..44f3ea7 100644
--- a/shell/common/shell_unittests.cc
+++ b/shell/common/shell_unittests.cc
@@ -79,6 +79,18 @@
MOCK_METHOD(void, OnPlatformViewScheduleFrame, (), (override));
MOCK_METHOD(void,
+ OnPlatformViewAddView,
+ (int64_t view_id,
+ const ViewportMetrics& viewport_metrics,
+ AddViewCallback callback),
+ (override));
+
+ MOCK_METHOD(void,
+ OnPlatformViewRemoveView,
+ (int64_t view_id, RemoveViewCallback callback),
+ (override));
+
+ MOCK_METHOD(void,
OnPlatformViewSetNextFrameCallback,
(const fml::closure& closure),
(override));
@@ -4505,8 +4517,8 @@
ASSERT_EQ(viewIds[0], 0ll);
PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell] {
- shell->AddView(2, ViewportMetrics{},
- [](bool added) { EXPECT_TRUE(added); });
+ shell->GetPlatformView()->AddView(2, ViewportMetrics{},
+ [](bool added) { EXPECT_TRUE(added); });
});
reportLatch.Wait();
ASSERT_TRUE(hasImplicitView);
@@ -4514,7 +4526,8 @@
ASSERT_EQ(viewIds[1], 2ll);
PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell] {
- shell->RemoveView(2, [](bool removed) { ASSERT_TRUE(removed); });
+ shell->GetPlatformView()->RemoveView(
+ 2, [](bool removed) { ASSERT_TRUE(removed); });
});
reportLatch.Wait();
ASSERT_TRUE(hasImplicitView);
@@ -4522,8 +4535,8 @@
ASSERT_EQ(viewIds[0], 0ll);
PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell] {
- shell->AddView(4, ViewportMetrics{},
- [](bool added) { EXPECT_TRUE(added); });
+ shell->GetPlatformView()->AddView(4, ViewportMetrics{},
+ [](bool added) { EXPECT_TRUE(added); });
});
reportLatch.Wait();
ASSERT_TRUE(hasImplicitView);
@@ -4570,13 +4583,13 @@
// Add view 123.
fml::AutoResetWaitableEvent add_latch;
- PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(),
- [&shell, &add_latch] {
- shell->AddView(123, ViewportMetrics{}, [&](bool added) {
- EXPECT_TRUE(added);
- add_latch.Signal();
- });
- });
+ PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell,
+ &add_latch] {
+ shell->GetPlatformView()->AddView(123, ViewportMetrics{}, [&](bool added) {
+ EXPECT_TRUE(added);
+ add_latch.Signal();
+ });
+ });
add_latch.Wait();
@@ -4586,13 +4599,13 @@
ASSERT_EQ(view_ids[1], 123);
// Attempt to add duplicate view ID 123. This should fail.
- PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(),
- [&shell, &add_latch] {
- shell->AddView(123, ViewportMetrics{}, [&](bool added) {
- EXPECT_FALSE(added);
- add_latch.Signal();
- });
- });
+ PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell,
+ &add_latch] {
+ shell->GetPlatformView()->AddView(123, ViewportMetrics{}, [&](bool added) {
+ EXPECT_FALSE(added);
+ add_latch.Signal();
+ });
+ });
add_latch.Wait();
@@ -4638,7 +4651,7 @@
fml::AutoResetWaitableEvent remove_latch;
PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(),
[&shell, &remove_latch] {
- shell->RemoveView(123, [&](bool removed) {
+ shell->GetPlatformView()->RemoveView(123, [&](bool removed) {
EXPECT_FALSE(removed);
remove_latch.Signal();
});
@@ -4690,8 +4703,8 @@
// The construtor for ViewportMetrics{_, width, _, _, _} (only the 2nd
// argument matters in this test).
platform_view->SetViewportMetrics(0, ViewportMetrics{1, 10, 1, 0, 0});
- shell->AddView(1, ViewportMetrics{1, 30, 1, 0, 0},
- [](bool added) { ASSERT_TRUE(added); });
+ shell->GetPlatformView()->AddView(1, ViewportMetrics{1, 30, 1, 0, 0},
+ [](bool added) { ASSERT_TRUE(added); });
platform_view->SetViewportMetrics(0, ViewportMetrics{1, 20, 1, 0, 0});
});
@@ -4743,9 +4756,10 @@
// A view can be added and removed all before the isolate launches.
// The pending add view operation is cancelled, the view is never
// added to the Dart isolate.
- shell->AddView(123, ViewportMetrics{1, 30, 1, 0, 0},
- [](bool added) { ASSERT_FALSE(added); });
- shell->RemoveView(123, [](bool removed) { ASSERT_FALSE(removed); });
+ shell->GetPlatformView()->AddView(123, ViewportMetrics{1, 30, 1, 0, 0},
+ [](bool added) { ASSERT_FALSE(added); });
+ shell->GetPlatformView()->RemoveView(
+ 123, [](bool removed) { ASSERT_FALSE(removed); });
});
bool first_report = true;
@@ -4791,15 +4805,15 @@
auto platform_view = shell->GetPlatformView();
// Add the same view twice. The second time should fail.
- shell->AddView(123, ViewportMetrics{1, 100, 1, 0, 0},
- [](bool added) { ASSERT_TRUE(added); });
+ shell->GetPlatformView()->AddView(123, ViewportMetrics{1, 100, 1, 0, 0},
+ [](bool added) { ASSERT_TRUE(added); });
- shell->AddView(123, ViewportMetrics{1, 200, 1, 0, 0},
- [](bool added) { ASSERT_FALSE(added); });
+ shell->GetPlatformView()->AddView(123, ViewportMetrics{1, 200, 1, 0, 0},
+ [](bool added) { ASSERT_FALSE(added); });
// Add another view. Previous failures should not affect this.
- shell->AddView(456, ViewportMetrics{1, 300, 1, 0, 0},
- [](bool added) { ASSERT_TRUE(added); });
+ shell->GetPlatformView()->AddView(456, ViewportMetrics{1, 300, 1, 0, 0},
+ [](bool added) { ASSERT_TRUE(added); });
});
bool first_report = true;
diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm
index 1333ef3..2e2515e 100644
--- a/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm
+++ b/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm
@@ -23,6 +23,10 @@
void OnPlatformViewCreated(std::unique_ptr<Surface> surface) override {}
void OnPlatformViewDestroyed() override {}
void OnPlatformViewScheduleFrame() override {}
+ void OnPlatformViewAddView(int64_t view_id,
+ const ViewportMetrics& viewport_metrics,
+ AddViewCallback callback) override {}
+ void OnPlatformViewRemoveView(int64_t view_id, RemoveViewCallback callback) override {}
void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) override {}
void OnPlatformViewSetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics) override {}
const flutter::Settings& OnPlatformViewGetSettings() const override { return settings_; }
diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm
index f64a4db..aad952f 100644
--- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm
+++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm
@@ -88,6 +88,10 @@
void OnPlatformViewCreated(std::unique_ptr<Surface> surface) override {}
void OnPlatformViewDestroyed() override {}
void OnPlatformViewScheduleFrame() override {}
+ void OnPlatformViewAddView(int64_t view_id,
+ const ViewportMetrics& viewport_metrics,
+ AddViewCallback callback) override {}
+ void OnPlatformViewRemoveView(int64_t view_id, RemoveViewCallback callback) override {}
void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) override {}
void OnPlatformViewSetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics) override {}
const flutter::Settings& OnPlatformViewGetSettings() const override { return settings_; }
diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm b/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm
index dfffa7b..7d90da6 100644
--- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm
+++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm
@@ -71,6 +71,10 @@
void OnPlatformViewCreated(std::unique_ptr<Surface> surface) override {}
void OnPlatformViewDestroyed() override {}
void OnPlatformViewScheduleFrame() override {}
+ void OnPlatformViewAddView(int64_t view_id,
+ const ViewportMetrics& viewport_metrics,
+ AddViewCallback callback) override {}
+ void OnPlatformViewRemoveView(int64_t view_id, RemoveViewCallback callback) override {}
void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) override {}
void OnPlatformViewSetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics) override {}
const flutter::Settings& OnPlatformViewGetSettings() const override { return settings_; }
diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc
index 4e7da07..26214cb 100644
--- a/shell/platform/embedder/embedder.cc
+++ b/shell/platform/embedder/embedder.cc
@@ -2229,7 +2229,7 @@
return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
}
- flutter::Shell::AddViewCallback callback =
+ flutter::PlatformView::AddViewCallback callback =
[c_callback = info->add_view_callback,
user_data = info->user_data](bool added) {
FlutterAddViewResult result = {};
@@ -2239,7 +2239,8 @@
c_callback(&result);
};
- embedder_engine->GetShell().AddView(view_id, metrics, callback);
+ embedder_engine->GetShell().GetPlatformView()->AddView(view_id, metrics,
+ callback);
return kSuccess;
}
@@ -2271,7 +2272,7 @@
return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
}
- flutter::Shell::RemoveViewCallback callback =
+ flutter::PlatformView::RemoveViewCallback callback =
[c_callback = info->remove_view_callback,
user_data = info->user_data](bool removed) {
FlutterRemoveViewResult result = {};
@@ -2281,7 +2282,8 @@
c_callback(&result);
};
- embedder_engine->GetShell().RemoveView(info->view_id, callback);
+ embedder_engine->GetShell().GetPlatformView()->RemoveView(info->view_id,
+ callback);
return kSuccess;
}
diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h
index fd6d3db..41b455c 100644
--- a/shell/platform/embedder/embedder.h
+++ b/shell/platform/embedder/embedder.h
@@ -2583,8 +2583,19 @@
/// @brief Adds a view.
///
/// This is an asynchronous operation. The view should not be used
-/// until the |add_view_callback| is invoked with an `added` of
-/// `true`.
+/// until the |info.add_view_callback| is invoked with an |added|
+/// value of true. The embedder should prepare resources in advance
+/// but be ready to clean up on failure.
+///
+/// A frame is scheduled if the operation succeeds.
+///
+/// The callback is invoked on a thread managed by the engine. The
+/// embedder should re-thread if needed.
+///
+/// Attempting to add the implicit view will fail and will return
+/// kInvalidArguments. Attempting to add a view with an already
+/// existing view ID will fail, and |info.add_view_callback| will be
+/// invoked with an |added| value of false.
///
/// @param[in] engine A running engine instance.
/// @param[in] info The add view arguments. This can be deallocated
@@ -2602,8 +2613,16 @@
/// @brief Removes a view.
///
/// This is an asynchronous operation. The view's resources must not
-/// be cleaned up until the |remove_view_callback| is invoked with
-/// a |removed| value of `true`.
+/// be cleaned up until |info.remove_view_callback| is invoked with
+/// a |removed| value of true.
+///
+/// The callback is invoked on a thread managed by the engine. The
+/// embedder should re-thread if needed.
+///
+/// Attempting to remove the implicit view will fail and will return
+/// kInvalidArguments. Attempting to remove a view with a
+/// non-existent view ID will fail, and |info.remove_view_callback|
+/// will be invoked with a |removed| value of false.
///
/// @param[in] engine A running engine instance.
/// @param[in] info The remove view arguments. This can be deallocated
diff --git a/shell/platform/embedder/platform_view_embedder_unittests.cc b/shell/platform/embedder/platform_view_embedder_unittests.cc
index 6f0e923..b76c745 100644
--- a/shell/platform/embedder/platform_view_embedder_unittests.cc
+++ b/shell/platform/embedder/platform_view_embedder_unittests.cc
@@ -23,6 +23,16 @@
MOCK_METHOD(void, OnPlatformViewDestroyed, (), (override));
MOCK_METHOD(void, OnPlatformViewScheduleFrame, (), (override));
MOCK_METHOD(void,
+ OnPlatformViewAddView,
+ (int64_t view_id,
+ const ViewportMetrics& viewport_metrics,
+ AddViewCallback callback),
+ (override));
+ MOCK_METHOD(void,
+ OnPlatformViewRemoveView,
+ (int64_t view_id, RemoveViewCallback callback),
+ (override));
+ MOCK_METHOD(void,
OnPlatformViewSetNextFrameCallback,
(const fml::closure& closure),
(override));
diff --git a/shell/platform/fuchsia/flutter/tests/platform_view_unittest.cc b/shell/platform/fuchsia/flutter/tests/platform_view_unittest.cc
index b61d87b..911c618 100644
--- a/shell/platform/fuchsia/flutter/tests/platform_view_unittest.cc
+++ b/shell/platform/fuchsia/flutter/tests/platform_view_unittest.cc
@@ -88,6 +88,13 @@
// |flutter::PlatformView::Delegate|
void OnPlatformViewScheduleFrame() {}
// |flutter::PlatformView::Delegate|
+ void OnPlatformViewAddView(int64_t view_id,
+ const flutter::ViewportMetrics& viewport_metrics,
+ AddViewCallback callback) override {}
+ // |flutter::PlatformView::Delegate|
+ void OnPlatformViewRemoveView(int64_t view_id,
+ RemoveViewCallback callback) override {}
+ // |flutter::PlatformView::Delegate|
void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) {}
// |flutter::PlatformView::Delegate|
void OnPlatformViewSetViewportMetrics(