18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2007 Apple Inc.  All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ProgressTracker.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "DocumentLoader.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameLoader.h"
3206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#include "FrameLoaderStateMachine.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameLoaderClient.h"
34692e5dbf12901edacf14812a6fae25462920af42Steve Block#include "Logging.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ResourceResponse.h"
36dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/text/CString.h>
37635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <wtf/CurrentTime.h>
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing std::min;
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Always start progress at initialProgressValue. This helps provide feedback as
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// soon as a load starts.
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const double initialProgressValue = 0.1;
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Similarly, always leave space at the end. This helps show the user that we're not done
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// until we're done.
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const double finalProgressValue = 0.9; // 1.0 - initialProgressValue
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const int progressItemDefaultEstimatedLength = 1024 * 16;
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
53ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochstruct ProgressItem {
54ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    WTF_MAKE_NONCOPYABLE(ProgressItem); WTF_MAKE_FAST_ALLOCATED;
55ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochpublic:
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ProgressItem(long long length)
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        : bytesReceived(0)
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        , estimatedLength(length) { }
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    long long bytesReceived;
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    long long estimatedLength;
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
64a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochunsigned long ProgressTracker::s_uniqueIdentifier = 0;
65a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectProgressTracker::ProgressTracker()
67a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    : m_totalPageAndResourceBytesToLoad(0)
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_totalBytesReceived(0)
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_lastNotifiedProgressValue(0)
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_lastNotifiedProgressTime(0)
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_progressNotificationInterval(0.02)
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_progressNotificationTimeInterval(0.1)
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_finalProgressChangedSent(false)
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_progressValue(0)
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_numProgressTrackedFrames(0)
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectProgressTracker::~ProgressTracker()
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    deleteAllValues(m_progressItems);
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectdouble ProgressTracker::estimatedProgress() const
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_progressValue;
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProgressTracker::reset()
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    deleteAllValues(m_progressItems);
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_progressItems.clear();
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_totalPageAndResourceBytesToLoad = 0;
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_totalBytesReceived = 0;
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_progressValue = 0;
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_lastNotifiedProgressValue = 0;
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_lastNotifiedProgressTime = 0;
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_finalProgressChangedSent = false;
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_numProgressTrackedFrames = 0;
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_originatingProgressFrame = 0;
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProgressTracker::progressStarted(Frame* frame)
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    LOG(Progress, "Progress started (%p) - frame %p(\"%s\"), value %f, tracked frames %d, originating frame %p", this, frame, frame->tree()->uniqueName().string().utf8().data(), m_progressValue, m_numProgressTrackedFrames, m_originatingProgressFrame.get());
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    frame->loader()->client()->willChangeEstimatedProgress();
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_numProgressTrackedFrames == 0 || m_originatingProgressFrame == frame) {
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        reset();
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_progressValue = initialProgressValue;
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_originatingProgressFrame = frame;
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_originatingProgressFrame->loader()->client()->postProgressStartedNotification();
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_numProgressTrackedFrames++;
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    frame->loader()->client()->didChangeEstimatedProgress();
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProgressTracker::progressCompleted(Frame* frame)
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
12428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    LOG(Progress, "Progress completed (%p) - frame %p(\"%s\"), value %f, tracked frames %d, originating frame %p", this, frame, frame->tree()->uniqueName().string().utf8().data(), m_progressValue, m_numProgressTrackedFrames, m_originatingProgressFrame.get());
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_numProgressTrackedFrames <= 0)
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    frame->loader()->client()->willChangeEstimatedProgress();
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_numProgressTrackedFrames--;
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_numProgressTrackedFrames == 0 ||
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        (frame == m_originatingProgressFrame && m_numProgressTrackedFrames != 0))
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        finalProgressComplete();
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    frame->loader()->client()->didChangeEstimatedProgress();
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProgressTracker::finalProgressComplete()
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
141692e5dbf12901edacf14812a6fae25462920af42Steve Block    LOG(Progress, "Final progress complete (%p)", this);
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Frame> frame = m_originatingProgressFrame.release();
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Before resetting progress value be sure to send client a least one notification
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // with final progress value.
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_finalProgressChangedSent) {
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_progressValue = 1;
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        frame->loader()->client()->postProgressEstimateChangedNotification();
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    reset();
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    frame->loader()->client()->setMainFrameDocumentReady(true);
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    frame->loader()->client()->postProgressFinishedNotification();
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProgressTracker::incrementProgress(unsigned long identifier, const ResourceResponse& response)
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
160692e5dbf12901edacf14812a6fae25462920af42Steve Block    LOG(Progress, "Progress incremented (%p) - value %f, tracked frames %d, originating frame %p", this, m_progressValue, m_numProgressTrackedFrames, m_originatingProgressFrame.get());
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_numProgressTrackedFrames <= 0)
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    long long estimatedLength = response.expectedContentLength();
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (estimatedLength < 0)
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        estimatedLength = progressItemDefaultEstimatedLength;
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_totalPageAndResourceBytesToLoad += estimatedLength;
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ProgressItem* item = m_progressItems.get(identifier)) {
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        item->bytesReceived = 0;
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        item->estimatedLength = estimatedLength;
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
1755ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        m_progressItems.set(identifier, adoptPtr(new ProgressItem(estimatedLength)).leakPtr());
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProgressTracker::incrementProgress(unsigned long identifier, const char*, int length)
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ProgressItem* item = m_progressItems.get(identifier);
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Can this ever happen?
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!item)
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
185643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
186643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    RefPtr<Frame> frame = m_originatingProgressFrame;
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
188643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    frame->loader()->client()->willChangeEstimatedProgress();
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned bytesReceived = length;
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double increment, percentOfRemainingBytes;
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    long long remainingBytes, estimatedBytesForPendingRequests;
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    item->bytesReceived += bytesReceived;
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (item->bytesReceived > item->estimatedLength) {
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_totalPageAndResourceBytesToLoad += ((item->bytesReceived * 2) - item->estimatedLength);
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        item->estimatedLength = item->bytesReceived * 2;
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
200643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    int numPendingOrLoadingRequests = frame->loader()->numPendingOrLoadingRequests(true);
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    estimatedBytesForPendingRequests = progressItemDefaultEstimatedLength * numPendingOrLoadingRequests;
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    remainingBytes = ((m_totalPageAndResourceBytesToLoad + estimatedBytesForPendingRequests) - m_totalBytesReceived);
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (remainingBytes > 0)  // Prevent divide by 0.
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        percentOfRemainingBytes = (double)bytesReceived / (double)remainingBytes;
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        percentOfRemainingBytes = 1.0;
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // For documents that use WebCore's layout system, treat first layout as the half-way point.
2095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // FIXME: The hasHTMLView function is a sort of roundabout way of asking "do you use WebCore's layout system".
210643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    bool useClampedMaxProgress = frame->loader()->client()->hasHTMLView()
21106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        && !frame->loader()->stateMachine()->firstLayoutDone();
2125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    double maxProgressValue = useClampedMaxProgress ? 0.5 : finalProgressValue;
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    increment = (maxProgressValue - m_progressValue) * percentOfRemainingBytes;
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_progressValue += increment;
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_progressValue = min(m_progressValue, maxProgressValue);
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_progressValue >= initialProgressValue);
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_totalBytesReceived += bytesReceived;
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double now = currentTime();
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double notifiedProgressTimeDelta = now - m_lastNotifiedProgressTime;
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
223692e5dbf12901edacf14812a6fae25462920af42Steve Block    LOG(Progress, "Progress incremented (%p) - value %f, tracked frames %d", this, m_progressValue, m_numProgressTrackedFrames);
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double notificationProgressDelta = m_progressValue - m_lastNotifiedProgressValue;
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if ((notificationProgressDelta >= m_progressNotificationInterval ||
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         notifiedProgressTimeDelta >= m_progressNotificationTimeInterval) &&
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_numProgressTrackedFrames > 0) {
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!m_finalProgressChangedSent) {
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (m_progressValue == 1)
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_finalProgressChangedSent = true;
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
232643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            frame->loader()->client()->postProgressEstimateChangedNotification();
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_lastNotifiedProgressValue = m_progressValue;
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_lastNotifiedProgressTime = now;
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
239643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    frame->loader()->client()->didChangeEstimatedProgress();
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProgressTracker::completeProgress(unsigned long identifier)
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ProgressItem* item = m_progressItems.get(identifier);
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2466b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // This can happen if a load fails without receiving any response data.
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!item)
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Adjust the total expected bytes to account for any overage/underage.
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    long long delta = item->bytesReceived - item->estimatedLength;
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_totalPageAndResourceBytesToLoad += delta;
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    item->estimatedLength = item->bytesReceived;
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_progressItems.remove(identifier);
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    delete item;
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectunsigned long ProgressTracker::createUniqueIdentifier()
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
261a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return ++s_uniqueIdentifier;
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
266