Bug 744710 - Enable getting updates on how many bytes of an appcache update have been downloaded, r=michal
authorHonza Bambas <honzab.moz@firemni.cz>
Tue, 22 May 2012 22:12:40 +0200
changeset 94611 10b04214089d6f778bfa2e3a8fc875b25082cf3f
parent 94610 a67b67adbb2bcbf828caa20a1f4d756659d4af97
child 94612 530d57b9046156350d085d926d2f138f7dbdf2a9
push id22732
push useremorley@mozilla.com
push dateWed, 23 May 2012 09:43:13 +0000
treeherdermozilla-central@aa2b52bd0374 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmichal
bugs744710
milestone15.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 744710 - Enable getting updates on how many bytes of an appcache update have been downloaded, r=michal
uriloader/prefetch/OfflineCacheUpdateChild.cpp
uriloader/prefetch/OfflineCacheUpdateChild.h
uriloader/prefetch/OfflineCacheUpdateGlue.h
uriloader/prefetch/OfflineCacheUpdateParent.cpp
uriloader/prefetch/POfflineCacheUpdate.ipdl
uriloader/prefetch/nsIOfflineCacheUpdate.idl
uriloader/prefetch/nsOfflineCacheUpdate.cpp
uriloader/prefetch/nsOfflineCacheUpdate.h
--- a/uriloader/prefetch/OfflineCacheUpdateChild.cpp
+++ b/uriloader/prefetch/OfflineCacheUpdateChild.cpp
@@ -73,16 +73,17 @@ OfflineCacheUpdateChild::RefcountHitZero
 // OfflineCacheUpdateChild <public>
 //-----------------------------------------------------------------------------
 
 OfflineCacheUpdateChild::OfflineCacheUpdateChild(nsIDOMWindow* aWindow)
     : mState(STATE_UNINITIALIZED)
     , mIsUpgrade(false)
     , mIPCActivated(false)
     , mWindow(aWindow)
+    , mByteProgress(0)
 {
 }
 
 OfflineCacheUpdateChild::~OfflineCacheUpdateChild()
 {
     LOG(("OfflineCacheUpdateChild::~OfflineCacheUpdateChild [%p]", this));
 }
 
