mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Update view attributes after creation (flutter/engine#20638)
This commit is contained in:
parent
2a57d6d22e
commit
a67ecd536d
@ -201,6 +201,16 @@ void SceneUpdateContext::CreateView(int64_t view_id,
|
||||
view_holder->set_focusable(focusable);
|
||||
}
|
||||
|
||||
void SceneUpdateContext::UpdateView(int64_t view_id,
|
||||
bool hit_testable,
|
||||
bool focusable) {
|
||||
auto* view_holder = ViewHolder::FromId(view_id);
|
||||
FML_DCHECK(view_holder);
|
||||
|
||||
view_holder->set_hit_testable(hit_testable);
|
||||
view_holder->set_focusable(focusable);
|
||||
}
|
||||
|
||||
void SceneUpdateContext::DestroyView(int64_t view_id) {
|
||||
ViewHolder::Destroy(view_id);
|
||||
}
|
||||
|
||||
@ -167,6 +167,7 @@ class SceneUpdateContext : public flutter::ExternalViewEmbedder {
|
||||
}
|
||||
|
||||
void CreateView(int64_t view_id, bool hit_testable, bool focusable);
|
||||
void UpdateView(int64_t view_id, bool hit_testable, bool focusable);
|
||||
void DestroyView(int64_t view_id);
|
||||
void UpdateView(int64_t view_id,
|
||||
const SkPoint& offset,
|
||||
|
||||
@ -7,6 +7,8 @@
|
||||
#include <lib/async/cpp/task.h>
|
||||
#include <zircon/status.h>
|
||||
|
||||
#include "../runtime/dart/utils/files.h"
|
||||
#include "compositor_context.h"
|
||||
#include "flutter/common/task_runners.h"
|
||||
#include "flutter/fml/make_copyable.h"
|
||||
#include "flutter/fml/synchronization/waitable_event.h"
|
||||
@ -14,14 +16,11 @@
|
||||
#include "flutter/runtime/dart_vm_lifecycle.h"
|
||||
#include "flutter/shell/common/rasterizer.h"
|
||||
#include "flutter/shell/common/run_configuration.h"
|
||||
#include "third_party/skia/include/ports/SkFontMgr_fuchsia.h"
|
||||
|
||||
#include "../runtime/dart/utils/files.h"
|
||||
#include "compositor_context.h"
|
||||
#include "flutter_runner_product_configuration.h"
|
||||
#include "fuchsia_intl.h"
|
||||
#include "platform_view.h"
|
||||
#include "task_runner_adapter.h"
|
||||
#include "third_party/skia/include/ports/SkFontMgr_fuchsia.h"
|
||||
#include "thread.h"
|
||||
|
||||
namespace flutter_runner {
|
||||
@ -146,6 +145,10 @@ Engine::Engine(Delegate& delegate,
|
||||
std::bind(&Engine::CreateView, this, std::placeholders::_1,
|
||||
std::placeholders::_2, std::placeholders::_3);
|
||||
|
||||
OnUpdateView on_update_view_callback =
|
||||
std::bind(&Engine::UpdateView, this, std::placeholders::_1,
|
||||
std::placeholders::_2, std::placeholders::_3);
|
||||
|
||||
OnDestroyView on_destroy_view_callback =
|
||||
std::bind(&Engine::DestroyView, this, std::placeholders::_1);
|
||||
|
||||
@ -182,6 +185,7 @@ Engine::Engine(Delegate& delegate,
|
||||
on_enable_wireframe_callback =
|
||||
std::move(on_enable_wireframe_callback),
|
||||
on_create_view_callback = std::move(on_create_view_callback),
|
||||
on_update_view_callback = std::move(on_update_view_callback),
|
||||
on_destroy_view_callback = std::move(on_destroy_view_callback),
|
||||
on_get_view_embedder_callback =
|
||||
std::move(on_get_view_embedder_callback),
|
||||
@ -200,6 +204,7 @@ Engine::Engine(Delegate& delegate,
|
||||
std::move(on_session_listener_error_callback),
|
||||
std::move(on_enable_wireframe_callback),
|
||||
std::move(on_create_view_callback),
|
||||
std::move(on_update_view_callback),
|
||||
std::move(on_destroy_view_callback),
|
||||
std::move(on_get_view_embedder_callback),
|
||||
std::move(on_get_gr_context_callback),
|
||||
@ -493,6 +498,17 @@ void Engine::CreateView(int64_t view_id, bool hit_testable, bool focusable) {
|
||||
});
|
||||
}
|
||||
|
||||
void Engine::UpdateView(int64_t view_id, bool hit_testable, bool focusable) {
|
||||
if (!shell_ || !scene_update_context_) {
|
||||
return;
|
||||
}
|
||||
|
||||
shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask(
|
||||
[this, view_id, hit_testable, focusable]() {
|
||||
scene_update_context_->UpdateView(view_id, hit_testable, focusable);
|
||||
});
|
||||
}
|
||||
|
||||
void Engine::DestroyView(int64_t view_id) {
|
||||
if (!shell_ || !scene_update_context_) {
|
||||
return;
|
||||
|
||||
@ -84,6 +84,7 @@ class Engine final {
|
||||
|
||||
void DebugWireframeSettingsChanged(bool enabled);
|
||||
void CreateView(int64_t view_id, bool hit_testable, bool focusable);
|
||||
void UpdateView(int64_t view_id, bool hit_testable, bool focusable);
|
||||
void DestroyView(int64_t view_id);
|
||||
|
||||
flutter::ExternalViewEmbedder* GetViewEmbedder();
|
||||
|
||||
@ -58,6 +58,7 @@ PlatformView::PlatformView(
|
||||
fit::closure session_listener_error_callback,
|
||||
OnEnableWireframe wireframe_enabled_callback,
|
||||
OnCreateView on_create_view_callback,
|
||||
OnUpdateView on_update_view_callback,
|
||||
OnDestroyView on_destroy_view_callback,
|
||||
OnGetViewEmbedder on_get_view_embedder_callback,
|
||||
OnGetGrContext on_get_gr_context_callback,
|
||||
@ -72,6 +73,7 @@ PlatformView::PlatformView(
|
||||
std::move(session_listener_error_callback)),
|
||||
wireframe_enabled_callback_(std::move(wireframe_enabled_callback)),
|
||||
on_create_view_callback_(std::move(on_create_view_callback)),
|
||||
on_update_view_callback_(std::move(on_update_view_callback)),
|
||||
on_destroy_view_callback_(std::move(on_destroy_view_callback)),
|
||||
on_get_view_embedder_callback_(std::move(on_get_view_embedder_callback)),
|
||||
on_get_gr_context_callback_(std::move(on_get_gr_context_callback)),
|
||||
@ -762,6 +764,35 @@ void PlatformView::HandleFlutterPlatformViewsChannelPlatformMessage(
|
||||
message->response()->Complete(
|
||||
std::make_unique<fml::NonOwnedMapping>((const uint8_t*)"[0]", 3u));
|
||||
}
|
||||
} else if (method->value == "View.update") {
|
||||
auto args_it = root.FindMember("args");
|
||||
if (args_it == root.MemberEnd() || !args_it->value.IsObject()) {
|
||||
FML_LOG(ERROR) << "No arguments found.";
|
||||
return;
|
||||
}
|
||||
const auto& args = args_it->value;
|
||||
|
||||
auto view_id = args.FindMember("viewId");
|
||||
if (!view_id->value.IsUint64()) {
|
||||
FML_LOG(ERROR) << "Argument 'viewId' is not a int64";
|
||||
return;
|
||||
}
|
||||
|
||||
auto hit_testable = args.FindMember("hitTestable");
|
||||
if (!hit_testable->value.IsBool()) {
|
||||
FML_LOG(ERROR) << "Argument 'hitTestable' is not a bool";
|
||||
return;
|
||||
}
|
||||
|
||||
auto focusable = args.FindMember("focusable");
|
||||
if (!focusable->value.IsBool()) {
|
||||
FML_LOG(ERROR) << "Argument 'focusable' is not a bool";
|
||||
return;
|
||||
}
|
||||
|
||||
on_update_view_callback_(view_id->value.GetUint64(),
|
||||
hit_testable->value.GetBool(),
|
||||
focusable->value.GetBool());
|
||||
} else if (method->value == "View.dispose") {
|
||||
auto args_it = root.FindMember("args");
|
||||
if (args_it == root.MemberEnd() || !args_it->value.IsObject()) {
|
||||
|
||||
@ -24,6 +24,7 @@ namespace flutter_runner {
|
||||
|
||||
using OnEnableWireframe = fit::function<void(bool)>;
|
||||
using OnCreateView = fit::function<void(int64_t, bool, bool)>;
|
||||
using OnUpdateView = fit::function<void(int64_t, bool, bool)>;
|
||||
using OnDestroyView = fit::function<void(int64_t)>;
|
||||
using OnGetViewEmbedder = fit::function<flutter::ExternalViewEmbedder*()>;
|
||||
using OnGetGrContext = fit::function<GrDirectContext*()>;
|
||||
@ -52,6 +53,7 @@ class PlatformView final : public flutter::PlatformView,
|
||||
fit::closure on_session_listener_error_callback,
|
||||
OnEnableWireframe wireframe_enabled_callback,
|
||||
OnCreateView on_create_view_callback,
|
||||
OnUpdateView on_update_view_callback,
|
||||
OnDestroyView on_destroy_view_callback,
|
||||
OnGetViewEmbedder on_get_view_embedder_callback,
|
||||
OnGetGrContext on_get_gr_context_callback,
|
||||
@ -83,6 +85,7 @@ class PlatformView final : public flutter::PlatformView,
|
||||
fit::closure session_listener_error_callback_;
|
||||
OnEnableWireframe wireframe_enabled_callback_;
|
||||
OnCreateView on_create_view_callback_;
|
||||
OnUpdateView on_update_view_callback_;
|
||||
OnDestroyView on_destroy_view_callback_;
|
||||
OnGetViewEmbedder on_get_view_embedder_callback_;
|
||||
OnGetGrContext on_get_gr_context_callback_;
|
||||
|
||||
@ -168,6 +168,7 @@ TEST_F(PlatformViewTests, ChangesAccessibilitySettings) {
|
||||
nullptr, // on_session_listener_error_callback
|
||||
nullptr, // on_enable_wireframe_callback,
|
||||
nullptr, // on_create_view_callback,
|
||||
nullptr, // on_update_view_callback,
|
||||
nullptr, // on_destroy_view_callback,
|
||||
nullptr, // on_get_view_embedder_callback,
|
||||
nullptr, // on_get_gr_context_callback,
|
||||
@ -224,6 +225,7 @@ TEST_F(PlatformViewTests, EnableWireframeTest) {
|
||||
nullptr, // on_session_listener_error_callback
|
||||
EnableWireframeCallback, // on_enable_wireframe_callback,
|
||||
nullptr, // on_create_view_callback,
|
||||
nullptr, // on_update_view_callback,
|
||||
nullptr, // on_destroy_view_callback,
|
||||
nullptr, // on_get_view_embedder_callback,
|
||||
nullptr, // on_get_gr_context_callback,
|
||||
@ -291,6 +293,7 @@ TEST_F(PlatformViewTests, CreateViewTest) {
|
||||
nullptr, // on_session_listener_error_callback
|
||||
nullptr, // on_enable_wireframe_callback,
|
||||
CreateViewCallback, // on_create_view_callback,
|
||||
nullptr, // on_update_view_callback,
|
||||
nullptr, // on_destroy_view_callback,
|
||||
nullptr, // on_get_view_embedder_callback,
|
||||
nullptr, // on_get_gr_context_callback,
|
||||
@ -326,6 +329,76 @@ TEST_F(PlatformViewTests, CreateViewTest) {
|
||||
EXPECT_TRUE(create_view_called);
|
||||
}
|
||||
|
||||
// Test to make sure that PlatformView correctly registers messages sent on
|
||||
// the "flutter/platform_views" channel, correctly parses the JSON it receives
|
||||
// and calls the UdpateViewCallback with the appropriate args.
|
||||
TEST_F(PlatformViewTests, UpdateViewTest) {
|
||||
sys::testing::ServiceDirectoryProvider services_provider(dispatcher());
|
||||
MockPlatformViewDelegate delegate;
|
||||
zx::eventpair a, b;
|
||||
zx::eventpair::create(/* flags */ 0u, &a, &b);
|
||||
auto view_ref = fuchsia::ui::views::ViewRef({
|
||||
.reference = std::move(a),
|
||||
});
|
||||
flutter::TaskRunners task_runners =
|
||||
flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr);
|
||||
|
||||
// Test wireframe callback function. If the message sent to the platform
|
||||
// view was properly handled and parsed, this function should be called,
|
||||
// setting |wireframe_enabled| to true.
|
||||
int64_t update_view_called = false;
|
||||
auto UpdateViewCallback = [&update_view_called](
|
||||
int64_t view_id, bool hit_testable,
|
||||
bool focusable) { update_view_called = true; };
|
||||
|
||||
auto platform_view = flutter_runner::PlatformView(
|
||||
delegate, // delegate
|
||||
"test_platform_view", // label
|
||||
std::move(view_ref), // view_refs
|
||||
std::move(task_runners), // task_runners
|
||||
services_provider.service_directory(), // runner_services
|
||||
nullptr, // parent_environment_service_provider_handle
|
||||
nullptr, // session_listener_request
|
||||
nullptr, // focuser,
|
||||
nullptr, // on_session_listener_error_callback
|
||||
nullptr, // on_enable_wireframe_callback,
|
||||
nullptr, // on_create_view_callback,
|
||||
UpdateViewCallback, // on_update_view_callback,
|
||||
nullptr, // on_destroy_view_callback,
|
||||
nullptr, // on_get_view_embedder_callback,
|
||||
nullptr, // on_get_gr_context_callback,
|
||||
0u, // vsync_event_handle
|
||||
{} // product_config
|
||||
);
|
||||
|
||||
// Cast platform_view to its base view so we can have access to the public
|
||||
// "HandlePlatformMessage" function.
|
||||
auto base_view = dynamic_cast<flutter::PlatformView*>(&platform_view);
|
||||
EXPECT_TRUE(base_view);
|
||||
|
||||
// JSON for the message to be passed into the PlatformView.
|
||||
const uint8_t txt[] =
|
||||
"{"
|
||||
" \"method\":\"View.update\","
|
||||
" \"args\": {"
|
||||
" \"viewId\":42,"
|
||||
" \"hitTestable\":true,"
|
||||
" \"focusable\":true"
|
||||
" }"
|
||||
"}";
|
||||
|
||||
fml::RefPtr<flutter::PlatformMessage> message =
|
||||
fml::MakeRefCounted<flutter::PlatformMessage>(
|
||||
"flutter/platform_views",
|
||||
std::vector<uint8_t>(txt, txt + sizeof(txt)),
|
||||
fml::RefPtr<flutter::PlatformMessageResponse>());
|
||||
base_view->HandlePlatformMessage(message);
|
||||
|
||||
RunLoopUntilIdle();
|
||||
|
||||
EXPECT_TRUE(update_view_called);
|
||||
}
|
||||
|
||||
// Test to make sure that PlatformView correctly registers messages sent on
|
||||
// the "flutter/platform_views" channel, correctly parses the JSON it receives
|
||||
// and calls the DestroyViewCallback with the appropriate args.
|
||||
@ -360,6 +433,7 @@ TEST_F(PlatformViewTests, DestroyViewTest) {
|
||||
nullptr, // on_session_listener_error_callback
|
||||
nullptr, // on_enable_wireframe_callback,
|
||||
nullptr, // on_create_view_callback,
|
||||
nullptr, // on_update_view_callback,
|
||||
DestroyViewCallback, // on_destroy_view_callback,
|
||||
nullptr, // on_get_view_embedder_callback,
|
||||
nullptr, // on_get_gr_context_callback,
|
||||
@ -423,6 +497,7 @@ TEST_F(PlatformViewTests, RequestFocusTest) {
|
||||
nullptr, // on_session_listener_error_callback
|
||||
nullptr, // on_enable_wireframe_callback,
|
||||
nullptr, // on_create_view_callback,
|
||||
nullptr, // on_update_view_callback,
|
||||
nullptr, // on_destroy_view_callback,
|
||||
nullptr, // on_get_gr_context_callback,
|
||||
nullptr, // on_get_view_embedder_callback,
|
||||
@ -493,6 +568,7 @@ TEST_F(PlatformViewTests, GetViewEmbedderTest) {
|
||||
nullptr, // on_session_listener_error_callback
|
||||
nullptr, // on_enable_wireframe_callback,
|
||||
nullptr, // on_create_view_callback,
|
||||
nullptr, // on_update_view_callback,
|
||||
nullptr, // on_destroy_view_callback,
|
||||
GetViewEmbedderCallback, // on_get_view_embedder_callback,
|
||||
nullptr, // on_get_gr_context_callback,
|
||||
@ -547,6 +623,7 @@ TEST_F(PlatformViewTests, GetGrContextTest) {
|
||||
nullptr, // on_session_listener_error_callback
|
||||
nullptr, // on_enable_wireframe_callback,
|
||||
nullptr, // on_create_view_callback,
|
||||
nullptr, // on_update_view_callback,
|
||||
nullptr, // on_destroy_view_callback,
|
||||
nullptr, // on_get_view_embedder_callback,
|
||||
GetGrContextCallback, // on_get_gr_context_callback,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user