| // Copyright 2017 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_SCHEDULER_H_ |
| #define CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_SCHEDULER_H_ |
| |
| #include <map> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/callback.h" |
| #include "base/containers/circular_deque.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "content/browser/background_fetch/background_fetch_data_manager_observer.h" |
| #include "content/browser/background_fetch/background_fetch_event_dispatcher.h" |
| #include "content/browser/background_fetch/background_fetch_registration_id.h" |
| #include "content/browser/service_worker/service_worker_context_core_observer.h" |
| #include "content/common/content_export.h" |
| #include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom.h" |
| |
| namespace blink { |
| class StorageKey; |
| } // namespace blink |
| |
| namespace content { |
| |
| class BackgroundFetchDataManager; |
| class BackgroundFetchDelegateProxy; |
| class BackgroundFetchJobController; |
| class BackgroundFetchRegistrationId; |
| class BackgroundFetchRegistrationNotifier; |
| class BackgroundFetchRequestInfo; |
| class DevToolsBackgroundServicesContextImpl; |
| |
| // Maintains a list of Controllers and chooses which ones should launch new |
| // downloads. |
| class CONTENT_EXPORT BackgroundFetchScheduler |
| : public BackgroundFetchDataManagerObserver, |
| public ServiceWorkerContextCoreObserver { |
| public: |
| BackgroundFetchScheduler( |
| BackgroundFetchContext* background_fetch_context, |
| BackgroundFetchDataManager* data_manager, |
| BackgroundFetchRegistrationNotifier* registration_notifier, |
| BackgroundFetchDelegateProxy* delegate_proxy, |
| DevToolsBackgroundServicesContextImpl* devtools_context, |
| scoped_refptr<ServiceWorkerContextWrapper> service_worker_context); |
| |
| BackgroundFetchScheduler(const BackgroundFetchScheduler&) = delete; |
| BackgroundFetchScheduler& operator=(const BackgroundFetchScheduler&) = delete; |
| |
| ~BackgroundFetchScheduler() override; |
| |
| // Aborts the background fetch identified by |registration_id|. |
| // Must only be used for background fetches aborted by the developer, |
| // other cases are handled elsewhere. |
| void Abort( |
| const BackgroundFetchRegistrationId& registration_id, |
| blink::mojom::BackgroundFetchFailureReason failure_reason, |
| blink::mojom::BackgroundFetchRegistrationService::AbortCallback callback); |
| |
| // BackgroundFetchDataManagerObserver implementation. |
| void OnRegistrationCreated( |
| const BackgroundFetchRegistrationId& registration_id, |
| const blink::mojom::BackgroundFetchRegistrationData& registration_data, |
| blink::mojom::BackgroundFetchOptionsPtr options, |
| const SkBitmap& icon, |
| int num_requests, |
| bool start_paused, |
| net::IsolationInfo isolation_info) override; |
| void OnRegistrationLoadedAtStartup( |
| const BackgroundFetchRegistrationId& registration_id, |
| const blink::mojom::BackgroundFetchRegistrationData& registration_data, |
| blink::mojom::BackgroundFetchOptionsPtr options, |
| const SkBitmap& icon, |
| int num_completed_requests, |
| int num_requests, |
| std::vector<scoped_refptr<BackgroundFetchRequestInfo>> |
| active_fetch_requests, |
| absl::optional<net::IsolationInfo> isolation_info) override; |
| void OnServiceWorkerDatabaseCorrupted( |
| int64_t service_worker_registration_id) override; |
| void OnRegistrationQueried( |
| const BackgroundFetchRegistrationId& registration_id, |
| blink::mojom::BackgroundFetchRegistrationData* registration_data) |
| override; |
| void OnRequestCompleted(const std::string& unique_id, |
| blink::mojom::FetchAPIRequestPtr request, |
| blink::mojom::FetchAPIResponsePtr response) override; |
| |
| // ServiceWorkerContextCoreObserver implementation. |
| void OnRegistrationDeleted(int64_t registration_id, |
| const GURL& pattern, |
| const blink::StorageKey& key) override; |
| void OnStorageWiped() override; |
| |
| private: |
| friend class BackgroundFetchJobControllerTest; |
| friend class BackgroundFetchSchedulerTest; |
| enum class Event; |
| |
| // Schedules a download, if possible, and returns whether successful. |
| bool ScheduleDownload(); |
| |
| // Helper method to abandon ongoing fetches for a given service worker. |
| // Abandons all of them if |service_worker_registration_id| is set to |
| // blink::mojom::kInvalidServiceWorkerRegistrationId. |
| void AbortFetches(int64_t service_worker_registration_id); |
| |
| // Returns the active job controller, if any, for |registration_id| or |
| // |unique_id|. Returns nullptr if the job isn't currently active. |
| BackgroundFetchJobController* GetActiveController( |
| const BackgroundFetchRegistrationId& registration_id); |
| BackgroundFetchJobController* GetActiveController( |
| const std::string& unique_id); |
| |
| std::unique_ptr<BackgroundFetchJobController> CreateInitializedController( |
| const BackgroundFetchRegistrationId& registration_id, |
| const blink::mojom::BackgroundFetchRegistrationData& registration_data, |
| blink::mojom::BackgroundFetchOptionsPtr options, |
| const SkBitmap& icon, |
| int num_completed_requests, |
| int num_requests, |
| std::vector<scoped_refptr<BackgroundFetchRequestInfo>> |
| active_fetch_requests, |
| bool start_paused, |
| absl::optional<net::IsolationInfo> isolation_info); |
| |
| void DidStartRequest(const BackgroundFetchRegistrationId& registration_id, |
| const BackgroundFetchRequestInfo* request_info); |
| void DidCompleteRequest( |
| const BackgroundFetchRegistrationId& registration_id, |
| scoped_refptr<BackgroundFetchRequestInfo> request_info); |
| |
| void FinishJob( |
| const BackgroundFetchRegistrationId& registration_id, |
| blink::mojom::BackgroundFetchFailureReason failure_reason, |
| base::OnceCallback<void(blink::mojom::BackgroundFetchError)> callback); |
| |
| void DidMarkForDeletion( |
| const BackgroundFetchRegistrationId& registration_id, |
| bool job_started, |
| base::OnceCallback<void(blink::mojom::BackgroundFetchError)> callback, |
| blink::mojom::BackgroundFetchError error, |
| blink::mojom::BackgroundFetchFailureReason failure_reason); |
| |
| void CleanupRegistration( |
| const BackgroundFetchRegistrationId& registration_id); |
| |
| void DispatchClickEvent(const std::string& unique_id); |
| |
| // Information needed to send over to the |
| // DevToolsBackgroundServicesContextImpl. |event| is an enum describing the |
| // stage of the fetch. |request_info| is nullptr if not available at the |
| // moment. Any additional data to log can be passed through the |metadata| |
| // map. |
| void LogBackgroundFetchEventForDevTools( |
| Event event, |
| const BackgroundFetchRegistrationId& registration_id, |
| const BackgroundFetchRequestInfo* request_info, |
| std::map<std::string, std::string> metadata = {}); |
| |
| // Owned by BackgroundFetchContext. |
| raw_ptr<BackgroundFetchDataManager> data_manager_; |
| raw_ptr<BackgroundFetchRegistrationNotifier> registration_notifier_; |
| raw_ptr<BackgroundFetchDelegateProxy> delegate_proxy_; |
| raw_ptr<DevToolsBackgroundServicesContextImpl> devtools_context_; |
| |
| BackgroundFetchEventDispatcher event_dispatcher_; |
| |
| // The order in which to process the job controllers. |
| base::circular_deque<BackgroundFetchRegistrationId> controller_ids_; |
| |
| // Map from background fetch registration |unique_id|s to active job |
| // controllers. Must be destroyed before |data_manager_|, |scheduler_| and |
| // |registration_notifier_|. |
| std::map<std::string, std::unique_ptr<BackgroundFetchJobController>> |
| job_controllers_; |
| |
| // The current fetch job controllers that are being processed. |
| base::circular_deque<BackgroundFetchJobController*> active_controllers_; |
| |
| struct RegistrationData { |
| RegistrationData( |
| const BackgroundFetchRegistrationId& registration_id, |
| blink::mojom::BackgroundFetchRegistrationDataPtr registration); |
| ~RegistrationData(); |
| |
| BackgroundFetchRegistrationId registration_id; |
| blink::mojom::BackgroundFetchRegistrationDataPtr registration; |
| // Wheter all processing is completed and this data is safe to erase now. |
| bool processing_completed = false; |
| }; |
| |
| // Map from |unique_id|s to the registration data. |
| // An entry in here means the fetch has completed. This information is needed |
| // after the fetch has completed to dispatch the backgroundfetchclick event. |
| // TODO(crbug.com/857122): Clean this up when the UI is no longer showing. |
| std::map<std::string, std::unique_ptr<RegistrationData>> completed_fetches_; |
| |
| // Scheduling params - Finch configurable. |
| int max_running_downloads_; |
| int max_active_registrations_; |
| int num_active_registrations_ = 0; |
| int num_running_downloads_ = 0; |
| |
| base::WeakPtrFactory<BackgroundFetchScheduler> weak_ptr_factory_{this}; |
| }; |
| |
| } // namespace content |
| |
| #endif // CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_SCHEDULER_H_ |