@@ -336,16 +337,25 @@ OfflineCacheUpdateChild::RemoveObserver(
             return NS_OK;
         }
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
+OfflineCacheUpdateChild::GetByteProgress(PRUint64 * _result)
+{
+    NS_ENSURE_ARG(_result);
+
+    *_result = mByteProgress;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
 OfflineCacheUpdateChild::Schedule()
 {
     LOG(("OfflineCacheUpdateChild::Schedule [%p]", this));
 
     NS_ASSERTION(mWindow, "Window must be provided to the offline cache update child");
 
     nsCOMPtr<nsPIDOMWindow> piWindow = 
         do_QueryInterface(mWindow);
@@ -430,20 +440,23 @@ OfflineCacheUpdateChild::RecvAssociateDo
 
     for (PRInt32 i = 0; i < observers.Count(); i++)
         observers[i]->ApplicationCacheAvailable(cache);
 
     return true;
 }
 
 bool
-OfflineCacheUpdateChild::RecvNotifyStateEvent(const PRUint32 &event)
+OfflineCacheUpdateChild::RecvNotifyStateEvent(const PRUint32 &event,
+                                              const PRUint64 &byteProgress)
 {
     LOG(("OfflineCacheUpdateChild::RecvNotifyStateEvent [%p]", this));
 
+    mByteProgress = byteProgress;
+
     // Convert the public observer state to our internal state
     switch (event) {
         case nsIOfflineCacheUpdateObserver::STATE_CHECKING:
             mState = STATE_CHECKING;
             break;
 
         case nsIOfflineCacheUpdateObserver::STATE_DOWNLOADING:
             mState = STATE_DOWNLOADING;
--- a/uriloader/prefetch/OfflineCacheUpdateChild.h
+++ b/uriloader/prefetch/OfflineCacheUpdateChild.h
@@ -18,24 +18,25 @@
 #include "nsIURI.h"
 #include "nsString.h"
 #include "nsWeakReference.h"
 
 namespace mozilla {
 namespace docshell {
 
 class OfflineCacheUpdateChild : public nsIOfflineCacheUpdate
-                                , public POfflineCacheUpdateChild
+                              , public POfflineCacheUpdateChild
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIOFFLINECACHEUPDATE
 
     virtual bool
-    RecvNotifyStateEvent(const PRUint32& stateEvent);
+    RecvNotifyStateEvent(const PRUint32& stateEvent,
+                         const PRUint64& byteProgress);
 
     virtual bool
     RecvAssociateDocuments(
             const nsCString& cacheGroupId,
             const nsCString& cacheClientId);
 
     virtual bool
     RecvFinish(const bool& succeded,
@@ -80,14 +81,16 @@ private:
     nsCOMArray<nsIOfflineCacheUpdateObserver> mObservers;
 
     /* Document that requested this update */
     nsCOMPtr<nsIDOMDocument> mDocument;
 
     /* Keep reference to the window that owns this update to call the
        parent offline cache update construcor */
     nsCOMPtr<nsIDOMWindow> mWindow;
+
+    PRUint64 mByteProgress;
 };
 
 }
 }
 
 #endif
--- a/uriloader/prefetch/OfflineCacheUpdateGlue.h
+++ b/uriloader/prefetch/OfflineCacheUpdateGlue.h
@@ -26,17 +26,18 @@ namespace docshell {
   NS_SCRIPTABLE NS_IMETHOD GetPartial(bool *aPartial) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetPartial(aPartial); } \
   NS_SCRIPTABLE NS_IMETHOD GetIsUpgrade(bool *aIsUpgrade) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetIsUpgrade(aIsUpgrade); } \
   NS_SCRIPTABLE NS_IMETHOD GetUpdateDomain(nsACString & aUpdateDomain) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetUpdateDomain(aUpdateDomain); } \
   NS_SCRIPTABLE NS_IMETHOD GetManifestURI(nsIURI **aManifestURI) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetManifestURI(aManifestURI); } \
   NS_SCRIPTABLE NS_IMETHOD GetSucceeded(bool *aSucceeded) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetSucceeded(aSucceeded); } \
   NS_SCRIPTABLE NS_IMETHOD InitPartial(nsIURI *aManifestURI, const nsACString & aClientID, nsIURI *aDocumentURI) { return !_to ? NS_ERROR_NULL_POINTER : _to->InitPartial(aManifestURI, aClientID, aDocumentURI); } \
   NS_SCRIPTABLE NS_IMETHOD AddDynamicURI(nsIURI *aURI) { return !_to ? NS_ERROR_NULL_POINTER : _to->AddDynamicURI(aURI); } \
   NS_SCRIPTABLE NS_IMETHOD AddObserver(nsIOfflineCacheUpdateObserver *aObserver, bool aHoldWeak) { return !_to ? NS_ERROR_NULL_POINTER : _to->AddObserver(aObserver, aHoldWeak); } \
