uriloader/prefetch/OfflineCacheUpdateChild.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "OfflineCacheUpdateChild.h"
michael@0 7 #include "nsOfflineCacheUpdate.h"
michael@0 8 #include "mozilla/dom/ContentChild.h"
michael@0 9 #include "mozilla/dom/TabChild.h"
michael@0 10 #include "mozilla/ipc/URIUtils.h"
michael@0 11 #include "mozilla/net/NeckoCommon.h"
michael@0 12
michael@0 13 #include "nsIApplicationCacheContainer.h"
michael@0 14 #include "nsIApplicationCacheChannel.h"
michael@0 15 #include "nsIApplicationCacheService.h"
michael@0 16 #include "nsIDocShell.h"
michael@0 17 #include "nsIDocShellTreeItem.h"
michael@0 18 #include "nsIDocShellTreeOwner.h"
michael@0 19 #include "nsIDOMWindow.h"
michael@0 20 #include "nsIDOMOfflineResourceList.h"
michael@0 21 #include "nsIDocument.h"
michael@0 22 #include "nsIObserverService.h"
michael@0 23 #include "nsIURL.h"
michael@0 24 #include "nsITabChild.h"
michael@0 25 #include "nsNetCID.h"
michael@0 26 #include "nsNetUtil.h"
michael@0 27 #include "nsServiceManagerUtils.h"
michael@0 28 #include "nsStreamUtils.h"
michael@0 29 #include "nsThreadUtils.h"
michael@0 30 #include "nsProxyRelease.h"
michael@0 31 #include "prlog.h"
michael@0 32 #include "nsIAsyncVerifyRedirectCallback.h"
michael@0 33
michael@0 34 using namespace mozilla::ipc;
michael@0 35 using namespace mozilla::net;
michael@0 36 using mozilla::dom::TabChild;
michael@0 37
michael@0 38 #if defined(PR_LOGGING)
michael@0 39 //
michael@0 40 // To enable logging (see prlog.h for full details):
michael@0 41 //
michael@0 42 // set NSPR_LOG_MODULES=nsOfflineCacheUpdate:5
michael@0 43 // set NSPR_LOG_FILE=offlineupdate.log
michael@0 44 //
michael@0 45 // this enables PR_LOG_ALWAYS level information and places all output in
michael@0 46 // the file offlineupdate.log
michael@0 47 //
michael@0 48 extern PRLogModuleInfo *gOfflineCacheUpdateLog;
michael@0 49 #endif
michael@0 50
michael@0 51 #undef LOG
michael@0 52 #define LOG(args) PR_LOG(gOfflineCacheUpdateLog, 4, args)
michael@0 53
michael@0 54 #undef LOG_ENABLED
michael@0 55 #define LOG_ENABLED() PR_LOG_TEST(gOfflineCacheUpdateLog, 4)
michael@0 56
michael@0 57 namespace mozilla {
michael@0 58 namespace docshell {
michael@0 59
michael@0 60 //-----------------------------------------------------------------------------
michael@0 61 // OfflineCacheUpdateChild::nsISupports
michael@0 62 //-----------------------------------------------------------------------------
michael@0 63
michael@0 64 NS_INTERFACE_MAP_BEGIN(OfflineCacheUpdateChild)
michael@0 65 NS_INTERFACE_MAP_ENTRY(nsISupports)
michael@0 66 NS_INTERFACE_MAP_ENTRY(nsIOfflineCacheUpdate)
michael@0 67 NS_INTERFACE_MAP_END
michael@0 68
michael@0 69 NS_IMPL_ADDREF(OfflineCacheUpdateChild)
michael@0 70 NS_IMPL_RELEASE(OfflineCacheUpdateChild)
michael@0 71
michael@0 72 //-----------------------------------------------------------------------------
michael@0 73 // OfflineCacheUpdateChild <public>
michael@0 74 //-----------------------------------------------------------------------------
michael@0 75
michael@0 76 OfflineCacheUpdateChild::OfflineCacheUpdateChild(nsIDOMWindow* aWindow)
michael@0 77 : mState(STATE_UNINITIALIZED)
michael@0 78 , mIsUpgrade(false)
michael@0 79 , mAppID(NECKO_NO_APP_ID)
michael@0 80 , mInBrowser(false)
michael@0 81 , mWindow(aWindow)
michael@0 82 , mByteProgress(0)
michael@0 83 {
michael@0 84 }
michael@0 85
michael@0 86 OfflineCacheUpdateChild::~OfflineCacheUpdateChild()
michael@0 87 {
michael@0 88 LOG(("OfflineCacheUpdateChild::~OfflineCacheUpdateChild [%p]", this));
michael@0 89 }
michael@0 90
michael@0 91 void
michael@0 92 OfflineCacheUpdateChild::GatherObservers(nsCOMArray<nsIOfflineCacheUpdateObserver> &aObservers)
michael@0 93 {
michael@0 94 for (int32_t i = 0; i < mWeakObservers.Count(); i++) {
michael@0 95 nsCOMPtr<nsIOfflineCacheUpdateObserver> observer =
michael@0 96 do_QueryReferent(mWeakObservers[i]);
michael@0 97 if (observer)
michael@0 98 aObservers.AppendObject(observer);
michael@0 99 else
michael@0 100 mWeakObservers.RemoveObjectAt(i--);
michael@0 101 }
michael@0 102
michael@0 103 for (int32_t i = 0; i < mObservers.Count(); i++) {
michael@0 104 aObservers.AppendObject(mObservers[i]);
michael@0 105 }
michael@0 106 }
michael@0 107
michael@0 108 void
michael@0 109 OfflineCacheUpdateChild::SetDocument(nsIDOMDocument *aDocument)
michael@0 110 {
michael@0 111 // The design is one document for one cache update on the content process.
michael@0 112 NS_ASSERTION(!mDocument, "Setting more then a single document on a child offline cache update");
michael@0 113
michael@0 114 LOG(("Document %p added to update child %p", aDocument, this));
michael@0 115
michael@0 116 // Add document only if it was not loaded from an offline cache.
michael@0 117 // If it were loaded from an offline cache then it has already
michael@0 118 // been associated with it and must not be again cached as
michael@0 119 // implicit (which are the reasons we collect documents here).
michael@0 120 nsCOMPtr<nsIDocument> document = do_QueryInterface(aDocument);
michael@0 121 if (!document)
michael@0 122 return;
michael@0 123
michael@0 124 nsIChannel* channel = document->GetChannel();
michael@0 125 nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel =
michael@0 126 do_QueryInterface(channel);
michael@0 127 if (!appCacheChannel)
michael@0 128 return;
michael@0 129
michael@0 130 bool loadedFromAppCache;
michael@0 131 appCacheChannel->GetLoadedFromApplicationCache(&loadedFromAppCache);
michael@0 132 if (loadedFromAppCache)
michael@0 133 return;
michael@0 134
michael@0 135 mDocument = aDocument;
michael@0 136 }
michael@0 137
michael@0 138 nsresult
michael@0 139 OfflineCacheUpdateChild::AssociateDocument(nsIDOMDocument *aDocument,
michael@0 140 nsIApplicationCache *aApplicationCache)
michael@0 141 {
michael@0 142 // Check that the document that requested this update was
michael@0 143 // previously associated with an application cache. If not, it
michael@0 144 // should be associated with the new one.
michael@0 145 nsCOMPtr<nsIApplicationCacheContainer> container =
michael@0 146 do_QueryInterface(aDocument);
michael@0 147 if (!container)
michael@0 148 return NS_OK;
michael@0 149
michael@0 150 nsCOMPtr<nsIApplicationCache> existingCache;
michael@0 151 nsresult rv = container->GetApplicationCache(getter_AddRefs(existingCache));
michael@0 152 NS_ENSURE_SUCCESS(rv, rv);
michael@0 153
michael@0 154 if (!existingCache) {
michael@0 155 #if defined(PR_LOGGING)
michael@0 156 if (LOG_ENABLED()) {
michael@0 157 nsAutoCString clientID;
michael@0 158 if (aApplicationCache) {
michael@0 159 aApplicationCache->GetClientID(clientID);
michael@0 160 }
michael@0 161 LOG(("Update %p: associating app cache %s to document %p",
michael@0 162 this, clientID.get(), aDocument));
michael@0 163 }
michael@0 164 #endif
michael@0 165
michael@0 166 rv = container->SetApplicationCache(aApplicationCache);
michael@0 167 NS_ENSURE_SUCCESS(rv, rv);
michael@0 168 }
michael@0 169
michael@0 170 return NS_OK;
michael@0 171 }
michael@0 172
michael@0 173 //-----------------------------------------------------------------------------
michael@0 174 // OfflineCacheUpdateChild::nsIOfflineCacheUpdate
michael@0 175 //-----------------------------------------------------------------------------
michael@0 176
michael@0 177 NS_IMETHODIMP
michael@0 178 OfflineCacheUpdateChild::Init(nsIURI *aManifestURI,
michael@0 179 nsIURI *aDocumentURI,
michael@0 180 nsIDOMDocument *aDocument,
michael@0 181 nsIFile *aCustomProfileDir,
michael@0 182 uint32_t aAppID,
michael@0 183 bool aInBrowser)
michael@0 184 {
michael@0 185 nsresult rv;
michael@0 186
michael@0 187 // Make sure the service has been initialized
michael@0 188 nsOfflineCacheUpdateService* service =
michael@0 189 nsOfflineCacheUpdateService::EnsureService();
michael@0 190 if (!service)
michael@0 191 return NS_ERROR_FAILURE;
michael@0 192
michael@0 193 if (aCustomProfileDir) {
michael@0 194 NS_ERROR("Custom Offline Cache Update not supported on child process");
michael@0 195 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 196 }
michael@0 197
michael@0 198 LOG(("OfflineCacheUpdateChild::Init [%p]", this));
michael@0 199
michael@0 200 // Only http and https applications are supported.
michael@0 201 bool match;
michael@0 202 rv = aManifestURI->SchemeIs("http", &match);
michael@0 203 NS_ENSURE_SUCCESS(rv, rv);
michael@0 204
michael@0 205 if (!match) {
michael@0 206 rv = aManifestURI->SchemeIs("https", &match);
michael@0 207 NS_ENSURE_SUCCESS(rv, rv);
michael@0 208 if (!match)
michael@0 209 return NS_ERROR_ABORT;
michael@0 210 }
michael@0 211
michael@0 212 mManifestURI = aManifestURI;
michael@0 213
michael@0 214 rv = mManifestURI->GetAsciiHost(mUpdateDomain);
michael@0 215 NS_ENSURE_SUCCESS(rv, rv);
michael@0 216
michael@0 217 mDocumentURI = aDocumentURI;
michael@0 218
michael@0 219 mState = STATE_INITIALIZED;
michael@0 220
michael@0 221 if (aDocument)
michael@0 222 SetDocument(aDocument);
michael@0 223
michael@0 224 mAppID = aAppID;
michael@0 225 mInBrowser = aInBrowser;
michael@0 226
michael@0 227 return NS_OK;
michael@0 228 }
michael@0 229
michael@0 230 NS_IMETHODIMP
michael@0 231 OfflineCacheUpdateChild::InitPartial(nsIURI *aManifestURI,
michael@0 232 const nsACString& clientID,
michael@0 233 nsIURI *aDocumentURI)
michael@0 234 {
michael@0 235 NS_NOTREACHED("Not expected to do partial offline cache updates"
michael@0 236 " on the child process");
michael@0 237 // For now leaving this method, we may discover we need it.
michael@0 238 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 239 }
michael@0 240
michael@0 241 NS_IMETHODIMP
michael@0 242 OfflineCacheUpdateChild::InitForUpdateCheck(nsIURI *aManifestURI,
michael@0 243 uint32_t aAppID,
michael@0 244 bool aInBrowser,
michael@0 245 nsIObserver *aObserver)
michael@0 246 {
michael@0 247 NS_NOTREACHED("Not expected to do only update checks"
michael@0 248 " from the child process");
michael@0 249 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 250 }
michael@0 251
michael@0 252 NS_IMETHODIMP
michael@0 253 OfflineCacheUpdateChild::GetUpdateDomain(nsACString &aUpdateDomain)
michael@0 254 {
michael@0 255 NS_ENSURE_TRUE(mState >= STATE_INITIALIZED, NS_ERROR_NOT_INITIALIZED);
michael@0 256
michael@0 257 aUpdateDomain = mUpdateDomain;
michael@0 258 return NS_OK;
michael@0 259 }
michael@0 260
michael@0 261 NS_IMETHODIMP
michael@0 262 OfflineCacheUpdateChild::GetStatus(uint16_t *aStatus)
michael@0 263 {
michael@0 264 switch (mState) {
michael@0 265 case STATE_CHECKING :
michael@0 266 *aStatus = nsIDOMOfflineResourceList::CHECKING;
michael@0 267 return NS_OK;
michael@0 268 case STATE_DOWNLOADING :
michael@0 269 *aStatus = nsIDOMOfflineResourceList::DOWNLOADING;
michael@0 270 return NS_OK;
michael@0 271 default :
michael@0 272 *aStatus = nsIDOMOfflineResourceList::IDLE;
michael@0 273 return NS_OK;
michael@0 274 }
michael@0 275
michael@0 276 return NS_ERROR_FAILURE;
michael@0 277 }
michael@0 278
michael@0 279 NS_IMETHODIMP
michael@0 280 OfflineCacheUpdateChild::GetPartial(bool *aPartial)
michael@0 281 {
michael@0 282 *aPartial = false;
michael@0 283 return NS_OK;
michael@0 284 }
michael@0 285
michael@0 286 NS_IMETHODIMP
michael@0 287 OfflineCacheUpdateChild::GetManifestURI(nsIURI **aManifestURI)
michael@0 288 {
michael@0 289 NS_ENSURE_TRUE(mState >= STATE_INITIALIZED, NS_ERROR_NOT_INITIALIZED);
michael@0 290
michael@0 291 NS_IF_ADDREF(*aManifestURI = mManifestURI);
michael@0 292 return NS_OK;
michael@0 293 }
michael@0 294
michael@0 295 NS_IMETHODIMP
michael@0 296 OfflineCacheUpdateChild::GetSucceeded(bool *aSucceeded)
michael@0 297 {
michael@0 298 NS_ENSURE_TRUE(mState == STATE_FINISHED, NS_ERROR_NOT_AVAILABLE);
michael@0 299
michael@0 300 *aSucceeded = mSucceeded;
michael@0 301
michael@0 302 return NS_OK;
michael@0 303 }
michael@0 304
michael@0 305 NS_IMETHODIMP
michael@0 306 OfflineCacheUpdateChild::GetIsUpgrade(bool *aIsUpgrade)
michael@0 307 {
michael@0 308 NS_ENSURE_TRUE(mState >= STATE_INITIALIZED, NS_ERROR_NOT_INITIALIZED);
michael@0 309
michael@0 310 *aIsUpgrade = mIsUpgrade;
michael@0 311
michael@0 312 return NS_OK;
michael@0 313 }
michael@0 314
michael@0 315 NS_IMETHODIMP
michael@0 316 OfflineCacheUpdateChild::AddDynamicURI(nsIURI *aURI)
michael@0 317 {
michael@0 318 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 319 }
michael@0 320
michael@0 321 NS_IMETHODIMP
michael@0 322 OfflineCacheUpdateChild::Cancel()
michael@0 323 {
michael@0 324 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 325 }
michael@0 326
michael@0 327 NS_IMETHODIMP
michael@0 328 OfflineCacheUpdateChild::AddObserver(nsIOfflineCacheUpdateObserver *aObserver,
michael@0 329 bool aHoldWeak)
michael@0 330 {
michael@0 331 LOG(("OfflineCacheUpdateChild::AddObserver [%p]", this));
michael@0 332
michael@0 333 NS_ENSURE_TRUE(mState >= STATE_INITIALIZED, NS_ERROR_NOT_INITIALIZED);
michael@0 334
michael@0 335 if (aHoldWeak) {
michael@0 336 nsCOMPtr<nsIWeakReference> weakRef = do_GetWeakReference(aObserver);
michael@0 337 mWeakObservers.AppendObject(weakRef);
michael@0 338 } else {
michael@0 339 mObservers.AppendObject(aObserver);
michael@0 340 }
michael@0 341
michael@0 342 return NS_OK;
michael@0 343 }
michael@0 344
michael@0 345 NS_IMETHODIMP
michael@0 346 OfflineCacheUpdateChild::RemoveObserver(nsIOfflineCacheUpdateObserver *aObserver)
michael@0 347 {
michael@0 348 LOG(("OfflineCacheUpdateChild::RemoveObserver [%p]", this));
michael@0 349
michael@0 350 NS_ENSURE_TRUE(mState >= STATE_INITIALIZED, NS_ERROR_NOT_INITIALIZED);
michael@0 351
michael@0 352 for (int32_t i = 0; i < mWeakObservers.Count(); i++) {
michael@0 353 nsCOMPtr<nsIOfflineCacheUpdateObserver> observer =
michael@0 354 do_QueryReferent(mWeakObservers[i]);
michael@0 355 if (observer == aObserver) {
michael@0 356 mWeakObservers.RemoveObjectAt(i);
michael@0 357 return NS_OK;
michael@0 358 }
michael@0 359 }
michael@0 360
michael@0 361 for (int32_t i = 0; i < mObservers.Count(); i++) {
michael@0 362 if (mObservers[i] == aObserver) {
michael@0 363 mObservers.RemoveObjectAt(i);
michael@0 364 return NS_OK;
michael@0 365 }
michael@0 366 }
michael@0 367
michael@0 368 return NS_OK;
michael@0 369 }
michael@0 370
michael@0 371 NS_IMETHODIMP
michael@0 372 OfflineCacheUpdateChild::GetByteProgress(uint64_t * _result)
michael@0 373 {
michael@0 374 NS_ENSURE_ARG(_result);
michael@0 375
michael@0 376 *_result = mByteProgress;
michael@0 377 return NS_OK;
michael@0 378 }
michael@0 379
michael@0 380 NS_IMETHODIMP
michael@0 381 OfflineCacheUpdateChild::Schedule()
michael@0 382 {
michael@0 383 LOG(("OfflineCacheUpdateChild::Schedule [%p]", this));
michael@0 384
michael@0 385 NS_ASSERTION(mWindow, "Window must be provided to the offline cache update child");
michael@0 386
michael@0 387 nsCOMPtr<nsPIDOMWindow> piWindow =
michael@0 388 do_QueryInterface(mWindow);
michael@0 389 mWindow = nullptr;
michael@0 390
michael@0 391 nsIDocShell *docshell = piWindow->GetDocShell();
michael@0 392
michael@0 393 nsCOMPtr<nsIDocShellTreeItem> item = do_QueryInterface(docshell);
michael@0 394 if (!item) {
michael@0 395 NS_WARNING("doc shell tree item is null");
michael@0 396 return NS_ERROR_FAILURE;
michael@0 397 }
michael@0 398
michael@0 399 nsCOMPtr<nsIDocShellTreeOwner> owner;
michael@0 400 item->GetTreeOwner(getter_AddRefs(owner));
michael@0 401
michael@0 402 nsCOMPtr<nsITabChild> tabchild = do_GetInterface(owner);
michael@0 403 // because owner implements nsITabChild, we can assume that it is
michael@0 404 // the one and only TabChild.
michael@0 405 TabChild* child = tabchild ? static_cast<TabChild*>(tabchild.get()) : nullptr;
michael@0 406
michael@0 407 if (MissingRequiredTabChild(child, "offlinecacheupdate")) {
michael@0 408 return NS_ERROR_FAILURE;
michael@0 409 }
michael@0 410
michael@0 411 URIParams manifestURI, documentURI;
michael@0 412 SerializeURI(mManifestURI, manifestURI);
michael@0 413 SerializeURI(mDocumentURI, documentURI);
michael@0 414
michael@0 415 nsCOMPtr<nsIObserverService> observerService =
michael@0 416 mozilla::services::GetObserverService();
michael@0 417 if (observerService) {
michael@0 418 LOG(("Calling offline-cache-update-added"));
michael@0 419 observerService->NotifyObservers(static_cast<nsIOfflineCacheUpdate*>(this),
michael@0 420 "offline-cache-update-added",
michael@0 421 nullptr);
michael@0 422 LOG(("Done offline-cache-update-added"));
michael@0 423 }
michael@0 424
michael@0 425 // mDocument is non-null if both:
michael@0 426 // 1. this update was initiated by a document that referred a manifest
michael@0 427 // 2. the document has not already been loaded from the application cache
michael@0 428 // This tells the update to cache this document even in case the manifest
michael@0 429 // has not been changed since the last fetch.
michael@0 430 // See also nsOfflineCacheUpdate::ScheduleImplicit.
michael@0 431 bool stickDocument = mDocument != nullptr;
michael@0 432
michael@0 433 // Need to addref ourself here, because the IPC stack doesn't hold
michael@0 434 // a reference to us. Will be released in RecvFinish() that identifies
michael@0 435 // the work has been done.
michael@0 436 child->SendPOfflineCacheUpdateConstructor(this, manifestURI, documentURI,
michael@0 437 stickDocument);
michael@0 438
michael@0 439 // TabChild::DeallocPOfflineCacheUpdate will release this.
michael@0 440 NS_ADDREF_THIS();
michael@0 441
michael@0 442 return NS_OK;
michael@0 443 }
michael@0 444
michael@0 445 bool
michael@0 446 OfflineCacheUpdateChild::RecvAssociateDocuments(const nsCString &cacheGroupId,
michael@0 447 const nsCString &cacheClientId)
michael@0 448 {
michael@0 449 LOG(("OfflineCacheUpdateChild::RecvAssociateDocuments [%p, cache=%s]", this, cacheClientId.get()));
michael@0 450
michael@0 451 nsresult rv;
michael@0 452
michael@0 453 nsCOMPtr<nsIApplicationCache> cache =
michael@0 454 do_CreateInstance(NS_APPLICATIONCACHE_CONTRACTID, &rv);
michael@0 455 if (NS_FAILED(rv))
michael@0 456 return true;
michael@0 457
michael@0 458 cache->InitAsHandle(cacheGroupId, cacheClientId);
michael@0 459
michael@0 460 if (mDocument) {
michael@0 461 AssociateDocument(mDocument, cache);
michael@0 462 }
michael@0 463
michael@0 464 nsCOMArray<nsIOfflineCacheUpdateObserver> observers;
michael@0 465 GatherObservers(observers);
michael@0 466
michael@0 467 for (int32_t i = 0; i < observers.Count(); i++)
michael@0 468 observers[i]->ApplicationCacheAvailable(cache);
michael@0 469
michael@0 470 return true;
michael@0 471 }
michael@0 472
michael@0 473 bool
michael@0 474 OfflineCacheUpdateChild::RecvNotifyStateEvent(const uint32_t &event,
michael@0 475 const uint64_t &byteProgress)
michael@0 476 {
michael@0 477 LOG(("OfflineCacheUpdateChild::RecvNotifyStateEvent [%p]", this));
michael@0 478
michael@0 479 mByteProgress = byteProgress;
michael@0 480
michael@0 481 // Convert the public observer state to our internal state
michael@0 482 switch (event) {
michael@0 483 case nsIOfflineCacheUpdateObserver::STATE_CHECKING:
michael@0 484 mState = STATE_CHECKING;
michael@0 485 break;
michael@0 486
michael@0 487 case nsIOfflineCacheUpdateObserver::STATE_DOWNLOADING:
michael@0 488 mState = STATE_DOWNLOADING;
michael@0 489 break;
michael@0 490
michael@0 491 default:
michael@0 492 break;
michael@0 493 }
michael@0 494
michael@0 495 nsCOMArray<nsIOfflineCacheUpdateObserver> observers;
michael@0 496 GatherObservers(observers);
michael@0 497
michael@0 498 for (int32_t i = 0; i < observers.Count(); i++)
michael@0 499 observers[i]->UpdateStateChanged(this, event);
michael@0 500
michael@0 501 return true;
michael@0 502 }
michael@0 503
michael@0 504 bool
michael@0 505 OfflineCacheUpdateChild::RecvFinish(const bool &succeeded,
michael@0 506 const bool &isUpgrade)
michael@0 507 {
michael@0 508 LOG(("OfflineCacheUpdateChild::RecvFinish [%p]", this));
michael@0 509
michael@0 510 nsRefPtr<OfflineCacheUpdateChild> kungFuDeathGrip(this);
michael@0 511
michael@0 512 mState = STATE_FINISHED;
michael@0 513 mSucceeded = succeeded;
michael@0 514 mIsUpgrade = isUpgrade;
michael@0 515
michael@0 516 nsCOMPtr<nsIObserverService> observerService =
michael@0 517 mozilla::services::GetObserverService();
michael@0 518 if (observerService) {
michael@0 519 LOG(("Calling offline-cache-update-completed"));
michael@0 520 observerService->NotifyObservers(static_cast<nsIOfflineCacheUpdate*>(this),
michael@0 521 "offline-cache-update-completed",
michael@0 522 nullptr);
michael@0 523 LOG(("Done offline-cache-update-completed"));
michael@0 524 }
michael@0 525
michael@0 526 // This is by contract the last notification from the parent, release
michael@0 527 // us now. This is corresponding to AddRef in Schedule().
michael@0 528 // TabChild::DeallocPOfflineCacheUpdate will call Release.
michael@0 529 OfflineCacheUpdateChild::Send__delete__(this);
michael@0 530
michael@0 531 return true;
michael@0 532 }
michael@0 533
michael@0 534 }
michael@0 535 }

mercurial