1 // Copyright 2013 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_CHILD_INDEXED_DB_INDEXED_DB_DISPATCHER_H_ 6 #define CONTENT_CHILD_INDEXED_DB_INDEXED_DB_DISPATCHER_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "base/gtest_prod_util.h" 13 #include "base/id_map.h" 14 #include "base/memory/ref_counted.h" 15 #include "base/strings/nullable_string16.h" 16 #include "content/child/worker_task_runner.h" 17 #include "content/common/content_export.h" 18 #include "ipc/ipc_sync_message_filter.h" 19 #include "third_party/WebKit/public/platform/WebBlobInfo.h" 20 #include "third_party/WebKit/public/platform/WebIDBCallbacks.h" 21 #include "third_party/WebKit/public/platform/WebIDBDatabaseCallbacks.h" 22 #include "third_party/WebKit/public/platform/WebIDBTypes.h" 23 24 struct IndexedDBDatabaseMetadata; 25 struct IndexedDBMsg_CallbacksSuccessCursorContinue_Params; 26 struct IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params; 27 struct IndexedDBMsg_CallbacksSuccessIDBCursor_Params; 28 struct IndexedDBMsg_CallbacksSuccessValue_Params; 29 struct IndexedDBMsg_CallbacksSuccessValueWithKey_Params; 30 struct IndexedDBMsg_CallbacksUpgradeNeeded_Params; 31 32 namespace blink { 33 class WebData; 34 } 35 36 namespace content { 37 class IndexedDBKey; 38 class IndexedDBKeyPath; 39 class IndexedDBKeyRange; 40 class WebIDBCursorImpl; 41 class WebIDBDatabaseImpl; 42 class ThreadSafeSender; 43 44 CONTENT_EXPORT extern const size_t kMaxIDBValueSizeInBytes; 45 46 // Handle the indexed db related communication for this context thread - the 47 // main thread and each worker thread have their own copies. 48 class CONTENT_EXPORT IndexedDBDispatcher : public WorkerTaskRunner::Observer { 49 public: 50 // Constructor made public to allow RenderThreadImpl to own a copy without 51 // failing a NOTREACHED in ThreadSpecificInstance in tests that instantiate 52 // two copies of RenderThreadImpl on the same thread. Everyone else probably 53 // wants to use ThreadSpecificInstance(). 54 explicit IndexedDBDispatcher(ThreadSafeSender* thread_safe_sender); 55 virtual ~IndexedDBDispatcher(); 56 57 // |thread_safe_sender| needs to be passed in because if the call leads to 58 // construction it will be needed. 59 static IndexedDBDispatcher* ThreadSpecificInstance( 60 ThreadSafeSender* thread_safe_sender); 61 62 // WorkerTaskRunner::Observer implementation. 63 virtual void OnWorkerRunLoopStopped() OVERRIDE; 64 65 static blink::WebIDBMetadata ConvertMetadata( 66 const IndexedDBDatabaseMetadata& idb_metadata); 67 68 void OnMessageReceived(const IPC::Message& msg); 69 70 // This method is virtual so it can be overridden in unit tests. 71 virtual bool Send(IPC::Message* msg); 72 73 void RequestIDBFactoryGetDatabaseNames( 74 blink::WebIDBCallbacks* callbacks, 75 const std::string& database_identifier); 76 77 void RequestIDBFactoryOpen( 78 const base::string16& name, 79 int64 version, 80 int64 transaction_id, 81 blink::WebIDBCallbacks* callbacks, 82 blink::WebIDBDatabaseCallbacks* database_callbacks, 83 const std::string& database_identifier); 84 85 void RequestIDBFactoryDeleteDatabase(const base::string16& name, 86 blink::WebIDBCallbacks* callbacks, 87 const std::string& database_identifier); 88 89 // This method is virtual so it can be overridden in unit tests. 90 virtual void RequestIDBCursorAdvance(unsigned long count, 91 blink::WebIDBCallbacks* callbacks_ptr, 92 int32 ipc_cursor_id, 93 int64 transaction_id); 94 95 // This method is virtual so it can be overridden in unit tests. 96 virtual void RequestIDBCursorContinue(const IndexedDBKey& key, 97 const IndexedDBKey& primary_key, 98 blink::WebIDBCallbacks* callbacks_ptr, 99 int32 ipc_cursor_id, 100 int64 transaction_id); 101 102 // This method is virtual so it can be overridden in unit tests. 103 virtual void RequestIDBCursorPrefetch(int n, 104 blink::WebIDBCallbacks* callbacks_ptr, 105 int32 ipc_cursor_id); 106 107 // This method is virtual so it can be overridden in unit tests. 108 virtual void RequestIDBCursorPrefetchReset(int used_prefetches, 109 int unused_prefetches, 110 int32 ipc_cursor_id); 111 112 void RequestIDBDatabaseClose(int32 ipc_database_id, 113 int32 ipc_database_callbacks_id); 114 115 void NotifyIDBDatabaseVersionChangeIgnored(int32 ipc_database_id); 116 117 void RequestIDBDatabaseCreateTransaction( 118 int32 ipc_database_id, 119 int64 transaction_id, 120 blink::WebIDBDatabaseCallbacks* database_callbacks_ptr, 121 blink::WebVector<long long> object_store_ids, 122 blink::WebIDBTransactionMode mode); 123 124 void RequestIDBDatabaseGet(int32 ipc_database_id, 125 int64 transaction_id, 126 int64 object_store_id, 127 int64 index_id, 128 const IndexedDBKeyRange& key_range, 129 bool key_only, 130 blink::WebIDBCallbacks* callbacks); 131 132 void RequestIDBDatabasePut( 133 int32 ipc_database_id, 134 int64 transaction_id, 135 int64 object_store_id, 136 const blink::WebData& value, 137 const blink::WebVector<blink::WebBlobInfo>& web_blob_info, 138 const IndexedDBKey& key, 139 blink::WebIDBPutMode put_mode, 140 blink::WebIDBCallbacks* callbacks, 141 const blink::WebVector<long long>& index_ids, 142 const blink::WebVector<blink::WebVector<blink::WebIDBKey> >& index_keys); 143 144 void RequestIDBDatabaseOpenCursor(int32 ipc_database_id, 145 int64 transaction_id, 146 int64 object_store_id, 147 int64 index_id, 148 const IndexedDBKeyRange& key_range, 149 blink::WebIDBCursorDirection direction, 150 bool key_only, 151 blink::WebIDBTaskType task_type, 152 blink::WebIDBCallbacks* callbacks); 153 154 void RequestIDBDatabaseCount(int32 ipc_database_id, 155 int64 transaction_id, 156 int64 object_store_id, 157 int64 index_id, 158 const IndexedDBKeyRange& key_range, 159 blink::WebIDBCallbacks* callbacks); 160 161 void RequestIDBDatabaseDeleteRange(int32 ipc_database_id, 162 int64 transaction_id, 163 int64 object_store_id, 164 const IndexedDBKeyRange& key_range, 165 blink::WebIDBCallbacks* callbacks); 166 167 void RequestIDBDatabaseClear(int32 ipc_database_id, 168 int64 transaction_id, 169 int64 object_store_id, 170 blink::WebIDBCallbacks* callbacks); 171 172 virtual void CursorDestroyed(int32 ipc_cursor_id); 173 void DatabaseDestroyed(int32 ipc_database_id); 174 175 private: 176 FRIEND_TEST_ALL_PREFIXES(IndexedDBDispatcherTest, CursorReset); 177 FRIEND_TEST_ALL_PREFIXES(IndexedDBDispatcherTest, CursorTransactionId); 178 FRIEND_TEST_ALL_PREFIXES(IndexedDBDispatcherTest, ValueSizeTest); 179 180 enum { kAllCursors = -1 }; 181 182 static int32 CurrentWorkerId() { 183 return WorkerTaskRunner::Instance()->CurrentWorkerId(); 184 } 185 186 template <typename T> 187 void init_params(T* params, blink::WebIDBCallbacks* callbacks_ptr) { 188 scoped_ptr<blink::WebIDBCallbacks> callbacks(callbacks_ptr); 189 params->ipc_thread_id = CurrentWorkerId(); 190 params->ipc_callbacks_id = pending_callbacks_.Add(callbacks.release()); 191 } 192 193 // IDBCallback message handlers. 194 void OnSuccessIDBDatabase(int32 ipc_thread_id, 195 int32 ipc_callbacks_id, 196 int32 ipc_database_callbacks_id, 197 int32 ipc_object_id, 198 const IndexedDBDatabaseMetadata& idb_metadata); 199 void OnSuccessIndexedDBKey(int32 ipc_thread_id, 200 int32 ipc_callbacks_id, 201 const IndexedDBKey& key); 202 203 void OnSuccessOpenCursor( 204 const IndexedDBMsg_CallbacksSuccessIDBCursor_Params& p); 205 void OnSuccessCursorContinue( 206 const IndexedDBMsg_CallbacksSuccessCursorContinue_Params& p); 207 void OnSuccessCursorPrefetch( 208 const IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params& p); 209 void OnSuccessStringList(int32 ipc_thread_id, 210 int32 ipc_callbacks_id, 211 const std::vector<base::string16>& value); 212 void OnSuccessValue(const IndexedDBMsg_CallbacksSuccessValue_Params& p); 213 void OnSuccessValueWithKey( 214 const IndexedDBMsg_CallbacksSuccessValueWithKey_Params& p); 215 void OnSuccessInteger(int32 ipc_thread_id, 216 int32 ipc_callbacks_id, 217 int64 value); 218 void OnSuccessUndefined(int32 ipc_thread_id, int32 ipc_callbacks_id); 219 void OnError(int32 ipc_thread_id, 220 int32 ipc_callbacks_id, 221 int code, 222 const base::string16& message); 223 void OnIntBlocked(int32 ipc_thread_id, 224 int32 ipc_callbacks_id, 225 int64 existing_version); 226 void OnUpgradeNeeded(const IndexedDBMsg_CallbacksUpgradeNeeded_Params& p); 227 void OnAbort(int32 ipc_thread_id, 228 int32 ipc_database_id, 229 int64 transaction_id, 230 int code, 231 const base::string16& message); 232 void OnComplete(int32 ipc_thread_id, 233 int32 ipc_database_id, 234 int64 transaction_id); 235 void OnForcedClose(int32 ipc_thread_id, int32 ipc_database_id); 236 void OnIntVersionChange(int32 ipc_thread_id, 237 int32 ipc_database_id, 238 int64 old_version, 239 int64 new_version); 240 241 // Reset cursor prefetch caches for all cursors except exception_cursor_id. 242 void ResetCursorPrefetchCaches(int64 transaction_id, 243 int32 ipc_exception_cursor_id); 244 245 scoped_refptr<ThreadSafeSender> thread_safe_sender_; 246 247 // Careful! WebIDBCallbacks wraps non-threadsafe data types. It must be 248 // destroyed and used on the same thread it was created on. 249 IDMap<blink::WebIDBCallbacks, IDMapOwnPointer> pending_callbacks_; 250 IDMap<blink::WebIDBDatabaseCallbacks, IDMapOwnPointer> 251 pending_database_callbacks_; 252 253 // Maps the ipc_callback_id from an open cursor request to the request's 254 // transaction_id. Used to assign the transaction_id to the WebIDBCursorImpl 255 // when it is created. 256 std::map<int32, int64> cursor_transaction_ids_; 257 258 // Map from cursor id to WebIDBCursorImpl. 259 std::map<int32, WebIDBCursorImpl*> cursors_; 260 261 std::map<int32, WebIDBDatabaseImpl*> databases_; 262 263 DISALLOW_COPY_AND_ASSIGN(IndexedDBDispatcher); 264 }; 265 266 } // namespace content 267 268 #endif // CONTENT_CHILD_INDEXED_DB_INDEXED_DB_DISPATCHER_H_ 269