OLD | NEW |
| (Empty) |
1 // Copyright 2016 The Chromium 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 "blimp/client/core/blimp_client_context_impl.h" | |
6 | |
7 #include <utility> | |
8 | |
9 #include "base/bind.h" | |
10 #include "base/command_line.h" | |
11 #include "base/memory/ptr_util.h" | |
12 #include "base/message_loop/message_loop.h" | |
13 #include "base/metrics/histogram_macros.h" | |
14 #include "base/threading/sequenced_task_runner_handle.h" | |
15 #include "blimp/client/core/blimp_client_switches.h" | |
16 #include "blimp/client/core/compositor/blimp_compositor_dependencies.h" | |
17 #include "blimp/client/core/compositor/blob_channel_feature.h" | |
18 #include "blimp/client/core/contents/blimp_contents_impl.h" | |
19 #include "blimp/client/core/contents/blimp_contents_manager.h" | |
20 #include "blimp/client/core/contents/ime_feature.h" | |
21 #include "blimp/client/core/contents/navigation_feature.h" | |
22 #include "blimp/client/core/contents/tab_control_feature.h" | |
23 #include "blimp/client/core/feedback/blimp_feedback_data.h" | |
24 #include "blimp/client/core/geolocation/geolocation_feature.h" | |
25 #include "blimp/client/core/render_widget/render_widget_feature.h" | |
26 #include "blimp/client/core/session/cross_thread_network_event_observer.h" | |
27 #include "blimp/client/core/settings/settings_feature.h" | |
28 #include "blimp/client/public/blimp_client_context_delegate.h" | |
29 #include "blimp/client/public/compositor/compositor_dependencies.h" | |
30 #include "device/geolocation/geolocation_delegate.h" | |
31 #include "device/geolocation/location_arbitrator.h" | |
32 #include "ui/gfx/native_widget_types.h" | |
33 | |
34 #if defined(OS_ANDROID) | |
35 #include "blimp/client/core/android/blimp_client_context_impl_android.h" | |
36 #endif // OS_ANDROID | |
37 | |
38 namespace blimp { | |
39 namespace client { | |
40 | |
41 namespace { | |
42 | |
43 const char kDefaultAssignerUrl[] = | |
44 "https://blimp-pa.googleapis.com/v1/assignment"; | |
45 | |
46 void DropConnectionOnIOThread(ClientNetworkComponents* net_components) { | |
47 net_components->GetBrowserConnectionHandler()->DropCurrentConnection(); | |
48 } | |
49 | |
50 } // namespace | |
51 | |
52 // This function is declared in //blimp/client/public/blimp_client_context.h, | |
53 // and either this function or the one in | |
54 // //blimp/client/core/dummy_blimp_client_context.cc should be linked in to | |
55 // any binary using BlimpClientContext::Create. | |
56 // static | |
57 BlimpClientContext* BlimpClientContext::Create( | |
58 scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner, | |
59 scoped_refptr<base::SingleThreadTaskRunner> file_thread_task_runner, | |
60 std::unique_ptr<CompositorDependencies> compositor_dependencies) { | |
61 #if defined(OS_ANDROID) | |
62 return new BlimpClientContextImplAndroid(io_thread_task_runner, | |
63 file_thread_task_runner, | |
64 std::move(compositor_dependencies)); | |
65 #else | |
66 return new BlimpClientContextImpl(io_thread_task_runner, | |
67 file_thread_task_runner, | |
68 std::move(compositor_dependencies)); | |
69 #endif // defined(OS_ANDROID) | |
70 } | |
71 | |
72 BlimpClientContextImpl::BlimpClientContextImpl( | |
73 scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner, | |
74 scoped_refptr<base::SingleThreadTaskRunner> file_thread_task_runner, | |
75 std::unique_ptr<CompositorDependencies> compositor_dependencies) | |
76 : BlimpClientContext(), | |
77 io_thread_task_runner_(io_thread_task_runner), | |
78 file_thread_task_runner_(file_thread_task_runner), | |
79 blimp_compositor_dependencies_( | |
80 base::MakeUnique<BlimpCompositorDependencies>( | |
81 std::move(compositor_dependencies))), | |
82 blob_channel_feature_(new BlobChannelFeature(this)), | |
83 geolocation_feature_(base::MakeUnique<GeolocationFeature>( | |
84 base::MakeUnique<device::LocationArbitrator>( | |
85 base::MakeUnique<device::GeolocationDelegate>()))), | |
86 ime_feature_(new ImeFeature), | |
87 navigation_feature_(new NavigationFeature), | |
88 render_widget_feature_(new RenderWidgetFeature), | |
89 settings_feature_(new SettingsFeature), | |
90 tab_control_feature_(new TabControlFeature), | |
91 blimp_contents_manager_( | |
92 new BlimpContentsManager(blimp_compositor_dependencies_.get(), | |
93 ime_feature_.get(), | |
94 navigation_feature_.get(), | |
95 render_widget_feature_.get(), | |
96 tab_control_feature_.get())), | |
97 weak_factory_(this) { | |
98 net_components_.reset(new ClientNetworkComponents( | |
99 base::MakeUnique<CrossThreadNetworkEventObserver>( | |
100 connection_status_.GetWeakPtr(), | |
101 base::SequencedTaskRunnerHandle::Get()))); | |
102 | |
103 // The |thread_pipe_manager_| must be set up correctly before features are | |
104 // registered. | |
105 thread_pipe_manager_ = base::MakeUnique<ThreadPipeManager>( | |
106 io_thread_task_runner_, net_components_->GetBrowserConnectionHandler()); | |
107 | |
108 RegisterFeatures(); | |
109 InitializeSettings(); | |
110 | |
111 // Initialize must only be posted after the features have been | |
112 // registered. | |
113 io_thread_task_runner_->PostTask( | |
114 FROM_HERE, base::Bind(&ClientNetworkComponents::Initialize, | |
115 base::Unretained(net_components_.get()))); | |
116 | |
117 UMA_HISTOGRAM_BOOLEAN("Blimp.Supported", true); | |
118 } | |
119 | |
120 BlimpClientContextImpl::~BlimpClientContextImpl() { | |
121 io_thread_task_runner_->DeleteSoon(FROM_HERE, net_components_.release()); | |
122 } | |
123 | |
124 void BlimpClientContextImpl::SetDelegate(BlimpClientContextDelegate* delegate) { | |
125 delegate_ = delegate; | |
126 } | |
127 | |
128 std::unique_ptr<BlimpContents> BlimpClientContextImpl::CreateBlimpContents( | |
129 gfx::NativeWindow window) { | |
130 std::unique_ptr<BlimpContents> blimp_contents = | |
131 blimp_contents_manager_->CreateBlimpContents(window); | |
132 if (blimp_contents) | |
133 delegate_->AttachBlimpContentsHelpers(blimp_contents.get()); | |
134 return blimp_contents; | |
135 } | |
136 | |
137 void BlimpClientContextImpl::Connect() { | |
138 // Start Blimp authentication flow. The OAuth2 token will be used in | |
139 // assignment source. | |
140 GetIdentitySource()->Connect(); | |
141 } | |
142 | |
143 void BlimpClientContextImpl::ConnectWithAssignment( | |
144 const Assignment& assignment) { | |
145 io_thread_task_runner_->PostTask( | |
146 FROM_HERE, | |
147 base::Bind(&ClientNetworkComponents::ConnectWithAssignment, | |
148 base::Unretained(net_components_.get()), assignment)); | |
149 } | |
150 | |
151 std::unordered_map<std::string, std::string> | |
152 BlimpClientContextImpl::CreateFeedbackData() { | |
153 return CreateBlimpFeedbackData(blimp_contents_manager_.get()); | |
154 } | |
155 | |
156 void BlimpClientContextImpl::OnAuthTokenReceived( | |
157 const std::string& client_auth_token) { | |
158 if (!assignment_source_) { | |
159 assignment_source_.reset(new AssignmentSource( | |
160 GetAssignerURL(), io_thread_task_runner_, file_thread_task_runner_)); | |
161 } | |
162 | |
163 VLOG(1) << "Trying to get assignment."; | |
164 assignment_source_->GetAssignment( | |
165 client_auth_token, | |
166 base::Bind(&BlimpClientContextImpl::OnAssignmentReceived, | |
167 weak_factory_.GetWeakPtr())); | |
168 } | |
169 | |
170 GURL BlimpClientContextImpl::GetAssignerURL() { | |
171 return GURL(kDefaultAssignerUrl); | |
172 } | |
173 | |
174 IdentitySource* BlimpClientContextImpl::GetIdentitySource() { | |
175 if (!identity_source_) { | |
176 CreateIdentitySource(); | |
177 } | |
178 return identity_source_.get(); | |
179 } | |
180 | |
181 ConnectionStatus* BlimpClientContextImpl::GetConnectionStatus() { | |
182 return &connection_status_; | |
183 } | |
184 | |
185 void BlimpClientContextImpl::OnAssignmentReceived( | |
186 AssignmentRequestResult result, | |
187 const Assignment& assignment) { | |
188 VLOG(1) << "Assignment result: " << result; | |
189 | |
190 // Cache engine info. | |
191 connection_status_.OnAssignmentResult(result, assignment); | |
192 | |
193 // Inform the embedder of the assignment result. | |
194 if (delegate_) { | |
195 delegate_->OnAssignmentConnectionAttempted(result, assignment); | |
196 } | |
197 | |
198 if (result != ASSIGNMENT_REQUEST_RESULT_OK) { | |
199 LOG(ERROR) << "Assignment failed, reason: " << result; | |
200 return; | |
201 } | |
202 | |
203 ConnectWithAssignment(assignment); | |
204 } | |
205 | |
206 void BlimpClientContextImpl::RegisterFeatures() { | |
207 // Register features' message senders and receivers. | |
208 thread_pipe_manager_->RegisterFeature(BlimpMessage::kBlobChannel, | |
209 blob_channel_feature_.get()); | |
210 geolocation_feature_->set_outgoing_message_processor( | |
211 thread_pipe_manager_->RegisterFeature(BlimpMessage::kGeolocation, | |
212 geolocation_feature_.get())); | |
213 ime_feature_->set_outgoing_message_processor( | |
214 thread_pipe_manager_->RegisterFeature(BlimpMessage::kIme, | |
215 ime_feature_.get())); | |
216 navigation_feature_->set_outgoing_message_processor( | |
217 thread_pipe_manager_->RegisterFeature(BlimpMessage::kNavigation, | |
218 navigation_feature_.get())); | |
219 render_widget_feature_->set_outgoing_input_message_processor( | |
220 thread_pipe_manager_->RegisterFeature(BlimpMessage::kInput, | |
221 render_widget_feature_.get())); | |
222 render_widget_feature_->set_outgoing_compositor_message_processor( | |
223 thread_pipe_manager_->RegisterFeature(BlimpMessage::kCompositor, | |
224 render_widget_feature_.get())); | |
225 thread_pipe_manager_->RegisterFeature(BlimpMessage::kRenderWidget, | |
226 render_widget_feature_.get()); | |
227 settings_feature_->set_outgoing_message_processor( | |
228 thread_pipe_manager_->RegisterFeature(BlimpMessage::kSettings, | |
229 settings_feature_.get())); | |
230 tab_control_feature_->set_outgoing_message_processor( | |
231 thread_pipe_manager_->RegisterFeature(BlimpMessage::kTabControl, | |
232 tab_control_feature_.get())); | |
233 } | |
234 | |
235 void BlimpClientContextImpl::InitializeSettings() { | |
236 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | |
237 switches::kDownloadWholeDocument)) | |
238 settings_feature_->SetRecordWholeDocument(true); | |
239 } | |
240 | |
241 void BlimpClientContextImpl::DropConnection() { | |
242 io_thread_task_runner_->PostTask( | |
243 FROM_HERE, base::Bind(&DropConnectionOnIOThread, net_components_.get())); | |
244 } | |
245 | |
246 void BlimpClientContextImpl::CreateIdentitySource() { | |
247 identity_source_ = base::MakeUnique<IdentitySource>( | |
248 delegate_, base::Bind(&BlimpClientContextImpl::OnAuthTokenReceived, | |
249 base::Unretained(this))); | |
250 } | |
251 | |
252 void BlimpClientContextImpl::OnImageDecodeError() { | |
253 // Currently we just drop the connection on image decoding error. | |
254 DropConnection(); | |
255 } | |
256 | |
257 } // namespace client | |
258 } // namespace blimp | |
OLD | NEW |