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