1 // Copyright 2013-2022 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 #include "flutter/lib/ui/ui_dart_state.h"
6
7 #include "flutter/runtime/window_manager.h"
8
9 namespace flutter {
10
11 constexpr int32_t MIN_PLUGIN_SUBCONTAINER_ID = 2000000;
12 static std::unique_ptr<UIDartState> g_ui_state;
13
UIDartState()14 UIDartState::UIDartState() {
15 }
16
~UIDartState()17 UIDartState::~UIDartState() {
18 }
19
Current()20 UIDartState* UIDartState::Current() {
21 if (!g_ui_state) {
22 FML_LOG(ERROR) << "UIDartState not initialize!";
23 return nullptr;
24 }
25 return g_ui_state.get();
26 }
27
Init(int32_t instanceId,fml::WeakPtr<IOManager> io_manager,TaskRunners task_runners)28 void UIDartState::Init(int32_t instanceId,
29 fml::WeakPtr<IOManager> io_manager,
30 TaskRunners task_runners) {
31 if (!g_ui_state) {
32 g_ui_state.reset(new UIDartState());
33 }
34 auto item = std::make_unique<UIDartState::UIStateItem>(std::move(io_manager), std::move(task_runners));
35 g_ui_state->SetCurInstance(instanceId);
36 g_ui_state->SetCurStateItem(instanceId, std::move(item));
37 }
38
DeInit(int32_t instanceId)39 void UIDartState::DeInit(int32_t instanceId) {
40 g_ui_state->RemoveStateItem(instanceId);
41 g_ui_state->RemovePluginParentContainer(instanceId);
42 }
43
SetCurStateItem(int32_t id,std::unique_ptr<UIDartState::UIStateItem> item)44 void UIDartState::SetCurStateItem(int32_t id, std::unique_ptr<UIDartState::UIStateItem> item) {
45 FML_LOG(INFO) << "SetCurStateItem id:" << id;
46 std::lock_guard<std::mutex> lock(mutex_);
47 auto iter = state_map_.find(id);
48 if (iter == state_map_.end()) {
49 state_map_.emplace(id, std::move(item));
50 } else {
51 FML_LOG(WARNING) << "already have item of this instance id:" << id;
52 }
53 }
54
RemoveStateItem(int32_t id)55 void UIDartState::RemoveStateItem(int32_t id) {
56 std::lock_guard<std::mutex> lock(mutex_);
57 state_map_.erase(id);
58 }
59
GetStateById(int32_t id) const60 UIDartState::UIStateItem* UIDartState::GetStateById(int32_t id) const {
61 if (id >= MIN_PLUGIN_SUBCONTAINER_ID) {
62 id = GetPluginParentContainerId(id);
63 }
64 std::lock_guard<std::mutex> lock(mutex_);
65 auto iter = state_map_.find(id);
66 if (iter != state_map_.end()) {
67 return iter->second.get();
68 } else {
69 return nullptr;
70 }
71 }
72
GetSkiaUnrefQueue() const73 fml::RefPtr<SkiaUnrefQueue> UIDartState::GetSkiaUnrefQueue() const {
74 int32_t *ptr = cur_instance_id_.get();
75 if (ptr == nullptr) {
76 FML_LOG(FATAL) << "UIDartState cur id is null";
77 }
78 int32_t id = *ptr;
79 auto item = GetStateById(id);
80 if (item == nullptr) {
81 FML_LOG(FATAL) << "UIDartState cur item is null";
82 }
83 return item->GetSkiaUnrefQueue();
84 }
85
GetIOManager() const86 fml::WeakPtr<IOManager> UIDartState::GetIOManager() const {
87 int32_t *ptr = cur_instance_id_.get();
88 if (ptr == nullptr) {
89 FML_LOG(FATAL) << "UIDartState cur id is null";
90 }
91 int32_t id = *ptr;
92 auto item = GetStateById(id);
93 if (item == nullptr) {
94 FML_LOG(FATAL) << "UIDartState cur item is null";
95 }
96 return item->GetIOManager();
97 }
98
GetTaskRunners() const99 const TaskRunners& UIDartState::GetTaskRunners() const {
100 int32_t *ptr = cur_instance_id_.get();
101 if (ptr == nullptr) {
102 FML_LOG(FATAL) << "UIDartState cur id is null";
103 }
104 int32_t id = *ptr;
105 auto item = GetStateById(id);
106 if (item == nullptr) {
107 FML_LOG(FATAL) << "UIDartState cur item is null";
108 }
109 return item->GetTaskRunners();
110 }
111
window() const112 Window* UIDartState::window() const {
113 int32_t *ptr = cur_instance_id_.get();
114 if (ptr == nullptr) {
115 FML_LOG(ERROR) << "UIDartState cur id is null";
116 return nullptr;
117 }
118 int32_t id = *ptr;
119 if (id >= MIN_PLUGIN_SUBCONTAINER_ID) {
120 id = GetPluginParentContainerId(id);
121 }
122 return WindowManager::GetWindow(id);
123 }
124
GetPluginParentContainerId(int64_t pluginId) const125 int64_t UIDartState::GetPluginParentContainerId(int64_t pluginId) const
126 {
127 std::lock_guard<std::mutex> lock(parentContainerMutex_);
128 auto result = parentContainerMap_.find(pluginId);
129 if (result != parentContainerMap_.end()) {
130 return result->second;
131 } else {
132 FML_LOG(ERROR) << "ParentContainerId is empty.";
133 return 0;
134 }
135 }
136
AddPluginParentContainer(int64_t pluginId,int32_t pluginParentContainerId)137 void UIDartState::AddPluginParentContainer(int64_t pluginId, int32_t pluginParentContainerId)
138 {
139 std::lock_guard<std::mutex> lock(parentContainerMutex_);
140 auto result = parentContainerMap_.try_emplace(pluginId, pluginParentContainerId);
141 if (!result.second) {
142 FML_LOG(ERROR) << "already have pluginSubContainer of this instance, pluginId: " << pluginId;
143 }
144 }
145
RemovePluginParentContainer(int64_t pluginParentContainerId)146 void UIDartState::RemovePluginParentContainer(int64_t pluginParentContainerId)
147 {
148 std::lock_guard<std::mutex> lock(parentContainerMutex_);
149 auto iter = parentContainerMap_.begin();
150 while(iter != parentContainerMap_.end()) {
151 if (iter->second == pluginParentContainerId) {
152 parentContainerMap_.erase(iter++);
153 } else {
154 ++iter;
155 }
156 }
157 }
158
159 } // namespcae blink
160
161