diff -r 79859ed3eea9 -r 919f36ff910f webengine/osswebengine/WebKit/s60/plugins/PluginSkin.cpp --- a/webengine/osswebengine/WebKit/s60/plugins/PluginSkin.cpp Tue Aug 31 16:17:46 2010 +0300 +++ b/webengine/osswebengine/WebKit/s60/plugins/PluginSkin.cpp Wed Sep 01 12:28:30 2010 +0100 @@ -16,11 +16,11 @@ */ //INCLUDES -#include +#include #include "../../bidi.h" #include "PlatformString.h" #include -#include +#include #include "PluginSkin.h" #include "PluginWin.h" #include "PluginHandler.h" @@ -33,9 +33,9 @@ #include "BrCtl.h" #include "WebCoreGraphicsContext.h" #include "StaticObjectsContainer.h" -#include "BrCtlDefs.h" +#include #include "SettingsContainer.h" -#include +#include #include #include #include "Frame.h" @@ -43,16 +43,17 @@ #include "DocumentLoader.h" #include "ResourceRequest.h" #include "Widget.h" -#include "PlatformScrollbar.h" +#include "PlatformScrollBar.h" +#include "Page.h" +#include "FocusController.h" #include -#include -#include +#include +#include #include -#include -#include "CString.h" #include "WidgetExtension.h" -#include +#include + // CONSTANTS using namespace WebCore; @@ -84,8 +85,11 @@ _LIT(KSecMgrScriptSession,"SecMgrScriptSession"); _LIT(KAllowNetworkAccess,"AllowNetworkAccess"); - +#if defined(__PLATFORM_VERSION_32__) +#define KArraySize 1 +#else #define KArraySize 3 +#endif const TInt32 KWidgetApplicationId = 0x10282822; const TInt32 KBrowserApplicationId = 0x10008D39; @@ -100,10 +104,13 @@ // return an absolute url that results from refUrl being resolved against // baseUrl. // ---------------------------------------------------------------------------- -HBufC8* makeAbsoluteUrlL(const TDesC8& baseUrl, const TDesC8& refUrl) +HBufC8* makeAbsoluteUrlL(const TDesC8* baseUrl,const TDesC8* docUrl, const TDesC8& refUrl) { TUriParser8 baseUrlparser; - baseUrlparser.Parse(baseUrl); + if(baseUrl == NULL) + baseUrlparser.Parse(*docUrl); + else + baseUrlparser.Parse(*baseUrl); TUriParser8 refUrlparser; refUrlparser.Parse(refUrl); @@ -155,12 +162,13 @@ m_canInteract( EFalse ), m_rect(TRect(0,0,0,0)), m_ref(1), + m_oldRect(TRect(0,0,0,0)), + m_oldViewport(TRect(0,0,0,0)), + m_NPObject(0), m_handle(-1), m_instance(0), m_pluginfuncs(0), - m_resized(false), - m_oldRect(TRect(0,0,0,0)), - m_oldViewport(TRect(0,0,0,0)) + m_resized(false) { } @@ -194,8 +202,11 @@ #endif TInt uid = wdgtExt->GetWidgetId(); + CWidgetPropertyValue* AccessValue = widgetregistry.GetWidgetPropertyValueL(TUid::Uid(uid), EAllowNetworkAccess ); - TInt networkAccess = *AccessValue; + TInt networkAccess = AccessValue && *AccessValue; + delete AccessValue; + const TDesC& allowNetworkAccess = KAllowNetworkAccess(); NPN_GenericElement NetworkAccess(allowNetworkAccess,networkAccess); iGenericElementArray->AppendL(NetworkAccess); @@ -397,12 +408,37 @@ delete m_attributeNames; m_attributeNames = 0; delete m_attributeValues; m_attributeValues = 0; delete m_url; m_url = 0; - delete iJavascriptTimer; iJavascriptTimer = 0; + if(iJavascriptTimer) + { + iJavascriptTimer->Cancel(); + delete iJavascriptTimer; + iJavascriptTimer = 0; + } m_pluginfuncs = 0; m_pluginSupported = EFalse; m_pluginClosed = true; + } +// ---------------------------------------------------------------------------- +// PluginSkin::HandleLosingForeground() +// PluginSkin function to handle Losing foreground event +// ---------------------------------------------------------------------------- +void PluginSkin::HandleLosingForeground() +{ + if(m_pluginwin) + m_pluginwin->HandleLosingForeground(); +} + +// ---------------------------------------------------------------------------- +// PluginSkin::HandleGainingForeground() +// PluginSkin function to handle Gaining foreground event +// ---------------------------------------------------------------------------- +void PluginSkin::HandleGainingForeground() +{ + if(m_pluginwin) + m_pluginwin->HandleGainingForeground(); +} // ---------------------------------------------------------------------------- // PluginSkin::pluginFocusChanged() @@ -462,7 +498,9 @@ CFbsBitmap* bitmap = m_cannedimg.m_img; TSize bmpSize( bitmap->SizeInPixels() ); - if ( !m_pluginwin && newRect.Height() >= bmpSize.iHeight && newRect.Width() >= bmpSize.iWidth ) + CWidgetExtension* wdgtExt = control(this->frame()) ? control(this->frame())->getWidgetExt(): NULL; + + if ( !wdgtExt && !m_pluginwin && newRect.Height() >= bmpSize.iHeight && newRect.Width() >= bmpSize.iWidth ) { // The inner rect is big enough, draw the placeholder image TPoint bitmapStartPoint( newRect.Center() ); @@ -472,9 +510,35 @@ } if(m_pluginwin) { - positionChanged(); - // Force the control to be redrawn. - m_pluginwin->refreshPlugin(*gc,newRect); + //if bitmap is shared from plugins then draw the shared bitmap + if(m_pluginwin->IsPluginBitMapSet()) + { + CFbsBitmap* bitmap = m_pluginwin->PluginBitmap(); + if(bitmap) + { + TRect clippingRect = context.clippingRect(); + TRect oldcontextrect = context.clippingRect(); + + if(newRect != clippingRect) + { + context.setClippingRect(newRect); + } + gc->DrawBitmap(newRect, bitmap); + context.setClippingRect(oldcontextrect); + } + else + { + //if not a valid bitmap, then hide that plugin + m_pluginwin->MakeVisible(EFalse); + } + positionChanged(); + } + else + { + positionChanged(); + // Force the control to be redrawn, for window less plugins + m_pluginwin->refreshPlugin(*gc,newRect); + } } } @@ -502,10 +566,37 @@ // ---------------------------------------------------------------------------- void PluginSkin::makeVisible( TBool visible ) { + // if visible is true for a plugin, make sure that the plugin is actually visible in the window before proceeding + TBool visibility = EFalse; + if (visible) { + TRect fullRect(getPluginWinRect()); + TRect clipRect(getClipRect()); + TRect frameRect(m_frame->frameView()->rect()); + TRect viewRect = control(m_frame)->webView()->Rect(); + TBool isPageViewMode = control(m_frame)->webView()->inPageViewMode(); + WebFrame* pf = m_frame; + TPoint p = frameRect.iTl; + + if (m_frame->parentFrame()) { + pf = m_frame->parentFrame(); + p = pf->frameView()->frameCoordsInViewCoords(frameRect.iTl); + } + TSize sz = pf->frameView()->toViewCoords(frameRect.Size()); + TRect frameRectInViewCoord = TRect(p, sz); + TBool isPluginVisible = frameRectInViewCoord.Intersects(fullRect); + TBool isFrameVisible = m_frame->frameView()->isVisible() && + frameRectInViewCoord.Intersects(viewRect); + + visibility = isFrameVisible && !isPageViewMode && isPluginVisible; + + } if ( m_pluginwin ) { + if (visible && !visibility) + visible = EFalse; + m_visible = visible; - if(m_active) + if(m_active && !visible) deActivate(); m_pluginwin->makeVisible(visible); } @@ -565,6 +656,7 @@ { m_active = ETrue; m_frame->frameView()->topView()->setFocusedElementType(TBrCtlDefs::EElementActivatedObjectBox); + control(m_frame)->webView()->page()->focusController()->setFocusedNode(getElement(), control(m_frame)->webView()->page()->focusController()->focusedOrMainFrame()); pluginHandler->setActivePlugin(this); pluginHandler->setPluginToActivate(NULL); } @@ -650,11 +742,9 @@ NPError error( NPERR_NO_ERROR ); m_instance = (NPP) User::AllocL(sizeof(NPP_t)); - m_instance->ndata = pluginWin(); - m_instance->pdata = NULL; - if (m_instance) { - + m_instance->ndata = pluginWin(); + m_instance->pdata = NULL; PluginHandler* pluginhandler = WebCore::StaticObjectsContainer::instance()->pluginHandler(); if ( pluginhandler ) { pluginhandler->loadPluginL( m_handle, &m_pluginfuncs ); @@ -671,9 +761,9 @@ } if (m_pluginwin) { m_pluginwin->ConstructL(*(control(m_frame)->webView())); + } } } - } switch ( error ) { case NPERR_OUT_OF_MEMORY_ERROR: { @@ -684,13 +774,11 @@ User::Leave( KErrNotSupported ); break; } - } + } if (m_pluginwin) - m_pluginwin->SetExtent( TPoint(0,0), TSize(0,0) ); - + m_pluginwin->SetExtent( TPoint(0,0), TSize(0,0) ); } - } // ----------------------------------------------------------------------------- @@ -800,11 +888,11 @@ int PluginSkin::getRequestL(const TDesC8& url, bool notify, void* notifydata,const TDesC* aWindowType) { TPluginLoadMode loadmode = GetLoadMode(aWindowType); - + if (url.Ptr() == NULL ) { return KErrArgument; } - + _LIT8(KJs, "javascript:"); if ((url.Length() > KJs().Length() ) &&(url.Left(KJs().Length()).FindF(KJs) == 0)) { HBufC* pBuffer = HBufC::NewL(url.Length()); @@ -821,24 +909,18 @@ } // make sure it is an absolute URL - HBufC8* absoluteUrl = makeAbsoluteUrlL(*m_url, url); + HBufC8* docUrl = HBufC8::NewLC(core(m_frame)->document()->baseURI().length()); + docUrl->Des().Copy(core(m_frame)->document()->baseURI()); + HBufC8* absoluteUrl = makeAbsoluteUrlL(m_url, docUrl, url); CleanupStack::PushL(absoluteUrl); - if (loadmode == ELoadModePlugin ) { - + PluginHandler* pluginHandler = StaticObjectsContainer::instance()->pluginHandler(); + if( (loadmode == ELoadModePlugin ) || (loadmode == ELoadModeTop && (pluginHandler->pluginMimeByExtention(url) != NULL)) ){ if (m_instance && m_pluginfuncs) { - NetscapePlugInStreamLoaderClient* pluginloader = NetscapePlugInStreamLoaderClient::NewL(url, this, core(m_frame), notifydata); + NetscapePlugInStreamLoaderClient* pluginloader = NetscapePlugInStreamLoaderClient::NewL(url, this, core(m_frame), notifydata, notify); if (pluginloader) { - pluginloader->start(); - - if ( notify ) { - HBufC* url16 = HBufC::NewLC( url.Length() ); - url16->Des().Copy( url ); - m_pluginfuncs->urlnotify( m_instance, *url16, NPRES_DONE, notifydata ); - CleanupStack::PopAndDestroy(url16); - } - + pluginloader->start(); } } } @@ -849,7 +931,7 @@ CleanupStack::PopAndDestroy(windowType); } - CleanupStack::PopAndDestroy(absoluteUrl); + CleanupStack::PopAndDestroy(2); return KErrNone; } @@ -857,7 +939,9 @@ int PluginSkin::postRequestL(const TDesC8& url,const TDesC& buffer, bool fromfile, bool notify, void* notifydata,const TDesC* aWindowType) { // make sure it is an absolute URL - HBufC8* absoluteUrl = makeAbsoluteUrlL(*m_url, url); + HBufC8* docUrl = HBufC8::NewLC(core(m_frame)->document()->baseURI().length()); + docUrl->Des().Copy(core(m_frame)->document()->baseURI()); + HBufC8* absoluteUrl = makeAbsoluteUrlL(m_url, docUrl, url); CleanupStack::PushL(absoluteUrl); TPluginLoadMode loadmode = GetLoadMode(aWindowType); @@ -907,11 +991,9 @@ int start_content = buffer.Find(KRequestEOH()); start_content = (start_content != KErrNotFound) ? start_content+ KRequestEOH().Length() : 0; - HBufC* body = HBufC::NewLC(buffer.Mid(start_content).Length()+1); - body->Des().Copy(buffer.Mid(start_content)); - TextEncoding *ecoder = new TextEncoding(core(mainFrame(m_frame))->loader()->encoding()); - CString decoded_body = ecoder->encode(body->Des().PtrZ(),body->Length()); - FormData* fd = new (ELeave) FormData(decoded_body.data(),decoded_body.length()); + HBufC8* body = HBufC8::NewLC(buffer.Mid(start_content).Length()); + body->Des().Copy(buffer.Mid(start_content)); + FormData* fd = new (ELeave) FormData(body->Ptr(),body->Length()); request.setHTTPBody(fd); CleanupStack::PopAndDestroy(); // body } @@ -920,17 +1002,9 @@ if (loadmode == ELoadModePlugin ) { if (m_instance && m_pluginfuncs) { - NetscapePlugInStreamLoaderClient* pluginloader = NetscapePlugInStreamLoaderClient::NewL(request, this, core(m_frame), notifydata); + NetscapePlugInStreamLoaderClient* pluginloader = NetscapePlugInStreamLoaderClient::NewL(request, this, core(m_frame), notifydata, notify); if (pluginloader) { - pluginloader->start(); - - if ( notify ) { - HBufC* url16 = HBufC::NewLC( url.Length() ); - url16->Des().Copy( url ); - m_pluginfuncs->urlnotify( m_instance, *url16, NPRES_DONE, notifydata ); - CleanupStack::PopAndDestroy(url16); - } - + pluginloader->start(); } } } @@ -942,7 +1016,7 @@ } - CleanupStack::PopAndDestroy(absoluteUrl); + CleanupStack::PopAndDestroy(2); return KErrNone; } @@ -993,15 +1067,32 @@ void* PluginSkin::pluginScriptableObject() { - // - if (m_pluginfuncs && m_pluginfuncs->getvalue) { - void *value = 0; - NPError npErr = m_pluginfuncs->getvalue( m_instance, NPPVpluginScriptableNPObject, (void *)&value); - if (npErr == NPERR_NO_ERROR) { - return value; + if (!m_NPObject && m_pluginfuncs && m_pluginfuncs->getvalue) { + NPError npErr = m_pluginfuncs->getvalue( m_instance, NPPVpluginScriptableNPObject, &m_NPObject); + if (npErr != NPERR_NO_ERROR) { + m_NPObject = 0; } } - return (void *)0; + return m_NPObject; +} + +TBool validateDataScheme(const TPtrC8& url) +{ + // Check if body part of "data:" exists = data:[][;base64],. RFC-2397 : http://www.faqs.org/rfcs/rfc2397 + TPtrC8 urlPtr8 = url; + + if(url.Length() <= 0 ) + return EFalse; + + TInt commaPos( urlPtr8.Locate( ',' ) ); + if (commaPos == KErrNotFound ) + return EFalse; + + TPtrC8 datapart (urlPtr8.Mid(commaPos + 1)); + if (datapart.Length() <= 0) + return EFalse; + + return ETrue; } TBool PluginSkin::isBrowserScheme(const TPtrC8& url) @@ -1011,9 +1102,13 @@ if( parser.Parse( url ) == KErrNone ) { TPtrC8 scheme = parser.Extract( EUriScheme ); if (scheme.CompareF( _L8("http" ) ) == 0 || scheme.CompareF( _L8("https" ) ) == 0 - || scheme.Length() == 1 || scheme.CompareF( _L8("file") ) == 0 || scheme.CompareF( _L8("data") ) == 0) { + || scheme.Length() == 1 || scheme.CompareF( _L8("file") ) == 0) { supported = ETrue; } + else if(scheme.CompareF( _L8("data") ) == 0) { + // if the scheme is "data", check its validity according to RFC-2397 : http://www.faqs.org/rfcs/rfc2397 + supported = validateDataScheme(url); + } } return supported; } @@ -1050,8 +1145,11 @@ frameRectInViewCoord.Intersects(viewRect); if (m_pluginwin) { - m_pluginwin->makeVisible( isFrameVisible && !isPageViewMode && isPluginVisible); - if (!m_pluginwin->isPluginInFullscreen()) { + TBool visibility = isFrameVisible && !isPageViewMode && isPluginVisible; + if(fullRect.Size() != TSize(0,0)) { + m_pluginwin->makeVisible(visibility); + } + if (!m_pluginwin->isPluginInFullscreen() && visibility) { clipRect.Intersection(fullRect); m_pluginwin->SetRect(clipRect); } @@ -1187,3 +1285,151 @@ return EWindowTypeUnknown; } + +void PluginSkin::reCreatePlugin() +{ + TBuf16<4> apId; + apId.Format( _L("%d"), m_frame->frameView()->topView()->accessPointId() ); + + if (m_pluginwin ) { + m_pluginwin->notifyAPChange((void*)&apId); + } + + if (m_streams.size() > 0) { + + //destroy the plugin + + Vector streams; + for (HashSet::iterator it = m_streams.begin(); it != m_streams.end(); ++it) { + streams.append(*it); + } + for (int i=0; iclose(); + } + m_streams.clear(); + + if (m_instance && m_pluginfuncs && m_pluginfuncs->destroy) { + m_pluginfuncs->destroy(m_instance, NULL); + } + User::Free(m_instance); m_instance = 0; + delete m_pluginwin; m_pluginwin = 0; + delete iJavascriptTimer; iJavascriptTimer = 0; + + RFs& rfs = StaticObjectsContainer::instance()->fsSession(); + for(TInt i=0; i < m_tempFilesArray.Count(); i++) { + rfs.Delete(m_tempFilesArray[i]->Des()); + } + m_tempFilesArray.ResetAndDestroy(); + + //create/load the destroyed plugin again + + NetscapePlugInStreamLoaderClient* pluginloader = NetscapePlugInStreamLoaderClient::NewL(m_url->Des(), this, core(m_frame)); + if (pluginloader) { + pluginloader->start(); + } + } +} + +// ----------------------------------------------------------------------------- +// PluginWin::NotifyPluginsForScrollOrPinch +// When ever there is Scroll or Pinch zoom is in progress, the webframe will +// Notify all the plugins "ETrue" for Start and "EFalse" for end +// ----------------------------------------------------------------------------- +void PluginSkin::NotifyPluginsForScrollOrPinch(bool status) + { + if(m_pluginwin) + { + //while pinch zoom, deactivate and activate the plugins. + WebView* view = control(frame())->webView(); + if(!view) + return; + + //check weather the collect bitmap is supported or not + TBool bitmapSupported = m_pluginwin->IsCollectBitmapSupported(); + + //if bitmap is not supported, check for pinch zoom and deactivate the plugins. + if((view->isPinchZoom())) + { + //if bitmap sharing is not supported then deactivate or activate the plugins + if(!bitmapSupported) + { + if(status) + { + if(m_pluginwin->IsVisible()) + { + m_pluginwin->MakeVisible(false); + m_pluginwin->setPluginFocusL(false); + } + } + else + { + activate(); + } + } + + } + + if(bitmapSupported) + { + m_pluginwin->GetBitmapFromPlugin(status); + if(!status) + { + m_pluginwin->ClearPluginBitmap(); + activateVisiblePlugins(); + } + } + } +} + +// ----------------------------------------------------------------------------- +// PluginWin::IsCollectBitmapSupported +// Check Plugin are supported for Bitmap Sharing +// ----------------------------------------------------------------------------- +TBool PluginSkin::IsCollectBitmapSupported() + { + if(m_pluginwin) + { + return m_pluginwin->IsCollectBitmapSupported(); + } + return false; + } + +void PluginSkin::activateVisiblePlugins() + { + TRect fullRect(getPluginWinRect()); + TRect clipRect(getClipRect()); + TRect frameRect(m_frame->frameView()->rect()); + TRect viewRect = control(m_frame)->webView()->Rect(); + TBool isPageViewMode = control(m_frame)->webView()->inPageViewMode(); + WebFrame* pf = m_frame; + TPoint p = frameRect.iTl; + + if (m_frame->parentFrame()) + { + pf = m_frame->parentFrame(); + p = pf->frameView()->frameCoordsInViewCoords(frameRect.iTl); + } + + TSize sz = pf->frameView()->toViewCoords(frameRect.Size()); + TRect frameRectInViewCoord = TRect(p, sz); + TBool isPluginVisible = frameRectInViewCoord.Intersects(fullRect); + TBool isFrameVisible = m_frame->frameView()->isVisible() && + frameRectInViewCoord.Intersects(viewRect); + + TBool visibility = isFrameVisible && !isPageViewMode && isPluginVisible; + if(fullRect.Size() != TSize(0,0)) + { + if (visibility) + { + m_pluginwin->MakeVisible(true); //forcefully make the plugin visible, this is for pinch exit + m_pluginwin->makeVisible(true); + } + else + { + //this is required for flash plugin to clear the EGL surface + //when the plugin window is outside the view port + m_pluginwin->makeVisible(false); + } + } + + }