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