Flutter Engine
 
Loading...
Searching...
No Matches
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
6#include <memory>
7
8#include <utility>
9
14#import "flutter/shell/platform/darwin/common/InternalFlutterSwiftCommon/InternalFlutterSwiftCommon.h"
17
19
20namespace flutter {
21
23 const std::shared_ptr<IOSContext>& context,
24 __weak FlutterPlatformViewsController* platform_views_controller,
25 const flutter::TaskRunners& task_runners)
26 : PlatformView(delegate, task_runners),
27 ios_context_(context),
28 platform_views_controller_(platform_views_controller),
29 platform_message_handler_(
30 new PlatformMessageHandlerIos(task_runners.GetPlatformTaskRunner())) {}
31
33 PlatformView::Delegate& delegate,
34 IOSRenderingAPI rendering_api,
35 __weak FlutterPlatformViewsController* platform_views_controller,
36 const flutter::TaskRunners& task_runners,
37 const std::shared_ptr<fml::ConcurrentTaskRunner>& worker_task_runner,
38 const std::shared_ptr<const fml::SyncSwitch>& is_gpu_disabled_sync_switch)
39 : PlatformViewIOS(delegate,
40 IOSContext::Create(rendering_api,
41 delegate.OnPlatformViewGetSettings().enable_impeller
44 is_gpu_disabled_sync_switch,
45 delegate.OnPlatformViewGetSettings()),
46 platform_views_controller,
47 task_runners) {}
48
50
51// |PlatformView|
52void PlatformViewIOS::HandlePlatformMessage(std::unique_ptr<flutter::PlatformMessage> message) {
53 platform_message_handler_->HandlePlatformMessage(std::move(message));
54}
55
57 return owner_controller_;
58}
59
62 std::lock_guard<std::mutex> guard(ios_surface_mutex_);
63 if (ios_surface_ || !owner_controller) {
65 ios_surface_.reset();
66 accessibility_bridge_.reset();
67 }
68 owner_controller_ = owner_controller;
69 ApplyLocaleToOwnerController();
70
71 // Add an observer that will clear out the owner_controller_ ivar and
72 // the accessibility_bridge_ in case the view controller is deleted.
73 dealloc_view_controller_observer_.reset([[NSNotificationCenter defaultCenter]
74 addObserverForName:FlutterViewControllerWillDealloc
75 object:owner_controller_
76 queue:[NSOperationQueue mainQueue]
77 usingBlock:^(NSNotification* note) {
78 // Implicit copy of 'this' is fine.
79 accessibility_bridge_.reset();
80 owner_controller_ = nil;
81 }]);
82
83 if (owner_controller_ && owner_controller_.isViewLoaded) {
84 this->attachView();
85 }
86 // Do not call `NotifyCreated()` here - let FlutterViewController take care
87 // of that when its Viewport is sized. If `NotifyCreated()` is called here,
88 // it can occasionally get invoked before the viewport is sized resulting in
89 // a framebuffer that will not be able to completely attach.
90}
91
93 FML_DCHECK(owner_controller_);
94 FML_DCHECK(owner_controller_.isViewLoaded) << "FlutterViewController's view should be loaded "
95 "before attaching to PlatformViewIOS.";
96 FlutterView* flutter_view = static_cast<FlutterView*>(owner_controller_.view);
97 CALayer* ca_layer = flutter_view.layer;
98 ios_surface_ = IOSSurface::Create(ios_context_, ca_layer);
99 FML_DCHECK(ios_surface_ != nullptr);
100
101 if (accessibility_bridge_) {
102 accessibility_bridge_ = std::make_unique<AccessibilityBridge>(
103 owner_controller_, this, owner_controller_.platformViewsController);
104 }
105}
106
108 return [](DefaultPointerDataDispatcher::Delegate& delegate) {
109 return std::make_unique<SmoothPointerDataDispatcher>(delegate);
110 };
111}
112
114 NSObject<FlutterTexture>* texture) {
115 RegisterTexture(ios_context_->CreateExternalTexture(texture_id, texture));
116}
117
118// |PlatformView|
119std::unique_ptr<Surface> PlatformViewIOS::CreateRenderingSurface() {
121 std::lock_guard<std::mutex> guard(ios_surface_mutex_);
122 if (!ios_surface_) {
123 FML_DLOG(INFO) << "Could not CreateRenderingSurface, this PlatformViewIOS "
124 "has no ViewController.";
125 return nullptr;
126 }
127 return ios_surface_->CreateGPUSurface();
128}
129
130// |PlatformView|
131std::shared_ptr<ExternalViewEmbedder> PlatformViewIOS::CreateExternalViewEmbedder() {
132 return std::make_shared<IOSExternalViewEmbedder>(platform_views_controller_, ios_context_);
133}
134
135// |PlatformView|
136std::shared_ptr<impeller::Context> PlatformViewIOS::GetImpellerContext() const {
137 return ios_context_->GetImpellerContext();
138}
139
140// |PlatformView|
144
145// |PlatformView|
149
150// |PlatformView|
154 FML_DCHECK(owner_controller_);
155 FML_DCHECK(accessibility_bridge_);
156 if (accessibility_bridge_) {
157 accessibility_bridge_.get()->UpdateSemantics(std::move(update), actions);
158 [[NSNotificationCenter defaultCenter] postNotificationName:FlutterSemanticsUpdateNotification
159 object:owner_controller_];
160 }
161}
162
163// |PlatformView|
165 application_locale_ = std::move(locale);
166 ApplyLocaleToOwnerController();
167}
168
169// |PlatformView|
171 FML_DCHECK(owner_controller_);
172 if (enabled) {
173 if (accessibility_bridge_) {
174 return;
175 }
176 accessibility_bridge_ =
177 std::make_unique<AccessibilityBridge>(owner_controller_, this, platform_views_controller_);
178 } else {
179 accessibility_bridge_.reset();
180 }
181}
182
183// |PlatformView|
184std::unique_ptr<VsyncWaiter> PlatformViewIOS::CreateVSyncWaiter() {
185 return std::make_unique<VsyncWaiterIOS>(task_runners_);
186}
187
188// |PlatformView|
190 if (accessibility_bridge_) {
191 accessibility_bridge_.get()->clearState();
192 }
193 if (!owner_controller_) {
194 return;
195 }
196 [owner_controller_.platformViewsController reset];
197 [owner_controller_.restorationPlugin reset];
198 [owner_controller_.textInputPlugin reset];
199}
200
201// |PlatformView|
202std::unique_ptr<std::vector<std::string>> PlatformViewIOS::ComputePlatformResolvedLocales(
203 const std::vector<std::string>& supported_locale_data) {
204 size_t localeDataLength = 3;
205 NSMutableArray<NSString*>* supported_locale_identifiers =
206 [NSMutableArray arrayWithCapacity:supported_locale_data.size() / localeDataLength];
207 for (size_t i = 0; i < supported_locale_data.size(); i += localeDataLength) {
208 NSDictionary<NSString*, NSString*>* dict = @{
209 NSLocaleLanguageCode : [NSString stringWithUTF8String:supported_locale_data[i].c_str()]
210 ?: @"",
211 NSLocaleCountryCode : [NSString stringWithUTF8String:supported_locale_data[i + 1].c_str()]
212 ?: @"",
213 NSLocaleScriptCode : [NSString stringWithUTF8String:supported_locale_data[i + 2].c_str()]
214 ?: @""
215 };
216 [supported_locale_identifiers addObject:[NSLocale localeIdentifierFromComponents:dict]];
217 }
218 NSArray<NSString*>* result =
219 [NSBundle preferredLocalizationsFromArray:supported_locale_identifiers];
220
221 // Output format should be either empty or 3 strings for language, country, and script.
222 std::unique_ptr<std::vector<std::string>> out = std::make_unique<std::vector<std::string>>();
223
224 if (result != nullptr && [result count] > 0) {
225 NSLocale* locale = [NSLocale localeWithLocaleIdentifier:[result firstObject]];
226 NSString* languageCode = [locale languageCode];
227 out->emplace_back(languageCode == nullptr ? "" : languageCode.UTF8String);
228 NSString* countryCode = [locale countryCode];
229 out->emplace_back(countryCode == nullptr ? "" : countryCode.UTF8String);
230 NSString* scriptCode = [locale scriptCode];
231 out->emplace_back(scriptCode == nullptr ? "" : scriptCode.UTF8String);
232 }
233 return out;
234}
235
236void PlatformViewIOS::ApplyLocaleToOwnerController() {
237 if (owner_controller_) {
238 owner_controller_.applicationLocale =
239 application_locale_.empty() ? nil : @(application_locale_.data());
240 }
241}
242
243PlatformViewIOS::ScopedObserver::ScopedObserver() {}
244
245PlatformViewIOS::ScopedObserver::~ScopedObserver() {
246 if (observer_) {
247 [[NSNotificationCenter defaultCenter] removeObserver:observer_];
248 }
249}
250
251void PlatformViewIOS::ScopedObserver::reset(id<NSObject> observer) {
252 if (observer != observer_) {
253 if (observer_) {
254 [[NSNotificationCenter defaultCenter] removeObserver:observer_];
255 }
256 observer_ = observer;
257 }
258}
259
260} // namespace flutter
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, CALayer *layer)
Used to forward events from the platform view to interested subsystems. This forwarding is done by th...
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...
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_
std::unique_ptr< Surface > CreateRenderingSurface() override
PointerDataDispatcherMaker GetDispatcherMaker() override
Returns a platform-specific PointerDataDispatcherMaker so the Engine can construct the PointerDataPac...
std::shared_ptr< impeller::Context > GetImpellerContext() const override
void SetAccessibilityFeatures(int32_t flags) override
Used by the embedder to specify the features to enable in the accessibility tree generated by the iso...
void UpdateSemantics(int64_t view_id, flutter::SemanticsNodeUpdates update, flutter::CustomAccessibilityActionUpdates actions) override
Used by the framework to tell the embedder to apply the specified semantics node updates....
std::unique_ptr< VsyncWaiter > CreateVSyncWaiter() override
Invoked by the shell to obtain a platform specific vsync waiter. It is optional for platforms to over...
std::shared_ptr< ExternalViewEmbedder > CreateExternalViewEmbedder() override
void SetSemanticsEnabled(bool enabled) override
Used by embedder to notify the running isolate hosted by the engine on the UI thread that the accessi...
void HandlePlatformMessage(std::unique_ptr< flutter::PlatformMessage > message) override
PlatformViewIOS(PlatformView::Delegate &delegate, const std::shared_ptr< IOSContext > &context, __weak FlutterPlatformViewsController *platform_views_controller, const flutter::TaskRunners &task_runners)
FlutterViewController * GetOwnerViewController() const __attribute__((cf_audited_transfer))
void SetSemanticsTreeEnabled(bool enabled) override
Used by the framework to tell the embedder to prepare or clear resoruce for accepting semantics tree.
void OnPreEngineRestart() const override
Gives embedders a chance to react to a "cold restart" of the running isolate. The default implementat...
void SetOwnerViewController(__weak FlutterViewController *owner_controller)
void RegisterExternalTexture(int64_t id, NSObject< FlutterTexture > *texture)
void SetApplicationLocale(std::string locale) override
Used by the framework to set application locale in the embedding.
std::unique_ptr< std::vector< std::string > > ComputePlatformResolvedLocales(const std::vector< std::string > &supported_locale_data) override
Directly invokes platform-specific APIs to compute the locale the platform would have natively resolv...
The interface for Engine to implement.
fml::RefPtr< fml::TaskRunner > GetRasterTaskRunner() const
fml::RefPtr< fml::TaskRunner > GetPlatformTaskRunner() const
virtual bool RunsTasksOnCurrentThread()
VkQueue queue
Definition main.cc:71
G_BEGIN_DECLS GBytes * message
G_BEGIN_DECLS FlutterViewId view_id
#define FML_DLOG(severity)
Definition logging.h:121
#define FML_DCHECK(condition)
Definition logging.h:122
FLUTTER_DARWIN_EXPORT NSNotificationName const FlutterSemanticsUpdateNotification
NSNotificationName const FlutterViewControllerWillDealloc
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.
int64_t texture_id