From 952f87a34ffe6ef40a712c6769bcccd5f6ba5362 Mon Sep 17 00:00:00 2001 From: Darren Chan Date: Fri, 25 Jun 2021 20:11:22 +0000 Subject: [PATCH] [refactor] Migrate to View.focus.*. This allows us to better encapsulate our platform_view delegates' responsibilities. This fixes https://fxbug.dev/79740. --- .../fuchsia/flutter/focus_delegate.cc | 79 +++++--- .../platform/fuchsia/flutter/focus_delegate.h | 36 +++- .../flutter/focus_delegate_unittests.cc | 129 +++++++++++++- .../platform/fuchsia/flutter/platform_view.cc | 24 +-- .../fuchsia/flutter/platform_view_unittest.cc | 168 +++++++++++++++++- 5 files changed, 385 insertions(+), 51 deletions(-) diff --git a/shell/platform/fuchsia/flutter/focus_delegate.cc b/shell/platform/fuchsia/flutter/focus_delegate.cc index e1169c2eaab4f..5fa339273a3ac 100644 --- a/shell/platform/fuchsia/flutter/focus_delegate.cc +++ b/shell/platform/fuchsia/flutter/focus_delegate.cc @@ -16,33 +16,49 @@ void FocusDelegate::WatchLoop(std::function callback) { watch_loop_ = [this, callback = std::move(callback)](auto focus_state) { callback(is_focused_ = focus_state.focused()); - if (next_focus_request_) { - CompleteCurrentFocusState(std::exchange(next_focus_request_, nullptr)); - } + Complete(std::exchange(next_focus_request_, nullptr), + is_focused_ ? "[true]" : "[false]"); view_ref_focused_->Watch(watch_loop_); }; view_ref_focused_->Watch(watch_loop_); } -bool FocusDelegate::CompleteCurrentFocusState( +bool FocusDelegate::HandlePlatformMessage( + rapidjson::Value request, fml::RefPtr response) { - std::string result(is_focused_ ? "[true]" : "[false]"); - response->Complete(std::make_unique( - std::vector(result.begin(), result.end()))); - return true; -} + auto method = request.FindMember("method"); + if (method == request.MemberEnd() || !method->value.IsString()) { + return false; + } -bool FocusDelegate::CompleteNextFocusState( - fml::RefPtr response) { - if (next_focus_request_) { - FML_LOG(ERROR) << "An outstanding PlatformMessageResponse already exists " - "for the next focus state!"; + if (method->value == "View.focus.getCurrent") { + Complete(std::move(response), is_focused_ ? "[true]" : "[false]"); + } else if (method->value == "View.focus.getNext") { + if (next_focus_request_) { + FML_LOG(ERROR) << "An outstanding PlatformMessageResponse already exists " + "for the next focus state!"; + Complete(std::move(response), "[null]"); + } else { + next_focus_request_ = std::move(response); + } + } else if (method->value == "View.focus.request") { + return RequestFocus(std::move(request), std::move(response)); + } else { return false; } - next_focus_request_ = std::move(response); + // All of our methods complete the platform message response. return true; } +void FocusDelegate::Complete( + fml::RefPtr response, + std::string value) { + if (response) { + response->Complete(std::make_unique( + std::vector(value.begin(), value.end()))); + } +} + bool FocusDelegate::RequestFocus( rapidjson::Value request, fml::RefPtr response) { @@ -55,7 +71,7 @@ bool FocusDelegate::RequestFocus( auto view_ref = args.FindMember("viewRef"); if (!view_ref->value.IsUint64()) { - FML_LOG(ERROR) << "Argument 'viewRef' is not a int64"; + FML_LOG(ERROR) << "Argument 'viewRef' is not a uint64"; return false; } @@ -72,25 +88,36 @@ bool FocusDelegate::RequestFocus( }); focuser_->RequestFocus( std::move(ref), - [view_ref = view_ref->value.GetUint64(), response = std::move(response)]( + [this, response = std::move(response)]( fuchsia::ui::views::Focuser_RequestFocus_Result result) { - if (!response) { - return; - } int result_code = result.is_err() ? static_cast< std::underlying_type_t>( result.err()) : 0; - - std::ostringstream out; - out << "[" << result_code << "]"; - std::string output = out.str(); - response->Complete(std::make_unique( - std::vector(output.begin(), output.end()))); + Complete(std::move(response), "[" + std::to_string(result_code) + "]"); }); return true; } +bool FocusDelegate::CompleteCurrentFocusState( + fml::RefPtr response) { + std::string result(is_focused_ ? "[true]" : "[false]"); + response->Complete(std::make_unique( + std::vector(result.begin(), result.end()))); + return true; +} + +bool FocusDelegate::CompleteNextFocusState( + fml::RefPtr response) { + if (next_focus_request_) { + FML_LOG(ERROR) << "An outstanding PlatformMessageResponse already exists " + "for the next focus state!"; + return false; + } + next_focus_request_ = std::move(response); + return true; +} + } // namespace flutter_runner diff --git a/shell/platform/fuchsia/flutter/focus_delegate.h b/shell/platform/fuchsia/flutter/focus_delegate.h index 3373f2d6714ed..324302fe7d933 100644 --- a/shell/platform/fuchsia/flutter/focus_delegate.h +++ b/shell/platform/fuchsia/flutter/focus_delegate.h @@ -21,17 +21,34 @@ class FocusDelegate { fidl::InterfaceHandle focuser) : view_ref_focused_(view_ref_focused.Bind()), focuser_(focuser.Bind()) {} - virtual ~FocusDelegate() = default; - /// Continuously watches the host viewRef for focus events, invoking a /// callback each time. /// /// This can only be called once. - virtual void WatchLoop(std::function callback); + void WatchLoop(std::function callback); + + /// Handles the following focus-related platform message requests: + /// View.focus.getCurrent + /// - Completes with the FocusDelegate's most recent focus state, either + /// [true] or [false]. + /// View.focus.getNext + /// - Completes with the FocusDelegate's next focus state, either [true] or + /// [false]. + /// - Only one outstanding request may exist at a time. Any others will be + /// completed with [null]. + /// View.focus.request + /// - Attempts to give focus for a given viewRef. Completes with [0] on + /// success, or [fuchsia::ui::views::Error] on failure. + /// + /// Returns false if a malformed/invalid request needs to be completed empty. + bool HandlePlatformMessage( + rapidjson::Value request, + fml::RefPtr response); /// Completes the platform message request with the FocusDelegate's most /// recent focus state. - virtual bool CompleteCurrentFocusState( + // TODO(fxbug.dev/79740): Delete after soft transition. + bool CompleteCurrentFocusState( fml::RefPtr response); /// Completes the platform message request with the FocusDelegate's next focus @@ -39,14 +56,15 @@ class FocusDelegate { /// /// Only one outstanding request may exist at a time. Any others will be /// completed empty. - virtual bool CompleteNextFocusState( + // TODO(fxbug.dev/79740): Delete after soft transition. + bool CompleteNextFocusState( fml::RefPtr response); /// Completes a platform message request by attempting to give focus for a /// given viewRef. - virtual bool RequestFocus( - rapidjson::Value request, - fml::RefPtr response); + // TODO(fxbug.dev/79740): Make private after soft transition. + bool RequestFocus(rapidjson::Value request, + fml::RefPtr response); private: fuchsia::ui::views::ViewRefFocusedPtr view_ref_focused_; @@ -57,7 +75,7 @@ class FocusDelegate { fml::RefPtr next_focus_request_; void Complete(fml::RefPtr response, - bool value); + std::string value); FML_DISALLOW_COPY_AND_ASSIGN(FocusDelegate); }; diff --git a/shell/platform/fuchsia/flutter/focus_delegate_unittests.cc b/shell/platform/fuchsia/flutter/focus_delegate_unittests.cc index bec0122dec0d8..5ea00992dd42b 100644 --- a/shell/platform/fuchsia/flutter/focus_delegate_unittests.cc +++ b/shell/platform/fuchsia/flutter/focus_delegate_unittests.cc @@ -64,6 +64,129 @@ class FocusDelegateTest : public ::testing::Test { // Tests that WatchLoop() should callback and complete PlatformMessageResponses // correctly, given a series of vrf invocations. TEST_F(FocusDelegateTest, WatchCallbackSeries) { + std::vector vrf_states{false, true, true, false, + true, false, true, true}; + std::size_t vrf_index = 0; + std::size_t callback_index = 0; + focus_delegate->WatchLoop([&](bool focus_state) { + // Make sure the focus state that FocusDelegate gives us is consistent with + // what was fired from the vrf. + EXPECT_EQ(vrf_states[callback_index], focus_state); + + // View.focus.getCurrent should complete with the current (up to date) focus + // state. + auto response = FakePlatformMessageResponse::Create(); + EXPECT_TRUE(focus_delegate->HandlePlatformMessage( + ParsePlatformMessage("{\"method\":\"View.focus.getCurrent\"}"), + response)); + response->ExpectCompleted(focus_state ? "[true]" : "[false]"); + + // Ensure this callback always happens in lockstep with + // vrf->ScheduleCallback. + EXPECT_EQ(vrf_index, callback_index++); + }); + + // Subsequent WatchLoop calls should not be respected. + focus_delegate->WatchLoop([](bool _) { + ADD_FAILURE() << "Subsequent WatchLoops should not be respected!"; + }); + + do { + // Ensure the next focus state is handled correctly. + auto response1 = FakePlatformMessageResponse::Create(); + EXPECT_TRUE(focus_delegate->HandlePlatformMessage( + ParsePlatformMessage("{\"method\":\"View.focus.getNext\"}"), + response1)); + + // Since there's already an outstanding PlatformMessageResponse, this one + // should be completed null. + auto response2 = FakePlatformMessageResponse::Create(); + EXPECT_TRUE(focus_delegate->HandlePlatformMessage( + ParsePlatformMessage("{\"method\":\"View.focus.getNext\"}"), + response2)); + response2->ExpectCompleted("[null]"); + + // Post watch events and trigger the next vrf event. + RunLoopUntilIdle(); + vrf->ScheduleCallback(vrf_states[vrf_index]); + RunLoopUntilIdle(); + + // Next focus state should be completed by now. + response1->ExpectCompleted(vrf_states[vrf_index] ? "[true]" : "[false]"); + + // Check View.focus.getCurrent again, and increment vrf_index since we move + // on to the next focus state. + auto response3 = FakePlatformMessageResponse::Create(); + EXPECT_TRUE(focus_delegate->HandlePlatformMessage( + ParsePlatformMessage("{\"method\":\"View.focus.getCurrent\"}"), + response3)); + response3->ExpectCompleted(vrf_states[vrf_index++] ? "[true]" : "[false]"); + + // vrf->times_watched should always be 1 more than the amount of vrf events + // emitted. + EXPECT_EQ(vrf_index + 1, vrf->times_watched); + } while (vrf_index < vrf_states.size()); +} + +// Tests that HandlePlatformMessage() completes a "View.focus.request" response +// with a non-error status code. +TEST_F(FocusDelegateTest, RequestFocusTest) { + // This "Mock" ViewRef serves as the target for the RequestFocus operation. + auto mock_view_ref_pair = scenic::ViewRefPair::New(); + // Create the platform message request. + std::ostringstream message; + message << "{" + << " \"method\":\"View.focus.request\"," + << " \"args\": {" + << " \"viewRef\":" + << mock_view_ref_pair.view_ref.reference.get() << " }" + << "}"; + + // Dispatch the plaform message request with an expected completion response. + auto response = FakePlatformMessageResponse::Create(); + EXPECT_TRUE(focus_delegate->HandlePlatformMessage( + ParsePlatformMessage(message.str()), response)); + RunLoopUntilIdle(); + + response->ExpectCompleted("[0]"); + EXPECT_TRUE(focuser->request_focus_called()); +} + +// Tests that HandlePlatformMessage() completes a "View.focus.request" response +// with a Error::DENIED status code. +TEST_F(FocusDelegateTest, RequestFocusFailTest) { + // This "Mock" ViewRef serves as the target for the RequestFocus operation. + auto mock_view_ref_pair = scenic::ViewRefPair::New(); + // We're testing the focus failure case. + focuser->fail_request_focus(); + // Create the platform message request. + std::ostringstream message; + message << "{" + << " \"method\":\"View.focus.request\"," + << " \"args\": {" + << " \"viewRef\":" + << mock_view_ref_pair.view_ref.reference.get() << " }" + << "}"; + + // Dispatch the plaform message request with an expected completion response. + auto response = FakePlatformMessageResponse::Create(); + EXPECT_TRUE(focus_delegate->HandlePlatformMessage( + ParsePlatformMessage(message.str()), response)); + RunLoopUntilIdle(); + + response->ExpectCompleted( + "[" + + std::to_string( + static_cast>( + fuchsia::ui::views::Error::DENIED)) + + "]"); + EXPECT_TRUE(focuser->request_focus_called()); +} + +// Tests that WatchLoop() should callback and complete PlatformMessageResponses +// correctly, given a series of vrf invocations. +// TODO(fxbug.dev/79740): Delete after soft transition. +TEST_F(FocusDelegateTest, DeprecatedWatchCallbackSeries) { std::vector vrf_states{false, true, true, false, true, false, true, true}; std::size_t vrf_index = 0; @@ -121,7 +244,8 @@ TEST_F(FocusDelegateTest, WatchCallbackSeries) { // Tests that RequestFocus() completes the platform message's response with a // non-error status code. -TEST_F(FocusDelegateTest, RequestFocusTest) { +// TODO(fxbug.dev/79740): Delete after soft transition. +TEST_F(FocusDelegateTest, DeprecatedRequestFocusTest) { // This "Mock" ViewRef serves as the target for the RequestFocus operation. auto mock_view_ref_pair = scenic::ViewRefPair::New(); // Create the platform message request. @@ -144,7 +268,8 @@ TEST_F(FocusDelegateTest, RequestFocusTest) { // Tests that RequestFocus() completes the platform message's response with a // Error::DENIED status code. -TEST_F(FocusDelegateTest, RequestFocusFailTest) { +// TODO(fxbug.dev/79740): Delete after soft transition. +TEST_F(FocusDelegateTest, DeprecatedRequestFocusFailTest) { // This "Mock" ViewRef serves as the target for the RequestFocus operation. auto mock_view_ref_pair = scenic::ViewRefPair::New(); // We're testing the focus failure case. diff --git a/shell/platform/fuchsia/flutter/platform_view.cc b/shell/platform/fuchsia/flutter/platform_view.cc index c20165fbd2a41..2849e918bbe3d 100644 --- a/shell/platform/fuchsia/flutter/platform_view.cc +++ b/shell/platform/fuchsia/flutter/platform_view.cc @@ -909,12 +909,13 @@ bool PlatformView::HandleFlutterPlatformViewsChannelPlatformMessage( return false; } auto root = document.GetObject(); - auto method = root.FindMember("method"); - if (method == root.MemberEnd() || !method->value.IsString()) { + auto method_member = root.FindMember("method"); + if (method_member == root.MemberEnd() || !method_member->value.IsString()) { return false; } + std::string method(method_member->value.GetString()); - if (method->value == "View.enableWireframe") { + if (method == "View.enableWireframe") { auto args_it = root.FindMember("args"); if (args_it == root.MemberEnd() || !args_it->value.IsObject()) { FML_LOG(ERROR) << "No arguments found."; @@ -929,7 +930,7 @@ bool PlatformView::HandleFlutterPlatformViewsChannelPlatformMessage( } wireframe_enabled_callback_(enable->value.GetBool()); - } else if (method->value == "View.create") { + } else if (method == "View.create") { auto args_it = root.FindMember("args"); if (args_it == root.MemberEnd() || !args_it->value.IsObject()) { FML_LOG(ERROR) << "No arguments found."; @@ -988,7 +989,7 @@ bool PlatformView::HandleFlutterPlatformViewsChannelPlatformMessage( view_id_raw, std::move(on_view_created), std::move(on_view_bound), hit_testable->value.GetBool(), focusable->value.GetBool()); return true; - } else if (method->value == "View.update") { + } else if (method == "View.update") { auto args_it = root.FindMember("args"); if (args_it == root.MemberEnd() || !args_it->value.IsObject()) { FML_LOG(ERROR) << "No arguments found."; @@ -1055,7 +1056,7 @@ bool PlatformView::HandleFlutterPlatformViewsChannelPlatformMessage( on_update_view_callback_( view_id->value.GetUint64(), view_occlusion_hint_raw, hit_testable->value.GetBool(), focusable->value.GetBool()); - } else if (method->value == "View.dispose") { + } else if (method == "View.dispose") { auto args_it = root.FindMember("args"); if (args_it == root.MemberEnd() || !args_it->value.IsObject()) { FML_LOG(ERROR) << "No arguments found."; @@ -1087,15 +1088,16 @@ bool PlatformView::HandleFlutterPlatformViewsChannelPlatformMessage( }); }; on_destroy_view_callback_(view_id_raw, std::move(on_view_unbound)); - } else if (method->value == "HostView.getCurrentFocusState") { + } else if (method.rfind("View.focus", 0) == 0) { + return focus_delegate_->HandlePlatformMessage(root, message->response()); + } else if (method == "HostView.getCurrentFocusState") { return focus_delegate_->CompleteCurrentFocusState(message->response()); - } else if (method->value == "HostView.getNextFocusState") { + } else if (method == "HostView.getNextFocusState") { return focus_delegate_->CompleteNextFocusState(message->response()); - } else if (method->value == "View.requestFocus") { + } else if (method == "View.requestFocus") { return focus_delegate_->RequestFocus(root, message->response()); } else { - FML_DLOG(ERROR) << "Unknown " << message->channel() << " method " - << method->value.GetString(); + FML_DLOG(ERROR) << "Unknown " << message->channel() << " method " << method; } // Complete with an empty response by default. return false; diff --git a/shell/platform/fuchsia/flutter/platform_view_unittest.cc b/shell/platform/fuchsia/flutter/platform_view_unittest.cc index 0f29da88c211d..56da3ce857fac 100644 --- a/shell/platform/fuchsia/flutter/platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/platform_view_unittest.cc @@ -1017,10 +1017,170 @@ TEST_F(PlatformViewTests, ViewEventsTest) { ToString(view_state_changed_msg->data())); } +// This test makes sure that the PlatformView forwards messages on the +// "flutter/platform_views" channel for View.focus.getCurrent and +// View.focus.getNext. +TEST_F(PlatformViewTests, GetFocusStatesTest) { + sys::testing::ServiceDirectoryProvider services_provider(dispatcher()); + MockPlatformViewDelegate delegate; + flutter::TaskRunners task_runners = + flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr); + + FakeViewRefFocused vrf; + fidl::BindingSet vrf_bindings; + auto vrf_handle = vrf_bindings.AddBinding(&vrf); + + flutter_runner::PlatformView platform_view = + PlatformViewBuilder(delegate, std::move(task_runners), + services_provider.service_directory()) + .SetViewRefFocused(std::move(vrf_handle)) + .Build(); + + // Cast platform_view to its base view so we can have access to the public + // "HandlePlatformMessage" function. + auto base_view = static_cast(&platform_view); + EXPECT_TRUE(base_view); + + std::vector vrf_states{false, true, true, false, + true, false, true, true}; + + for (std::size_t i = 0; i < vrf_states.size(); ++i) { + // View.focus.getNext should complete with the next focus state. + auto response1 = FakePlatformMessageResponse::Create(); + base_view->HandlePlatformMessage(response1->WithMessage( + "flutter/platform_views", "{\"method\":\"View.focus.getNext\"}")); + // Duplicate View.focus.getNext requests should complete empty. + auto response2 = FakePlatformMessageResponse::Create(); + base_view->HandlePlatformMessage(response2->WithMessage( + "flutter/platform_views", "{\"method\":\"View.focus.getNext\"}")); + + // Post watch events and make sure the hanging get is invoked each time. + RunLoopUntilIdle(); + EXPECT_EQ(vrf.times_watched, i + 1); + + // Dispatch the next vrf event. + vrf.ScheduleCallback(vrf_states[i]); + RunLoopUntilIdle(); + + // Make sure View.focus.getCurrent completes with the current focus state. + auto response3 = FakePlatformMessageResponse::Create(); + base_view->HandlePlatformMessage(response3->WithMessage( + "flutter/platform_views", "{\"method\":\"View.focus.getCurrent\"}")); + // Duplicate View.focus.getCurrent are allowed. + auto response4 = FakePlatformMessageResponse::Create(); + base_view->HandlePlatformMessage(response4->WithMessage( + "flutter/platform_views", "{\"method\":\"View.focus.getCurrent\"}")); + + // Run event loop and check our results. + RunLoopUntilIdle(); + response1->ExpectCompleted(vrf_states[i] ? "[true]" : "[false]"); + response2->ExpectCompleted("[null]"); + response3->ExpectCompleted(vrf_states[i] ? "[true]" : "[false]"); + response4->ExpectCompleted(vrf_states[i] ? "[true]" : "[false]"); + } +} + +// This test makes sure that the PlatformView forwards messages on the +// "flutter/platform_views" channel for View.focus.request. +TEST_F(PlatformViewTests, RequestFocusTest) { + sys::testing::ServiceDirectoryProvider services_provider(dispatcher()); + MockPlatformViewDelegate delegate; + flutter::TaskRunners task_runners = + flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr); + + FakeFocuser focuser; + fidl::BindingSet focuser_bindings; + auto focuser_handle = focuser_bindings.AddBinding(&focuser); + + flutter_runner::PlatformView platform_view = + PlatformViewBuilder(delegate, std::move(task_runners), + services_provider.service_directory()) + .SetFocuser(std::move(focuser_handle)) + .Build(); + + // Cast platform_view to its base view so we can have access to the public + // "HandlePlatformMessage" function. + auto base_view = static_cast(&platform_view); + EXPECT_TRUE(base_view); + + // This "Mock" ViewRef serves as the target for the RequestFocus operation. + auto mock_view_ref_pair = scenic::ViewRefPair::New(); + + // JSON for the message to be passed into the PlatformView. + std::ostringstream message; + message << "{" + << " \"method\":\"View.focus.request\"," + << " \"args\": {" + << " \"viewRef\":" + << mock_view_ref_pair.view_ref.reference.get() << " }" + << "}"; + + // Dispatch the plaform message request. + auto response = FakePlatformMessageResponse::Create(); + base_view->HandlePlatformMessage( + response->WithMessage("flutter/platform_views", message.str())); + RunLoopUntilIdle(); + + response->ExpectCompleted("[0]"); + EXPECT_TRUE(focuser.request_focus_called()); +} + +// This test makes sure that the PlatformView correctly replies with an error +// response when a View.focus.request call fails. +TEST_F(PlatformViewTests, RequestFocusFailTest) { + sys::testing::ServiceDirectoryProvider services_provider(dispatcher()); + MockPlatformViewDelegate delegate; + flutter::TaskRunners task_runners = + flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr); + + FakeFocuser focuser; + focuser.fail_request_focus(); + fidl::BindingSet focuser_bindings; + auto focuser_handle = focuser_bindings.AddBinding(&focuser); + + flutter_runner::PlatformView platform_view = + PlatformViewBuilder(delegate, std::move(task_runners), + services_provider.service_directory()) + .SetFocuser(std::move(focuser_handle)) + .Build(); + + // Cast platform_view to its base view so we can have access to the public + // "HandlePlatformMessage" function. + auto base_view = static_cast(&platform_view); + EXPECT_TRUE(base_view); + + // This "Mock" ViewRef serves as the target for the RequestFocus operation. + auto mock_view_ref_pair = scenic::ViewRefPair::New(); + + // JSON for the message to be passed into the PlatformView. + std::ostringstream message; + message << "{" + << " \"method\":\"View.focus.request\"," + << " \"args\": {" + << " \"viewRef\":" + << mock_view_ref_pair.view_ref.reference.get() << " }" + << "}"; + + // Dispatch the plaform message request. + auto response = FakePlatformMessageResponse::Create(); + base_view->HandlePlatformMessage( + response->WithMessage("flutter/platform_views", message.str())); + RunLoopUntilIdle(); + + response->ExpectCompleted( + "[" + + std::to_string( + static_cast>( + fuchsia::ui::views::Error::DENIED)) + + "]"); + EXPECT_TRUE(focuser.request_focus_called()); +} + // This test makes sure that the PlatformView forwards messages on the // "flutter/platform_views" channel for GetCurrentFocusState and // GetNextFocusState. -TEST_F(PlatformViewTests, GetFocusStatesTest) { +// TODO(fxbug.dev/79740): Delete after soft transition. +TEST_F(PlatformViewTests, DeprecatedGetFocusStatesTest) { sys::testing::ServiceDirectoryProvider services_provider(dispatcher()); MockPlatformViewDelegate delegate; flutter::TaskRunners task_runners = @@ -1087,7 +1247,8 @@ TEST_F(PlatformViewTests, GetFocusStatesTest) { // This test makes sure that the PlatformView forwards messages on the // "flutter/platform_views" channel for RequestFocus. -TEST_F(PlatformViewTests, RequestFocusTest) { +// TODO(fxbug.dev/79740): Delete after soft transition. +TEST_F(PlatformViewTests, DeprecatedRequestFocusTest) { sys::testing::ServiceDirectoryProvider services_provider(dispatcher()); MockPlatformViewDelegate delegate; flutter::TaskRunners task_runners = @@ -1132,7 +1293,8 @@ TEST_F(PlatformViewTests, RequestFocusTest) { // This test makes sure that the PlatformView correctly replies with an error // response when a RequestFocus call fails. -TEST_F(PlatformViewTests, RequestFocusFailTest) { +// TODO(fxbug.dev/79740): Delete after soft transition. +TEST_F(PlatformViewTests, DeprecatedRequestFocusFailTest) { sys::testing::ServiceDirectoryProvider services_provider(dispatcher()); MockPlatformViewDelegate delegate; flutter::TaskRunners task_runners =