| 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 |