1 // Copyright (c) 2012 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_INDEXED_DB_INDEXED_DB_DISPATCHER_HOST_H_ 6 #define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DISPATCHER_HOST_H_ 7 8 #include <map> 9 #include <vector> 10 11 #include "base/basictypes.h" 12 #include "base/id_map.h" 13 #include "base/memory/ref_counted.h" 14 #include "content/public/browser/browser_message_filter.h" 15 #include "url/gurl.h" 16 17 struct IndexedDBDatabaseMetadata; 18 struct IndexedDBHostMsg_DatabaseCount_Params; 19 struct IndexedDBHostMsg_DatabaseCreateIndex_Params; 20 struct IndexedDBHostMsg_DatabaseCreateObjectStore_Params; 21 struct IndexedDBHostMsg_DatabaseCreateTransaction_Params; 22 struct IndexedDBHostMsg_DatabaseDeleteRange_Params; 23 struct IndexedDBHostMsg_DatabaseGet_Params; 24 struct IndexedDBHostMsg_DatabaseOpenCursor_Params; 25 struct IndexedDBHostMsg_DatabasePut_Params; 26 struct IndexedDBHostMsg_DatabaseSetIndexKeys_Params; 27 struct IndexedDBHostMsg_FactoryDeleteDatabase_Params; 28 struct IndexedDBHostMsg_FactoryGetDatabaseNames_Params; 29 struct IndexedDBHostMsg_FactoryOpen_Params; 30 31 namespace content { 32 class IndexedDBConnection; 33 class IndexedDBContextImpl; 34 class IndexedDBCursor; 35 class IndexedDBKey; 36 class IndexedDBKeyPath; 37 class IndexedDBKeyRange; 38 struct IndexedDBDatabaseMetadata; 39 40 // Handles all IndexedDB related messages from a particular renderer process. 41 class IndexedDBDispatcherHost : public BrowserMessageFilter { 42 public: 43 // Only call the constructor from the UI thread. 44 explicit IndexedDBDispatcherHost(IndexedDBContextImpl* indexed_db_context); 45 46 static ::IndexedDBDatabaseMetadata ConvertMetadata( 47 const content::IndexedDBDatabaseMetadata& metadata); 48 49 // BrowserMessageFilter implementation. 50 virtual void OnChannelClosing() OVERRIDE; 51 virtual void OnDestruct() const OVERRIDE; 52 virtual base::TaskRunner* OverrideTaskRunnerForMessage( 53 const IPC::Message& message) OVERRIDE; 54 virtual bool OnMessageReceived(const IPC::Message& message, 55 bool* message_was_ok) OVERRIDE; 56 57 void FinishTransaction(int64 host_transaction_id, bool committed); 58 59 // A shortcut for accessing our context. 60 IndexedDBContextImpl* Context() { return indexed_db_context_; } 61 62 // IndexedDBCallbacks call these methods to add the results into the 63 // applicable map. See below for more details. 64 int32 Add(IndexedDBCursor* cursor); 65 int32 Add(IndexedDBConnection* connection, 66 int32 ipc_thread_id, 67 const GURL& origin_url); 68 69 void RegisterTransactionId(int64 host_transaction_id, const GURL& origin_url); 70 71 IndexedDBCursor* GetCursorFromId(int32 ipc_cursor_id); 72 73 // These are called to map a 32-bit front-end (renderer-specific) transaction 74 // id to and from a back-end ("host") transaction id that encodes the process 75 // id in the high 32 bits. The mapping is host-specific and ids are validated. 76 int64 HostTransactionId(int64 transaction_id); 77 int64 RendererTransactionId(int64 host_transaction_id); 78 79 // These are called to decode a host transaction ID, for diagnostic purposes. 80 static uint32 TransactionIdToRendererTransactionId(int64 host_transaction_id); 81 static uint32 TransactionIdToProcessId(int64 host_transaction_id); 82 83 private: 84 // Friends to enable OnDestruct() delegation. 85 friend class BrowserThread; 86 friend class base::DeleteHelper<IndexedDBDispatcherHost>; 87 88 virtual ~IndexedDBDispatcherHost(); 89 90 // Message processing. Most of the work is delegated to the dispatcher hosts 91 // below. 92 void OnIDBFactoryGetDatabaseNames( 93 const IndexedDBHostMsg_FactoryGetDatabaseNames_Params& p); 94 void OnIDBFactoryOpen(const IndexedDBHostMsg_FactoryOpen_Params& p); 95 96 void OnIDBFactoryDeleteDatabase( 97 const IndexedDBHostMsg_FactoryDeleteDatabase_Params& p); 98 99 void ResetDispatcherHosts(); 100 101 // IDMap for RefCounted types 102 template <typename RefCountedType> 103 class RefIDMap { 104 private: 105 typedef int32 KeyType; 106 107 public: 108 RefIDMap() {} 109 ~RefIDMap() {} 110 111 KeyType Add(RefCountedType* data) { 112 return map_.Add(new scoped_refptr<RefCountedType>(data)); 113 } 114 115 RefCountedType* Lookup(KeyType id) { 116 scoped_refptr<RefCountedType>* ptr = map_.Lookup(id); 117 if (ptr == NULL) 118 return NULL; 119 return ptr->get(); 120 } 121 122 void Remove(KeyType id) { map_.Remove(id); } 123 124 void set_check_on_null_data(bool value) { 125 map_.set_check_on_null_data(value); 126 } 127 128 private: 129 IDMap<scoped_refptr<RefCountedType>, IDMapOwnPointer> map_; 130 }; 131 132 // Helper templates. 133 template <class ReturnType> 134 ReturnType* GetOrTerminateProcess(IDMap<ReturnType, IDMapOwnPointer>* map, 135 int32 ipc_return_object_id); 136 template <class ReturnType> 137 ReturnType* GetOrTerminateProcess(RefIDMap<ReturnType>* map, 138 int32 ipc_return_object_id); 139 140 template <typename MapType> 141 void DestroyObject(MapType* map, int32 ipc_object_id); 142 143 // Used in nested classes. 144 typedef std::map<int32, GURL> WebIDBObjectIDToURLMap; 145 146 typedef std::map<int64, GURL> TransactionIDToURLMap; 147 typedef std::map<int64, uint64> TransactionIDToSizeMap; 148 typedef std::map<int64, int64> TransactionIDToDatabaseIDMap; 149 150 class DatabaseDispatcherHost { 151 public: 152 explicit DatabaseDispatcherHost(IndexedDBDispatcherHost* parent); 153 ~DatabaseDispatcherHost(); 154 155 void CloseAll(); 156 bool OnMessageReceived(const IPC::Message& message, bool* msg_is_ok); 157 158 void OnCreateObjectStore( 159 const IndexedDBHostMsg_DatabaseCreateObjectStore_Params& params); 160 void OnDeleteObjectStore(int32 ipc_database_id, 161 int64 transaction_id, 162 int64 object_store_id); 163 void OnCreateTransaction( 164 const IndexedDBHostMsg_DatabaseCreateTransaction_Params&); 165 void OnClose(int32 ipc_database_id); 166 void OnDestroyed(int32 ipc_database_id); 167 168 void OnGet(const IndexedDBHostMsg_DatabaseGet_Params& params); 169 void OnPut(const IndexedDBHostMsg_DatabasePut_Params& params); 170 void OnSetIndexKeys( 171 const IndexedDBHostMsg_DatabaseSetIndexKeys_Params& params); 172 void OnSetIndexesReady(int32 ipc_database_id, 173 int64 transaction_id, 174 int64 object_store_id, 175 const std::vector<int64>& ids); 176 void OnOpenCursor(const IndexedDBHostMsg_DatabaseOpenCursor_Params& params); 177 void OnCount(const IndexedDBHostMsg_DatabaseCount_Params& params); 178 void OnDeleteRange( 179 const IndexedDBHostMsg_DatabaseDeleteRange_Params& params); 180 void OnClear(int32 ipc_thread_id, 181 int32 ipc_callbacks_id, 182 int32 ipc_database_id, 183 int64 transaction_id, 184 int64 object_store_id); 185 void OnCreateIndex( 186 const IndexedDBHostMsg_DatabaseCreateIndex_Params& params); 187 void OnDeleteIndex(int32 ipc_database_id, 188 int64 transaction_id, 189 int64 object_store_id, 190 int64 index_id); 191 192 void OnAbort(int32 ipc_database_id, int64 transaction_id); 193 void OnCommit(int32 ipc_database_id, int64 transaction_id); 194 IndexedDBDispatcherHost* parent_; 195 IDMap<IndexedDBConnection, IDMapOwnPointer> map_; 196 WebIDBObjectIDToURLMap database_url_map_; 197 TransactionIDToSizeMap transaction_size_map_; 198 TransactionIDToURLMap transaction_url_map_; 199 TransactionIDToDatabaseIDMap transaction_database_map_; 200 }; 201 202 class CursorDispatcherHost { 203 public: 204 explicit CursorDispatcherHost(IndexedDBDispatcherHost* parent); 205 ~CursorDispatcherHost(); 206 207 bool OnMessageReceived(const IPC::Message& message, bool* msg_is_ok); 208 209 void OnAdvance(int32 ipc_object_store_id, 210 int32 ipc_thread_id, 211 int32 ipc_callbacks_id, 212 unsigned long count); 213 void OnContinue(int32 ipc_object_store_id, 214 int32 ipc_thread_id, 215 int32 ipc_callbacks_id, 216 const IndexedDBKey& key, 217 const IndexedDBKey& primary_key); 218 void OnPrefetch(int32 ipc_cursor_id, 219 int32 ipc_thread_id, 220 int32 ipc_callbacks_id, 221 int n); 222 void OnPrefetchReset(int32 ipc_cursor_id, 223 int used_prefetches, 224 int unused_prefetches); 225 void OnDestroyed(int32 ipc_cursor_id); 226 227 IndexedDBDispatcherHost* parent_; 228 RefIDMap<IndexedDBCursor> map_; 229 }; 230 231 scoped_refptr<IndexedDBContextImpl> indexed_db_context_; 232 233 // Only access on IndexedDB thread. 234 scoped_ptr<DatabaseDispatcherHost> database_dispatcher_host_; 235 scoped_ptr<CursorDispatcherHost> cursor_dispatcher_host_; 236 237 DISALLOW_IMPLICIT_CONSTRUCTORS(IndexedDBDispatcherHost); 238 }; 239 240 } // namespace content 241 242 #endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DISPATCHER_HOST_H_ 243