Skip to content

Commit

Permalink
Revert 29789 revert 29542 freiling view ref (flutter#29793)
Browse files Browse the repository at this point in the history
  • Loading branch information
godofredoc committed Nov 17, 2021
1 parent 29ea28d commit c30375b
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 29 deletions.
30 changes: 28 additions & 2 deletions shell/platform/fuchsia/flutter/flatland_platform_view.cc
Expand Up @@ -136,6 +136,21 @@ void FlatlandPlatformView::OnChildViewStatus(
});
}

void FlatlandPlatformView::OnChildViewViewRef(
uint64_t content_id,
uint64_t view_id,
fuchsia::ui::views::ViewRef view_ref) {
FML_CHECK(child_view_info_.count(content_id) == 1);

focus_delegate_->OnChildViewViewRef(view_id, std::move(view_ref));

child_view_info_.at(content_id)
.child_view_watcher->GetViewRef(
[this, content_id, view_id](fuchsia::ui::views::ViewRef view_ref) {
this->OnChildViewViewRef(content_id, view_id, std::move(view_ref));
});
}

void FlatlandPlatformView::OnCreateView(ViewCallback on_view_created,
int64_t view_id_raw,
bool hit_testable,
Expand All @@ -147,10 +162,15 @@ void FlatlandPlatformView::OnCreateView(ViewCallback on_view_created,
fuchsia::ui::composition::ContentId content_id,
fuchsia::ui::composition::ChildViewWatcherPtr
child_view_watcher) {
FML_CHECK(weak);
FML_CHECK(weak->child_view_info_.count(content_id.value) == 0);
FML_CHECK(child_view_watcher);

child_view_watcher.set_error_handler([](zx_status_t status) {
FML_LOG(ERROR) << "Interface error on: ChildViewWatcher status: "
<< status;
});

platform_task_runner->PostTask(
fml::MakeCopyable([weak, view_id, content_id,
watcher = std::move(child_view_watcher)]() mutable {
Expand All @@ -161,8 +181,6 @@ void FlatlandPlatformView::OnCreateView(ViewCallback on_view_created,
return;
}

FML_DCHECK(weak->child_view_info_.count(content_id.value) == 0);
FML_DCHECK(watcher);
weak->child_view_info_.emplace(
std::piecewise_construct, std::forward_as_tuple(content_id.value),
std::forward_as_tuple(view_id, std::move(watcher)));
Expand All @@ -173,6 +191,14 @@ void FlatlandPlatformView::OnCreateView(ViewCallback on_view_created,
fuchsia::ui::composition::ChildViewStatus status) {
weak->OnChildViewStatus(id, status);
});

weak->child_view_info_.at(content_id.value)
.child_view_watcher->GetViewRef(
[weak, content_id = content_id.value,
view_id](fuchsia::ui::views::ViewRef view_ref) {
weak->OnChildViewViewRef(content_id, view_id,
std::move(view_ref));
});
}));
};
on_create_view_callback_(view_id_raw, std::move(on_view_created),
Expand Down
3 changes: 3 additions & 0 deletions shell/platform/fuchsia/flutter/flatland_platform_view.h
Expand Up @@ -53,6 +53,9 @@ class FlatlandPlatformView final : public flutter_runner::PlatformView {
fuchsia::ui::composition::ParentViewportStatus status);
void OnChildViewStatus(uint64_t content_id,
fuchsia::ui::composition::ChildViewStatus status);
void OnChildViewViewRef(uint64_t content_id,
uint64_t view_id,
fuchsia::ui::views::ViewRef view_ref);

private:
void OnCreateView(ViewCallback on_view_created,
Expand Down
90 changes: 66 additions & 24 deletions shell/platform/fuchsia/flutter/focus_delegate.cc
Expand Up @@ -43,14 +43,67 @@ bool FocusDelegate::HandlePlatformMessage(
next_focus_request_ = std::move(response);
}
} else if (method->value == "View.focus.request") {
return RequestFocus(std::move(request), std::move(response));
auto args_it = request.FindMember("args");
if (args_it == request.MemberEnd() || !args_it->value.IsObject()) {
FML_LOG(ERROR) << "No arguments found.";
return false;
}
const auto& args = args_it->value;

auto view_ref = args.FindMember("viewRef");
if (!view_ref->value.IsUint64()) {
FML_LOG(ERROR) << "Argument 'viewRef' is not a uint64";
return false;
}

zx_handle_t handle = view_ref->value.GetUint64();
zx_handle_t out_handle;
zx_status_t status =
zx_handle_duplicate(handle, ZX_RIGHT_SAME_RIGHTS, &out_handle);
if (status != ZX_OK) {
FML_LOG(ERROR) << "Argument 'viewRef' is not valid";
return false;
}
auto ref = fuchsia::ui::views::ViewRef({
.reference = zx::eventpair(out_handle),
});
return RequestFocusByViewRef(std::move(ref), std::move(response));

} else if (method->value == "View.focus.requestById") {
auto args_it = request.FindMember("args");
if (args_it == request.MemberEnd() || !args_it->value.IsObject()) {
FML_LOG(ERROR) << "No arguments found.";
return false;
}
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 uint64";
return false;
}

auto id = view_id->value.GetUint64();
if (child_view_view_refs_.count(id) != 1) {
FML_LOG(ERROR) << "Argument 'viewId' (" << id
<< ") does not refer to a valid ChildView";
return false;
}

return RequestFocusById(id, std::move(response));
} else {
return false;
}
// All of our methods complete the platform message response.
return true;
}

