summaryrefslogtreecommitdiffstats
path: root/webkit/appcache/appcache_host.h
blob: 5be3c5c2983826f3b8eecdb2b5197b2c52fac597 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef WEBKIT_APPCACHE_APPCACHE_HOST_H_
#define WEBKIT_APPCACHE_APPCACHE_HOST_H_

#include "base/observer_list.h"
#include "base/ref_counted.h"
#include "base/task.h"
#include "googleurl/src/gurl.h"
#include "testing/gtest/include/gtest/gtest_prod.h"
#include "webkit/appcache/appcache.h"
#include "webkit/appcache/appcache_interfaces.h"
#include "webkit/appcache/appcache_service.h"
#include "webkit/appcache/appcache_storage.h"

class URLRequest;

namespace appcache {

class AppCache;
class AppCacheFrontend;
class AppCacheGroup;
class AppCacheRequestHandler;

typedef Callback2<Status, void*>::Type GetStatusCallback;
typedef Callback2<bool, void*>::Type StartUpdateCallback;
typedef Callback2<bool, void*>::Type SwapCacheCallback;

// Server-side representation of an application cache host.
class AppCacheHost : public AppCacheStorage::Delegate {
 public:

  class Observer {
   public:
    // Called just after the cache selection algorithm completes.
    virtual void OnCacheSelectionComplete(AppCacheHost* host) = 0;

    // Called just prior to the instance being deleted.
    virtual void OnDestructionImminent(AppCacheHost* host) = 0;

    virtual ~Observer() {}
  };

  AppCacheHost(int host_id, AppCacheFrontend* frontend,
               AppCacheService* service);
  ~AppCacheHost();

  // Adds/removes an observer, the AppCacheHost does not take
  // ownership of the observer.
  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  // Support for cache selection and scriptable method calls.
  void SelectCache(const GURL& document_url,
                   const int64 cache_document_was_loaded_from,
                   const GURL& manifest_url);
  void MarkAsForeignEntry(const GURL& document_url,
                          int64 cache_document_was_loaded_from);
  void GetStatusWithCallback(GetStatusCallback* callback,
                             void* callback_param);
  void StartUpdateWithCallback(StartUpdateCallback* callback,
                               void* callback_param);
  void SwapCacheWithCallback(SwapCacheCallback* callback,
                             void* callback_param);

  // Support for loading resources out of the appcache.
  // Returns NULL if the host is not associated with a complete cache.
  AppCacheRequestHandler* CreateRequestHandler(URLRequest* request,
                                               bool is_main_request);

  // Establishes an association between this host and a cache. 'cache' may be
  // NULL to break any existing association. Associations are established
  // either thru the cache selection algorithm implemented (in this class),
  // or by the update algorithm (see AppCacheUpdateJob).
  void AssociateCache(AppCache* cache);

  int host_id() const { return host_id_; }
  AppCacheService* service() const { return service_; }
  AppCacheFrontend* frontend() const { return frontend_; }
  AppCache* associated_cache() const { return associated_cache_.get(); }

 private:
  bool is_selection_pending() const {
    return pending_selected_cache_id_ != kNoCacheId ||
           !pending_selected_manifest_url_.is_empty();
  }
  Status GetStatus();
  void LoadCache(int64 cache_id);
  void LoadOrCreateGroup(const GURL& manifest_url);

  // AppCacheStorage::Delegate impl
  virtual void OnCacheLoaded(AppCache* cache, int64 cache_id);
  virtual void OnGroupLoaded(AppCacheGroup* group,
                             const GURL& manifest_url);

  void FinishCacheSelection(AppCache* cache, AppCacheGroup* group);
  void DoPendingGetStatus();
  void DoPendingStartUpdate();
  void DoPendingSwapCache();

  // Identifies the corresponding appcache host in the child process.
  int host_id_;

  // The cache associated with this host, if any.
  scoped_refptr<AppCache> associated_cache_;

  // The reference to the group ensures the group exists
  // while we have an association with a cache in the group.
  scoped_refptr<AppCacheGroup> group_;

  // Cache loading is async, if we're loading a specific cache or group
  // for the purposes of cache selection, one or the other of these will
  // indicate which cache or group is being loaded.
  int64 pending_selected_cache_id_;
  GURL pending_selected_manifest_url_;

  // A new master entry to be added to the cache, may be empty.
  GURL new_master_entry_url_;

  // The frontend proxy to deliver notifications to the child process.
  AppCacheFrontend* frontend_;

  // Our central service object.
  AppCacheService* service_;

  // Since these are synchronous scriptable api calls in the client,
  // there can only be one type of callback pending.
  // Also, we have to wait until we have a cache selection prior
  // to responding to these calls, as cache selection involves
  // async loading of a cache or a group from storage.
  GetStatusCallback* pending_get_status_callback_;
  StartUpdateCallback* pending_start_update_callback_;
  SwapCacheCallback* pending_swap_cache_callback_;
  void* pending_callback_param_;

  // List of objects observing us.
  ObserverList<Observer> observers_;

  FRIEND_TEST(AppCacheTest, CleanupUnusedCache);
  FRIEND_TEST(AppCacheGroupTest, CleanupUnusedGroup);
  FRIEND_TEST(AppCacheHostTest, Basic);
  FRIEND_TEST(AppCacheHostTest, SelectNoCache);
  FRIEND_TEST(AppCacheHostTest, ForeignEntry);
  FRIEND_TEST(AppCacheHostTest, FailedCacheLoad);
  FRIEND_TEST(AppCacheHostTest, FailedGroupLoad);
  DISALLOW_COPY_AND_ASSIGN(AppCacheHost);
};

}  // namespace appcache

#endif  // WEBKIT_APPCACHE_APPCACHE_HOST_H_