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"
19 PlatformViewIOS::AccessibilityBridgeManager::AccessibilityBridgeManager(
20 const std::function<
void(
bool)>& set_semantics_enabled)
21 : AccessibilityBridgeManager(set_semantics_enabled, nullptr) {}
23 PlatformViewIOS::AccessibilityBridgeManager::AccessibilityBridgeManager(
24 const std::function<
void(
bool)>& set_semantics_enabled,
25 AccessibilityBridge* bridge)
26 : accessibility_bridge_(bridge), set_semantics_enabled_(set_semantics_enabled) {
28 set_semantics_enabled_(
true);
32 void PlatformViewIOS::AccessibilityBridgeManager::Set(std::unique_ptr<AccessibilityBridge> bridge) {
33 accessibility_bridge_ = std::move(bridge);
34 set_semantics_enabled_(
true);
37 void PlatformViewIOS::AccessibilityBridgeManager::Clear() {
38 set_semantics_enabled_(
false);
39 accessibility_bridge_.reset();
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_(
55 PlatformView::Delegate& delegate,
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)
67 static_cast<MsaaSampleCount>(delegate.OnPlatformViewGetSettings().msaa_samples),
68 is_gpu_disabled_sync_switch),
69 platform_views_controller,
75 void PlatformViewIOS::HandlePlatformMessage(std::unique_ptr<flutter::PlatformMessage> message) {
76 platform_message_handler_->HandlePlatformMessage(std::move(message));
80 return owner_controller_;
84 const fml::WeakNSObject<FlutterViewController>& owner_controller) {
85 FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread());
86 std::lock_guard<std::mutex> guard(ios_surface_mutex_);
87 if (ios_surface_ || !owner_controller) {
90 accessibility_bridge_.Clear();
92 owner_controller_ = owner_controller;
96 dealloc_view_controller_observer_.reset(
98 object:owner_controller_.get()
99 queue:[NSOperationQueue mainQueue]
100 usingBlock:^(NSNotification* note) {
102 accessibility_bridge_.Clear();
103 owner_controller_.reset();
106 if (owner_controller_ && [owner_controller_.get() isViewLoaded]) {
116 FML_DCHECK(owner_controller_);
117 FML_DCHECK(owner_controller_.get().isViewLoaded)
118 <<
"FlutterViewController's view should be loaded "
119 "before attaching to PlatformViewIOS.";
120 auto flutter_view =
static_cast<FlutterView*
>(owner_controller_.get().view);
121 auto ca_layer = fml::scoped_nsobject<CALayer>{[[flutter_view layer] retain]};
123 FML_DCHECK(ios_surface_ !=
nullptr);
125 if (accessibility_bridge_) {
126 accessibility_bridge_.Set(std::make_unique<AccessibilityBridge>(
127 owner_controller_.get(),
this, [owner_controller_.get() platformViewsController]));
132 return [](DefaultPointerDataDispatcher::Delegate& delegate) {
133 return std::make_unique<SmoothPointerDataDispatcher>(delegate);
138 NSObject<FlutterTexture>* texture) {
139 RegisterTexture(ios_context_->CreateExternalTexture(
140 texture_id, fml::scoped_nsobject<NSObject<FlutterTexture>>{[texture retain]}));
144 std::unique_ptr<Surface> PlatformViewIOS::CreateRenderingSurface() {
145 FML_DCHECK(task_runners_.GetRasterTaskRunner()->RunsTasksOnCurrentThread());
146 std::lock_guard<std::mutex> guard(ios_surface_mutex_);
148 FML_DLOG(INFO) <<
"Could not CreateRenderingSurface, this PlatformViewIOS "
149 "has no ViewController.";
152 return ios_surface_->CreateGPUSurface(ios_context_->GetMainContext().get());
156 std::shared_ptr<ExternalViewEmbedder> PlatformViewIOS::CreateExternalViewEmbedder() {
157 return std::make_shared<IOSExternalViewEmbedder>(platform_views_controller_, ios_context_);
161 sk_sp<GrDirectContext> PlatformViewIOS::CreateResourceContext()
const {
162 return ios_context_->CreateResourceContext();
166 std::shared_ptr<impeller::Context> PlatformViewIOS::GetImpellerContext()
const {
167 return ios_context_->GetImpellerContext();
172 if (!owner_controller_) {
173 FML_LOG(WARNING) <<
"Could not set semantics to enabled, this "
174 "PlatformViewIOS has no ViewController.";
177 if (enabled && !accessibility_bridge_) {
178 accessibility_bridge_.Set(std::make_unique<AccessibilityBridge>(
179 owner_controller_.get(),
this, [owner_controller_.get() platformViewsController]));
180 }
else if (!enabled && accessibility_bridge_) {
181 accessibility_bridge_.Clear();
183 PlatformView::SetSemanticsEnabled(enabled);
188 void PlatformViewIOS::SetAccessibilityFeatures(int32_t flags) {
189 PlatformView::SetAccessibilityFeatures(flags);
193 void PlatformViewIOS::UpdateSemantics(flutter::SemanticsNodeUpdates update,
194 flutter::CustomAccessibilityActionUpdates actions) {
195 FML_DCHECK(owner_controller_);
196 if (accessibility_bridge_) {
197 accessibility_bridge_.get()->UpdateSemantics(std::move(update), actions);
199 object:owner_controller_.get()];
204 std::unique_ptr<VsyncWaiter> PlatformViewIOS::CreateVSyncWaiter() {
205 return std::make_unique<VsyncWaiterIOS>(task_runners_);
208 void PlatformViewIOS::OnPreEngineRestart()
const {
209 if (accessibility_bridge_) {
210 accessibility_bridge_.get()->clearState();
212 if (!owner_controller_) {
215 [owner_controller_.get() platformViewsController]->Reset();
216 [[owner_controller_.get() restorationPlugin] reset];
219 std::unique_ptr<std::vector<std::string>> PlatformViewIOS::ComputePlatformResolvedLocales(
220 const std::vector<std::string>& supported_locale_data) {
221 size_t localeDataLength = 3;
222 NSMutableArray<NSString*>* supported_locale_identifiers =
223 [NSMutableArray arrayWithCapacity:supported_locale_data.size() / localeDataLength];
224 for (
size_t i = 0; i < supported_locale_data.size(); i += localeDataLength) {
225 NSDictionary<NSString*, NSString*>* dict = @{
226 NSLocaleLanguageCode : [NSString stringWithUTF8String:supported_locale_data[i].c_str()]
228 NSLocaleCountryCode : [NSString stringWithUTF8String:supported_locale_data[i + 1].c_str()]
230 NSLocaleScriptCode : [NSString stringWithUTF8String:supported_locale_data[i + 2].c_str()]
233 [supported_locale_identifiers addObject:[NSLocale localeIdentifierFromComponents:dict]];
235 NSArray<NSString*>* result =
236 [NSBundle preferredLocalizationsFromArray:supported_locale_identifiers];
239 std::unique_ptr<std::vector<std::string>> out = std::make_unique<std::vector<std::string>>();
241 if (result !=
nullptr && [result count] > 0) {
242 NSLocale* locale = [NSLocale localeWithLocaleIdentifier:[result firstObject]];
243 NSString* languageCode = [locale languageCode];
244 out->emplace_back(languageCode ==
nullptr ?
"" : languageCode.UTF8String);
245 NSString* countryCode = [locale countryCode];
246 out->emplace_back(countryCode ==
nullptr ?
"" : countryCode.UTF8String);
247 NSString* scriptCode = [locale scriptCode];
248 out->emplace_back(scriptCode ==
nullptr ?
"" : scriptCode.UTF8String);
253 PlatformViewIOS::ScopedObserver::ScopedObserver() {}
255 PlatformViewIOS::ScopedObserver::~ScopedObserver() {
257 [[NSNotificationCenter defaultCenter] removeObserver:observer_];
262 void PlatformViewIOS::ScopedObserver::reset(id<NSObject> observer) {
263 if (observer != observer_) {
265 [[NSNotificationCenter defaultCenter] removeObserver:observer_];
268 observer_ = observer;