1 // Copyright 2014 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 #ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DISK_CACHE_H_ 6 #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DISK_CACHE_H_ 7 8 #include <stdint.h> 9 10 #include <memory> 11 #include <set> 12 #include <vector> 13 14 #include "base/callback_forward.h" 15 #include "base/memory/ref_counted.h" 16 #include "base/sequence_checker.h" 17 #include "content/common/content_export.h" 18 #include "net/base/completion_once_callback.h" 19 #include "net/disk_cache/disk_cache.h" 20 21 namespace content { 22 23 // TODO(crbug.com/586174): Use disk_cache::EntryResult for better lifetime 24 // management of disk cache entries. Using EntryResult will eliminate allocating 25 // raw pointers and static methods in service worker resource readers/writers. 26 27 class ServiceWorkerDiskCache; 28 29 // Thin wrapper around disk_cache::Entry. 30 class CONTENT_EXPORT ServiceWorkerDiskCacheEntry { 31 public: 32 // The newly created entry takes ownership of `disk_cache_entry` and closes it 33 // on destruction. |cache| must outlive the newly created entry. 34 ServiceWorkerDiskCacheEntry(disk_cache::Entry* disk_cache_entry, 35 ServiceWorkerDiskCache* cache); 36 ~ServiceWorkerDiskCacheEntry(); 37 38 // See `disk_cache::Entry::ReadData()`. 39 int Read(int index, 40 int64_t offset, 41 net::IOBuffer* buf, 42 int buf_len, 43 net::CompletionOnceCallback callback); 44 45 // See `disk_cache::Entry::WriteData()`. 46 int Write(int index, 47 int64_t offset, 48 net::IOBuffer* buf, 49 int buf_len, 50 net::CompletionOnceCallback callback); 51 int64_t GetSize(int index); 52 53 // Should only be called by ServiceWorkerDiskCache. 54 void Abandon(); 55 56 private: 57 // The disk_cache::Entry is owned by this entry and closed on destruction. 58 disk_cache::Entry* disk_cache_entry_; 59 60 // The cache that this entry belongs to. 61 ServiceWorkerDiskCache* const cache_; 62 }; 63 64 // net::DiskCache wrapper for the cache used by service worker resources. 65 // 66 // Provides ways to create/open/doom service worker disk cache entries. 67 class CONTENT_EXPORT ServiceWorkerDiskCache { 68 public: 69 ServiceWorkerDiskCache(); 70 ~ServiceWorkerDiskCache(); 71 72 // Initializes the object to use disk backed storage. 73 net::Error InitWithDiskBackend(const base::FilePath& disk_cache_directory, 74 bool force, 75 base::OnceClosure post_cleanup_callback, 76 net::CompletionOnceCallback callback); 77 78 // Initializes the object to use memory only storage. 79 // This is used for Chrome's incognito browsing. 80 net::Error InitWithMemBackend(int64_t disk_cache_size, 81 net::CompletionOnceCallback callback); 82 83 void Disable(); is_disabled()84 bool is_disabled() const { return is_disabled_; } 85 86 using EntryCallback = 87 base::OnceCallback<void(int rv, 88 std::unique_ptr<ServiceWorkerDiskCacheEntry>)>; 89 90 // Creates/opens/dooms a disk cache entry associated with `key`. 91 void CreateEntry(int64_t key, EntryCallback callback); 92 void OpenEntry(int64_t key, EntryCallback callback); 93 void DoomEntry(int64_t key, net::CompletionOnceCallback callback); 94 95 base::WeakPtr<ServiceWorkerDiskCache> GetWeakPtr(); 96 set_is_waiting_to_initialize(bool is_waiting_to_initialize)97 void set_is_waiting_to_initialize(bool is_waiting_to_initialize) { 98 is_waiting_to_initialize_ = is_waiting_to_initialize; 99 } 100 disk_cache()101 disk_cache::Backend* disk_cache() { return disk_cache_.get(); } 102 103 private: 104 class CreateBackendCallbackShim; 105 friend class ServiceWorkerDiskCacheEntry; 106 is_initializing_or_waiting_to_initialize()107 bool is_initializing_or_waiting_to_initialize() const { 108 return create_backend_callback_.get() != nullptr || 109 is_waiting_to_initialize_; 110 } 111 112 net::Error Init(net::CacheType cache_type, 113 const base::FilePath& directory, 114 int64_t cache_size, 115 bool force, 116 base::OnceClosure post_cleanup_callback, 117 net::CompletionOnceCallback callback); 118 void OnCreateBackendComplete(int return_value); 119 120 uint64_t GetNextCallId(); 121 122 void DidGetEntryResult(uint64_t call_id, disk_cache::EntryResult result); 123 void DidDoomEntry(uint64_t call_id, int net_error); 124 125 // Called by ServiceWorkerDiskCacheEntry constructor. 126 void AddOpenEntry(ServiceWorkerDiskCacheEntry* entry); 127 // Called by ServiceWorkerDiskCacheEntry destructor. 128 void RemoveOpenEntry(ServiceWorkerDiskCacheEntry* entry); 129 130 bool is_disabled_ = false; 131 bool is_waiting_to_initialize_ = false; 132 net::CompletionOnceCallback init_callback_; 133 scoped_refptr<CreateBackendCallbackShim> create_backend_callback_; 134 std::vector<base::OnceClosure> pending_calls_; 135 uint64_t next_call_id_ = 0; 136 std::map</*call_id=*/uint64_t, EntryCallback> active_entry_calls_; 137 std::map</*call_id=*/uint64_t, net::CompletionOnceCallback> 138 active_doom_calls_; 139 std::set<ServiceWorkerDiskCacheEntry*> open_entries_; 140 std::unique_ptr<disk_cache::Backend> disk_cache_; 141 142 SEQUENCE_CHECKER(sequence_checker_); 143 144 base::WeakPtrFactory<ServiceWorkerDiskCache> weak_factory_{this}; 145 }; 146 147 } // namespace content 148 149 #endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DISK_CACHE_H_ 150