-  NS_SCRIPTABLE NS_IMETHOD RemoveObserver(nsIOfflineCacheUpdateObserver *aObserver) { return !_to ? NS_ERROR_NULL_POINTER : _to->RemoveObserver(aObserver); } 
+  NS_SCRIPTABLE NS_IMETHOD RemoveObserver(nsIOfflineCacheUpdateObserver *aObserver) { return !_to ? NS_ERROR_NULL_POINTER : _to->RemoveObserver(aObserver); } \
+  NS_SCRIPTABLE NS_IMETHOD GetByteProgress(PRUint64 * _result) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetByteProgress(_result); }
 
 class OfflineCacheUpdateGlue : public nsSupportsWeakReference
                                , public nsIOfflineCacheUpdate
                                , public nsIOfflineCacheUpdateObserver
 {
 public:
     NS_DECL_ISUPPORTS
 
--- a/uriloader/prefetch/OfflineCacheUpdateParent.cpp
+++ b/uriloader/prefetch/OfflineCacheUpdateParent.cpp
@@ -104,17 +104,19 @@ OfflineCacheUpdateParent::Schedule(const
 NS_IMETHODIMP
 OfflineCacheUpdateParent::UpdateStateChanged(nsIOfflineCacheUpdate *aUpdate, PRUint32 state)
 {
     if (mIPCClosed)
         return NS_ERROR_UNEXPECTED;
 
     LOG(("OfflineCacheUpdateParent::StateEvent [%p]", this));
 
-    SendNotifyStateEvent(state);
+    PRUint64 byteProgress;
+    aUpdate->GetByteProgress(&byteProgress);
+    SendNotifyStateEvent(state, byteProgress);
 
     if (state == nsIOfflineCacheUpdateObserver::STATE_FINISHED) {
         // Tell the child the particulars after the update has finished.
         // Sending the Finish event will release the child side of the protocol
         // and notify "offline-cache-update-completed" on the child process.
         bool isUpgrade;
         aUpdate->GetIsUpgrade(&isUpgrade);
         bool succeeded;
--- a/uriloader/prefetch/POfflineCacheUpdate.ipdl
+++ b/uriloader/prefetch/POfflineCacheUpdate.ipdl
@@ -18,15 +18,15 @@ namespace docshell {
 protocol POfflineCacheUpdate
 {
   manager PBrowser;
 
 parent:
   __delete__();
 
 child:
-  NotifyStateEvent(PRUint32 stateEvent);
+  NotifyStateEvent(PRUint32 stateEvent, PRUint64 byteProgress);
   AssociateDocuments(nsCString cacheGroupId, nsCString cacheClientId);
   Finish(bool succeded, bool isUpgrate);
 };
 
 }
 }
--- a/uriloader/prefetch/nsIOfflineCacheUpdate.idl
+++ b/uriloader/prefetch/nsIOfflineCacheUpdate.idl
@@ -19,16 +19,17 @@ interface nsIApplicationCache;
 interface nsIOfflineCacheUpdateObserver : nsISupports {
   const unsigned long STATE_ERROR = 1;
   const unsigned long STATE_CHECKING = 2;
   const unsigned long STATE_NOUPDATE = 3;
   const unsigned long STATE_OBSOLETE = 4;
   const unsigned long STATE_DOWNLOADING = 5;
   const unsigned long STATE_ITEMSTARTED = 6;
   const unsigned long STATE_ITEMCOMPLETED = 7;
+  const unsigned long STATE_ITEMPROGRESS = 8;
   const unsigned long STATE_FINISHED = 10;
 
   /**
    * aUpdate has changed its state.
    *
    * @param aUpdate
    *        The nsIOfflineCacheUpdate being processed.
    * @param event
@@ -55,17 +56,17 @@ interface nsIOfflineCacheUpdateObserver 
  * Each update object maintains a list of nsIDOMLoadStatus items for the
  * resources it is updating.  The list of these items will be available
  * after the object is scheduled.
  *
  * One update object will be updating at a time.  The active object will
  * load its items one by one, sending itemCompleted() to any registered
  * observers.
  */
-[scriptable, uuid(24605d81-8cf9-4021-8575-7f39aacbf31a)]
+[scriptable, uuid(2FA574B8-AE62-426b-BE95-08E6AA957455)]
 interface nsIOfflineCacheUpdate : nsISupports {
   /**
    * Fetch the status of the running update.  This will return a value
    * defined in nsIDOMOfflineResourceList.
    */
   readonly attribute unsigned short status;
 
   /**
@@ -149,16 +150,21 @@ interface nsIOfflineCacheUpdate : nsISup
 
   /**
    * Remove an observer from the update.
    *
    * @param aObserver
    *        the observer to remove.
    */
   void removeObserver(in nsIOfflineCacheUpdateObserver aObserver);
+
+  /**
+   * Return the number of bytes downloaded so far
+   */
+  readonly attribute PRUint64 byteProgress;
 };
 
 [scriptable, uuid(6fd2030f-7b00-4102-a0e3-d73078821eb1)]
 interface nsIOfflineCacheUpdateService : nsISupports {
     /**
      * Constants for the offline-app permission.
      *
      * XXX: This isn't a great place for this, but it's really the only
--- a/uriloader/prefetch/nsOfflineCacheUpdate.cpp
+++ b/uriloader/prefetch/nsOfflineCacheUpdate.cpp
@@ -397,16 +397,19 @@ nsOfflineCacheUpdateItem::OnDataAvailabl
                                           PRUint32 aOffset,
                                           PRUint32 aCount)
 {
     PRUint32 bytesRead = 0;
     aStream->ReadSegments(NS_DiscardSegment, nsnull, aCount, &bytesRead);
     mBytesRead += bytesRead;
     LOG(("loaded %u bytes into offline cache [offset=%u]\n",
          bytesRead, aOffset));
+
+    mUpdate->OnByteProgress(bytesRead);
+
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsOfflineCacheUpdateItem::OnStopRequest(nsIRequest *aRequest,
                                         nsISupports *aContext,
                                         nsresult aStatus)
 {
@@ -414,16 +417,17 @@ nsOfflineCacheUpdateItem::OnStopRequest(
 
     mState = nsIDOMLoadStatus::LOADED;
 
     if (mBytesRead == 0 && aStatus == NS_OK) {
         // we didn't need to read (because LOAD_ONLY_IF_MODIFIED was
         // specified), but the object should report loadedSize as if it
         // did.
         mChannel->GetContentLength(&mBytesRead);
+        mUpdate->OnByteProgress(mBytesRead);
     }
 
     // We need to notify the update that the load is complete, but we
     // want to give the channel a chance to close the cache entries.
     NS_DispatchToCurrentThread(this);
 
     return NS_OK;
 }
@@ -1543,16 +1547,17 @@ nsOfflineCacheUpdate::Begin()
                                               mDocumentURI,
                                               mPreviousApplicationCache,
                                               mClientID);
     if (!mManifestItem) {
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
     mState = STATE_CHECKING;
+    mByteProgress = 0;
     NotifyState(nsIOfflineCacheUpdateObserver::STATE_CHECKING);
 
     nsresult rv = mManifestItem->OpenChannel();
     if (NS_FAILED(rv)) {
         LoadCompleted();
     }
 
     return NS_OK;
@@ -1748,16 +1753,23 @@ nsOfflineCacheUpdate::UpdateFinished(nsO
     mImplicitUpdate = nsnull;
 
     NotifyState(nsIOfflineCacheUpdateObserver::STATE_NOUPDATE);
     Finish();
 
     return NS_OK;
 }
 
+void
+nsOfflineCacheUpdate::OnByteProgress(PRUint64 byteIncrement)
+{
+    mByteProgress += byteIncrement;
+    NotifyState(nsIOfflineCacheUpdateObserver::STATE_ITEMPROGRESS);
+}
+
 nsresult
 nsOfflineCacheUpdate::ScheduleImplicit()
 {
     if (mDocumentURIs.Count() == 0)
         return NS_OK;
 
     nsresult rv;
 
@@ -2080,16 +2092,24 @@ nsOfflineCacheUpdate::RemoveObserver(nsI
             mObservers.RemoveObjectAt(i);
             return NS_OK;
         }
     }
 
     return NS_OK;
 }
 
+NS_IMETHODIMP
+nsOfflineCacheUpdate::GetByteProgress(PRUint64 * _result)
+{
+    NS_ENSURE_ARG(_result);
+
+    *_result = mByteProgress;
+    return NS_OK;
+}
 
 NS_IMETHODIMP
 nsOfflineCacheUpdate::Schedule()
 {
     LOG(("nsOfflineCacheUpdate::Schedule [%p]", this));
 
     nsOfflineCacheUpdateService* service =
         nsOfflineCacheUpdateService::EnsureService();
--- a/uriloader/prefetch/nsOfflineCacheUpdate.h
+++ b/uriloader/prefetch/nsOfflineCacheUpdate.h
@@ -200,16 +200,20 @@ public:
     void ManifestCheckCompleted(nsresult aStatus,
                                 const nsCString &aManifestHash);
     void StickDocument(nsIURI *aDocumentURI);
 
     void SetOwner(nsOfflineCacheUpdateOwner *aOwner);
 
     virtual nsresult UpdateFinished(nsOfflineCacheUpdate *aUpdate);
 
+protected:
+    friend class nsOfflineCacheUpdateItem;
+    void OnByteProgress(PRUint64 byteIncrement);
+
 private:
     nsresult HandleManifest(bool *aDoUpdate);
     nsresult AddURI(nsIURI *aURI, PRUint32 aItemType);
 
     nsresult ProcessNextURI();
 
     // Adds items from the previous cache witha type matching aType.
     // If namespaceFilter is non-null, only items matching the
@@ -272,16 +276,18 @@ private:
 
     /* Whena an entry for a pinned app is retried, retries count is
      * increaded. */
     PRUint32 mPinnedEntryRetriesCount;
 
     nsRefPtr<nsOfflineCacheUpdate> mImplicitUpdate;
 
     bool                           mPinned;
+
+    PRUint64                       mByteProgress;
 };
 
 class nsOfflineCacheUpdateService : public nsIOfflineCacheUpdateService
                                   , public nsIObserver
                                   , public nsOfflineCacheUpdateOwner
                                   , public nsSupportsWeakReference
 {
 public: