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