| Flutter iOS Embedder |

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/common/InternalFlutterSwiftCommon/InternalFlutterSwiftCommon.h"
15 #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h"
16 #import "flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h"
17
18 FLUTTER_ASSERT_ARC
19
20 namespace flutter {
21
22 PlatformViewIOS::PlatformViewIOS(PlatformView::Delegate& delegate,
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
32 PlatformViewIOS::PlatformViewIOS(
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
42 ? IOSRenderingBackend::kImpeller
43 : IOSRenderingBackend::kSkia,
44 is_gpu_disabled_sync_switch,
45 delegate.OnPlatformViewGetSettings()),
46 platform_views_controller,
47 task_runners) {}
48
49 PlatformViewIOS::~PlatformViewIOS() = default;
50
51 // |PlatformView|
52 void PlatformViewIOS::HandlePlatformMessage(std::unique_ptr<flutter::PlatformMessage> message) {
53 platform_message_handler_->HandlePlatformMessage(std::move(message));
54 }
55
56 FlutterViewController* PlatformViewIOS::GetOwnerViewController() const {
57 return owner_controller_;
58 }
59
60 void PlatformViewIOS::SetOwnerViewController(__weak FlutterViewController* owner_controller) {
61 FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread());
62 std::lock_guard<std::mutex> guard(ios_surface_mutex_);
63 if (ios_surface_ || !owner_controller) {
64 NotifyDestroyed();
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
92 void PlatformViewIOS::attachView() {
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
107 PointerDataDispatcherMaker PlatformViewIOS::GetDispatcherMaker() {
108 return [](DefaultPointerDataDispatcher::Delegate& delegate) {
109 return std::make_unique<SmoothPointerDataDispatcher>(delegate);
110 };
111 }
112
113 void PlatformViewIOS::RegisterExternalTexture(int64_t texture_id,
114 NSObject<FlutterTexture>* texture) {
115 RegisterTexture(ios_context_->CreateExternalTexture(texture_id, texture));
116 }
117
118 // |PlatformView|
119 std::unique_ptr<Surface> PlatformViewIOS::CreateRenderingSurface() {
120 FML_DCHECK(task_runners_.GetRasterTaskRunner()->RunsTasksOnCurrentThread());
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|
131 std::shared_ptr<ExternalViewEmbedder> PlatformViewIOS::CreateExternalViewEmbedder() {
132 return std::make_shared<IOSExternalViewEmbedder>(platform_views_controller_, ios_context_);
133 }
134
135 // |PlatformView|
136 std::shared_ptr<impeller::Context> PlatformViewIOS::GetImpellerContext() const {
137 return ios_context_->GetImpellerContext();
138 }
139
140 // |PlatformView|
141 void PlatformViewIOS::SetSemanticsEnabled(bool enabled) {
142 PlatformView::SetSemanticsEnabled(enabled);
143 }
144
145 // |PlatformView|
146 void PlatformViewIOS::SetAccessibilityFeatures(int32_t flags) {
147 PlatformView::SetAccessibilityFeatures(flags);
148 }
149
150 // |PlatformView|
151 void PlatformViewIOS::UpdateSemantics(int64_t view_id,
152 flutter::SemanticsNodeUpdates update,
153 flutter::CustomAccessibilityActionUpdates actions) {
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|
164 void PlatformViewIOS::SetApplicationLocale(std::string locale) {
165 application_locale_ = std::move(locale);
166 ApplyLocaleToOwnerController();
167 }
168
169 // |PlatformView|
170 void PlatformViewIOS::SetSemanticsTreeEnabled(bool enabled) {
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|
184 std::unique_ptr<VsyncWaiter> PlatformViewIOS::CreateVSyncWaiter() {
185 return std::make_unique<VsyncWaiterIOS>(task_runners_);
186 }
187
188 // |PlatformView|
189 void PlatformViewIOS::OnPreEngineRestart() const {
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|
202 std::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
236 void PlatformViewIOS::ApplyLocaleToOwnerController() {
237 if (owner_controller_) {
238 owner_controller_.applicationLocale =
239 application_locale_.empty() ? nil : @(application_locale_.data());
240 }
241 }
242
243 PlatformViewIOS::ScopedObserver::ScopedObserver() {}
244
245 PlatformViewIOS::ScopedObserver::~ScopedObserver() {
246 if (observer_) {
247 [[NSNotificationCenter defaultCenter] removeObserver:observer_];
248 }
249 }
250
251 void 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
FlutterSemanticsUpdateNotification
FLUTTER_DARWIN_EXPORT NSNotificationName const FlutterSemanticsUpdateNotification
Definition: FlutterViewController.mm:48
FlutterViewControllerWillDealloc
NSNotificationName const FlutterViewControllerWillDealloc
Definition: FlutterViewController.mm:49
FlutterViewController_Internal.h
flutter::IOSContext
Manages the lifetime of the on-screen and off-screen rendering contexts on iOS. On-screen contexts ar...
Definition: ios_context.h:39
flutter::IOSSurface::Create
static std::unique_ptr< IOSSurface > Create(std::shared_ptr< IOSContext > context, CALayer *layer)
Definition: ios_surface.mm:18
flutter::PlatformMessageHandlerIos
Definition: platform_message_handler_ios.h:14
flutter::PlatformViewIOS
Definition: platform_view_ios.h:40
flutter::PlatformViewIOS::attachView
void attachView()
Definition: platform_view_ios.mm:92
flutter::PlatformViewIOS::CreateRenderingSurface
std::unique_ptr< Surface > CreateRenderingSurface() override
Definition: platform_view_ios.mm:119
flutter::PlatformViewIOS::GetDispatcherMaker
PointerDataDispatcherMaker GetDispatcherMaker() override
Definition: platform_view_ios.mm:107
flutter::PlatformViewIOS::GetImpellerContext
std::shared_ptr< impeller::Context > GetImpellerContext() const override
Definition: platform_view_ios.mm:136
flutter::PlatformViewIOS::SetAccessibilityFeatures
void SetAccessibilityFeatures(int32_t flags) override
Definition: platform_view_ios.mm:146
flutter::PlatformViewIOS::UpdateSemantics
void UpdateSemantics(int64_t view_id, flutter::SemanticsNodeUpdates update, flutter::CustomAccessibilityActionUpdates actions) override
Definition: platform_view_ios.mm:151
flutter::PlatformViewIOS::CreateVSyncWaiter
std::unique_ptr< VsyncWaiter > CreateVSyncWaiter() override
Definition: platform_view_ios.mm:184
flutter::PlatformViewIOS::CreateExternalViewEmbedder
std::shared_ptr< ExternalViewEmbedder > CreateExternalViewEmbedder() override
Definition: platform_view_ios.mm:131
flutter::PlatformViewIOS::SetSemanticsEnabled
void SetSemanticsEnabled(bool enabled) override
Definition: platform_view_ios.mm:141
flutter::PlatformViewIOS::HandlePlatformMessage
void HandlePlatformMessage(std::unique_ptr< flutter::PlatformMessage > message) override
Definition: platform_view_ios.mm:52
flutter::PlatformViewIOS::PlatformViewIOS
PlatformViewIOS(PlatformView::Delegate &delegate, const std::shared_ptr< IOSContext > &context, __weak FlutterPlatformViewsController *platform_views_controller, const flutter::TaskRunners &task_runners)
Definition: platform_view_ios.mm:22
flutter::PlatformViewIOS::GetOwnerViewController
FlutterViewController * GetOwnerViewController() const __attribute__((cf_audited_transfer))
Definition: platform_view_ios.mm:56
flutter::PlatformViewIOS::SetSemanticsTreeEnabled
void SetSemanticsTreeEnabled(bool enabled) override
Definition: platform_view_ios.mm:170
flutter::PlatformViewIOS::OnPreEngineRestart
void OnPreEngineRestart() const override
Definition: platform_view_ios.mm:189
flutter::PlatformViewIOS::SetOwnerViewController
void SetOwnerViewController(__weak FlutterViewController *owner_controller)
Definition: platform_view_ios.mm:60
flutter::PlatformViewIOS::RegisterExternalTexture
void RegisterExternalTexture(int64_t id, NSObject< FlutterTexture > *texture)
Definition: platform_view_ios.mm:113
flutter::PlatformViewIOS::SetApplicationLocale
void SetApplicationLocale(std::string locale) override
Definition: platform_view_ios.mm:164
flutter::PlatformViewIOS::~PlatformViewIOS
~PlatformViewIOS() override
flutter::PlatformViewIOS::ComputePlatformResolvedLocales
std::unique_ptr< std::vector< std::string > > ComputePlatformResolvedLocales(const std::vector< std::string > &supported_locale_data) override
Definition: platform_view_ios.mm:202
FlutterPlatformViewsController
Definition: FlutterPlatformViewsController.h:31
FlutterViewController
Definition: FlutterViewController.h:57
FlutterView
Definition: FlutterView.h:33
FLUTTER_ASSERT_ARC
Definition: FlutterChannelKeyResponder.mm:13
flutter
Definition: accessibility_bridge.h:26
flutter::IOSRenderingBackend
IOSRenderingBackend
Definition: rendering_api_selection.h:19
flutter::IOSRenderingBackend::kImpeller
@ kImpeller
flutter::IOSRenderingBackend::kSkia
@ kSkia
flutter::IOSRenderingAPI
IOSRenderingAPI
Definition: rendering_api_selection.h:14
platform_view_ios.h
texture_id
int64_t texture_id
Definition: texture_registrar_unittests.cc:24
vsync_waiter_ios.h