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