18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2008 Collabora, Ltd. All rights reserved.
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PluginStream.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CString.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DocumentLoader.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameLoader.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PluginDebug.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SharedBuffer.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SubresourceLoader.h"
375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include <StringExtras.h>
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// We use -2 here because some plugins like to return -1 to indicate error
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// and this way we won't clash with them.
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const int WebReasonNone = -2;
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing std::max;
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing std::min;
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttypedef HashMap<NPStream*, NPP> StreamMap;
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic StreamMap& streams()
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static StreamMap staticStreams;
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return staticStreams;
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPluginStream::PluginStream(PluginStreamClient* client, Frame* frame, const ResourceRequest& resourceRequest, bool sendNotification, void* notifyData, const NPPluginFuncs* pluginFuncs, NPP instance, const PluginQuirkSet& quirks)
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : m_resourceRequest(resourceRequest)
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_client(client)
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_frame(frame)
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_notifyData(notifyData)
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_sendNotification(sendNotification)
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_streamState(StreamBeforeStarted)
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_loadManually(false)
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_delayDeliveryTimer(this, &PluginStream::delayDeliveryTimerFired)
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_deliveryData(0)
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_tempFileHandle(invalidPlatformFileHandle)
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_pluginFuncs(pluginFuncs)
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_instance(instance)
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_quirks(quirks)
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_instance);
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_stream.url = 0;
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_stream.ndata = 0;
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_stream.pdata = 0;
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_stream.end = 0;
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_stream.notifyData = 0;
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_stream.lastmodified = 0;
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    streams().add(&m_stream, m_instance);
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPluginStream::~PluginStream()
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_streamState != StreamStarted);
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!m_loader);
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
878a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    fastFree((char*)m_stream.url);
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    streams().remove(&m_stream);
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid PluginStream::start()
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!m_loadManually);
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_loader = NetscapePlugInStreamLoader::create(m_frame, this);
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_loader->setShouldBufferData(false);
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_loader->documentLoader()->addPlugInStreamLoader(m_loader.get());
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_loader->load(m_resourceRequest);
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid PluginStream::stop()
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_streamState = StreamStopped;
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_loadManually) {
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(!m_loader);
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DocumentLoader* documentLoader = m_frame->loader()->activeDocumentLoader();
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(documentLoader);
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (documentLoader->isLoadingMainResource())
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            documentLoader->cancelMainResourceLoad(m_frame->loader()->cancelledError(m_resourceRequest));
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_loader) {
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_loader->cancel();
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_loader = 0;
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
123643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
124643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    m_client = 0;
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid PluginStream::startStream()
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_streamState == StreamBeforeStarted);
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const KURL& responseURL = m_resourceResponse.url();
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Some plugins (Flash) expect that javascript URLs are passed back decoded as this is the
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // format used when requesting the URL.
1355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (protocolIsJavaScript(responseURL))
1368a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        m_stream.url = fastStrDup(decodeURLEscapeSequences(responseURL.string()).utf8().data());
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
1388a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        m_stream.url = fastStrDup(responseURL.string().utf8().data());
1395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CString mimeTypeStr = m_resourceResponse.mimeType().utf8();
1415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    long long expectedContentLength = m_resourceResponse.expectedContentLength();
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_resourceResponse.isHTTP()) {
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Vector<UChar> stringBuilder;
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String separator(": ");
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        String statusLine = String::format("HTTP %d OK\n", m_resourceResponse.httpStatusCode());
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        stringBuilder.append(statusLine.characters(), statusLine.length());
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HTTPHeaderMap::const_iterator end = m_resourceResponse.httpHeaderFields().end();
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (HTTPHeaderMap::const_iterator it = m_resourceResponse.httpHeaderFields().begin(); it != end; ++it) {
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            stringBuilder.append(it->first.characters(), it->first.length());
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            stringBuilder.append(separator.characters(), separator.length());
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            stringBuilder.append(it->second.characters(), it->second.length());
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            stringBuilder.append('\n');
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_headers = String::adopt(stringBuilder).utf8();
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // If the content is encoded (most likely compressed), then don't send its length to the plugin,
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // which is only interested in the decoded length, not yet known at the moment.
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // <rdar://problem/4470599> tracks a request for -[NSURLResponse expectedContentLength] to incorporate this logic.
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String contentEncoding = m_resourceResponse.httpHeaderField("Content-Encoding");
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!contentEncoding.isNull() && contentEncoding != "identity")
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            expectedContentLength = -1;
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_stream.headers = m_headers.data();
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_stream.pdata = 0;
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_stream.ndata = this;
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_stream.end = max(expectedContentLength, 0LL);
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_stream.lastmodified = m_resourceResponse.lastModifiedDate();
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_stream.notifyData = m_notifyData;
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_transferMode = NP_NORMAL;
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_offset = 0;
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_reason = WebReasonNone;
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Protect the stream if destroystream is called from within the newstream handler
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<PluginStream> protect(this);
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // calling into a plug-in could result in re-entrance if the plug-in yields
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // control to the system (rdar://5744899). prevent this by deferring further
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // loading while calling into the plug-in.
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_loader)
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_loader->setDefersLoading(true);
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NPError npErr = m_pluginFuncs->newstream(m_instance, (NPMIMEType)mimeTypeStr.data(), &m_stream, false, &m_transferMode);
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_loader)
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_loader->setDefersLoading(false);
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the stream was destroyed in the call to newstream we return
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_reason != WebReasonNone)
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (npErr != NPERR_NO_ERROR) {
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cancelAndDestroyStream(npErr);
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_streamState = StreamStarted;
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_transferMode == NP_NORMAL)
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_path = openTemporaryFile("WKP", m_tempFileHandle);
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Something went wrong, cancel loading the stream
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!isHandleValid(m_tempFileHandle))
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cancelAndDestroyStream(NPRES_NETWORK_ERR);
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNPP PluginStream::ownerForStream(NPStream* stream)
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return streams().get(stream);
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid PluginStream::cancelAndDestroyStream(NPReason reason)
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<PluginStream> protect(this);
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    destroyStream(reason);
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    stop();
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid PluginStream::destroyStream(NPReason reason)
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_reason = reason;
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_reason != NPRES_DONE) {
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Stop any pending data from being streamed
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_deliveryData)
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_deliveryData->resize(0);
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (m_deliveryData && m_deliveryData->size() > 0) {
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // There is more data to be streamed, don't destroy the stream now.
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    destroyStream();
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid PluginStream::destroyStream()
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_streamState == StreamStopped)
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_reason != WebReasonNone);
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!m_deliveryData || m_deliveryData->size() == 0);
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    closeFile(m_tempFileHandle);
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool newStreamCalled = m_stream.ndata;
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Protect from destruction if:
2540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    //  NPN_DestroyStream is called from NPP_NewStream or
2550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    //  PluginStreamClient::streamDidFinishLoading() removes the last reference
2560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    RefPtr<PluginStream> protect(this);
2570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (newStreamCalled) {
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_reason == NPRES_DONE && (m_transferMode == NP_ASFILE || m_transferMode == NP_ASFILEONLY)) {
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(!m_path.isNull());
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (m_loader)
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_loader->setDefersLoading(true);
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_pluginFuncs->asfile(m_instance, &m_stream, m_path.data());
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (m_loader)
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_loader->setDefersLoading(false);
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_streamState != StreamBeforeStarted) {
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (m_loader)
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_loader->setDefersLoading(true);
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            NPError npErr = m_pluginFuncs->destroystream(m_instance, &m_stream, m_reason);
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (m_loader)
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_loader->setDefersLoading(false);
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            LOG_NPERROR(npErr);
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_stream.ndata = 0;
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_sendNotification) {
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Flash 9 can dereference null if we call NPP_URLNotify without first calling NPP_NewStream
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // for requests made with NPN_PostURLNotify; see <rdar://5588807>
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_loader)
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_loader->setDefersLoading(true);
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!newStreamCalled && m_quirks.contains(PluginQuirkFlashURLNotifyBug) &&
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            equalIgnoringCase(m_resourceRequest.httpMethod(), "POST")) {
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_transferMode = NP_NORMAL;
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_stream.url = "";
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_stream.notifyData = m_notifyData;
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
295635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            static char emptyMimeType[] = "";
296635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            m_pluginFuncs->newstream(m_instance, emptyMimeType, &m_stream, false, &m_transferMode);
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_pluginFuncs->destroystream(m_instance, &m_stream, m_reason);
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // in successful requests, the URL is dynamically allocated and freed in our
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // destructor, so reset it to 0
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_stream.url = 0;
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_pluginFuncs->urlnotify(m_instance, m_resourceRequest.url().string().utf8().data(), m_reason, m_notifyData);
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_loader)
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_loader->setDefersLoading(false);
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_streamState = StreamStopped;
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
310643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!m_loadManually && m_client)
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_client->streamDidFinishLoading(this);
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_path.isNull()) {
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String tempFilePath = String::fromUTF8(m_path.data());
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        deleteFile(tempFilePath);
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid PluginStream::delayDeliveryTimerFired(Timer<PluginStream>* timer)
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(timer == &m_delayDeliveryTimer);
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    deliverData();
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid PluginStream::deliverData()
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_deliveryData);
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_streamState == StreamStopped)
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: We should cancel our job in the SubresourceLoader on error so we don't reach this case
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_streamState != StreamBeforeStarted);
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_stream.ndata || m_deliveryData->size() == 0)
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int32 totalBytes = m_deliveryData->size();
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int32 totalBytesDelivered = 0;
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_loader)
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_loader->setDefersLoading(true);
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (totalBytesDelivered < totalBytes) {
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int32 deliveryBytes = m_pluginFuncs->writeready(m_instance, &m_stream);
3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (deliveryBytes <= 0) {
348a923424180b9d2cbe3a3951caed13039eef1edf6Ben Murdoch#if PLATFORM(ANDROID)
349a923424180b9d2cbe3a3951caed13039eef1edf6Ben Murdoch// TODO: This needs to be upstreamed.
350a923424180b9d2cbe3a3951caed13039eef1edf6Ben Murdoch            if (m_loader)
351a923424180b9d2cbe3a3951caed13039eef1edf6Ben Murdoch                m_loader->pauseLoad(true);
352f9115700a452dad0c9d5d9556045d0be30da33adAndrei Popescu
353f9115700a452dad0c9d5d9556045d0be30da33adAndrei Popescu            // ask the plugin for a delay value.
354f9115700a452dad0c9d5d9556045d0be30da33adAndrei Popescu            int delay = deliveryDelay();
355726a250195dce8f58044e80342e99ec8c0fa98dfGrace Kloba            m_delayDeliveryTimer.startOneShot(delay * 0.001);
356f9115700a452dad0c9d5d9556045d0be30da33adAndrei Popescu#else
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_delayDeliveryTimer.startOneShot(0);
358f9115700a452dad0c9d5d9556045d0be30da33adAndrei Popescu#endif
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            deliveryBytes = min(deliveryBytes, totalBytes - totalBytesDelivered);
3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int32 dataLength = deliveryBytes;
3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            char* data = m_deliveryData->data() + totalBytesDelivered;
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Write the data
3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            deliveryBytes = m_pluginFuncs->write(m_instance, &m_stream, m_offset, dataLength, (void*)data);
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (deliveryBytes < 0) {
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                LOG_PLUGIN_NET_ERROR();
3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                cancelAndDestroyStream(NPRES_NETWORK_ERR);
3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return;
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            deliveryBytes = min(deliveryBytes, dataLength);
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_offset += deliveryBytes;
3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            totalBytesDelivered += deliveryBytes;
3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_loader)
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_loader->setDefersLoading(false);
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (totalBytesDelivered > 0) {
3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (totalBytesDelivered < totalBytes) {
3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int remainingBytes = totalBytes - totalBytesDelivered;
3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            memmove(m_deliveryData->data(), m_deliveryData->data() + totalBytesDelivered, remainingBytes);
3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_deliveryData->resize(remainingBytes);
3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
386a923424180b9d2cbe3a3951caed13039eef1edf6Ben Murdoch#if PLATFORM(ANDROID)
387a923424180b9d2cbe3a3951caed13039eef1edf6Ben Murdoch//TODO: This needs to be upstreamed to WebKit.
388a923424180b9d2cbe3a3951caed13039eef1edf6Ben Murdoch            if (m_loader)
389a923424180b9d2cbe3a3951caed13039eef1edf6Ben Murdoch                m_loader->pauseLoad(false);
390a923424180b9d2cbe3a3951caed13039eef1edf6Ben Murdoch#endif
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_deliveryData->resize(0);
3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (m_reason != WebReasonNone)
3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                destroyStream();
3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid PluginStream::sendJavaScriptStream(const KURL& requestURL, const CString& resultString)
3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    didReceiveResponse(0, ResourceResponse(requestURL, "text/plain", resultString.length(), "", ""));
4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_streamState == StreamStopped)
4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!resultString.isNull()) {
4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        didReceiveData(0, resultString.data(), resultString.length());
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_streamState == StreamStopped)
4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_loader = 0;
4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    destroyStream(resultString.isNull() ? NPRES_NETWORK_ERR : NPRES_DONE);
4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid PluginStream::didReceiveResponse(NetscapePlugInStreamLoader* loader, const ResourceResponse& response)
4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(loader == m_loader);
4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_streamState == StreamBeforeStarted);
4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_resourceResponse = response;
4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    startStream();
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid PluginStream::didReceiveData(NetscapePlugInStreamLoader* loader, const char* data, int length)
4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(loader == m_loader);
4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(length > 0);
4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_streamState == StreamStarted);
4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the plug-in cancels the stream in deliverData it could be deleted,
4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // so protect it here.
4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<PluginStream> protect(this);
4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_transferMode != NP_ASFILEONLY) {
4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!m_deliveryData)
4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_deliveryData.set(new Vector<char>);
4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int oldSize = m_deliveryData->size();
4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_deliveryData->resize(oldSize + length);
4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        memcpy(m_deliveryData->data() + oldSize, data, length);
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
444726a250195dce8f58044e80342e99ec8c0fa98dfGrace Kloba#if PLATFORM(ANDROID)
445726a250195dce8f58044e80342e99ec8c0fa98dfGrace Kloba//TODO: This needs to be upstreamed to WebKit.
446726a250195dce8f58044e80342e99ec8c0fa98dfGrace Kloba        if (!m_delayDeliveryTimer.isActive())
447726a250195dce8f58044e80342e99ec8c0fa98dfGrace Kloba#endif
4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        deliverData();
4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_streamState != StreamStopped && isHandleValid(m_tempFileHandle)) {
4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int bytesWritten = writeToFile(m_tempFileHandle, data, length);
4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (bytesWritten != length)
4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cancelAndDestroyStream(NPRES_NETWORK_ERR);
4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid PluginStream::didFail(NetscapePlugInStreamLoader* loader, const ResourceError&)
4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(loader == m_loader);
4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    LOG_PLUGIN_NET_ERROR();
4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // destroyStream can result in our being deleted
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<PluginStream> protect(this);
4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    destroyStream(NPRES_NETWORK_ERR);
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_loader = 0;
4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid PluginStream::didFinishLoading(NetscapePlugInStreamLoader* loader)
4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(loader == m_loader);
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_streamState == StreamStarted);
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // destroyStream can result in our being deleted
4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<PluginStream> protect(this);
4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    destroyStream(NPRES_DONE);
4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_loader = 0;
4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool PluginStream::wantsAllStreams() const
4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_pluginFuncs->getvalue)
4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void* result = 0;
4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_pluginFuncs->getvalue(m_instance, NPPVpluginWantsAllNetworkStreams, &result) != NPERR_NO_ERROR)
4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result != 0;
4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
497f9115700a452dad0c9d5d9556045d0be30da33adAndrei Popescu#if PLATFORM(ANDROID)
498f9115700a452dad0c9d5d9556045d0be30da33adAndrei Popescuint PluginStream::deliveryDelay() const
499f9115700a452dad0c9d5d9556045d0be30da33adAndrei Popescu{
500f9115700a452dad0c9d5d9556045d0be30da33adAndrei Popescu    if (!m_pluginFuncs->getvalue)
501f9115700a452dad0c9d5d9556045d0be30da33adAndrei Popescu        return 0;
502f9115700a452dad0c9d5d9556045d0be30da33adAndrei Popescu
503f9115700a452dad0c9d5d9556045d0be30da33adAndrei Popescu    int delay = 0;
504f9115700a452dad0c9d5d9556045d0be30da33adAndrei Popescu    if (m_pluginFuncs->getvalue(m_instance, NPPDataDeliveryDelayMs, &delay) != NPERR_NO_ERROR)
505f9115700a452dad0c9d5d9556045d0be30da33adAndrei Popescu        return 0;
506f9115700a452dad0c9d5d9556045d0be30da33adAndrei Popescu
507f9115700a452dad0c9d5d9556045d0be30da33adAndrei Popescu    return delay;
508f9115700a452dad0c9d5d9556045d0be30da33adAndrei Popescu}
509f9115700a452dad0c9d5d9556045d0be30da33adAndrei Popescu#endif
510f9115700a452dad0c9d5d9556045d0be30da33adAndrei Popescu
5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
512