LCOV - code coverage report
Current view: directory - uriloader/prefetch - nsOfflineCacheUpdateService.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 190 67 35.3 %
Date: 2012-06-02 Functions: 30 14 46.7 %

       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) 2007
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Dave Camp <dcamp@mozilla.com>
      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 "OfflineCacheUpdateChild.h"
      40                 : #include "OfflineCacheUpdateParent.h"
      41                 : #include "nsXULAppAPI.h"
      42                 : #include "OfflineCacheUpdateGlue.h"
      43                 : #include "nsOfflineCacheUpdate.h"
      44                 : 
      45                 : #include "nsCPrefetchService.h"
      46                 : #include "nsCURILoader.h"
      47                 : #include "nsIApplicationCacheContainer.h"
      48                 : #include "nsIApplicationCacheChannel.h"
      49                 : #include "nsIApplicationCacheService.h"
      50                 : #include "nsICache.h"
      51                 : #include "nsICacheService.h"
      52                 : #include "nsICacheSession.h"
      53                 : #include "nsICachingChannel.h"
      54                 : #include "nsIContent.h"
      55                 : #include "nsIDocumentLoader.h"
      56                 : #include "nsIDOMElement.h"
      57                 : #include "nsIDOMWindow.h"
      58                 : #include "nsIDOMOfflineResourceList.h"
      59                 : #include "nsIDocument.h"
      60                 : #include "nsIObserverService.h"
      61                 : #include "nsIURL.h"
      62                 : #include "nsIWebProgress.h"
      63                 : #include "nsICryptoHash.h"
      64                 : #include "nsICacheEntryDescriptor.h"
      65                 : #include "nsIPermissionManager.h"
      66                 : #include "nsIPrincipal.h"
      67                 : #include "nsNetCID.h"
      68                 : #include "nsNetUtil.h"
      69                 : #include "nsServiceManagerUtils.h"
      70                 : #include "nsStreamUtils.h"
      71                 : #include "nsThreadUtils.h"
      72                 : #include "nsProxyRelease.h"
      73                 : #include "prlog.h"
      74                 : #include "nsIAsyncVerifyRedirectCallback.h"
      75                 : #include "mozilla/Preferences.h"
      76                 : 
      77                 : using namespace mozilla;
      78                 : 
      79                 : static nsOfflineCacheUpdateService *gOfflineCacheUpdateService = nsnull;
      80                 : 
      81                 : typedef mozilla::docshell::OfflineCacheUpdateParent OfflineCacheUpdateParent;
      82                 : typedef mozilla::docshell::OfflineCacheUpdateChild OfflineCacheUpdateChild;
      83                 : typedef mozilla::docshell::OfflineCacheUpdateGlue OfflineCacheUpdateGlue;
      84                 : 
      85                 : #if defined(PR_LOGGING)
      86                 : //
      87                 : // To enable logging (see prlog.h for full details):
      88                 : //
      89                 : //    set NSPR_LOG_MODULES=nsOfflineCacheUpdate:5
      90                 : //    set NSPR_LOG_FILE=offlineupdate.log
      91                 : //
      92                 : // this enables PR_LOG_ALWAYS level information and places all output in
      93                 : // the file offlineupdate.log
      94                 : //
      95                 : PRLogModuleInfo *gOfflineCacheUpdateLog;
      96                 : #endif
      97                 : #define LOG(args) PR_LOG(gOfflineCacheUpdateLog, 4, args)
      98                 : #define LOG_ENABLED() PR_LOG_TEST(gOfflineCacheUpdateLog, 4)
      99                 : 
     100                 : class AutoFreeArray {
     101                 : public:
     102                 :     AutoFreeArray(PRUint32 count, char **values)
     103                 :         : mCount(count), mValues(values) {};
     104                 :     ~AutoFreeArray() { NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(mCount, mValues); }
     105                 : private:
     106                 :     PRUint32 mCount;
     107                 :     char **mValues;
     108                 : };
     109                 : 
     110                 : //-----------------------------------------------------------------------------
     111                 : // nsOfflineCachePendingUpdate
     112                 : //-----------------------------------------------------------------------------
     113                 : 
     114                 : class nsOfflineCachePendingUpdate : public nsIWebProgressListener
     115                 :                                   , public nsSupportsWeakReference
     116               0 : {
     117                 : public:
     118                 :     NS_DECL_ISUPPORTS
     119                 :     NS_DECL_NSIWEBPROGRESSLISTENER
     120                 : 
     121               0 :     nsOfflineCachePendingUpdate(nsOfflineCacheUpdateService *aService,
     122                 :                                 nsIURI *aManifestURI,
     123                 :                                 nsIURI *aDocumentURI,
     124                 :                                 nsIDOMDocument *aDocument)
     125                 :         : mService(aService)
     126                 :         , mManifestURI(aManifestURI)
     127               0 :         , mDocumentURI(aDocumentURI)
     128                 :         {
     129               0 :             mDocument = do_GetWeakReference(aDocument);
     130               0 :         }
     131                 : 
     132                 : private:
     133                 :     nsRefPtr<nsOfflineCacheUpdateService> mService;
     134                 :     nsCOMPtr<nsIURI> mManifestURI;
     135                 :     nsCOMPtr<nsIURI> mDocumentURI;
     136                 :     nsCOMPtr<nsIWeakReference> mDocument;
     137                 : };
     138                 : 
     139               0 : NS_IMPL_ISUPPORTS2(nsOfflineCachePendingUpdate,
     140                 :                    nsIWebProgressListener,
     141                 :                    nsISupportsWeakReference)
     142                 : 
     143                 : //-----------------------------------------------------------------------------
     144                 : // nsOfflineCacheUpdateService::nsIWebProgressListener
     145                 : //-----------------------------------------------------------------------------
     146                 : 
     147                 : NS_IMETHODIMP
     148               0 : nsOfflineCachePendingUpdate::OnProgressChange(nsIWebProgress *aProgress,
     149                 :                                               nsIRequest *aRequest,
     150                 :                                               PRInt32 curSelfProgress,
     151                 :                                               PRInt32 maxSelfProgress,
     152                 :                                               PRInt32 curTotalProgress,
     153                 :                                               PRInt32 maxTotalProgress)
     154                 : {
     155               0 :     NS_NOTREACHED("notification excluded in AddProgressListener(...)");
     156               0 :     return NS_OK;
     157                 : }
     158                 : 
     159                 : NS_IMETHODIMP
     160               0 : nsOfflineCachePendingUpdate::OnStateChange(nsIWebProgress* aWebProgress,
     161                 :                                            nsIRequest *aRequest,
     162                 :                                            PRUint32 progressStateFlags,
     163                 :                                            nsresult aStatus)
     164                 : {
     165               0 :     nsCOMPtr<nsIDOMDocument> updateDoc = do_QueryReferent(mDocument);
     166               0 :     if (!updateDoc) {
     167                 :         // The document that scheduled this update has gone away,
     168                 :         // we don't need to listen anymore.
     169               0 :         aWebProgress->RemoveProgressListener(this);
     170               0 :         NS_RELEASE_THIS();
     171               0 :         return NS_OK;
     172                 :     }
     173                 : 
     174               0 :     if (!(progressStateFlags & STATE_STOP)) {
     175               0 :         return NS_OK;
     176                 :     }
     177                 : 
     178               0 :     nsCOMPtr<nsIDOMWindow> window;
     179               0 :     aWebProgress->GetDOMWindow(getter_AddRefs(window));
     180               0 :     if (!window) return NS_OK;
     181                 : 
     182               0 :     nsCOMPtr<nsIDOMDocument> progressDoc;
     183               0 :     window->GetDocument(getter_AddRefs(progressDoc));
     184               0 :     if (!progressDoc) return NS_OK;
     185                 : 
     186               0 :     if (!SameCOMIdentity(progressDoc, updateDoc)) {
     187               0 :         return NS_OK;
     188                 :     }
     189                 : 
     190               0 :     LOG(("nsOfflineCachePendingUpdate::OnStateChange [%p, doc=%p]",
     191                 :          this, progressDoc.get()));
     192                 : 
     193                 :     // Only schedule the update if the document loaded successfully
     194               0 :     if (NS_SUCCEEDED(aStatus)) {
     195               0 :         nsCOMPtr<nsIOfflineCacheUpdate> update;
     196                 :         mService->Schedule(mManifestURI, mDocumentURI,
     197               0 :                            updateDoc, window, getter_AddRefs(update));
     198                 :     }
     199                 : 
     200               0 :     aWebProgress->RemoveProgressListener(this);
     201               0 :     NS_RELEASE_THIS();
     202                 : 
     203               0 :     return NS_OK;
     204                 : }
     205                 : 
     206                 : NS_IMETHODIMP
     207               0 : nsOfflineCachePendingUpdate::OnLocationChange(nsIWebProgress* aWebProgress,
     208                 :                                               nsIRequest* aRequest,
     209                 :                                               nsIURI *location,
     210                 :                                               PRUint32 aFlags)
     211                 : {
     212               0 :     NS_NOTREACHED("notification excluded in AddProgressListener(...)");
     213               0 :     return NS_OK;
     214                 : }
     215                 : 
     216                 : NS_IMETHODIMP
     217               0 : nsOfflineCachePendingUpdate::OnStatusChange(nsIWebProgress* aWebProgress,
     218                 :                                             nsIRequest* aRequest,
     219                 :                                             nsresult aStatus,
     220                 :                                             const PRUnichar* aMessage)
     221                 : {
     222               0 :     NS_NOTREACHED("notification excluded in AddProgressListener(...)");
     223               0 :     return NS_OK;
     224                 : }
     225                 : 
     226                 : NS_IMETHODIMP
     227               0 : nsOfflineCachePendingUpdate::OnSecurityChange(nsIWebProgress *aWebProgress,
     228                 :                                               nsIRequest *aRequest,
     229                 :                                               PRUint32 state)
     230                 : {
     231               0 :     NS_NOTREACHED("notification excluded in AddProgressListener(...)");
     232               0 :     return NS_OK;
     233                 : }
     234                 : 
     235                 : //-----------------------------------------------------------------------------
     236                 : // nsOfflineCacheUpdateService::nsISupports
     237                 : //-----------------------------------------------------------------------------
     238                 : 
     239             264 : NS_IMPL_ISUPPORTS3(nsOfflineCacheUpdateService,
     240                 :                    nsIOfflineCacheUpdateService,
     241                 :                    nsIObserver,
     242                 :                    nsISupportsWeakReference)
     243                 : 
     244                 : //-----------------------------------------------------------------------------
     245                 : // nsOfflineCacheUpdateService <public>
     246                 : //-----------------------------------------------------------------------------
     247                 : 
     248               8 : nsOfflineCacheUpdateService::nsOfflineCacheUpdateService()
     249                 :     : mDisabled(false)
     250               8 :     , mUpdateRunning(false)
     251                 : {
     252               8 : }
     253                 : 
     254              16 : nsOfflineCacheUpdateService::~nsOfflineCacheUpdateService()
     255                 : {
     256               8 :     gOfflineCacheUpdateService = nsnull;
     257               8 : }
     258                 : 
     259                 : nsresult
     260               8 : nsOfflineCacheUpdateService::Init()
     261                 : {
     262                 : #if defined(PR_LOGGING)
     263               8 :     if (!gOfflineCacheUpdateLog)
     264               8 :         gOfflineCacheUpdateLog = PR_NewLogModule("nsOfflineCacheUpdate");
     265                 : #endif
     266                 : 
     267                 :     // Observe xpcom-shutdown event
     268                 :     nsCOMPtr<nsIObserverService> observerService =
     269              16 :       mozilla::services::GetObserverService();
     270               8 :     if (!observerService)
     271               0 :       return NS_ERROR_FAILURE;
     272                 : 
     273               8 :     nsresult rv = observerService->AddObserver(this,
     274                 :                                                NS_XPCOM_SHUTDOWN_OBSERVER_ID,
     275               8 :                                                true);
     276               8 :     NS_ENSURE_SUCCESS(rv, rv);
     277                 : 
     278               8 :     gOfflineCacheUpdateService = this;
     279                 : 
     280               8 :     return NS_OK;
     281                 : }
     282                 : 
     283                 : /* static */
     284                 : nsOfflineCacheUpdateService *
     285               8 : nsOfflineCacheUpdateService::GetInstance()
     286                 : {
     287               8 :     if (!gOfflineCacheUpdateService) {
     288               8 :         gOfflineCacheUpdateService = new nsOfflineCacheUpdateService();
     289               8 :         if (!gOfflineCacheUpdateService)
     290               0 :             return nsnull;
     291               8 :         NS_ADDREF(gOfflineCacheUpdateService);
     292               8 :         nsresult rv = gOfflineCacheUpdateService->Init();
     293               8 :         if (NS_FAILED(rv)) {
     294               0 :             NS_RELEASE(gOfflineCacheUpdateService);
     295               0 :             return nsnull;
     296                 :         }
     297               8 :         return gOfflineCacheUpdateService;
     298                 :     }
     299                 : 
     300               0 :     NS_ADDREF(gOfflineCacheUpdateService);
     301                 : 
     302               0 :     return gOfflineCacheUpdateService;
     303                 : }
     304                 : 
     305                 : /* static */
     306                 : nsOfflineCacheUpdateService *
     307              16 : nsOfflineCacheUpdateService::EnsureService()
     308                 : {
     309              16 :     if (!gOfflineCacheUpdateService) {
     310                 :         // Make the service manager hold a long-lived reference to the service
     311                 :         nsCOMPtr<nsIOfflineCacheUpdateService> service =
     312               0 :             do_GetService(NS_OFFLINECACHEUPDATESERVICE_CONTRACTID);
     313                 :     }
     314                 : 
     315              16 :     return gOfflineCacheUpdateService;
     316                 : }
     317                 : 
     318                 : nsresult
     319               8 : nsOfflineCacheUpdateService::ScheduleUpdate(nsOfflineCacheUpdate *aUpdate)
     320                 : {
     321               8 :     LOG(("nsOfflineCacheUpdateService::Schedule [%p, update=%p]",
     322                 :          this, aUpdate));
     323                 : 
     324               8 :     aUpdate->SetOwner(this);
     325                 : 
     326               8 :     mUpdates.AppendElement(aUpdate);
     327               8 :     ProcessNextUpdate();
     328                 : 
     329               8 :     return NS_OK;
     330                 : }
     331                 : 
     332                 : NS_IMETHODIMP
     333               0 : nsOfflineCacheUpdateService::ScheduleOnDocumentStop(nsIURI *aManifestURI,
     334                 :                                                     nsIURI *aDocumentURI,
     335                 :                                                     nsIDOMDocument *aDocument)
     336                 : {
     337               0 :     LOG(("nsOfflineCacheUpdateService::ScheduleOnDocumentStop [%p, manifestURI=%p, documentURI=%p doc=%p]",
     338                 :          this, aManifestURI, aDocumentURI, aDocument));
     339                 : 
     340               0 :     nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDocument);
     341               0 :     nsCOMPtr<nsISupports> container = doc->GetContainer();
     342               0 :     nsCOMPtr<nsIWebProgress> progress = do_QueryInterface(container);
     343               0 :     NS_ENSURE_TRUE(progress, NS_ERROR_INVALID_ARG);
     344                 : 
     345                 :     // Proceed with cache update
     346                 :     nsRefPtr<nsOfflineCachePendingUpdate> update =
     347                 :         new nsOfflineCachePendingUpdate(this, aManifestURI,
     348               0 :                                         aDocumentURI, aDocument);
     349               0 :     NS_ENSURE_TRUE(update, NS_ERROR_OUT_OF_MEMORY);
     350                 : 
     351               0 :     nsresult rv = progress->AddProgressListener
     352               0 :         (update, nsIWebProgress::NOTIFY_STATE_DOCUMENT);
     353               0 :     NS_ENSURE_SUCCESS(rv, rv);
     354                 : 
     355                 :     // The update will release when it has scheduled itself.
     356               0 :     update.forget();
     357                 : 
     358               0 :     return NS_OK;
     359                 : }
     360                 : 
     361                 : nsresult
     362               8 : nsOfflineCacheUpdateService::UpdateFinished(nsOfflineCacheUpdate *aUpdate)
     363                 : {
     364               8 :     LOG(("nsOfflineCacheUpdateService::UpdateFinished [%p, update=%p]",
     365                 :          this, aUpdate));
     366                 : 
     367               8 :     NS_ASSERTION(mUpdates.Length() > 0 &&
     368                 :                  mUpdates[0] == aUpdate, "Unknown update completed");
     369                 : 
     370                 :     // keep this item alive until we're done notifying observers
     371              16 :     nsRefPtr<nsOfflineCacheUpdate> update = mUpdates[0];
     372               8 :     mUpdates.RemoveElementAt(0);
     373               8 :     mUpdateRunning = false;
     374                 : 
     375               8 :     ProcessNextUpdate();
     376                 : 
     377               8 :     return NS_OK;
     378                 : }
     379                 : 
     380                 : //-----------------------------------------------------------------------------
     381                 : // nsOfflineCacheUpdateService <private>
     382                 : //-----------------------------------------------------------------------------
     383                 : 
     384                 : nsresult
     385              16 : nsOfflineCacheUpdateService::ProcessNextUpdate()
     386                 : {
     387              16 :     LOG(("nsOfflineCacheUpdateService::ProcessNextUpdate [%p, num=%d]",
     388                 :          this, mUpdates.Length()));
     389                 : 
     390              16 :     if (mDisabled)
     391               0 :         return NS_ERROR_ABORT;
     392                 : 
     393              16 :     if (mUpdateRunning)
     394               0 :         return NS_OK;
     395                 : 
     396              16 :     if (mUpdates.Length() > 0) {
     397               8 :         mUpdateRunning = true;
     398               8 :         return mUpdates[0]->Begin();
     399                 :     }
     400                 : 
     401               8 :     return NS_OK;
     402                 : }
     403                 : 
     404                 : //-----------------------------------------------------------------------------
     405                 : // nsOfflineCacheUpdateService::nsIOfflineCacheUpdateService
     406                 : //-----------------------------------------------------------------------------
     407                 : 
     408                 : NS_IMETHODIMP
     409               0 : nsOfflineCacheUpdateService::GetNumUpdates(PRUint32 *aNumUpdates)
     410                 : {
     411               0 :     LOG(("nsOfflineCacheUpdateService::GetNumUpdates [%p]", this));
     412                 : 
     413               0 :     *aNumUpdates = mUpdates.Length();
     414               0 :     return NS_OK;
     415                 : }
     416                 : 
     417                 : NS_IMETHODIMP
     418               0 : nsOfflineCacheUpdateService::GetUpdate(PRUint32 aIndex,
     419                 :                                        nsIOfflineCacheUpdate **aUpdate)
     420                 : {
     421               0 :     LOG(("nsOfflineCacheUpdateService::GetUpdate [%p, %d]", this, aIndex));
     422                 : 
     423               0 :     if (aIndex < mUpdates.Length()) {
     424               0 :         NS_ADDREF(*aUpdate = mUpdates[aIndex]);
     425                 :     } else {
     426               0 :         *aUpdate = nsnull;
     427                 :     }
     428                 : 
     429               0 :     return NS_OK;
     430                 : }
     431                 : 
     432                 : nsresult
     433               0 : nsOfflineCacheUpdateService::FindUpdate(nsIURI *aManifestURI,
     434                 :                                         nsIURI *aDocumentURI,
     435                 :                                         nsOfflineCacheUpdate **aUpdate)
     436                 : {
     437                 :     nsresult rv;
     438                 : 
     439               0 :     nsRefPtr<nsOfflineCacheUpdate> update;
     440               0 :     for (PRUint32 i = 0; i < mUpdates.Length(); i++) {
     441               0 :         update = mUpdates[i];
     442                 : 
     443                 :         bool partial;
     444               0 :         rv = update->GetPartial(&partial);
     445               0 :         NS_ENSURE_SUCCESS(rv, rv);
     446                 : 
     447               0 :         if (partial) {
     448                 :             // Partial updates aren't considered
     449               0 :             continue;
     450                 :         }
     451                 : 
     452               0 :         nsCOMPtr<nsIURI> manifestURI;
     453               0 :         update->GetManifestURI(getter_AddRefs(manifestURI));
     454               0 :         if (manifestURI) {
     455                 :             bool equals;
     456               0 :             rv = manifestURI->Equals(aManifestURI, &equals);
     457               0 :             if (equals) {
     458               0 :                 update.swap(*aUpdate);
     459               0 :                 return NS_OK;
     460                 :             }
     461                 :         }
     462                 :     }
     463                 : 
     464               0 :     return NS_ERROR_NOT_AVAILABLE;
     465                 : }
     466                 : 
     467                 : nsresult
     468               8 : nsOfflineCacheUpdateService::Schedule(nsIURI *aManifestURI,
     469                 :                                       nsIURI *aDocumentURI,
     470                 :                                       nsIDOMDocument *aDocument,
     471                 :                                       nsIDOMWindow* aWindow,
     472                 :                                       nsIOfflineCacheUpdate **aUpdate)
     473                 : {
     474              16 :     nsCOMPtr<nsIOfflineCacheUpdate> update;
     475               8 :     if (GeckoProcessType_Default != XRE_GetProcessType()) {
     476               0 :         update = new OfflineCacheUpdateChild(aWindow);
     477                 :     }
     478                 :     else {
     479               8 :         update = new OfflineCacheUpdateGlue();
     480                 :     }
     481                 : 
     482                 :     nsresult rv;
     483                 : 
     484               8 :     rv = update->Init(aManifestURI, aDocumentURI, aDocument);
     485               8 :     NS_ENSURE_SUCCESS(rv, rv);
     486                 : 
     487               8 :     rv = update->Schedule();
     488               8 :     NS_ENSURE_SUCCESS(rv, rv);
     489                 : 
     490               8 :     NS_ADDREF(*aUpdate = update);
     491                 : 
     492               8 :     return NS_OK;
     493                 : }
     494                 : 
     495                 : NS_IMETHODIMP
     496               8 : nsOfflineCacheUpdateService::ScheduleUpdate(nsIURI *aManifestURI,
     497                 :                                             nsIURI *aDocumentURI,
     498                 :                                             nsIDOMWindow *aWindow,
     499                 :                                             nsIOfflineCacheUpdate **aUpdate)
     500                 : {
     501               8 :     return Schedule(aManifestURI, aDocumentURI, nsnull, aWindow, aUpdate);
     502                 : }
     503                 : 
     504                 : //-----------------------------------------------------------------------------
     505                 : // nsOfflineCacheUpdateService::nsIObserver
     506                 : //-----------------------------------------------------------------------------
     507                 : 
     508                 : NS_IMETHODIMP
     509               8 : nsOfflineCacheUpdateService::Observe(nsISupports     *aSubject,
     510                 :                                      const char      *aTopic,
     511                 :                                      const PRUnichar *aData)
     512                 : {
     513               8 :     if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
     514               8 :         if (mUpdates.Length() > 0)
     515               0 :             mUpdates[0]->Cancel();
     516               8 :         mDisabled = true;
     517                 :     }
     518                 : 
     519               8 :     return NS_OK;
     520                 : }
     521                 : 
     522                 : //-----------------------------------------------------------------------------
     523                 : // nsOfflineCacheUpdateService::nsIOfflineCacheUpdateService
     524                 : //-----------------------------------------------------------------------------
     525                 : 
     526                 : NS_IMETHODIMP
     527               0 : nsOfflineCacheUpdateService::OfflineAppAllowed(nsIPrincipal *aPrincipal,
     528                 :                                                nsIPrefBranch *aPrefBranch,
     529                 :                                                bool *aAllowed)
     530                 : {
     531               0 :     nsCOMPtr<nsIURI> codebaseURI;
     532               0 :     nsresult rv = aPrincipal->GetURI(getter_AddRefs(codebaseURI));
     533               0 :     NS_ENSURE_SUCCESS(rv, rv);
     534                 : 
     535               0 :     return OfflineAppAllowedForURI(codebaseURI, aPrefBranch, aAllowed);
     536                 : }
     537                 : 
     538                 : NS_IMETHODIMP
     539               0 : nsOfflineCacheUpdateService::OfflineAppAllowedForURI(nsIURI *aURI,
     540                 :                                                      nsIPrefBranch *aPrefBranch,
     541                 :                                                      bool *aAllowed)
     542                 : {
     543               0 :     *aAllowed = false;
     544               0 :     if (!aURI)
     545               0 :         return NS_OK;
     546                 : 
     547               0 :     nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(aURI);
     548               0 :     if (!innerURI)
     549               0 :         return NS_OK;
     550                 : 
     551                 :     // only http and https applications can use offline APIs.
     552                 :     bool match;
     553               0 :     nsresult rv = innerURI->SchemeIs("http", &match);
     554               0 :     NS_ENSURE_SUCCESS(rv, rv);
     555                 : 
     556               0 :     if (!match) {
     557               0 :         rv = innerURI->SchemeIs("https", &match);
     558               0 :         NS_ENSURE_SUCCESS(rv, rv);
     559               0 :         if (!match) {
     560               0 :             return NS_OK;
     561                 :         }
     562                 :     }
     563                 : 
     564                 :     nsCOMPtr<nsIPermissionManager> permissionManager =
     565               0 :         do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
     566               0 :     if (!permissionManager) {
     567               0 :         return NS_OK;
     568                 :     }
     569                 : 
     570                 :     PRUint32 perm;
     571               0 :     permissionManager->TestExactPermission(innerURI, "offline-app", &perm);
     572                 : 
     573               0 :     if (perm == nsIPermissionManager::UNKNOWN_ACTION) {
     574                 :         static const char kPrefName[] = "offline-apps.allow_by_default";
     575               0 :         if (aPrefBranch) {
     576               0 :             aPrefBranch->GetBoolPref(kPrefName, aAllowed);
     577                 :         } else {
     578               0 :             *aAllowed = Preferences::GetBool(kPrefName, false);
     579                 :         }
     580                 : 
     581               0 :         return NS_OK;
     582                 :     }
     583                 : 
     584               0 :     if (perm == nsIPermissionManager::DENY_ACTION) {
     585               0 :         return NS_OK;
     586                 :     }
     587                 : 
     588               0 :     *aAllowed = true;
     589                 : 
     590               0 :     return NS_OK;
     591                 : }

Generated by: LCOV version 1.7