Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
platform_view_android.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include <android/api-level.h>
8#include <sys/system_properties.h>
9#include <memory>
10#include <utility>
11
12#include "common/settings.h"
26
27#if !SLIMPELLER
33#endif // !SLIMPELLER
34
35#include "fml/logging.h"
37#if IMPELLER_ENABLE_VULKAN // b/258506856 for why this is behind an if
40#endif
48
49namespace flutter {
50
51namespace {
52
53static constexpr int kMinAPILevelHCPP = 34;
54static constexpr int64_t kImplicitViewId = 0;
55
56AndroidContext::ContextSettings CreateContextSettings(
57 const Settings& p_settings) {
58 AndroidContext::ContextSettings settings;
59 settings.enable_gpu_tracing = p_settings.enable_vulkan_gpu_tracing;
60 settings.enable_validation = p_settings.enable_vulkan_validation;
61 settings.enable_surface_control = p_settings.enable_surface_control;
62 return settings;
63}
64} // namespace
65
67 const std::shared_ptr<AndroidContext>& context,
68 bool enable_impeller,
69 bool lazy_shader_mode)
70 : android_context_(context),
71 enable_impeller_(enable_impeller),
72 lazy_shader_mode_(lazy_shader_mode) {}
73
75
76std::unique_ptr<AndroidSurface> AndroidSurfaceFactoryImpl::CreateSurface() {
77 if (android_context_->IsDynamicSelection()) {
78 auto cast_ptr = std::static_pointer_cast<AndroidContextDynamicImpeller>(
79 android_context_);
80 return std::make_unique<AndroidSurfaceDynamicImpeller>(cast_ptr);
81 }
82 switch (android_context_->RenderingApi()) {
83#if !SLIMPELLER
85 return std::make_unique<AndroidSurfaceSoftware>();
87 return std::make_unique<AndroidSurfaceGLSkia>(
88 std::static_pointer_cast<AndroidContextGLSkia>(android_context_));
89#endif // !SLIMPELLER
91 return std::make_unique<AndroidSurfaceGLImpeller>(
92 std::static_pointer_cast<AndroidContextGLImpeller>(android_context_));
94 return std::make_unique<AndroidSurfaceVKImpeller>(
95 std::static_pointer_cast<AndroidContextVKImpeller>(android_context_));
97 auto cast_ptr = std::static_pointer_cast<AndroidContextDynamicImpeller>(
98 android_context_);
99 return std::make_unique<AndroidSurfaceDynamicImpeller>(cast_ptr);
100 }
101 }
103}
104
105static std::shared_ptr<flutter::AndroidContext> CreateAndroidContext(
106 const flutter::TaskRunners& task_runners,
107 AndroidRenderingAPI android_rendering_api,
108 bool enable_opengl_gpu_tracing,
109 const AndroidContext::ContextSettings& settings,
110 std::shared_ptr<fml::BasicTaskRunner> io_task_runner) {
111 switch (android_rendering_api) {
112#if !SLIMPELLER
114 return std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
116 return std::make_unique<AndroidContextGLSkia>(
117 fml::MakeRefCounted<AndroidEnvironmentGL>(), //
118 task_runners //
119 );
120#endif // !SLIMPELLER
122 return std::make_unique<AndroidContextVKImpeller>(settings);
124 return std::make_unique<AndroidContextGLImpeller>(
125 std::make_unique<impeller::egl::Display>(), enable_opengl_gpu_tracing,
126 std::move(io_task_runner));
128 // Determine if we're using GL or Vulkan.
129 return std::make_unique<AndroidContextDynamicImpeller>(
130 settings, std::move(io_task_runner));
131 }
133}
134
136 PlatformView::Delegate& delegate,
137 const flutter::TaskRunners& task_runners,
138 const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade,
139 AndroidRenderingAPI rendering_api)
141 delegate,
142 task_runners,
143 jni_facade,
145 task_runners,
146 rendering_api,
147 delegate.OnPlatformViewGetSettings().enable_opengl_gpu_tracing,
148 CreateContextSettings(delegate.OnPlatformViewGetSettings()),
149 delegate.OnPlatformViewGetShutdownSafeIOTaskRunner())) {}
150
152 PlatformView::Delegate& delegate,
153 const flutter::TaskRunners& task_runners,
154 const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade,
155 const std::shared_ptr<flutter::AndroidContext>& android_context)
156 : PlatformView(delegate, task_runners),
157 jni_facade_(jni_facade),
158 android_context_(android_context),
159 platform_view_android_delegate_(jni_facade),
160 platform_message_handler_(new PlatformMessageHandlerAndroid(jni_facade)) {
161 if (android_context_) {
162 FML_CHECK(android_context_->IsValid())
163 << "Could not create surface from invalid Android context.";
164 surface_factory_ = std::make_shared<AndroidSurfaceFactoryImpl>(
165 android_context_, //
169 );
170 android_surface_ = surface_factory_->CreateSurface();
171 android_meets_hcpp_criteria_ =
173 android_get_device_api_level() >= kMinAPILevelHCPP &&
175 FML_CHECK(android_surface_ && android_surface_->IsValid())
176 << "Could not create an OpenGL, Vulkan or Software surface to set "
177 "up "
178 "rendering.";
179 }
180}
181
183
185 fml::RefPtr<AndroidNativeWindow> native_window) {
186 if (android_surface_) {
187 InstallFirstFrameCallback();
188
192 [&latch, surface = android_surface_.get(),
193 native_window = std::move(native_window), jni_facade = jni_facade_]() {
194 surface->SetNativeWindow(native_window, jni_facade);
195 latch.Signal();
196 });
197 latch.Wait();
198 }
199
201}
202
204 fml::RefPtr<AndroidNativeWindow> native_window) {
205 if (android_surface_) {
209 [&latch, surface = android_surface_.get(),
210 native_window = std::move(native_window), jni_facade = jni_facade_]() {
211 surface->TeardownOnScreenContext();
212 surface->SetNativeWindow(native_window, jni_facade);
213 latch.Signal();
214 });
215 latch.Wait();
216 }
217
219}
220
223
224 if (android_surface_) {
228 [&latch, surface = android_surface_.get()]() {
229 surface->TeardownOnScreenContext();
230 latch.Signal();
231 });
232 latch.Wait();
233 }
234}
235
237 if (!android_surface_) {
238 return;
239 }
243 [&latch, surface = android_surface_.get(), size]() {
244 surface->OnScreenSurfaceResize(size);
245 latch.Signal();
246 });
247 latch.Wait();
248}
249
251 std::string name,
252 jobject java_message_data,
253 jint java_message_position,
254 jint response_id) {
255 uint8_t* message_data =
256 static_cast<uint8_t*>(env->GetDirectBufferAddress(java_message_data));
258 fml::MallocMapping::Copy(message_data, java_message_position);
259
261 if (response_id) {
262 response = fml::MakeRefCounted<PlatformMessageResponseAndroid>(
263 response_id, jni_facade_, task_runners_.GetPlatformTaskRunner());
264 }
265
267 std::make_unique<flutter::PlatformMessage>(
268 std::move(name), std::move(message), std::move(response)));
269}
270
272 std::string name,
273 jint response_id) {
275 if (response_id) {
276 response = fml::MakeRefCounted<PlatformMessageResponseAndroid>(
277 response_id, jni_facade_, task_runners_.GetPlatformTaskRunner());
278 }
279
281 std::make_unique<flutter::PlatformMessage>(std::move(name),
282 std::move(response)));
283}
284
285// |PlatformView|
286void PlatformViewAndroid::HandlePlatformMessage(
287 std::unique_ptr<flutter::PlatformMessage> message) {
288 // Called from the ui thread.
289 platform_message_handler_->HandlePlatformMessage(std::move(message));
290}
291
292// |PlatformView|
293void PlatformViewAndroid::OnPreEngineRestart() const {
294 jni_facade_->FlutterViewOnPreEngineRestart();
295}
296
298 jint node_id,
299 jint action,
300 jobject args,
301 jint args_position) {
302 // TODO(team-android): Remove implicit view assumption.
303 // https://github.com/flutter/flutter/issues/142845
304 if (env->IsSameObject(args, NULL)) {
306 kImplicitViewId, node_id, static_cast<flutter::SemanticsAction>(action),
308 return;
309 }
310
311 uint8_t* args_data = static_cast<uint8_t*>(env->GetDirectBufferAddress(args));
312 auto args_vector = fml::MallocMapping::Copy(args_data, args_position);
313
315 kImplicitViewId, node_id, static_cast<flutter::SemanticsAction>(action),
316 std::move(args_vector));
317}
318
319// |PlatformView|
320void PlatformViewAndroid::UpdateSemantics(
321 int64_t view_id,
324 platform_view_android_delegate_.UpdateSemantics(update, actions);
325}
326
327// |PlatformView|
328void PlatformViewAndroid::SetApplicationLocale(std::string locale) {
329 jni_facade_->FlutterViewSetApplicationLocale(std::move(locale));
330}
331
332// |PlatformView|
333void PlatformViewAndroid::SetSemanticsTreeEnabled(bool enabled) {
334 jni_facade_->FlutterViewSetSemanticsTreeEnabled(enabled);
335}
336
338 int64_t texture_id,
339 const fml::jni::ScopedJavaGlobalRef<jobject>& surface_texture) {
340 switch (android_context_->RenderingApi()) {
342 // Impeller GLES.
343 RegisterTexture(std::make_shared<SurfaceTextureExternalTextureGLImpeller>(
344 std::static_pointer_cast<impeller::ContextGLES>(
345 android_context_->GetImpellerContext()), //
346 texture_id, //
347 surface_texture, //
348 jni_facade_ //
349 ));
350 break;
351#if !SLIMPELLER
353 // Legacy GL.
354 RegisterTexture(std::make_shared<SurfaceTextureExternalTextureGLSkia>(
355 texture_id, //
356 surface_texture, //
357 jni_facade_ //
358 ));
359 break;
361 FML_LOG(INFO) << "Software rendering does not support external textures.";
362 break;
363#endif // !SLIMPELLER
365 FML_LOG(IMPORTANT)
366 << "Flutter recommends migrating plugins that create and "
367 "register surface textures to the new surface producer "
368 "API. See https://docs.flutter.dev/release/breaking-changes/"
369 "android-surface-plugins";
370 RegisterTexture(std::make_shared<SurfaceTextureExternalTextureVKImpeller>(
371 std::static_pointer_cast<impeller::ContextVK>(
372 android_context_->GetImpellerContext()), //
373 texture_id, //
374 surface_texture, //
375 jni_facade_ //
376 ));
377 break;
379 default:
380 FML_CHECK(false);
381 break;
382 }
383}
384
386 int64_t texture_id,
387 const fml::jni::ScopedJavaGlobalRef<jobject>& image_texture_entry,
389 switch (android_context_->RenderingApi()) {
390#if !SLIMPELLER
392 // Legacy GL.
393 RegisterTexture(std::make_shared<ImageExternalTextureGLSkia>(
394 std::static_pointer_cast<AndroidContextGLSkia>(android_context_),
395 texture_id, image_texture_entry, jni_facade_, lifecycle));
396 break;
398 FML_LOG(INFO) << "Software rendering does not support external textures.";
399 break;
400#endif // !SLIMPELLER
402 // Impeller GLES.
403 RegisterTexture(std::make_shared<ImageExternalTextureGLImpeller>(
404 std::static_pointer_cast<impeller::ContextGLES>(
405 android_context_->GetImpellerContext()),
406 texture_id, image_texture_entry, jni_facade_, lifecycle));
407 break;
409 RegisterTexture(std::make_shared<ImageExternalTextureVKImpeller>(
410 std::static_pointer_cast<impeller::ContextVK>(
411 android_context_->GetImpellerContext()),
412 texture_id, image_texture_entry, jni_facade_, lifecycle));
413 break;
415 FML_CHECK(false);
416 break;
417 }
418}
419
420// |PlatformView|
421std::unique_ptr<VsyncWaiter> PlatformViewAndroid::CreateVSyncWaiter() {
422 return std::make_unique<VsyncWaiterAndroid>(task_runners_);
423}
424
425// |PlatformView|
426std::unique_ptr<Surface> PlatformViewAndroid::CreateRenderingSurface() {
427 if (!android_surface_) {
428 return nullptr;
429 }
430 return android_surface_->CreateGPUSurface(
431 android_context_->GetMainSkiaContext().get());
432}
433
434// |PlatformView|
435std::shared_ptr<ExternalViewEmbedder>
436PlatformViewAndroid::CreateExternalViewEmbedder() {
437 return std::make_shared<AndroidExternalViewEmbedderWrapper>(
438 android_meets_hcpp_criteria_, *android_context_, jni_facade_,
439 surface_factory_, task_runners_);
440}
441
442// |PlatformView|
443std::unique_ptr<SnapshotSurfaceProducer>
444PlatformViewAndroid::CreateSnapshotSurfaceProducer() {
445 if (!android_surface_) {
446 return nullptr;
447 }
448 return std::make_unique<AndroidSnapshotSurfaceProducer>(*android_surface_);
449}
450
451// |PlatformView|
452sk_sp<GrDirectContext> PlatformViewAndroid::CreateResourceContext() const {
453 if (!android_surface_) {
454 return nullptr;
455 }
456#if !SLIMPELLER
457 sk_sp<GrDirectContext> resource_context;
458 if (android_surface_->ResourceContextMakeCurrent()) {
459 // TODO(chinmaygarde): Currently, this code depends on the fact that only
460 // the OpenGL surface will be able to make a resource context current. If
461 // this changes, this assumption breaks. Handle the same.
463 GrBackendApi::kOpenGL,
465 } else {
466 FML_DLOG(ERROR) << "Could not make the resource context current.";
467 }
468 return resource_context;
469#else
470 android_surface_->ResourceContextMakeCurrent();
471 return nullptr;
472#endif // !SLIMPELLER
473}
474
475// |PlatformView|
476void PlatformViewAndroid::ReleaseResourceContext() const {
477 if (android_surface_) {
478 android_surface_->ResourceContextClearCurrent();
479 }
480}
481
482// |PlatformView|
483std::shared_ptr<impeller::Context> PlatformViewAndroid::GetImpellerContext()
484 const {
485 if (android_surface_) {
486 return android_surface_->GetImpellerContext();
487 }
488 return android_context_->GetImpellerContext();
489}
490
491// |PlatformView|
492std::unique_ptr<std::vector<std::string>>
493PlatformViewAndroid::ComputePlatformResolvedLocales(
494 const std::vector<std::string>& supported_locale_data) {
495 return jni_facade_->FlutterViewComputePlatformResolvedLocale(
496 supported_locale_data);
497}
498
499// |PlatformView|
500void PlatformViewAndroid::RequestDartDeferredLibrary(intptr_t loading_unit_id) {
501 if (jni_facade_->RequestDartDeferredLibrary(loading_unit_id)) {
502 return;
503 }
504 return; // TODO(garyq): Call LoadDartDeferredLibraryFailure()
505}
506
507// |PlatformView|
509 intptr_t loading_unit_id,
510 std::unique_ptr<const fml::Mapping> snapshot_data,
511 std::unique_ptr<const fml::Mapping> snapshot_instructions) {
512 delegate_.LoadDartDeferredLibrary(loading_unit_id, std::move(snapshot_data),
513 std::move(snapshot_instructions));
514}
515
516// |PlatformView|
518 intptr_t loading_unit_id,
519 const std::string error_message,
520 bool transient) {
521 delegate_.LoadDartDeferredLibraryError(loading_unit_id, error_message,
522 transient);
523}
524
525// |PlatformView|
527 std::unique_ptr<AssetResolver> updated_asset_resolver,
529 delegate_.UpdateAssetResolverByType(std::move(updated_asset_resolver), type);
530}
531
532void PlatformViewAndroid::InstallFirstFrameCallback() {
533 // On Platform Task Runner.
536 platform_task_runner = task_runners_.GetPlatformTaskRunner()]() {
537 // On GPU Task Runner.
538 platform_task_runner->PostTask([platform_view]() {
539 // Back on Platform Task Runner.
540 if (platform_view) {
541 reinterpret_cast<PlatformViewAndroid*>(platform_view.get())
542 ->FireFirstFrameCallback();
543 }
544 });
545 });
546}
547
548void PlatformViewAndroid::FireFirstFrameCallback() {
549 jni_facade_->FlutterViewOnFirstFrame();
550}
551
552double PlatformViewAndroid::GetScaledFontSize(double unscaled_font_size,
553 int configuration_id) const {
554 return jni_facade_->FlutterViewGetScaledFontSize(unscaled_font_size,
555 configuration_id);
556}
557
558bool PlatformViewAndroid::IsSurfaceControlEnabled() const {
559 // This needs to know if we're actually using HCPP.
560 return android_meets_hcpp_criteria_ &&
561 android_context_->RenderingApi() ==
562 AndroidRenderingAPI::kImpellerVulkan &&
563 impeller::ContextVK::Cast(*android_context_->GetImpellerContext())
565}
566
567void PlatformViewAndroid::SetupImpellerContext() {
568 android_context_->SetupImpellerContext();
569 android_surface_->SetupImpellerSurface();
570}
571
572} // namespace flutter
std::unique_ptr< flutter::PlatformViewIOS > platform_view
std::unique_ptr< AndroidSurface > CreateSurface() override
AndroidSurfaceFactoryImpl(const std::shared_ptr< AndroidContext > &context, bool enable_impeller, bool lazy_shader_mode)
AssetResolverType
Identifies the type of AssetResolver an instance is.
static sk_sp< const GrGLInterface > GetDefaultPlatformGLInterface()
ImageLifecycle
Whether the last image should be reset when the context is destroyed.
Used to forward events from the platform view to interested subsystems. This forwarding is done by th...
virtual void UpdateAssetResolverByType(std::unique_ptr< AssetResolver > updated_asset_resolver, AssetResolver::AssetResolverType type)=0
Replaces the asset resolver handled by the engine's AssetManager of the specified type with updated_a...
virtual const Settings & OnPlatformViewGetSettings() const =0
Called by the platform view on the platform thread to get the settings object associated with the pla...
virtual void LoadDartDeferredLibrary(intptr_t loading_unit_id, std::unique_ptr< const fml::Mapping > snapshot_data, std::unique_ptr< const fml::Mapping > snapshot_instructions)=0
Loads the dart shared library into the dart VM. When the dart library is loaded successfully,...
virtual void LoadDartDeferredLibraryError(intptr_t loading_unit_id, const std::string error_message, bool transient)=0
Indicates to the dart VM that the request to load a deferred library with the specified loading unit ...
void UpdateSemantics(const flutter::SemanticsNodeUpdates &update, const flutter::CustomAccessibilityActionUpdates &actions)
void RegisterImageTexture(int64_t texture_id, const fml::jni::ScopedJavaGlobalRef< jobject > &image_texture_entry, ImageExternalTexture::ImageLifecycle lifecycle)
PlatformViewAndroid(PlatformView::Delegate &delegate, const flutter::TaskRunners &task_runners, const std::shared_ptr< PlatformViewAndroidJNI > &jni_facade, AndroidRenderingAPI rendering_api)
void DispatchPlatformMessage(JNIEnv *env, std::string name, jobject message_data, jint message_position, jint response_id)
void RegisterExternalTexture(int64_t texture_id, const fml::jni::ScopedJavaGlobalRef< jobject > &surface_texture)
void NotifySurfaceWindowChanged(fml::RefPtr< AndroidNativeWindow > native_window)
void NotifyChanged(const DlISize &size)
void DispatchEmptyPlatformMessage(JNIEnv *env, std::string name, jint response_id)
void NotifyDestroyed() override
Used by embedders to notify the shell that the platform view has been destroyed. This notification us...
void UpdateAssetResolverByType(std::unique_ptr< AssetResolver > updated_asset_resolver, AssetResolver::AssetResolverType type) override
Replaces the asset resolver handled by the engine's AssetManager of the specified type with updated_a...
void DispatchSemanticsAction(JNIEnv *env, jint id, jint action, jobject args, jint args_position)
void LoadDartDeferredLibraryError(intptr_t loading_unit_id, const std::string error_message, bool transient) override
Indicates to the dart VM that the request to load a deferred library with the specified loading unit ...
void LoadDartDeferredLibrary(intptr_t loading_unit_id, std::unique_ptr< const fml::Mapping > snapshot_data, std::unique_ptr< const fml::Mapping > snapshot_instructions) override
Loads the Dart shared library into the Dart VM. When the Dart library is loaded successfully,...
Platform views are created by the shell on the platform task runner. Unless explicitly specified,...
virtual void NotifyDestroyed()
Used by embedders to notify the shell that the platform view has been destroyed. This notification us...
void SetNextFrameCallback(const fml::closure &closure)
Sets a callback that gets executed when the rasterizer renders the next frame. Due to the asynchronou...
void RegisterTexture(std::shared_ptr< flutter::Texture > texture)
Used by the embedder to specify a texture that it wants the rasterizer to composite within the Flutte...
void DispatchSemanticsAction(int64_t view_id, int32_t node_id, SemanticsAction action, fml::MallocMapping args)
Used by embedders to dispatch an accessibility action to a running isolate hosted by the engine.
void DispatchPlatformMessage(std::unique_ptr< PlatformMessage > message)
Used by embedders to dispatch a platform message to a running root isolate hosted by the engine....
PlatformView::Delegate & delegate_
void NotifyCreated()
Used by embedders to notify the shell that a platform view has been created. This notification is use...
fml::WeakPtr< PlatformView > GetWeakPtr() const
Returns a weak pointer to the platform view. Since the platform view may only be created,...
void ScheduleFrame()
Used by embedders to schedule a frame. In response to this call, the framework may need to start gene...
const TaskRunners task_runners_
static sk_sp< GrDirectContext > CreateCompatibleResourceLoadingContext(GrBackendApi backend, const sk_sp< const GrGLInterface > &gl_interface)
fml::RefPtr< fml::TaskRunner > GetRasterTaskRunner() const
fml::RefPtr< fml::TaskRunner > GetPlatformTaskRunner() const
A Mapping like NonOwnedMapping, but uses Free as its release proc.
Definition mapping.h:144
static MallocMapping Copy(const T *begin, const T *end)
Definition mapping.h:162
static void RunNowOrPostTask(const fml::RefPtr< fml::TaskRunner > &runner, const fml::closure &task)
static ContextVK & Cast(Context &base)
bool GetShouldEnableSurfaceControlSwapchain() const
Whether the Android Surface control based swapchain should be enabled.
VkSurfaceKHR surface
Definition main.cc:65
const char * message
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
G_BEGIN_DECLS FlutterViewId view_id
#define FML_DLOG(severity)
Definition logging.h:121
#define FML_LOG(severity)
Definition logging.h:101
#define FML_CHECK(condition)
Definition logging.h:104
#define FML_UNREACHABLE()
Definition logging.h:128
std::unordered_map< int32_t, SemanticsNode > SemanticsNodeUpdates
std::unordered_map< int32_t, CustomAccessibilityAction > CustomAccessibilityActionUpdates
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
DEF_SWITCHES_START aot vmservice shared library name
Definition switch_defs.h:27
constexpr FlutterViewId kImplicitViewId
static std::shared_ptr< flutter::AndroidContext > CreateAndroidContext(const flutter::TaskRunners &task_runners, AndroidRenderingAPI android_rendering_api, bool enable_opengl_gpu_tracing, const AndroidContext::ContextSettings &settings, std::shared_ptr< fml::BasicTaskRunner > io_task_runner)
std::shared_ptr< ContextGLES > context
impeller::ShaderType type
bool impeller_enable_lazy_shader_mode
Definition settings.h:242
bool enable_surface_control
Definition settings.h:239
int64_t texture_id