1 : /* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Mozilla Corporation
19 : * Portions created by the Initial Developer are Copyright (C) 2010
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Honza Bambas <honzab@firemni.cz>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #include "OfflineCacheUpdateGlue.h"
40 : #include "nsOfflineCacheUpdate.h"
41 : #include "mozilla/Services.h"
42 :
43 : #include "nsIApplicationCache.h"
44 : #include "nsIApplicationCacheChannel.h"
45 : #include "nsIApplicationCacheContainer.h"
46 : #include "nsIChannel.h"
47 : #include "nsIDocument.h"
48 : #include "prlog.h"
49 :
50 : #if defined(PR_LOGGING)
51 : //
52 : // To enable logging (see prlog.h for full details):
53 : //
54 : // set NSPR_LOG_MODULES=nsOfflineCacheUpdate:5
55 : // set NSPR_LOG_FILE=offlineupdate.log
56 : //
57 : // this enables PR_LOG_ALWAYS level information and places all output in
58 : // the file offlineupdate.log
59 : //
60 : extern PRLogModuleInfo *gOfflineCacheUpdateLog;
61 : #endif
62 : #define LOG(args) PR_LOG(gOfflineCacheUpdateLog, 4, args)
63 : #define LOG_ENABLED() PR_LOG_TEST(gOfflineCacheUpdateLog, 4)
64 :
65 : namespace mozilla {
66 : namespace docshell {
67 :
68 : //-----------------------------------------------------------------------------
69 : // OfflineCacheUpdateGlue::nsISupports
70 : //-----------------------------------------------------------------------------
71 :
72 400 : NS_IMPL_ISUPPORTS3(OfflineCacheUpdateGlue,
73 : nsIOfflineCacheUpdate,
74 : nsIOfflineCacheUpdateObserver,
75 : nsISupportsWeakReference)
76 :
77 : //-----------------------------------------------------------------------------
78 : // OfflineCacheUpdateGlue <public>
79 : //-----------------------------------------------------------------------------
80 :
81 8 : OfflineCacheUpdateGlue::OfflineCacheUpdateGlue()
82 : {
83 8 : LOG(("OfflineCacheUpdateGlue::OfflineCacheUpdateGlue [%p]", this));
84 8 : }
85 :
86 16 : OfflineCacheUpdateGlue::~OfflineCacheUpdateGlue()
87 : {
88 8 : LOG(("OfflineCacheUpdateGlue::~OfflineCacheUpdateGlue [%p]", this));
89 8 : }
90 :
91 : nsIOfflineCacheUpdate*
92 16 : OfflineCacheUpdateGlue::EnsureUpdate()
93 : {
94 16 : if (!mUpdate) {
95 8 : mUpdate = new nsOfflineCacheUpdate();
96 8 : LOG(("OfflineCacheUpdateGlue [%p] is using update [%p]", this, mUpdate.get()));
97 : }
98 :
99 16 : return mUpdate;
100 : }
101 :
102 : NS_IMETHODIMP
103 8 : OfflineCacheUpdateGlue::Schedule()
104 : {
105 : nsCOMPtr<nsIObserverService> observerService =
106 16 : mozilla::services::GetObserverService();
107 8 : if (observerService) {
108 8 : LOG(("Calling offline-cache-update-added"));
109 8 : observerService->NotifyObservers(static_cast<nsIOfflineCacheUpdate*>(this),
110 : "offline-cache-update-added",
111 8 : nsnull);
112 8 : LOG(("Done offline-cache-update-added"));
113 : }
114 :
115 8 : if (!EnsureUpdate())
116 0 : return NS_ERROR_NULL_POINTER;
117 :
118 : // Do not use weak reference, we must survive!
119 8 : mUpdate->AddObserver(this, false);
120 :
121 8 : return mUpdate->Schedule();
122 : }
123 :
124 : NS_IMETHODIMP
125 8 : OfflineCacheUpdateGlue::Init(nsIURI *aManifestURI,
126 : nsIURI *aDocumentURI,
127 : nsIDOMDocument *aDocument)
128 : {
129 8 : if (!EnsureUpdate())
130 0 : return NS_ERROR_NULL_POINTER;
131 :
132 8 : mDocumentURI = aDocumentURI;
133 :
134 8 : if (aDocument)
135 0 : SetDocument(aDocument);
136 :
137 8 : return mUpdate->Init(aManifestURI, aDocumentURI, nsnull);
138 : }
139 :
140 : void
141 0 : OfflineCacheUpdateGlue::SetDocument(nsIDOMDocument *aDocument)
142 : {
143 : // The design is one document for one cache update on the content process.
144 0 : NS_ASSERTION(!mDocument,
145 : "Setting more then a single document on an instance of OfflineCacheUpdateGlue");
146 :
147 0 : LOG(("Document %p added to update glue %p", aDocument, this));
148 :
149 : // Add document only if it was not loaded from an offline cache.
150 : // If it were loaded from an offline cache then it has already
151 : // been associated with it and must not be again cached as
152 : // implicit (which are the reasons we collect documents here).
153 0 : nsCOMPtr<nsIDocument> document = do_QueryInterface(aDocument);
154 0 : if (!document)
155 : return;
156 :
157 0 : nsIChannel* channel = document->GetChannel();
158 : nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel =
159 0 : do_QueryInterface(channel);
160 0 : if (!appCacheChannel)
161 : return;
162 :
163 : bool loadedFromAppCache;
164 0 : appCacheChannel->GetLoadedFromApplicationCache(&loadedFromAppCache);
165 0 : if (loadedFromAppCache)
166 : return;
167 :
168 0 : if (EnsureUpdate()) {
169 0 : mUpdate->StickDocument(mDocumentURI);
170 : }
171 :
172 0 : mDocument = aDocument;
173 : }
174 :
175 : NS_IMETHODIMP
176 56 : OfflineCacheUpdateGlue::UpdateStateChanged(nsIOfflineCacheUpdate *aUpdate, PRUint32 state)
177 : {
178 56 : if (state == nsIOfflineCacheUpdateObserver::STATE_FINISHED) {
179 8 : LOG(("OfflineCacheUpdateGlue got STATE_FINISHED [%p]", this));
180 :
181 : nsCOMPtr<nsIObserverService> observerService =
182 16 : mozilla::services::GetObserverService();
183 8 : if (observerService) {
184 8 : LOG(("Calling offline-cache-update-completed"));
185 8 : observerService->NotifyObservers(static_cast<nsIOfflineCacheUpdate*>(this),
186 : "offline-cache-update-completed",
187 8 : nsnull);
188 8 : LOG(("Done offline-cache-update-completed"));
189 : }
190 :
191 8 : aUpdate->RemoveObserver(this);
192 : }
193 :
194 56 : return NS_OK;
195 : }
196 :
197 : NS_IMETHODIMP
198 8 : OfflineCacheUpdateGlue::ApplicationCacheAvailable(nsIApplicationCache *aApplicationCache)
199 : {
200 8 : NS_ENSURE_ARG(aApplicationCache);
201 :
202 : // Check that the document that requested this update was
203 : // previously associated with an application cache. If not, it
204 : // should be associated with the new one.
205 : nsCOMPtr<nsIApplicationCacheContainer> container =
206 16 : do_QueryInterface(mDocument);
207 8 : if (!container)
208 8 : return NS_OK;
209 :
210 0 : nsCOMPtr<nsIApplicationCache> existingCache;
211 0 : nsresult rv = container->GetApplicationCache(getter_AddRefs(existingCache));
212 0 : NS_ENSURE_SUCCESS(rv, rv);
213 :
214 0 : if (!existingCache) {
215 : #if defined(PR_LOGGING)
216 0 : if (LOG_ENABLED()) {
217 0 : nsCAutoString clientID;
218 0 : if (aApplicationCache) {
219 0 : aApplicationCache->GetClientID(clientID);
220 : }
221 0 : LOG(("Update %p: associating app cache %s to document %p",
222 : this, clientID.get(), mDocument.get()));
223 : }
224 : #endif
225 :
226 0 : rv = container->SetApplicationCache(aApplicationCache);
227 0 : NS_ENSURE_SUCCESS(rv, rv);
228 : }
229 :
230 0 : return NS_OK;
231 : }
232 :
233 : }
234 : }
|