18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2008 Collabora Ltd. All rights reserved. 45f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * Copyright (C) 2009 Holger Hans Peter Freyther 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PluginPackage.h" 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "MIMETypeRegistry.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PluginDatabase.h" 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PluginDebug.h" 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Timer.h" 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "npruntime_impl.h" 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <string.h> 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/OwnArrayPtr.h> 38dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/text/CString.h> 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPluginPackage::~PluginPackage() 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This destructor gets called during refresh() if PluginDatabase's 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // PluginSet hash is already populated, as it removes items from 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the hash table. Calling the destructor on a loaded plug-in of 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // course would cause a crash, so we check to call unload before we 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // ASSERT. 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: There is probably a better way to fix this. 500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!m_loadCount) 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unloadWithoutShutdown(); 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unload(); 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!m_isLoaded); 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid PluginPackage::freeLibrarySoon() 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!m_freeLibraryTimer.isActive()); 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_module); 620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(!m_loadCount); 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_freeLibraryTimer.startOneShot(0); 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid PluginPackage::freeLibraryTimerFired(Timer<PluginPackage>*) 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_module); 700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(!m_loadCount); 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unloadModule(m_module); 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_module = 0; 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint PluginPackage::compare(const PluginPackage& compareTo) const 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Sort plug-ins that allow multiple instances first. 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool AallowsMultipleInstances = !quirks().contains(PluginQuirkDontAllowMultipleInstances); 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool BallowsMultipleInstances = !compareTo.quirks().contains(PluginQuirkDontAllowMultipleInstances); 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (AallowsMultipleInstances != BallowsMultipleInstances) 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return AallowsMultipleInstances ? -1 : 1; 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Sort plug-ins in a preferred path first. 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool AisInPreferredDirectory = PluginDatabase::isPreferredPluginDirectory(parentDirectory()); 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool BisInPreferredDirectory = PluginDatabase::isPreferredPluginDirectory(compareTo.parentDirectory()); 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (AisInPreferredDirectory != BisInPreferredDirectory) 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return AisInPreferredDirectory ? -1 : 1; 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int diff = strcmp(name().utf8().data(), compareTo.name().utf8().data()); 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (diff) 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return diff; 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian diff = compareFileVersion(compareTo.version()); 968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (diff) 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return diff; 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return strcmp(parentDirectory().utf8().data(), compareTo.parentDirectory().utf8().data()); 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPluginPackage::PluginPackage(const String& path, const time_t& lastModified) 1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch : m_isEnabled(true) 1040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch , m_isLoaded(false) 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_loadCount(0) 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_path(path) 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_moduleVersion(0) 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_module(0) 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_lastModified(lastModified) 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_freeLibraryTimer(this, &PluginPackage::freeLibraryTimerFired) 1115ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE) 1125ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen , m_infoIsFromCache(true) 1135ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#endif 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_fileName = pathGetFileName(m_path); 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_parentDirectory = m_path.left(m_path.length() - m_fileName.length() - 1); 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 119d0825bca7fe65beaee391d30da42e937db621564Steve Block#if !OS(SYMBIAN) 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid PluginPackage::unload() 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_isLoaded) 1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (--m_loadCount > 0) 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_NPP_Shutdown(); 1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unloadWithoutShutdown(); 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 132d0825bca7fe65beaee391d30da42e937db621564Steve Block#endif // !OS(SYMBIAN) 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid PluginPackage::unloadWithoutShutdown() 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_isLoaded) 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(!m_loadCount); 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_module); 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // <rdar://5530519>: Crash when closing tab with pdf file (Reader 7 only) 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If the plugin has subclassed its parent window, as with Reader 7, we may have 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // gotten here by way of the plugin's internal window proc forwarding a message to our 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // original window proc. If we free the plugin library from here, we will jump back 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // to code we just freed when we return, so delay calling FreeLibrary at least until 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the next message loop 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project freeLibrarySoon(); 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_isLoaded = false; 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid PluginPackage::setEnabled(bool enabled) 1540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_isEnabled = enabled; 1560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<PluginPackage> PluginPackage::createPackage(const String& path, const time_t& lastModified) 1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<PluginPackage> package = adoptRef(new PluginPackage(path, lastModified)); 1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!package->fetchInfo()) 1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 164635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return package.release(); 1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1685ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE) 1695ddde30071f639962dd557c453f2ad01f8f0fd00Kristian MonsenPassRefPtr<PluginPackage> PluginPackage::createPackageFromCache(const String& path, const time_t& lastModified, const String& name, const String& description, const String& mimeDescription) 1705ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 1715ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen RefPtr<PluginPackage> package = adoptRef(new PluginPackage(path, lastModified)); 1725ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen package->m_name = name; 1735ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen package->m_description = description; 1745ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen package->determineModuleVersionFromDescription(); 1755ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen package->setMIMEDescription(mimeDescription); 1765ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen package->m_infoIsFromCache = true; 1775ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen return package.release(); 1785ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 1795ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#endif 1805ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 181635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if defined(XP_UNIX) 182635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid PluginPackage::determineQuirks(const String& mimeType) 183635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 184635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (MIMETypeRegistry::isJavaAppletMIMEType(mimeType)) { 185635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Because a single process cannot create multiple VMs, and we cannot reliably unload a 186635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Java VM, we cannot unload the Java plugin, or we'll lose reference to our only VM 187635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_quirks.add(PluginQuirkDontUnloadPlugin); 188635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 189635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Setting the window region to an empty region causes bad scrolling repaint problems 190635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // with the Java plug-in. 191635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_quirks.add(PluginQuirkDontClipToZeroRectWhenScrolling); 192635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 193635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 194635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 195635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (mimeType == "application/x-shockwave-flash") { 196635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project static const PlatformModuleVersion flashTenVersion(0x0a000000); 197635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 198635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (compareFileVersion(flashTenVersion) >= 0) { 199635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Flash 10.0 b218 doesn't like having a NULL window handle 200635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_quirks.add(PluginQuirkDontSetNullWindowHandleOnDestroy); 201635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if PLATFORM(QT) 202635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_quirks.add(PluginQuirkRequiresGtkToolKit); 203635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif 204635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } else { 205635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Flash 9 and older requests windowless plugins if we return a mozilla user agent 206635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_quirks.add(PluginQuirkWantsMozillaUserAgent); 207635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 208635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 209a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#if PLATFORM(QT) 210a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // Flash will crash on repeated calls to SetWindow in windowed mode 211bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_quirks.add(PluginQuirkDontCallSetWindowMoreThanOnce); 212a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 213a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#if CPU(X86_64) 214a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // 64-bit Flash freezes if right-click is sent in windowless mode 215a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_quirks.add(PluginQuirkIgnoreRightClickInWindowlessMode); 216a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#endif 217bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#endif 218bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 219f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick m_quirks.add(PluginQuirkRequiresDefaultScreenDepth); 220635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_quirks.add(PluginQuirkThrottleInvalidate); 221635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_quirks.add(PluginQuirkThrottleWMUserPlusOneMessages); 222635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_quirks.add(PluginQuirkFlashURLNotifyBug); 223635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 2245abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 2255abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6) 2265abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick // Passing a 32-bit depth pixmap to NPAPI plugins is too inefficient. Instead, pass a X Pixmap 2275abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick // that has same depth as the screen depth since graphics operations are optimized 2285abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick // for this depth. 2295abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick m_quirks.add(PluginQuirkRequiresDefaultScreenDepth); 2305abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#endif 231635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 232635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif 233635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 234d0825bca7fe65beaee391d30da42e937db621564Steve Block#if !OS(WINDOWS) 235635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid PluginPackage::determineModuleVersionFromDescription() 236635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 237635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // It's a bit lame to detect the plugin version by parsing it 238635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // from the plugin description string, but it doesn't seem that 239635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // version information is available in any standardized way at 240635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // the module level, like in Windows 241635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 242635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_description.isEmpty()) 243635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 244635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 245635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_description.startsWith("Shockwave Flash") && m_description.length() >= 19) { 246635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // The flash version as a PlatformModuleVersion differs on Unix from Windows 247635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // since the revision can be larger than a 8 bits, so we allow it 16 here and 248635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // push the major/minor up 8 bits. Thus on Unix, Flash's version may be 249635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // 0x0a000000 instead of 0x000a0000. 250635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 251635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Vector<String> versionParts; 252635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_description.substring(16).split(' ', /*allowEmptyEntries =*/ false, versionParts); 253635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (versionParts.isEmpty()) 254635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 255635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 256635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (versionParts.size() >= 1) { 257635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Vector<String> majorMinorParts; 258635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project versionParts[0].split('.', majorMinorParts); 259635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (majorMinorParts.size() >= 1) { 260635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project bool converted = false; 261635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project unsigned major = majorMinorParts[0].toUInt(&converted); 262635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (converted) 263635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_moduleVersion = (major & 0xff) << 24; 264635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 265635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (majorMinorParts.size() == 2) { 266635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project bool converted = false; 267635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project unsigned minor = majorMinorParts[1].toUInt(&converted); 268635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (converted) 269635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_moduleVersion |= (minor & 0xff) << 16; 270635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 271635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 272635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 273635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (versionParts.size() >= 2) { 274635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project String revision = versionParts[1]; 275635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (revision.length() > 1 && (revision[0] == 'r' || revision[0] == 'b')) { 276635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project revision.remove(0, 1); 277635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_moduleVersion |= revision.toInt() & 0xffff; 278635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 279635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 280635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 281635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 282635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif 283635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 2845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if ENABLE(NETSCAPE_PLUGIN_API) 2855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid PluginPackage::initializeBrowserFuncs() 2865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 2875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian memset(&m_browserFuncs, 0, sizeof(m_browserFuncs)); 2880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_browserFuncs.size = sizeof(m_browserFuncs); 289692e5dbf12901edacf14812a6fae25462920af42Steve Block m_browserFuncs.version = NPVersion(); 2905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 2915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.geturl = NPN_GetURL; 2925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.posturl = NPN_PostURL; 2935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.requestread = NPN_RequestRead; 2945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.newstream = NPN_NewStream; 2955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.write = NPN_Write; 2965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.destroystream = NPN_DestroyStream; 2975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.status = NPN_Status; 2985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.uagent = NPN_UserAgent; 2995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.memalloc = NPN_MemAlloc; 3005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.memfree = NPN_MemFree; 3015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.memflush = NPN_MemFlush; 3025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.reloadplugins = NPN_ReloadPlugins; 3035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.geturlnotify = NPN_GetURLNotify; 3045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.posturlnotify = NPN_PostURLNotify; 3055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.getvalue = NPN_GetValue; 3065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.setvalue = NPN_SetValue; 3075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.invalidaterect = NPN_InvalidateRect; 3085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.invalidateregion = NPN_InvalidateRegion; 3095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.forceredraw = NPN_ForceRedraw; 3105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.getJavaEnv = NPN_GetJavaEnv; 3115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.getJavaPeer = NPN_GetJavaPeer; 3125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.pushpopupsenabledstate = NPN_PushPopupsEnabledState; 3135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.poppopupsenabledstate = NPN_PopPopupsEnabledState; 3145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.pluginthreadasynccall = NPN_PluginThreadAsyncCall; 3155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.releasevariantvalue = _NPN_ReleaseVariantValue; 3175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.getstringidentifier = _NPN_GetStringIdentifier; 3185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.getstringidentifiers = _NPN_GetStringIdentifiers; 3195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.getintidentifier = _NPN_GetIntIdentifier; 3205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.identifierisstring = _NPN_IdentifierIsString; 3215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.utf8fromidentifier = _NPN_UTF8FromIdentifier; 3225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.intfromidentifier = _NPN_IntFromIdentifier; 3235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.createobject = _NPN_CreateObject; 3245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.retainobject = _NPN_RetainObject; 3255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.releaseobject = _NPN_ReleaseObject; 3265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.invoke = _NPN_Invoke; 3275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.invokeDefault = _NPN_InvokeDefault; 3285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.evaluate = _NPN_Evaluate; 3295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.getproperty = _NPN_GetProperty; 3305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.setproperty = _NPN_SetProperty; 3315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.removeproperty = _NPN_RemoveProperty; 3325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.hasproperty = _NPN_HasProperty; 3335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.hasmethod = _NPN_HasMethod; 3345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.setexception = _NPN_SetException; 3355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.enumerate = _NPN_Enumerate; 3365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_browserFuncs.construct = _NPN_Construct; 337a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_browserFuncs.getvalueforurl = NPN_GetValueForURL; 338a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_browserFuncs.setvalueforurl = NPN_SetValueForURL; 339a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_browserFuncs.getauthenticationinfo = NPN_GetAuthenticationInfo; 3405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 3415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif 3425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if ENABLE(PLUGIN_PACKAGE_SIMPLE_HASH) 3445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianunsigned PluginPackage::hash() const 3455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 3465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned hashCodes[] = { 3475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_path.impl()->hash(), 3485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_lastModified 3495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian }; 3505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3512bde8e466a4451c7319e3a072d118917957d6554Steve Block return StringHasher::hashMemory<sizeof(hashCodes)>(hashCodes); 3525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 3535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool PluginPackage::equal(const PluginPackage& a, const PluginPackage& b) 3555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 3565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return a.m_description == b.m_description; 3575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 358cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#endif 3595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianint PluginPackage::compareFileVersion(const PlatformModuleVersion& compareVersion) const 3615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 3625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // return -1, 0, or 1 if plug-in version is less than, equal to, or greater than 3635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // the passed version 364cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 365d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINDOWS) 366cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (m_moduleVersion.mostSig != compareVersion.mostSig) 367cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return m_moduleVersion.mostSig > compareVersion.mostSig ? 1 : -1; 368cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (m_moduleVersion.leastSig != compareVersion.leastSig) 369cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return m_moduleVersion.leastSig > compareVersion.leastSig ? 1 : -1; 370cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#else 3715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (m_moduleVersion != compareVersion) 3725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return m_moduleVersion > compareVersion ? 1 : -1; 373cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#endif 374cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 3755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return 0; 3765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 3775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3785ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE) 3795ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenbool PluginPackage::ensurePluginLoaded() 3805ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 3815ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (!m_infoIsFromCache) 3825ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen return m_isLoaded; 3835ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 3845ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen m_quirks = PluginQuirkSet(); 3855ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen m_name = String(); 3865ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen m_description = String(); 3875ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen m_fullMIMEDescription = String(); 3885ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen m_moduleVersion = 0; 3895ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 3905ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen return fetchInfo(); 3915ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 3925ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#endif 3935ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 395