Home | History | Annotate | Download | only in indexed_db
      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 "storage/browser/blob/blob_data_handle.h"
     19 #include "url/gurl.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.
     71   IndexedDBContextImpl* Context() { return indexed_db_context_.get(); }
     72   storage::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(const std::string& uuid,
     98                           scoped_ptr<storage::BlobDataHandle> blob_data_handle);
     99   void DropBlobDataHandle(const std::string& uuid);
    100 
    101  private:
    102   // Friends to enable OnDestruct() delegation.
    103   friend class BrowserThread;
    104   friend class base::DeleteHelper<IndexedDBDispatcherHost>;
    105 
    106   // Used in nested classes.
    107   typedef std::map<std::string, storage::BlobDataHandle*> BlobDataHandleMap;
    108   typedef std::map<int64, int64> TransactionIDToDatabaseIDMap;
    109   typedef std::map<int64, uint64> TransactionIDToSizeMap;
    110   typedef std::map<int64, GURL> TransactionIDToURLMap;
    111   typedef std::map<int32, GURL> WebIDBObjectIDToURLMap;
    112 
    113   // IDMap for RefCounted types
    114   template <typename RefCountedType>
    115   class RefIDMap {
    116    public:
    117     typedef int32 KeyType;
    118 
    119     RefIDMap() {}
    120     ~RefIDMap() {}
    121 
    122     KeyType Add(RefCountedType* data) {
    123       return map_.Add(new scoped_refptr<RefCountedType>(data));
    124     }
    125 
    126     RefCountedType* Lookup(KeyType id) {
    127       scoped_refptr<RefCountedType>* ptr = map_.Lookup(id);
    128       if (ptr == NULL)
    129         return NULL;
    130       return ptr->get();
    131     }
    132 
    133     void Remove(KeyType id) { map_.Remove(id); }
    134 
    135     void set_check_on_null_data(bool value) {
    136       map_.set_check_on_null_data(value);
    137     }
    138 
    139    private:
    140     IDMap<scoped_refptr<RefCountedType>, IDMapOwnPointer> map_;
    141 
    142     DISALLOW_COPY_AND_ASSIGN(RefIDMap);
    143   };
    144 
    145   class DatabaseDispatcherHost {
    146    public:
    147     explicit DatabaseDispatcherHost(IndexedDBDispatcherHost* parent);
    148     ~DatabaseDispatcherHost();
    149 
    150     void CloseAll();
    151     bool OnMessageReceived(const IPC::Message& message);
    152 
    153     void OnCreateObjectStore(
    154         const IndexedDBHostMsg_DatabaseCreateObjectStore_Params& params);
    155     void OnDeleteObjectStore(int32 ipc_database_id,
    156                              int64 transaction_id,
    157                              int64 object_store_id);
    158     void OnCreateTransaction(
    159         const IndexedDBHostMsg_DatabaseCreateTransaction_Params&);
    160     void OnClose(int32 ipc_database_id);
    161     void OnVersionChangeIgnored(int32 ipc_database_id);
    162     void OnDestroyed(int32 ipc_database_id);
    163 
    164     void OnGet(const IndexedDBHostMsg_DatabaseGet_Params& params);
    165     // OnPutWrapper starts on the IO thread so that it can grab BlobDataHandles
    166     // before posting to the IDB TaskRunner for the rest of the job.
    167     void OnPutWrapper(const IndexedDBHostMsg_DatabasePut_Params& params);
    168     void OnPut(const IndexedDBHostMsg_DatabasePut_Params& params,
    169                std::vector<storage::BlobDataHandle*> handles);
    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    private:
    202     DISALLOW_COPY_AND_ASSIGN(DatabaseDispatcherHost);
    203   };
    204 
    205   class CursorDispatcherHost {
    206    public:
    207     explicit CursorDispatcherHost(IndexedDBDispatcherHost* parent);
    208     ~CursorDispatcherHost();
    209 
    210     bool OnMessageReceived(const IPC::Message& message);
    211 
    212     void OnAdvance(int32 ipc_object_store_id,
    213                    int32 ipc_thread_id,
    214                    int32 ipc_callbacks_id,
    215                    uint32 count);
    216     void OnContinue(int32 ipc_object_store_id,
    217                     int32 ipc_thread_id,
    218                     int32 ipc_callbacks_id,
    219                     const IndexedDBKey& key,
    220                     const IndexedDBKey& primary_key);
    221     void OnPrefetch(int32 ipc_cursor_id,
    222                     int32 ipc_thread_id,
    223                     int32 ipc_callbacks_id,
    224                     int n);
    225     void OnPrefetchReset(int32 ipc_cursor_id,
    226                          int used_prefetches,
    227                          int unused_prefetches);
    228     void OnDestroyed(int32 ipc_cursor_id);
    229 
    230     IndexedDBDispatcherHost* parent_;
    231     RefIDMap<IndexedDBCursor> map_;
    232 
    233    private:
    234     DISALLOW_COPY_AND_ASSIGN(CursorDispatcherHost);
    235   };
    236 
    237   virtual ~IndexedDBDispatcherHost();
    238 
    239   // Helper templates.
    240   template <class ReturnType>
    241   ReturnType* GetOrTerminateProcess(IDMap<ReturnType, IDMapOwnPointer>* map,
    242                                     int32 ipc_return_object_id);
    243   template <class ReturnType>
    244   ReturnType* GetOrTerminateProcess(RefIDMap<ReturnType>* map,
    245                                     int32 ipc_return_object_id);
    246 
    247   template <typename MapType>
    248   void DestroyObject(MapType* map, int32 ipc_object_id);
    249 
    250   // Message processing. Most of the work is delegated to the dispatcher hosts
    251   // below.
    252   void OnIDBFactoryGetDatabaseNames(
    253       const IndexedDBHostMsg_FactoryGetDatabaseNames_Params& p);
    254   void OnIDBFactoryOpen(const IndexedDBHostMsg_FactoryOpen_Params& p);
    255 
    256   void OnIDBFactoryDeleteDatabase(
    257       const IndexedDBHostMsg_FactoryDeleteDatabase_Params& p);
    258 
    259   void OnAckReceivedBlobs(const std::vector<std::string>& uuids);
    260   void OnPutHelper(const IndexedDBHostMsg_DatabasePut_Params& params,
    261                    std::vector<storage::BlobDataHandle*> handles);
    262 
    263   void ResetDispatcherHosts();
    264 
    265   // The getter holds the context until OnChannelConnected() can be called from
    266   // the IO thread, which will extract the net::URLRequestContext from it.
    267   scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
    268   net::URLRequestContext* request_context_;
    269   scoped_refptr<IndexedDBContextImpl> indexed_db_context_;
    270   scoped_refptr<ChromeBlobStorageContext> blob_storage_context_;
    271 
    272   BlobDataHandleMap blob_data_handle_map_;
    273 
    274   // Only access on IndexedDB thread.
    275   scoped_ptr<DatabaseDispatcherHost> database_dispatcher_host_;
    276   scoped_ptr<CursorDispatcherHost> cursor_dispatcher_host_;
    277 
    278   // Used to set file permissions for blob storage.
    279   int ipc_process_id_;
    280 
    281   DISALLOW_IMPLICIT_CONSTRUCTORS(IndexedDBDispatcherHost);
    282 };
    283 
    284 }  // namespace content
    285 
    286 #endif  // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DISPATCHER_HOST_H_
    287