Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
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"
15#import "flutter/shell/platform/darwin/ios/InternalFlutterSwift/InternalFlutterSwift.h"
18
20
21namespace flutter {
22
24 const std::shared_ptr<IOSContext>& context,
25 __weak FlutterPlatformViewsController* platform_views_controller,
26 const flutter::TaskRunners& task_runners)
27 : PlatformView(delegate, task_runners),
28 ios_context_(context),
29 platform_views_controller_(platform_views_controller),
30 platform_message_handler_(
31 new PlatformMessageHandlerIos(task_runners.GetPlatformTaskRunner())) {}
32
34 PlatformView::Delegate& delegate,
35 IOSRenderingAPI rendering_api,
36 __weak FlutterPlatformViewsController* platform_views_controller,
37 const flutter::TaskRunners& task_runners,
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 FML_DCHECK(owner_controller_);
145 if (accessibility_bridge_) {
146 accessibility_bridge_.get()->UpdateSemantics(std::move(update), actions);
147 [[NSNotificationCenter defaultCenter] postNotificationName:FlutterSemanticsUpdateNotification
148 object:owner_controller_];
149 }
150}
151
152// |PlatformView|
154 application_locale_ = std::move(locale);
155 ApplyLocaleToOwnerController();
156}
157
158// |PlatformView|
160 FML_DCHECK(owner_controller_);
161 if (enabled) {
162 if (accessibility_bridge_) {
163 return;
164 }
165 accessibility_bridge_ =
166 std::make_unique<AccessibilityBridge>(owner_controller_, this, platform_views_controller_);
167 } else {
168 accessibility_bridge_.reset();
169 }
170}
171
172// |PlatformView|
173std::unique_ptr<VsyncWaiter> PlatformViewIOS::CreateVSyncWaiter() {
174 return std::make_unique<VsyncWaiterIOS>(task_runners_, FlutterDisplayLinkManager.shared);
175}
176
177// |PlatformView|
179 if (accessibility_bridge_) {
180 accessibility_bridge_.get()->clearState();
181 }
182 if (!owner_controller_) {
183 return;
184 }
185 [owner_controller_.platformViewsController reset];
186 [owner_controller_.restorationPlugin reset];
187 [owner_controller_.textInputPlugin reset];
188}
189
190// |PlatformView|
191std::unique_ptr<std::vector<std::string>> PlatformViewIOS::ComputePlatformResolvedLocales(
192 const std::vector<std::string>& supported_locale_data) {
193 size_t localeDataLength = 3;
194 NSMutableArray<NSString*>* supported_locale_identifiers =
195 [NSMutableArray arrayWithCapacity:supported_locale_data.size() / localeDataLength];
196 for (size_t i = 0; i < supported_locale_data.size(); i += localeDataLength) {
197 NSDictionary<NSString*, NSString*>* dict = @{
198 NSLocaleLanguageCode : [NSString stringWithUTF8String:supported_locale_data[i].c_str()]
199 ?: @"",
200 NSLocaleCountryCode : [NSString stringWithUTF8String:supported_locale_data[i + 1].c_str()]
201 ?: @"",
202 NSLocaleScriptCode : [NSString stringWithUTF8String:supported_locale_data[i + 2].c_str()]
203 ?: @""
204 };
205 [supported_locale_identifiers addObject:[NSLocale localeIdentifierFromComponents:dict]];
206 }
207 NSArray<NSString*>* result =
208 [NSBundle preferredLocalizationsFromArray:supported_locale_identifiers];
209
210 // Output format should be either empty or 3 strings for language, country, and script.
211 std::unique_ptr<std::vector<std::string>> out = std::make_unique<std::vector<std::string>>();
212
213 if (result != nullptr && [result count] > 0) {
214 NSLocale* locale = [NSLocale localeWithLocaleIdentifier:[result firstObject]];
215 NSString* languageCode = [locale languageCode];
216 out->emplace_back(languageCode == nullptr ? "" : languageCode.UTF8String);
217 NSString* countryCode = [locale countryCode];
218 out->emplace_back(countryCode == nullptr ? "" : countryCode.UTF8String);
219 NSString* scriptCode = [locale scriptCode];
220 out->emplace_back(scriptCode == nullptr ? "" : scriptCode.UTF8String);
221 }
222 return out;
223}
224
225void PlatformViewIOS::ApplyLocaleToOwnerController() {
226 if (owner_controller_) {
227 owner_controller_.applicationLocale =
228 application_locale_.empty() ? nil : @(application_locale_.data());
229 }
230}
231
232PlatformViewIOS::ScopedObserver::ScopedObserver() {}
233
234PlatformViewIOS::ScopedObserver::~ScopedObserver() {
235 if (observer_) {
236 [[NSNotificationCenter defaultCenter] removeObserver:observer_];
237 }
238}
239
240void PlatformViewIOS::ScopedObserver::reset(id<NSObject> observer) {
241 if (observer != observer_) {
242 if (observer_) {
243 [[NSNotificationCenter defaultCenter] removeObserver:observer_];
244 }
245 observer_ = observer;
246 }
247}
248
249} // 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...
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...
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 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 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
const char * 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.
std::shared_ptr< ContextGLES > context
int64_t texture_id