18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006, 2007 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 "PluginPackage.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "MIMETypeRegistry.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "npruntime_impl.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PluginDatabase.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PluginDebug.h"
34dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/text/CString.h>
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool PluginPackage::fetchInfo()
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!load())
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NPP_GetValueProcPtr gv = (NPP_GetValueProcPtr)m_module->resolve("NP_GetValue");
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    typedef char *(*NPP_GetMIMEDescriptionProcPtr)();
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NPP_GetMIMEDescriptionProcPtr gm =
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        (NPP_GetMIMEDescriptionProcPtr)m_module->resolve("NP_GetMIMEDescription");
470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!gm || !gv)
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char *buf = 0;
510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    NPError err = gv(0, NPPVpluginNameString, (void*) &buf);
520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (err != NPERR_NO_ERROR)
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_name = buf;
560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    err = gv(0, NPPVpluginDescriptionString, (void*) &buf);
570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (err != NPERR_NO_ERROR)
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_description = buf;
61635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    determineModuleVersionFromDescription();
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
635ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    String mimeDescription = gm();
645ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    setMIMEDescription(mimeDescription);
655ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_infoIsFromCache = false;
665ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
675ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return true;
685ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
695ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
705ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid PluginPackage::setMIMEDescription(const String& mimeDescription)
715ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
7228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    m_fullMIMEDescription = mimeDescription.lower();
735ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<String> types;
7528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    mimeDescription.lower().split(UChar(';'), false, types);
76231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    for (unsigned i = 0; i < types.size(); ++i) {
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Vector<String> mime;
780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        types[i].split(UChar(':'), true, mime);
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (mime.size() > 0) {
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Vector<String> exts;
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (mime.size() > 1)
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                mime[1].split(UChar(','), false, exts);
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            determineQuirks(mime[0]);
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_mimeToExtensions.add(mime[0], exts);
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (mime.size() > 2)
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_mimeToDescriptions.add(mime[0], mime[2]);
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
91231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic NPError staticPluginQuirkRequiresGtkToolKit_NPN_GetValue(NPP instance, NPNVariable variable, void* value)
92231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
93231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (variable == NPNVToolkit) {
9421939df44de1705786c545cd1bf519d47250322dBen Murdoch        *static_cast<uint32_t*>(value) = 2;
95231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return NPERR_NO_ERROR;
96231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
97231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
98231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return NPN_GetValue(instance, variable, value);
99231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
100231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
101e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic void initializeGtk(QLibrary* module = 0)
102e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{
103e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    // Ensures missing Gtk initialization in some versions of Adobe's flash player
104e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    // plugin do not cause crashes. See BR# 40567, 44324, and 44405 for details.
105e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (module) {
106e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        typedef void *(*gtk_init_ptr)(int*, char***);
107e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        gtk_init_ptr gtkInit = (gtk_init_ptr)module->resolve("gtk_init");
108e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        if (gtkInit) {
109e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            // Prevent gtk_init() from replacing the X error handlers, since the Gtk
110e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            // handlers abort when they receive an X error, thus killing the viewer.
111e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#ifdef Q_WS_X11
112e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            int (*old_error_handler)(Display*, XErrorEvent*) = XSetErrorHandler(0);
113e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            int (*old_io_error_handler)(Display*) = XSetIOErrorHandler(0);
114e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#endif
115e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            gtkInit(0, 0);
116e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#ifdef Q_WS_X11
117e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            XSetErrorHandler(old_error_handler);
118e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            XSetIOErrorHandler(old_io_error_handler);
119e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#endif
120e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            return;
121e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        }
122e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    }
123e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
1242bde8e466a4451c7319e3a072d118917957d6554Steve Block    QLibrary library(QLatin1String("libgtk-x11-2.0.so.0"));
125e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (library.load()) {
126e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        typedef void *(*gtk_init_check_ptr)(int*, char***);
127e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        gtk_init_check_ptr gtkInitCheck = (gtk_init_check_ptr)library.resolve("gtk_init_check");
128e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        // NOTE: We're using gtk_init_check() since gtk_init() calls exit() on failure.
129e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        if (gtkInitCheck)
130e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            (void) gtkInitCheck(0, 0);
131e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    }
132e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block}
133e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool PluginPackage::load()
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_isLoaded) {
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_loadCount++;
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_module = new QLibrary((QString)m_path);
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_module->setLoadHints(QLibrary::ResolveAllSymbolsHint);
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_module->load()) {
1440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        LOG(Plugins, "%s not loaded (%s)", m_path.utf8().data(),
145635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                m_module->errorString().toLatin1().constData());
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_isLoaded = true;
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NP_InitializeFuncPtr NP_Initialize;
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NPError npErr;
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NP_Initialize = (NP_InitializeFuncPtr)m_module->resolve("NP_Initialize");
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_NPP_Shutdown = (NPP_ShutdownProcPtr)m_module->resolve("NP_Shutdown");
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!NP_Initialize || !m_NPP_Shutdown)
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        goto abort;
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    memset(&m_pluginFuncs, 0, sizeof(m_pluginFuncs));
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_pluginFuncs.size = sizeof(m_pluginFuncs);
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    initializeBrowserFuncs();
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
165231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (m_path.contains("npwrapper.")) {
166231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // nspluginwrapper relies on the toolkit value to know if glib is available
167231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // It does so in NP_Initialize with a null instance, therefore it is done this way:
168231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        m_browserFuncs.getvalue = staticPluginQuirkRequiresGtkToolKit_NPN_GetValue;
169e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        // Workaround Adobe's failure to properly initialize Gtk in some versions
170e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        // of their flash player plugin.
171e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        initializeGtk();
172e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    } else if (m_path.contains("flashplayer")) {
173e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        // Workaround Adobe's failure to properly initialize Gtk in some versions
174e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        // of their flash player plugin.
175e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        initializeGtk(m_module);
17606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    }
17706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if defined(XP_UNIX)
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    npErr = NP_Initialize(&m_browserFuncs, &m_pluginFuncs);
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    npErr = NP_Initialize(&m_browserFuncs);
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (npErr != NPERR_NO_ERROR)
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        goto abort;
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_loadCount++;
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectabort:
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unloadWithoutShutdown();
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19421939df44de1705786c545cd1bf519d47250322dBen Murdochuint16_t PluginPackage::NPVersion() const
195692e5dbf12901edacf14812a6fae25462920af42Steve Block{
196692e5dbf12901edacf14812a6fae25462920af42Steve Block    return NP_VERSION_MINOR;
197692e5dbf12901edacf14812a6fae25462920af42Steve Block}
1985ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
200