void FocusDelegate::OnChildViewViewRef(uint64_t view_id,
fuchsia::ui::views::ViewRef view_ref) {
FML_CHECK(child_view_view_refs_.count(view_id) == 0);
child_view_view_refs_[view_id] = std::move(view_ref);
}

void FocusDelegate::Complete(
fml::RefPtr<flutter::PlatformMessageResponse> response,
std::string value) {
Expand All @@ -60,35 +113,24 @@ void FocusDelegate::Complete(
}
}

bool FocusDelegate::RequestFocus(
rapidjson::Value request,
bool FocusDelegate::RequestFocusById(
uint64_t view_id,
fml::RefPtr<flutter::PlatformMessageResponse> response) {
auto args_it = request.FindMember("args");
if (args_it == request.MemberEnd() || !args_it->value.IsObject()) {
FML_LOG(ERROR) << "No arguments found.";
fuchsia::ui::views::ViewRef ref;
auto status = child_view_view_refs_[view_id].Clone(&ref);
if (status != ZX_OK) {
FML_LOG(ERROR) << "Failed to clone ViewRef";
return false;
}
const auto& args = args_it->value;

auto view_ref = args.FindMember("viewRef");
if (!view_ref->value.IsUint64()) {
FML_LOG(ERROR) << "Argument 'viewRef' is not a uint64";
return false;
}
return RequestFocusByViewRef(std::move(ref), std::move(response));
}

zx_handle_t handle = view_ref->value.GetUint64();
zx_handle_t out_handle;
zx_status_t status =
zx_handle_duplicate(handle, ZX_RIGHT_SAME_RIGHTS, &out_handle);
if (status != ZX_OK) {
FML_LOG(ERROR) << "Argument 'viewRef' is not valid";
return false;
}
auto ref = fuchsia::ui::views::ViewRef({
.reference = zx::eventpair(out_handle),
});
bool FocusDelegate::RequestFocusByViewRef(
fuchsia::ui::views::ViewRef view_ref,
fml::RefPtr<flutter::PlatformMessageResponse> response) {
focuser_->RequestFocus(
std::move(ref),
std::move(view_ref),
[this, response = std::move(response)](
fuchsia::ui::views::Focuser_RequestFocus_Result result) {
int result_code =
Expand Down
18 changes: 15 additions & 3 deletions shell/platform/fuchsia/flutter/focus_delegate.h
Expand Up @@ -8,6 +8,8 @@
#include <fuchsia/sys/cpp/fidl.h>
#include <fuchsia/ui/views/cpp/fidl.h>

#include <unordered_map>

#include "flutter/fml/macros.h"
#include "flutter/lib/ui/window/platform_message.h"
#include "third_party/rapidjson/include/rapidjson/document.h"
Expand Down Expand Up @@ -48,10 +50,17 @@ class FocusDelegate {
rapidjson::Value request,
fml::RefPtr<flutter::PlatformMessageResponse> response);

void OnChildViewViewRef(uint64_t view_id,
fuchsia::ui::views::ViewRef view_ref);

private:
fuchsia::ui::views::ViewRefFocusedPtr view_ref_focused_;
fuchsia::ui::views::FocuserPtr focuser_;

std::unordered_map<uint64_t /*fuchsia::ui::composition::ContentId*/,
fuchsia::ui::views::ViewRef>
child_view_view_refs_;

std::function<void(fuchsia::ui::views::FocusState)> watch_loop_;
bool is_focused_ = false;
fml::RefPtr<flutter::PlatformMessageResponse> next_focus_request_;
Expand All @@ -60,9 +69,12 @@ class FocusDelegate {
std::string value);

/// Completes a platform message request by attempting to give focus for a
/// given viewRef.
bool RequestFocus(rapidjson::Value request,
fml::RefPtr<flutter::PlatformMessageResponse> response);
/// given view.
bool RequestFocusById(uint64_t view_id,
fml::RefPtr<flutter::PlatformMessageResponse> response);
bool RequestFocusByViewRef(
fuchsia::ui::views::ViewRef view_ref,
fml::RefPtr<flutter::PlatformMessageResponse> response);

FML_DISALLOW_COPY_AND_ASSIGN(FocusDelegate);
};
Expand Down

0 comments on commit c30375b

Please sign in to comment.