mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Supplant the temporary solution https://github.com/flutter/engine/pull/44238 with a more elegant solution with am embedder API callback. The windows engine provides a callback that enables graceful exit and app lifecycle when the platform and lifecycle channels are listened to, respectively. https://github.com/flutter/flutter/issues/131616 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide] and the [C++, Objective-C, Java style guides]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test-exempt. See [testing the engine] for instructions on writing and running engine tests. - [x] I updated/added relevant documentation (doc comments with `///`). - [ ] I signed the [CLA]. - [x] 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 [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 --------- Co-authored-by: Chris Bracken <chris@bracken.jp>
213 lines
6.9 KiB
C++
213 lines
6.9 KiB
C++
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "flutter/shell/common/platform_view.h"
|
|
|
|
#include <utility>
|
|
|
|
#include "flutter/fml/make_copyable.h"
|
|
#include "flutter/fml/synchronization/waitable_event.h"
|
|
#include "flutter/shell/common/vsync_waiter_fallback.h"
|
|
#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
|
|
|
|
namespace flutter {
|
|
|
|
PlatformView::PlatformView(Delegate& delegate, const TaskRunners& task_runners)
|
|
: delegate_(delegate), task_runners_(task_runners), weak_factory_(this) {}
|
|
|
|
PlatformView::~PlatformView() = default;
|
|
|
|
std::unique_ptr<VsyncWaiter> PlatformView::CreateVSyncWaiter() {
|
|
FML_DLOG(WARNING)
|
|
<< "This platform does not provide a Vsync waiter implementation. A "
|
|
"simple timer based fallback is being used.";
|
|
return std::make_unique<VsyncWaiterFallback>(task_runners_);
|
|
}
|
|
|
|
void PlatformView::DispatchPlatformMessage(
|
|
std::unique_ptr<PlatformMessage> message) {
|
|
delegate_.OnPlatformViewDispatchPlatformMessage(std::move(message));
|
|
}
|
|
|
|
void PlatformView::DispatchPointerDataPacket(
|
|
std::unique_ptr<PointerDataPacket> packet) {
|
|
delegate_.OnPlatformViewDispatchPointerDataPacket(
|
|
pointer_data_packet_converter_.Convert(std::move(packet)));
|
|
}
|
|
|
|
void PlatformView::DispatchSemanticsAction(int32_t node_id,
|
|
SemanticsAction action,
|
|
fml::MallocMapping args) {
|
|
delegate_.OnPlatformViewDispatchSemanticsAction(node_id, action,
|
|
std::move(args));
|
|
}
|
|
|
|
void PlatformView::SetSemanticsEnabled(bool enabled) {
|
|
delegate_.OnPlatformViewSetSemanticsEnabled(enabled);
|
|
}
|
|
|
|
void PlatformView::SetAccessibilityFeatures(int32_t flags) {
|
|
delegate_.OnPlatformViewSetAccessibilityFeatures(flags);
|
|
}
|
|
|
|
void PlatformView::SetViewportMetrics(int64_t view_id,
|
|
const ViewportMetrics& metrics) {
|
|
delegate_.OnPlatformViewSetViewportMetrics(view_id, metrics);
|
|
}
|
|
|
|
void PlatformView::NotifyCreated() {
|
|
std::unique_ptr<Surface> surface;
|
|
// Threading: We want to use the platform view on the non-platform thread.
|
|
// Using the weak pointer is illegal. But, we are going to introduce a latch
|
|
// so that the platform view is not collected till the surface is obtained.
|
|
auto* platform_view = this;
|
|
fml::ManualResetWaitableEvent latch;
|
|
fml::TaskRunner::RunNowOrPostTask(
|
|
task_runners_.GetRasterTaskRunner(), [platform_view, &surface, &latch]() {
|
|
surface = platform_view->CreateRenderingSurface();
|
|
if (surface && !surface->IsValid()) {
|
|
surface.reset();
|
|
}
|
|
latch.Signal();
|
|
});
|
|
latch.Wait();
|
|
if (!surface) {
|
|
FML_LOG(ERROR) << "Failed to create platform view rendering surface";
|
|
return;
|
|
}
|
|
delegate_.OnPlatformViewCreated(std::move(surface));
|
|
}
|
|
|
|
void PlatformView::NotifyDestroyed() {
|
|
delegate_.OnPlatformViewDestroyed();
|
|
}
|
|
|
|
void PlatformView::ScheduleFrame() {
|
|
delegate_.OnPlatformViewScheduleFrame();
|
|
}
|
|
|
|
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.";
|
|
return nullptr;
|
|
}
|
|
|
|
std::shared_ptr<impeller::Context> PlatformView::GetImpellerContext() const {
|
|
return nullptr;
|
|
}
|
|
|
|
void PlatformView::ReleaseResourceContext() const {}
|
|
|
|
PointerDataDispatcherMaker PlatformView::GetDispatcherMaker() {
|
|
return [](DefaultPointerDataDispatcher::Delegate& delegate) {
|
|
return std::make_unique<DefaultPointerDataDispatcher>(delegate);
|
|
};
|
|
}
|
|
|
|
fml::WeakPtr<PlatformView> PlatformView::GetWeakPtr() const {
|
|
return weak_factory_.GetWeakPtr();
|
|
}
|
|
|
|
void PlatformView::UpdateSemantics(
|
|
SemanticsNodeUpdates update, // NOLINT(performance-unnecessary-value-param)
|
|
// NOLINTNEXTLINE(performance-unnecessary-value-param)
|
|
CustomAccessibilityActionUpdates actions) {}
|
|
|
|
void PlatformView::SendChannelUpdate(const std::string& name, bool listening) {}
|
|
|
|
void PlatformView::HandlePlatformMessage(
|
|
std::unique_ptr<PlatformMessage> message) {
|
|
if (auto response = message->response()) {
|
|
response->CompleteEmpty();
|
|
}
|
|
}
|
|
|
|
void PlatformView::OnPreEngineRestart() const {}
|
|
|
|
void PlatformView::RegisterTexture(std::shared_ptr<flutter::Texture> texture) {
|
|
delegate_.OnPlatformViewRegisterTexture(std::move(texture));
|
|
}
|
|
|
|
void PlatformView::UnregisterTexture(int64_t texture_id) {
|
|
delegate_.OnPlatformViewUnregisterTexture(texture_id);
|
|
}
|
|
|
|
void PlatformView::MarkTextureFrameAvailable(int64_t texture_id) {
|
|
delegate_.OnPlatformViewMarkTextureFrameAvailable(texture_id);
|
|
}
|
|
|
|
std::unique_ptr<Surface> PlatformView::CreateRenderingSurface() {
|
|
// We have a default implementation because tests create a platform view but
|
|
// never a rendering surface.
|
|
FML_DCHECK(false) << "This platform does not provide a rendering surface but "
|
|
"it was notified of surface rendering surface creation.";
|
|
return nullptr;
|
|
}
|
|
|
|
std::shared_ptr<ExternalViewEmbedder>
|
|
PlatformView::CreateExternalViewEmbedder() {
|
|
FML_DLOG(WARNING)
|
|
<< "This platform doesn't support embedding external views.";
|
|
return nullptr;
|
|
}
|
|
|
|
void PlatformView::SetNextFrameCallback(const fml::closure& closure) {
|
|
if (!closure) {
|
|
return;
|
|
}
|
|
|
|
delegate_.OnPlatformViewSetNextFrameCallback(closure);
|
|
}
|
|
|
|
std::unique_ptr<std::vector<std::string>>
|
|
PlatformView::ComputePlatformResolvedLocales(
|
|
const std::vector<std::string>& supported_locale_data) {
|
|
std::unique_ptr<std::vector<std::string>> out =
|
|
std::make_unique<std::vector<std::string>>();
|
|
return out;
|
|
}
|
|
|
|
void PlatformView::RequestDartDeferredLibrary(intptr_t loading_unit_id) {}
|
|
|
|
void PlatformView::LoadDartDeferredLibrary(
|
|
intptr_t loading_unit_id,
|
|
std::unique_ptr<const fml::Mapping> snapshot_data,
|
|
std::unique_ptr<const fml::Mapping> snapshot_instructions) {}
|
|
|
|
void PlatformView::LoadDartDeferredLibraryError(
|
|
intptr_t loading_unit_id,
|
|
const std::string
|
|
error_message, // NOLINT(performance-unnecessary-value-param)
|
|
bool transient) {}
|
|
|
|
void PlatformView::UpdateAssetResolverByType(
|
|
std::unique_ptr<AssetResolver> updated_asset_resolver,
|
|
AssetResolver::AssetResolverType type) {
|
|
delegate_.UpdateAssetResolverByType(std::move(updated_asset_resolver), type);
|
|
}
|
|
|
|
std::unique_ptr<SnapshotSurfaceProducer>
|
|
PlatformView::CreateSnapshotSurfaceProducer() {
|
|
return nullptr;
|
|
}
|
|
|
|
std::shared_ptr<PlatformMessageHandler>
|
|
PlatformView::GetPlatformMessageHandler() const {
|
|
return nullptr;
|
|
}
|
|
|
|
const Settings& PlatformView::GetSettings() const {
|
|
return delegate_.OnPlatformViewGetSettings();
|
|
}
|
|
|
|
double PlatformView::GetScaledFontSize(double unscaled_font_size,
|
|
int configuration_id) const {
|
|
// Unreachable by default, as most platforms do not support nonlinear scaling
|
|
// and the Flutter application never invokes this method.
|
|
FML_UNREACHABLE();
|
|
return -1;
|
|
}
|
|
|
|
} // namespace flutter
|