| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 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 "content/child/background_sync/background_sync_provider.h" | |
| 6 | |
| 7 #include <stddef.h> | |
| 8 | |
| 9 #include <memory> | |
| 10 #include <utility> | |
| 11 | |
| 12 #include "base/bind.h" | |
| 13 #include "base/lazy_instance.h" | |
| 14 #include "base/single_thread_task_runner.h" | |
| 15 #include "base/threading/thread_local.h" | |
| 16 #include "content/child/background_sync/background_sync_type_converters.h" | |
| 17 #include "content/child/child_thread_impl.h" | |
| 18 #include "content/child/service_worker/web_service_worker_registration_impl.h" | |
| 19 #include "services/service_manager/public/cpp/interface_provider.h" | |
| 20 #include "third_party/WebKit/public/platform/modules/background_sync/WebSyncErro
r.h" | |
| 21 #include "third_party/WebKit/public/platform/modules/background_sync/WebSyncRegi
stration.h" | |
| 22 | |
| 23 using base::LazyInstance; | |
| 24 using base::ThreadLocalPointer; | |
| 25 | |
| 26 namespace content { | |
| 27 namespace { | |
| 28 | |
| 29 // Returns the id of the given |service_worker_registration|, which | |
| 30 // is only available on the implementation of the interface. | |
| 31 int64_t GetServiceWorkerRegistrationId( | |
| 32 blink::WebServiceWorkerRegistration* service_worker_registration) { | |
| 33 return static_cast<WebServiceWorkerRegistrationImpl*>( | |
| 34 service_worker_registration)->registration_id(); | |
| 35 } | |
| 36 | |
| 37 void ConnectToServiceOnMainThread( | |
| 38 blink::mojom::BackgroundSyncServiceRequest request) { | |
| 39 DCHECK(ChildThreadImpl::current()); | |
| 40 ChildThreadImpl::current()->GetRemoteInterfaces()->GetInterface( | |
| 41 std::move(request)); | |
| 42 } | |
| 43 | |
| 44 LazyInstance<ThreadLocalPointer<BackgroundSyncProvider>>::Leaky | |
| 45 g_sync_provider_tls = LAZY_INSTANCE_INITIALIZER; | |
| 46 | |
| 47 } // namespace | |
| 48 | |
| 49 BackgroundSyncProvider::BackgroundSyncProvider( | |
| 50 const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) | |
| 51 : main_thread_task_runner_(main_task_runner) { | |
| 52 DCHECK(main_task_runner); | |
| 53 g_sync_provider_tls.Pointer()->Set(this); | |
| 54 } | |
| 55 | |
| 56 BackgroundSyncProvider::~BackgroundSyncProvider() { | |
| 57 g_sync_provider_tls.Pointer()->Set(nullptr); | |
| 58 } | |
| 59 | |
| 60 // static | |
| 61 BackgroundSyncProvider* | |
| 62 BackgroundSyncProvider::GetOrCreateThreadSpecificInstance( | |
| 63 base::SingleThreadTaskRunner* main_thread_task_runner) { | |
| 64 DCHECK(main_thread_task_runner); | |
| 65 if (g_sync_provider_tls.Pointer()->Get()) | |
| 66 return g_sync_provider_tls.Pointer()->Get(); | |
| 67 | |
| 68 bool have_worker_id = (WorkerThread::GetCurrentId() > 0); | |
| 69 if (!main_thread_task_runner->BelongsToCurrentThread() && !have_worker_id) { | |
| 70 // On a worker thread, this could happen if this method is called | |
| 71 // very late (say by a garbage collected blink::mojom::SyncRegistration). | |
| 72 return nullptr; | |
| 73 } | |
| 74 | |
| 75 BackgroundSyncProvider* instance = | |
| 76 new BackgroundSyncProvider(main_thread_task_runner); | |
| 77 | |
| 78 if (have_worker_id) { | |
| 79 // For worker threads, use the observer interface to clean up when workers | |
| 80 // are stopped. | |
| 81 WorkerThread::AddObserver(instance); | |
| 82 } | |
| 83 | |
| 84 return instance; | |
| 85 } | |
| 86 | |
| 87 void BackgroundSyncProvider::registerBackgroundSync( | |
| 88 const blink::WebSyncRegistration* options, | |
| 89 blink::WebServiceWorkerRegistration* service_worker_registration, | |
| 90 blink::WebSyncRegistrationCallbacks* callbacks) { | |
| 91 DCHECK(options); | |
| 92 DCHECK(service_worker_registration); | |
| 93 DCHECK(callbacks); | |
| 94 int64_t service_worker_registration_id = | |
| 95 GetServiceWorkerRegistrationId(service_worker_registration); | |
| 96 std::unique_ptr<const blink::WebSyncRegistration> optionsPtr(options); | |
| 97 std::unique_ptr<blink::WebSyncRegistrationCallbacks> callbacksPtr(callbacks); | |
| 98 | |
| 99 // base::Unretained is safe here, as the mojo channel will be deleted (and | |
| 100 // will wipe its callbacks) before 'this' is deleted. | |
| 101 GetBackgroundSyncServicePtr()->Register( | |
| 102 mojo::ConvertTo<blink::mojom::SyncRegistrationPtr>(*(optionsPtr.get())), | |
| 103 service_worker_registration_id, | |
| 104 base::Bind(&BackgroundSyncProvider::RegisterCallback, | |
| 105 base::Unretained(this), | |
| 106 base::Passed(std::move(callbacksPtr)))); | |
| 107 } | |
| 108 | |
| 109 void BackgroundSyncProvider::getRegistrations( | |
| 110 blink::WebServiceWorkerRegistration* service_worker_registration, | |
| 111 blink::WebSyncGetRegistrationsCallbacks* callbacks) { | |
| 112 DCHECK(service_worker_registration); | |
| 113 DCHECK(callbacks); | |
| 114 int64_t service_worker_registration_id = | |
| 115 GetServiceWorkerRegistrationId(service_worker_registration); | |
| 116 std::unique_ptr<blink::WebSyncGetRegistrationsCallbacks> callbacksPtr( | |
| 117 callbacks); | |
| 118 | |
| 119 // base::Unretained is safe here, as the mojo channel will be deleted (and | |
| 120 // will wipe its callbacks) before 'this' is deleted. | |
| 121 GetBackgroundSyncServicePtr()->GetRegistrations( | |
| 122 service_worker_registration_id, | |
| 123 base::Bind(&BackgroundSyncProvider::GetRegistrationsCallback, | |
| 124 base::Unretained(this), | |
| 125 base::Passed(std::move(callbacksPtr)))); | |
| 126 } | |
| 127 | |
| 128 void BackgroundSyncProvider::WillStopCurrentWorkerThread() { | |
| 129 delete this; | |
| 130 } | |
| 131 | |
| 132 void BackgroundSyncProvider::RegisterCallback( | |
| 133 std::unique_ptr<blink::WebSyncRegistrationCallbacks> callbacks, | |
| 134 blink::mojom::BackgroundSyncError error, | |
| 135 blink::mojom::SyncRegistrationPtr options) { | |
| 136 // TODO(iclelland): Determine the correct error message to return in each case | |
| 137 std::unique_ptr<blink::WebSyncRegistration> result; | |
| 138 switch (error) { | |
| 139 case blink::mojom::BackgroundSyncError::NONE: | |
| 140 if (!options.is_null()) | |
| 141 result = mojo::ConvertTo<std::unique_ptr<blink::WebSyncRegistration>>( | |
| 142 options); | |
| 143 callbacks->onSuccess(std::move(result)); | |
| 144 break; | |
| 145 case blink::mojom::BackgroundSyncError::NOT_FOUND: | |
| 146 NOTREACHED(); | |
| 147 break; | |
| 148 case blink::mojom::BackgroundSyncError::STORAGE: | |
| 149 callbacks->onError( | |
| 150 blink::WebSyncError(blink::WebSyncError::ErrorTypeUnknown, | |
| 151 "Background Sync is disabled.")); | |
| 152 break; | |
| 153 case blink::mojom::BackgroundSyncError::NOT_ALLOWED: | |
| 154 callbacks->onError( | |
| 155 blink::WebSyncError(blink::WebSyncError::ErrorTypeNoPermission, | |
| 156 "Attempted to register a sync event without a " | |
| 157 "window or registration tag too long.")); | |
| 158 break; | |
| 159 case blink::mojom::BackgroundSyncError::PERMISSION_DENIED: | |
| 160 callbacks->onError( | |
| 161 blink::WebSyncError(blink::WebSyncError::ErrorTypePermissionDenied, | |
| 162 "Permission denied.")); | |
| 163 break; | |
| 164 case blink::mojom::BackgroundSyncError::NO_SERVICE_WORKER: | |
| 165 callbacks->onError( | |
| 166 blink::WebSyncError(blink::WebSyncError::ErrorTypeUnknown, | |
| 167 "No service worker is active.")); | |
| 168 break; | |
| 169 } | |
| 170 } | |
| 171 | |
| 172 void BackgroundSyncProvider::GetRegistrationsCallback( | |
| 173 std::unique_ptr<blink::WebSyncGetRegistrationsCallbacks> callbacks, | |
| 174 blink::mojom::BackgroundSyncError error, | |
| 175 mojo::Array<blink::mojom::SyncRegistrationPtr> registrations) { | |
| 176 // TODO(iclelland): Determine the correct error message to return in each case | |
| 177 switch (error) { | |
| 178 case blink::mojom::BackgroundSyncError::NONE: { | |
| 179 blink::WebVector<blink::WebSyncRegistration*> results( | |
| 180 registrations.size()); | |
| 181 for (size_t i = 0; i < registrations.size(); ++i) { | |
| 182 results[i] = | |
| 183 mojo::ConvertTo<std::unique_ptr<blink::WebSyncRegistration>>( | |
| 184 registrations[i]) | |
| 185 .release(); | |
| 186 } | |
| 187 callbacks->onSuccess(results); | |
| 188 break; | |
| 189 } | |
| 190 case blink::mojom::BackgroundSyncError::NOT_FOUND: | |
| 191 case blink::mojom::BackgroundSyncError::NOT_ALLOWED: | |
| 192 case blink::mojom::BackgroundSyncError::PERMISSION_DENIED: | |
| 193 // These errors should never be returned from | |
| 194 // BackgroundSyncManager::GetRegistrations | |
| 195 NOTREACHED(); | |
| 196 break; | |
| 197 case blink::mojom::BackgroundSyncError::STORAGE: | |
| 198 callbacks->onError( | |
| 199 blink::WebSyncError(blink::WebSyncError::ErrorTypeUnknown, | |
| 200 "Background Sync is disabled.")); | |
| 201 break; | |
| 202 case blink::mojom::BackgroundSyncError::NO_SERVICE_WORKER: | |
| 203 callbacks->onError( | |
| 204 blink::WebSyncError(blink::WebSyncError::ErrorTypeUnknown, | |
| 205 "No service worker is active.")); | |
| 206 break; | |
| 207 } | |
| 208 } | |
| 209 | |
| 210 blink::mojom::BackgroundSyncServicePtr& | |
| 211 BackgroundSyncProvider::GetBackgroundSyncServicePtr() { | |
| 212 if (!background_sync_service_.get()) { | |
| 213 mojo::InterfaceRequest<blink::mojom::BackgroundSyncService> request = | |
| 214 mojo::GetProxy(&background_sync_service_); | |
| 215 main_thread_task_runner_->PostTask( | |
| 216 FROM_HERE, | |
| 217 base::Bind(&ConnectToServiceOnMainThread, base::Passed(&request))); | |
| 218 } | |
| 219 return background_sync_service_; | |
| 220 } | |
| 221 | |
| 222 } // namespace content | |
| OLD | NEW |