Flutter Engine
The Flutter Engine
platform_view_ios.mm
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
5#import "flutter/shell/platform/darwin/ios/platform_view_ios.h"
6#include <memory>
7
8#include <utility>
9
10#include "flutter/common/task_runners.h"
11#include "flutter/fml/synchronization/waitable_event.h"
12#include "flutter/fml/trace_event.h"
13#include "flutter/shell/common/shell_io_manager.h"
14#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h"
15#import "flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h"
16
17namespace flutter {
18
19PlatformViewIOS::AccessibilityBridgeManager::AccessibilityBridgeManager(
20 const std::function<void(bool)>& set_semantics_enabled)
21 : AccessibilityBridgeManager(set_semantics_enabled, nullptr) {}
22
23PlatformViewIOS::AccessibilityBridgeManager::AccessibilityBridgeManager(
24 const std::function<void(bool)>& set_semantics_enabled,
25 AccessibilityBridge* bridge)
26 : accessibility_bridge_(bridge), set_semantics_enabled_(set_semantics_enabled) {
27 if (bridge) {
28 set_semantics_enabled_(true);
29 }
30}
31
32void PlatformViewIOS::AccessibilityBridgeManager::Set(std::unique_ptr<AccessibilityBridge> bridge) {
33 accessibility_bridge_ = std::move(bridge);
34 set_semantics_enabled_(true);
35}
36
37void PlatformViewIOS::AccessibilityBridgeManager::Clear() {
38 set_semantics_enabled_(false);
39 accessibility_bridge_.reset();
40}
41
42PlatformViewIOS::PlatformViewIOS(
43 PlatformView::Delegate& delegate,
44 const std::shared_ptr<IOSContext>& context,
45 const std::shared_ptr<FlutterPlatformViewsController>& platform_views_controller,
46 const flutter::TaskRunners& task_runners)
47 : PlatformView(delegate, task_runners),
48 ios_context_(context),
49 platform_views_controller_(platform_views_controller),
50 accessibility_bridge_([this](bool enabled) { PlatformView::SetSemanticsEnabled(enabled); }),
51 platform_message_handler_(
52 new PlatformMessageHandlerIos(task_runners.GetPlatformTaskRunner())) {}
53
55 PlatformView::Delegate& delegate,
56 IOSRenderingAPI rendering_api,
57 const std::shared_ptr<FlutterPlatformViewsController>& platform_views_controller,
58 const flutter::TaskRunners& task_runners,
59 const std::shared_ptr<fml::ConcurrentTaskRunner>& worker_task_runner,
60 const std::shared_ptr<const fml::SyncSwitch>& is_gpu_disabled_sync_switch)
61 : PlatformViewIOS(delegate,
62 IOSContext::Create(rendering_api,
63 delegate.OnPlatformViewGetSettings().enable_impeller
66 is_gpu_disabled_sync_switch),
67 platform_views_controller,
68 task_runners) {}
69
71
72// |PlatformView|
73void PlatformViewIOS::HandlePlatformMessage(std::unique_ptr<flutter::PlatformMessage> message) {
74 platform_message_handler_->HandlePlatformMessage(std::move(message));
75}
76
78 return owner_controller_;
79}
80
82 const fml::WeakNSObject<FlutterViewController>& owner_controller) {
84 std::lock_guard<std::mutex> guard(ios_surface_mutex_);
85 if (ios_surface_ || !owner_controller) {
87 ios_surface_.reset();
88 accessibility_bridge_.Clear();
89 }
90 owner_controller_ = owner_controller;
91
92 // Add an observer that will clear out the owner_controller_ ivar and
93 // the accessibility_bridge_ in case the view controller is deleted.
94 dealloc_view_controller_observer_.reset(
95 [[[NSNotificationCenter defaultCenter] addObserverForName:FlutterViewControllerWillDealloc
96 object:owner_controller_.get()
97 queue:[NSOperationQueue mainQueue]
98 usingBlock:^(NSNotification* note) {
99 // Implicit copy of 'this' is fine.
100 accessibility_bridge_.Clear();
101 owner_controller_.reset();
102 }] retain]);
103
104 if (owner_controller_ && [owner_controller_.get() isViewLoaded]) {
105 this->attachView();
106 }
107 // Do not call `NotifyCreated()` here - let FlutterViewController take care
108 // of that when its Viewport is sized. If `NotifyCreated()` is called here,
109 // it can occasionally get invoked before the viewport is sized resulting in
110 // a framebuffer that will not be able to completely attach.
111}
112
114 FML_DCHECK(owner_controller_);
115 FML_DCHECK(owner_controller_.get().isViewLoaded)
116 << "FlutterViewController's view should be loaded "
117 "before attaching to PlatformViewIOS.";
118 auto flutter_view = static_cast<FlutterView*>(owner_controller_.get().view);
119 auto ca_layer = fml::scoped_nsobject<CALayer>{[[flutter_view layer] retain]};
120 ios_surface_ = IOSSurface::Create(ios_context_, ca_layer);
121 FML_DCHECK(ios_surface_ != nullptr);
122
123 if (accessibility_bridge_) {
124 accessibility_bridge_.Set(std::make_unique<AccessibilityBridge>(
125 owner_controller_.get(), this, [owner_controller_.get() platformViewsController]));
126 }
127}
128
130 return [](DefaultPointerDataDispatcher::Delegate& delegate) {
131 return std::make_unique<SmoothPointerDataDispatcher>(delegate);
132 };
133}
134
136 NSObject<FlutterTexture>* texture) {
137 RegisterTexture(ios_context_->CreateExternalTexture(
138 texture_id, fml::scoped_nsobject<NSObject<FlutterTexture>>{[texture retain]}));
139}
140
141// |PlatformView|
142std::unique_ptr<Surface> PlatformViewIOS::CreateRenderingSurface() {
144 std::lock_guard<std::mutex> guard(ios_surface_mutex_);
145 if (!ios_surface_) {
146 FML_DLOG(INFO) << "Could not CreateRenderingSurface, this PlatformViewIOS "
147 "has no ViewController.";
148 return nullptr;
149 }
150 return ios_surface_->CreateGPUSurface(ios_context_->GetMainContext().get());
151}
152
153// |PlatformView|
154std::shared_ptr<ExternalViewEmbedder> PlatformViewIOS::CreateExternalViewEmbedder() {
155 return std::make_shared<IOSExternalViewEmbedder>(platform_views_controller_, ios_context_);
156}
157
158// |PlatformView|
159sk_sp<GrDirectContext> PlatformViewIOS::CreateResourceContext() const {
160 return ios_context_->CreateResourceContext();
161}
162
163// |PlatformView|
164std::shared_ptr<impeller::Context> PlatformViewIOS::GetImpellerContext() const {
165 return ios_context_->GetImpellerContext();
166}
167
168// |PlatformView|
170 if (!owner_controller_) {
171 FML_LOG(WARNING) << "Could not set semantics to enabled, this "
172 "PlatformViewIOS has no ViewController.";
173 return;
174 }
175 if (enabled && !accessibility_bridge_) {
176 accessibility_bridge_.Set(std::make_unique<AccessibilityBridge>(
177 owner_controller_.get(), this, [owner_controller_.get() platformViewsController]));
178 } else if (!enabled && accessibility_bridge_) {
179 accessibility_bridge_.Clear();
180 } else {
182 }
183}
184
185// |shell:PlatformView|
186void PlatformViewIOS::SetAccessibilityFeatures(int32_t flags) {
188}
189
190// |PlatformView|
191void PlatformViewIOS::UpdateSemantics(flutter::SemanticsNodeUpdates update,
193 FML_DCHECK(owner_controller_);
194 if (accessibility_bridge_) {
195 accessibility_bridge_.get()->UpdateSemantics(std::move(update), actions);
196 [[NSNotificationCenter defaultCenter] postNotificationName:FlutterSemanticsUpdateNotification
197 object:owner_controller_.get()];
198 }
199}
200
201// |PlatformView|
202std::unique_ptr<VsyncWaiter> PlatformViewIOS::CreateVSyncWaiter() {
203 return std::make_unique<VsyncWaiterIOS>(task_runners_);
204}
205
206void PlatformViewIOS::OnPreEngineRestart() const {
207 if (accessibility_bridge_) {
208 accessibility_bridge_.get()->clearState();
209 }
210 if (!owner_controller_) {
211 return;
212 }
213 [owner_controller_.get() platformViewsController]->Reset();
214 [[owner_controller_.get() restorationPlugin] reset];
215}
216
217std::unique_ptr<std::vector<std::string>> PlatformViewIOS::ComputePlatformResolvedLocales(
218 const std::vector<std::string>& supported_locale_data) {
219 size_t localeDataLength = 3;
220 NSMutableArray<NSString*>* supported_locale_identifiers =
221 [NSMutableArray arrayWithCapacity:supported_locale_data.size() / localeDataLength];
222 for (size_t i = 0; i < supported_locale_data.size(); i += localeDataLength) {
223 NSDictionary<NSString*, NSString*>* dict = @{
224 NSLocaleLanguageCode : [NSString stringWithUTF8String:supported_locale_data[i].c_str()]
225 ?: @"",
226 NSLocaleCountryCode : [NSString stringWithUTF8String:supported_locale_data[i + 1].c_str()]
227 ?: @"",
228 NSLocaleScriptCode : [NSString stringWithUTF8String:supported_locale_data[i + 2].c_str()]
229 ?: @""
230 };
231 [supported_locale_identifiers addObject:[NSLocale localeIdentifierFromComponents:dict]];
232 }
233 NSArray<NSString*>* result =
234 [NSBundle preferredLocalizationsFromArray:supported_locale_identifiers];
235
236 // Output format should be either empty or 3 strings for language, country, and script.
237 std::unique_ptr<std::vector<std::string>> out = std::make_unique<std::vector<std::string>>();
238
239 if (result != nullptr && [result count] > 0) {
240 NSLocale* locale = [NSLocale localeWithLocaleIdentifier:[result firstObject]];
241 NSString* languageCode = [locale languageCode];
242 out->emplace_back(languageCode == nullptr ? "" : languageCode.UTF8String);
243 NSString* countryCode = [locale countryCode];
244 out->emplace_back(countryCode == nullptr ? "" : countryCode.UTF8String);
245 NSString* scriptCode = [locale scriptCode];
246 out->emplace_back(scriptCode == nullptr ? "" : scriptCode.UTF8String);
247 }
248 return out;
249}
250
251PlatformViewIOS::ScopedObserver::ScopedObserver() {}
252
253PlatformViewIOS::ScopedObserver::~ScopedObserver() {
254 if (observer_) {
255 [[NSNotificationCenter defaultCenter] removeObserver:observer_];
256 [observer_ release];
257 }
258}
259
260void PlatformViewIOS::ScopedObserver::reset(id<NSObject> observer) {
261 if (observer != observer_) {
262 if (observer_) {
263 [[NSNotificationCenter defaultCenter] removeObserver:observer_];
264 [observer_ release];
265 }
266 observer_ = observer;
267 }
268}
269
270} // namespace flutter
m reset()
int count
Definition: FontMgrTest.cpp:50
static sk_sp< Effect > Create()
Definition: RefCntTest.cpp:117
Manages the lifetime of the on-screen and off-screen rendering contexts on iOS. On-screen contexts ar...
Definition: ios_context.h:39
static std::unique_ptr< IOSSurface > Create(std::shared_ptr< IOSContext > context, const fml::scoped_nsobject< CALayer > &layer)
Definition: ios_surface.mm:16
PointerDataDispatcherMaker GetDispatcherMaker() override
Returns a platform-specific PointerDataDispatcherMaker so the Engine can construct the PointerDataPac...
void SetOwnerViewController(const fml::WeakNSObject< FlutterViewController > &owner_controller)
PlatformViewIOS(PlatformView::Delegate &delegate, const std::shared_ptr< IOSContext > &context, const std::shared_ptr< FlutterPlatformViewsController > &platform_views_controller, const flutter::TaskRunners &task_runners)
void SetSemanticsEnabled(bool enabled) override
Used by embedder to notify the running isolate hosted by the engine on the UI thread that the accessi...
fml::WeakNSObject< FlutterViewController > GetOwnerViewController() const
void RegisterExternalTexture(int64_t id, NSObject< FlutterTexture > *texture)
Used to forward events from the platform view to interested subsystems. This forwarding is done by th...
Definition: platform_view.h:60
Platform views are created by the shell on the platform task runner. Unless explicitly specified,...
Definition: platform_view.h:51
virtual void NotifyDestroyed()
Used by embedders to notify the shell that the platform view has been destroyed. This notification us...
virtual void SetSemanticsEnabled(bool enabled)
Used by embedder to notify the running isolate hosted by the engine on the UI thread that the accessi...
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...
virtual void SetAccessibilityFeatures(int32_t flags)
Used by the embedder to specify the features to enable in the accessibility tree generated by the iso...
const TaskRunners task_runners_
The interface for Engine to implement.
fml::RefPtr< fml::TaskRunner > GetRasterTaskRunner() const
Definition: task_runners.cc:42
fml::RefPtr< fml::TaskRunner > GetPlatformTaskRunner() const
Definition: task_runners.cc:30
virtual bool RunsTasksOnCurrentThread()
Definition: task_runner.cc:43
VkQueue queue
Definition: main.cc:55
FlutterSemanticsFlag flags
GAsyncResult * result
#define FML_DLOG(severity)
Definition: logging.h:102
#define FML_LOG(severity)
Definition: logging.h:82
#define FML_DCHECK(condition)
Definition: logging.h:103
Dart_NativeFunction function
Definition: fuchsia.cc:51
FLUTTER_DARWIN_EXPORT NSNotificationName const FlutterSemanticsUpdateNotification
NSNotificationName const FlutterViewControllerWillDealloc
Win32Message message
FlTexture * texture
std::unordered_map< int32_t, SemanticsNode > SemanticsNodeUpdates
std::unordered_map< int32_t, CustomAccessibilityAction > CustomAccessibilityActionUpdates
std::function< std::unique_ptr< PointerDataDispatcher >(PointerDataDispatcher::Delegate &)> PointerDataDispatcherMaker
Signature for constructing PointerDataDispatcher.
Definition: update.py:1
int64_t texture_id