# HG changeset patch # User Dremov Kirill (Nokia-D-MSW/Tampere) # Date 1251348299 -10800 # Node ID a359256acfc607ca298d54800697abd39fce6086 # Parent 10e98eab6f850e8f1deab0039ff2a1a2d0803bb7 Revision: 200929 Kit: 200935 diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/browserdialogsprovider/Src/BrowserSelectElementDlg.cpp --- a/browserutilities/browserdialogsprovider/Src/BrowserSelectElementDlg.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/browserdialogsprovider/Src/BrowserSelectElementDlg.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -160,6 +160,7 @@ iHistoryList->SetCurrentItemIndex( 0 ); } SetTitleL( aTitle ); + EnableFind(); } } diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/connectionmanager/Src/InternetConnectionManager.cpp --- a/browserutilities/connectionmanager/Src/InternetConnectionManager.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/connectionmanager/Src/InternetConnectionManager.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -413,8 +413,8 @@ CLOG_WRITE_1( "ConnMan connAllowed: %d", connAllowed ); if( !connAllowed && ( KErrNone == err ) ) { - CLOG_WRITE( "ConnMan SetBearerSet: EApBearerTypeWLAN" ); - overrides->SetBearerSet( EApBearerTypeWLAN ); + CLOG_WRITE( "ConnMan SetBearerSet: ECommDbBearerWLAN" ); + overrides->SetBearerSet( ECommDbBearerWLAN ); } @@ -1391,10 +1391,11 @@ iVpnItem = CVpnApItem::NewLC(); CleanupStack::Pop(); - iVpnEngine->VpnDataL( aAPId, *iVpnItem ); + TRAP_IGNORE(iVpnEngine->VpnDataL( aAPId, *iVpnItem )); // get real WAP id - iVpnItem->ReadUint( EApVpnRealWapID, aAPId ); + if( NULL != iVpnItem ) + iVpnItem->ReadUint( EApVpnRealWapID, aAPId ); } TRAP_IGNORE(iApDataHandler->AccessPointDataL( aAPId, *apItem )); diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/downloadmgr/DownloadMgrClntSrv/src/DownloadMgrClntSession.cpp --- a/browserutilities/downloadmgr/DownloadMgrClntSrv/src/DownloadMgrClntSession.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/downloadmgr/DownloadMgrClntSrv/src/DownloadMgrClntSession.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -345,7 +345,10 @@ // Update CodData in Download Mgr Server HBufC8* mediaInfo8 = NULL; - mediaInfo8 = download->iCodDownload->UpdatedDownloadDataL(); + if(download->iCodDownload) + { + mediaInfo8 = download->iCodDownload->UpdatedDownloadDataL(); + } if (mediaInfo8) { download->SetDownloadDataAttribute(*mediaInfo8); diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/downloadmgr/DownloadMgrClntSrv/src/DownloadMgrClntSubSession.cpp --- a/browserutilities/downloadmgr/DownloadMgrClntSrv/src/DownloadMgrClntSubSession.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/downloadmgr/DownloadMgrClntSrv/src/DownloadMgrClntSubSession.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -3305,9 +3305,11 @@ SDMgrCodUserData* userData = new (ELeave) SDMgrCodUserData; userData->iHandle = iHandle; userData->iPrevCodEvent = (MCodDownloadObserver::EDone); - iCodDownload->SetUserData( (TAny*)userData ); - iDownloadMgr->IncrementEventPriorityFlag(); - + if(iCodDownload) + { + iCodDownload->SetUserData( (TAny*)userData ); + iDownloadMgr->IncrementEventPriorityFlag(); + } } // --------------------------------------------------------- diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/downloadmgr/DownloadMgrClntSrv/src/DownloadMgrCod.cpp --- a/browserutilities/downloadmgr/DownloadMgrClntSrv/src/DownloadMgrCod.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/downloadmgr/DownloadMgrClntSrv/src/DownloadMgrCod.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -233,8 +233,6 @@ // download->Delete(); download->StopWaitingAS(); } - else - { TBool doNextUrl( EFalse ); switch( progress.iState ) { @@ -339,7 +337,6 @@ } } } - } } break; diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/downloadmgr/DownloadMgrClntSrv/src/DownloadMgrSrvObject.cpp --- a/browserutilities/downloadmgr/DownloadMgrClntSrv/src/DownloadMgrSrvObject.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/downloadmgr/DownloadMgrClntSrv/src/DownloadMgrSrvObject.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -739,7 +739,7 @@ RFile* file = new (ELeave) RFile; CleanupStack::PushL( file ); - file->AdoptFromClient( Message(), 0, 1 ); + User::LeaveIfError( file->AdoptFromClient( Message(), 0, 1 ) ); // ownership is passed to the engine iDownload->SetFileHandleAttributeL( file ); diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/downloadmgr/DownloadMgrServEng/Inc/DownloadDataServ.h --- a/browserutilities/downloadmgr/DownloadMgrServEng/Inc/DownloadDataServ.h Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/downloadmgr/DownloadMgrServEng/Inc/DownloadDataServ.h Thu Aug 27 07:44:59 2009 +0300 @@ -212,6 +212,12 @@ */ TBool SetTempFilenameL( const TDesC& aTempFilename ); + /** + * Set StatusCode attribute. + * @param aStatusCode. + * @return void. + */ + void SetStatusCode( TInt aStatusCode ); private: // implementation details /** diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/downloadmgr/DownloadMgrServEng/Src/DownloadDataServ.cpp --- a/browserutilities/downloadmgr/DownloadMgrServEng/Src/DownloadDataServ.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/downloadmgr/DownloadMgrServEng/Src/DownloadDataServ.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -193,6 +193,14 @@ { iResult = aResult; } +// --------------------------------------------------------- +// CMediaDataServ::SetStatusCode() +// --------------------------------------------------------- +// +void CMediaDataServ::SetStatusCode( TInt aStatusCode ) + { + iStatusCode = aStatusCode; + } // --------------------------------------------------------- // CMediaDataServ::SetRedirUrlL() @@ -379,6 +387,7 @@ iTempFilename = HBufC::NewL(KMaxFileName); + iStatusCode = aStream.ReadInt32L(); } // --------------------------------------------------------- diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/downloadmgr/DownloadMgrServEng/Src/HttpDownload.cpp --- a/browserutilities/downloadmgr/DownloadMgrServEng/Src/HttpDownload.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/downloadmgr/DownloadMgrServEng/Src/HttpDownload.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -60,7 +60,8 @@ const TInt KRespSizeForRecognition = 1024; //for THttpProgressState EHttpContTypeRecognitionAvail const TInt KMinDataSizeToSend = (32*1024); //for Browser Control to call NewDownloadL const TInt KErrCodHttpDownloadPaused = -20045; //Error code set by the CodHandler if the download is paused by the client - +const TInt KHttp903LossOfService = 903; //Error code set by the CodHandler if connection is lost +const TInt KHttp954LoaderError = 954; //Error code set by the CodHandler if Loader error is found _LIT8( KHttpScheme, "http" ); _LIT8( KHttpsScheme, "https" ); _LIT8( KDefDestFilename, "content.bin" ); @@ -3172,9 +3173,10 @@ mediaData->ResetTypes(); for (TInt type = 0; type < updatedMediaData->TypesCount(); ++type) mediaData->AddTypeL( updatedMediaData->Types().MdcaPoint(type) ); - + mediaData->SetStatusCode( updatedMediaData->StatusCode() ); TInt result = updatedMediaData->Result(); - + TInt statusCode = updatedMediaData->StatusCode(); + TBool pausable = updatedMediaData->Pausable(); //New track download Begins.Hence make track size as 0 //iStorage->SetDownloadedSize ( 0 ); // Active MO completed OR failed. Notify clients. @@ -3202,7 +3204,7 @@ } //if the client pauses the download, Codhandler sets error code to KErrCodHttpDownloadPaused. In that case, no need to trigger EHttpDlFailed Event - if ( result != KErrCodHttpDownloadPaused ) + if ( !( result == KErrCodHttpDownloadPaused || ( pausable && statusCode == KHttp903LossOfService ) || ( pausable && statusCode == KHttp954LoaderError ) ) ) { TriggerEvent( EHttpDlFailed, EHttpProgNone ); } @@ -6561,7 +6563,7 @@ size = size + fieldName->Size() + fieldRawData->Size(); - CLOG_WRITE8_1( "Size = %S:", size ); + CLOG_WRITE8_1( "Size = %d:", size ); } return size; diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/downloadmgr/DownloadMgrUiLib/Inc/CUserInteractionsUtils.h --- a/browserutilities/downloadmgr/DownloadMgrUiLib/Inc/CUserInteractionsUtils.h Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/downloadmgr/DownloadMgrUiLib/Inc/CUserInteractionsUtils.h Thu Aug 27 07:44:59 2009 +0300 @@ -326,10 +326,10 @@ TBool IsNetworkPdCompatibleL() const; /** - * Sends a message to the PD applications (MP, VP ) - * before browser exits + * Sends a message to the PD applications (MP, VP ) before browser exits + * @param aProgressiveDownloadLaunched Progressive Play Launched or not */ - void SendMsgTerminateToPdAppsL(); + void SendMsgTerminateToPdAppsL( TBool aProgressiveDownloadLaunched ); /** * Checks if the WLAN is available diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/downloadmgr/DownloadMgrUiLib/Src/CDownloadMgrUiDownloadsList.cpp --- a/browserutilities/downloadmgr/DownloadMgrUiLib/Src/CDownloadMgrUiDownloadsList.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/downloadmgr/DownloadMgrUiLib/Src/CDownloadMgrUiDownloadsList.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -1845,31 +1845,30 @@ ( currDownload.GetStringAttribute( EDlAttrDestFilename, fileNamePtr ) ); CLOG_WRITE_FORMAT(" EDlAttrDestFilename: %S", &fileNamePtr); + HBufC* fileName1 = HBufC::NewLC(fileName->Length()); + TPtr fileNamePtr1 = fileName1->Des(); + fileNamePtr1.Copy(fileNamePtr); + RFs fs; + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + TFindFile file(fs); + TPtrC ptr(KNullDesC); + TInt found = file.FindByPath(fileNamePtr1,&ptr); //when second parameter to the API is Null then the it searches for the file in the Dir specified in the first parameter + CleanupStack::PopAndDestroy(&fs); + CleanupStack::PopAndDestroy(fileName1); // Delete in DMgr TBool deleted = iUiUtils->DeleteWithUserConfirmL( currDownload ); if ( deleted ) { - if(!iUiUtils->IsCodDownload()) { - HBufC* fileName1 = HBufC::NewLC(fileName->Length()); - TPtr fileNamePtr1 = fileName1->Des(); - fileNamePtr1.Copy(fileNamePtr); - RFs fs; - User::LeaveIfError(fs.Connect()); - CleanupClosePushL(fs); - TFindFile file(fs); - TPtrC ptr(KNullDesC); - TInt found = file.FindByPath(fileNamePtr1,&ptr); //when second parameter to the API is Null then the it searches for the file in the Dir specified in the first parameter - if(found == KErrNotFound) - { - HBufC* infoPrompt = StringLoader::LoadLC( R_DMUL_ERROR_FILE_NOT_FOUND); - CAknInformationNote* note = new(ELeave) CAknInformationNote(); - note->ExecuteLD(*infoPrompt); - CleanupStack::PopAndDestroy(infoPrompt); - } - CleanupStack::PopAndDestroy(&fs); - CleanupStack::PopAndDestroy(fileName1); + if(found == KErrNotFound) + { + HBufC* infoPrompt = StringLoader::LoadLC( R_DMUL_ERROR_FILE_NOT_FOUND); + CAknInformationNote* note = new(ELeave) CAknInformationNote(); + note->ExecuteLD(*infoPrompt); + CleanupStack::PopAndDestroy(infoPrompt); + } // Do not wait until the delete event is reported through the // observer callback, but update the list right now, // so the user will not be able to access and modify an already @@ -2016,12 +2015,16 @@ User::LeaveIfError(err); } TInt count = Count(); - for ( TInt i = 0; i < count; i++ ) + TInt i = 0; + while((count>0) && (i < count)) { RHttpDownload& download = iListModel->Download(i); + i++; if ( cancelled ) { DeleteDownloadL( download ); + i--; + count--; } } iIsCancelInProgress = EFalse; diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/downloadmgr/DownloadMgrUiLib/Src/CDownloadMgrUiUserInteractions.cpp --- a/browserutilities/downloadmgr/DownloadMgrUiLib/Src/CDownloadMgrUiUserInteractions.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/downloadmgr/DownloadMgrUiLib/Src/CDownloadMgrUiUserInteractions.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -266,7 +266,8 @@ CDownloadMgrUiUserInteractions::CDownloadMgrUiUserInteractions ( CDownloadMgrUiLibRegistry& aRegistryModel ) : CDownloadMgrUiBase( aRegistryModel ), - iDlgActive ( EFalse ) + iDlgActive ( EFalse ), + iProgressiveDownloadLaunched ( EFalse ) { } @@ -500,7 +501,7 @@ CLOG_ENTERFN("CDownloadMgrUiUserInteractions::PrepareToExit"); // send a message to all running PD applications and tell that browser is exiting - TRAP_IGNORE( iUiUtils->SendMsgTerminateToPdAppsL()); + TRAP_IGNORE( iUiUtils->SendMsgTerminateToPdAppsL( iProgressiveDownloadLaunched )); TRAPD( err, PrepareToExitL( &aAppUi, aExitType, aViewId, aCustomMessageId, aViewActivationMsg ) ); @@ -522,7 +523,7 @@ CLOG_ENTERFN("CDownloadMgrUiUserInteractions::PrepareToExit 2"); // send a message to all running PD applications and tell that browser is exiting - TRAP_IGNORE( iUiUtils->SendMsgTerminateToPdAppsL()); + TRAP_IGNORE( iUiUtils->SendMsgTerminateToPdAppsL( iProgressiveDownloadLaunched )); // Convert parameters to the necessary form TVwsViewId viewId( TUid::Uid(aAppUid), TUid::Uid(aViewId) ); diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/downloadmgr/DownloadMgrUiLib/Src/CDownloadsListDlg.cpp --- a/browserutilities/downloadmgr/DownloadMgrUiLib/Src/CDownloadsListDlg.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/downloadmgr/DownloadMgrUiLib/Src/CDownloadsListDlg.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -668,6 +668,10 @@ // See SCB CR GKOA-6KPC5L. if ( iListBox ) { + if( iListBox->CurrentItemIndex() >= 0 ) + { + TRAP_IGNORE( HandleMiddleSoftKeyChangeL() ); + } iListBox->SetFocus(IsFocused(), aDrawNow); } // We have no find box, so this part can be omitted: diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/downloadmgr/DownloadMgrUiLib/Src/CUserInteractionsUtils.cpp --- a/browserutilities/downloadmgr/DownloadMgrUiLib/Src/CUserInteractionsUtils.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/downloadmgr/DownloadMgrUiLib/Src/CUserInteractionsUtils.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -1071,10 +1071,11 @@ { TInt count = iRegistryModel.DownloadMgr().CurrentDownloads().Count(); TInt32 dlState; - for(TInt i = 0; i < count; i++) + TInt i = 0; + while((i < count)&& (count>0)) { (iRegistryModel.DownloadMgr().CurrentDownloads().At(i))->GetIntAttribute(EDlAttrState, dlState); - + i++; //add fix for the bug JERI-7P8CF2, if checking against EHttpDlMultipleMOCompleted EHttpDlMultipleMOFailed //Changes for the bug JERI-7P8CF2 //Changes made in the server side to fix for the video center receiving unexpected events @@ -1090,9 +1091,9 @@ if(dlState == EHttpDlInprogress || dlState == EHttpDlPaused ) { - User::LeaveIfError( (iRegistryModel.DownloadMgr().CurrentDownloads().At(i))->Delete()); i--; count--; + User::LeaveIfError( (iRegistryModel.DownloadMgr().CurrentDownloads().At(i))->Delete()); } } CLOG_LEAVEFN("CUserInteractionsUtils::CancelAllWithUserConfirmL"); @@ -1780,6 +1781,9 @@ CleanupStack::PopAndDestroy( &appArcSession ); CleanupStack::PopAndDestroy( param ); } + + //Store the information whether progressive play is launched or not + iRegistryModel.UserInteractions().SetProgressiveDownloadLaunched( ETrue ); if( aProgressively ) { User::LeaveIfError( aDownload.SetIntAttribute( EDlAttrActivePlayedDownload, activeDownloadID ) ); @@ -1953,7 +1957,7 @@ // ----------------------------------------------------------------------------- // -void CUserInteractionsUtils::SendMsgTerminateToPdAppsL() +void CUserInteractionsUtils::SendMsgTerminateToPdAppsL(TBool aProgressiveDownloadLaunched ) { CLOG_ENTERFN("CUserInteractionsEventHandler::SendMsgTerminateToPdAppsL"); // Pack EGenericParamTerminate. @@ -1991,12 +1995,15 @@ { TUid KTestPdPlayerUid = {KDocPDAppUidList[ i ]}; TApaTask task = taskList.FindApp(KTestPdPlayerUid ); // task for MP app - if ( task.Exists() && isProgressive ) + if ( task.Exists() && ( isProgressive || aProgressiveDownloadLaunched ) ) { - RHttpDownload* dl = downloads.At(j); // current download - //This Atribute will tell if MP called Delete - //on exit of Browser - dl->SetBoolAttribute( EDlAttrProgressive, EFalse ); + if ( isProgressive ) + { + RHttpDownload* dl = downloads.At(j); // current download + //This Atribute will tell if MP called Delete + //on exit of Browser + dl->SetBoolAttribute( EDlAttrProgressive, EFalse ); + } // 8-bit buffer is required. task.SendMessage( TUid::Uid( 0 ), *param8 ); // Uid is not used task.BringToForeground(); diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/feedsengine/FeedsServer/Server/inc/FeedsDatabase.h --- a/browserutilities/feedsengine/FeedsServer/Server/inc/FeedsDatabase.h Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/feedsengine/FeedsServer/Server/inc/FeedsDatabase.h Thu Aug 27 07:44:59 2009 +0300 @@ -90,7 +90,7 @@ * @return ETrue if the feed was resolved. */ - TBool CFeedsDatabase::FeedIdFromEntryId(const TInt& aEntryId, TInt aFolderListId, TInt& aFeedId); + TBool CFeedsDatabase::FeedIdFromEntryIdL(const TInt& aEntryId, TInt aFolderListId, TInt& aFeedId); /** * Returns the feed id of the entry id with the given feed. @@ -101,7 +101,7 @@ * @param aEntryId The feed's folder item id * @return ETrue if the feed was resolved. */ - TBool CFeedsDatabase::EntryIdFromFeedId(const TInt& aFeedId, TInt aFolderListId, TInt& aEntryId); + TBool CFeedsDatabase::EntryIdFromFeedIdL(const TInt& aFeedId, TInt aFolderListId, TInt& aEntryId); /** * Return the folder list ID of the feed with the given feed-id. diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/feedsengine/FeedsServer/Server/inc/FeedsServerSession.h --- a/browserutilities/feedsengine/FeedsServer/Server/inc/FeedsServerSession.h Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/feedsengine/FeedsServer/Server/inc/FeedsServerSession.h Thu Aug 27 07:44:59 2009 +0300 @@ -459,6 +459,14 @@ static TInt LazyCallBack(TAny* aPtr); /** + * This function checks whether disk space has not gone below critical level + * + * @since 7.1 + * @return ETrue if the there is sufficient space. + */ + TBool IsSpaceAvailableL(); + + /** * Called upon completion of the task. * * @since 7.1 @@ -506,20 +514,20 @@ // for GetRootFolder iCurrentRequest = 0 // for GetFeed iCurrentRequest = 1; TInt iCurrentRequest; - TBool iResponseTokensSent[2]; - TInt iResponseOffset[2]; - + TBool iResponseTokensSent[2]; + TInt iResponseOffset[2]; + CImportFeedsTask* iOPMLImportTask; - - TInt iCurrOp; - TInt iPrevOp; - HBufC* iExportOPMLFileName; - CIdle* iLazyCaller; //To call SetTokenChunkL function; - TInt iPendingStatus; - TInt iPendingMessageHandle; - TBool iGetFeedCalled; - - + + TInt iCurrOp; + TInt iPrevOp; + HBufC* iExportOPMLFileName; + CIdle* iLazyCaller; //To call SetTokenChunkL function; + TInt iPendingStatus; + TInt iPendingMessageHandle; + TBool iGetFeedCalled; + + }; diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/feedsengine/FeedsServer/Server/inc/UpdateManager.h --- a/browserutilities/feedsengine/FeedsServer/Server/inc/UpdateManager.h Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/feedsengine/FeedsServer/Server/inc/UpdateManager.h Thu Aug 27 07:44:59 2009 +0300 @@ -203,6 +203,8 @@ TInt iMins; CRoamingInfo* iRoamingInfo; + TTime iLastAutoUpdate; + //friend class friend class CRoamingInfo; friend class CFeedsServer; diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/feedsengine/FeedsServer/Server/inc/UpdateQueue.h --- a/browserutilities/feedsengine/FeedsServer/Server/inc/UpdateQueue.h Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/feedsengine/FeedsServer/Server/inc/UpdateQueue.h Thu Aug 27 07:44:59 2009 +0300 @@ -97,13 +97,21 @@ */ TInt GetFreq(); - /** + /** * This method return the Count * * @since 7.1 * @return Integer. */ - TInt Count(); + TInt Count(); + + /** + * This method resets all the auto update timers + * + * @since 7.1 + * @return void. + */ + void ResetTimers(); private: diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/feedsengine/FeedsServer/Server/src/FeedsDatabase.cpp --- a/browserutilities/feedsengine/FeedsServer/Server/src/FeedsDatabase.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/feedsengine/FeedsServer/Server/src/FeedsDatabase.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -2789,7 +2789,7 @@ { //update the folder table. TInt entryId; - EntryIdFromFeedId(aFeedId, aFolderListId, entryId); + EntryIdFromFeedIdL(aFeedId, aFolderListId, entryId); FolderItemUpdateL(entryId, title, KNullDesC, KAutoUpdatingOff); } } @@ -4392,12 +4392,12 @@ } // ----------------------------------------------------------------------------- -// CFeedsDatabase::FeedIdFromEntryId +// CFeedsDatabase::FeedIdFromEntryIdL // // Returns the feed id of the feed with the given entry id. // ----------------------------------------------------------------------------- // -TBool CFeedsDatabase::FeedIdFromEntryId(const TInt& aEntryId, TInt aFolderListId, TInt& aFeedId) +TBool CFeedsDatabase::FeedIdFromEntryIdL(const TInt& aEntryId, TInt aFolderListId, TInt& aFeedId) { RDbView view; TBool found = EFalse; @@ -4437,12 +4437,12 @@ } // ----------------------------------------------------------------------------- -// CFeedsDatabase::EntryIdFromFeedId +// CFeedsDatabase::EntryIdFromFeedIdL // // Returns the feed id of the feed with the given entry id. // ----------------------------------------------------------------------------- // -TBool CFeedsDatabase::EntryIdFromFeedId(const TInt& aFeedId, TInt aFolderListId, TInt& aEntryId) +TBool CFeedsDatabase::EntryIdFromFeedIdL(const TInt& aFeedId, TInt aFolderListId, TInt& aEntryId) { RDbView view; TBool found = EFalse; diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/feedsengine/FeedsServer/Server/src/FeedsServerSession.cpp --- a/browserutilities/feedsengine/FeedsServer/Server/src/FeedsServerSession.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/feedsengine/FeedsServer/Server/src/FeedsServerSession.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -416,7 +416,17 @@ // Ensure the server is ready. iFeedsServer.WakeupServerL(); iCurrOp = aMessage.Function(); - + + if ( (!IsSpaceAvailableL()) && ((iCurrOp != EFeedsServerGetRootFolder) || + (iCurrOp != EFeedsServerWatchFolderList) || (iCurrOp != EFeedsServerGetSettings) || + (iCurrOp != EFeedsServerWatchSettings) || (iCurrOp != EFeedsServerSetConnection) || + (iCurrOp != EFeedsServerDisconnectManualUpdateConnection) || + (iCurrOp != EFeedsServerCancelAll) || (iCurrOp != EFeedsServerGetFeed) || + (iCurrOp != EFeedsServerPrintDBTables))) + { + User::Leave(KErrNoMemory); + } + switch (iCurrOp) { case EFeedsServerGetRootFolder: @@ -681,10 +691,16 @@ //Gyanendra TODO // should create entry into database if (!iFeedsServer.iFeedsDatabase->FeedIdFromUrlL(feedUrl, folderListId, feedId)) { + + if (!IsSpaceAvailableL()) + { + aMessage.Complete(KErrNoMemory); + } + //Find feed id from folder id iFeedsServer.iFeedsDatabase->SetIsFolderTableUpdateNeeded(ETrue); TInt entryId = iFeedsServer.iFeedsDatabase->FolderItemAddL(folderListId, feedUrl, feedUrl, EFalse, KRootFolderId, KAutoUpdatingOff); - iFeedsServer.iFeedsDatabase->FeedIdFromEntryId(entryId, folderListId, feedId); + iFeedsServer.iFeedsDatabase->FeedIdFromEntryIdL(entryId, folderListId, feedId); updateNeeded = ETrue; } } @@ -728,23 +744,8 @@ // Otherwise create a task to update the feed. else { - - TInt drive( EDriveC ); - TBool isSpace( EFalse ); - RFs rfs; - - User::LeaveIfError(rfs.Connect()); - CleanupClosePushL(rfs); - - TRAP_IGNORE( isSpace = !SysUtil::DiskSpaceBelowCriticalLevelL( - &rfs, - KMinFreebytes, - drive )); - - CleanupStack::PopAndDestroy(); //rfs - // Abort the updation of feeds under low memory. - if(isSpace) + if ( IsSpaceAvailableL() ) { // If need be clean up the previous task. @@ -2105,3 +2106,27 @@ } return EFalse; } + +// ----------------------------------------------------------------------------- +// CFeedsServerSession::IsSpaceAvailableL +// +// This function checks whether disk space has not gone below critical level +// ----------------------------------------------------------------------------- +// +TBool CFeedsServerSession::IsSpaceAvailableL() +{ + TInt drive( EDriveC ); + RFs rfs; + TBool isSpaceAvailable(EFalse); + + User::LeaveIfError(rfs.Connect()); + CleanupClosePushL(rfs); + + TRAP_IGNORE( isSpaceAvailable = !SysUtil::DiskSpaceBelowCriticalLevelL( + &rfs, + KMinFreebytes, + drive )); + CleanupStack::PopAndDestroy(); //rfs + + return isSpaceAvailable; +} diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/feedsengine/FeedsServer/Server/src/UpdateManager.cpp --- a/browserutilities/feedsengine/FeedsServer/Server/src/UpdateManager.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/feedsengine/FeedsServer/Server/src/UpdateManager.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -56,6 +56,7 @@ iHttpConnection = CServerHttpConnection::NewL( aAutoUpdateAP ); iRoamingInfo = CRoamingInfo::NewL(this); iAutoUpdateAp = aAutoUpdateAP; + iLastAutoUpdate.HomeTime(); } // ----------------------------------------------------------------------------- @@ -121,6 +122,20 @@ // ----------------------------------------------------------------------------- void CUpdateManager::RunL() { + TTime currentTime; + currentTime.HomeTime(); + TTimeIntervalMinutes diff; + currentTime.MinutesFrom(iLastAutoUpdate,diff); + + if (diff.Int() < 0) + { + for(TInt i =0 ; i < iQueueArray.Count(); i++) + { + iQueueArray[i]->ResetTimers(); + } + } + iLastAutoUpdate.HomeTime(); + if (iStatus.Int() == KErrNone || iStatus.Int() == KErrAbort) { StartTimer(); diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/feedsengine/FeedsServer/Server/src/UpdateQueue.cpp --- a/browserutilities/feedsengine/FeedsServer/Server/src/UpdateQueue.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/feedsengine/FeedsServer/Server/src/UpdateQueue.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -154,3 +154,28 @@ { return iFeedIds.Count(); } + +// ----------------------------------------------------------------------------- +// CUpdateQueue::ResetTimers +// +// Resets all the auto update timers +// ----------------------------------------------------------------------------- + +void CUpdateQueue::ResetTimers() +{ + iLastAutoUpdate.HomeTime(); + TDateTime dateTime = iLastAutoUpdate.DateTime(); + TInt mins; + + switch(iFreq) + { + case 10080: + mins = iLastAutoUpdate.DayNoInWeek()*60*24 + dateTime.Hour() * 60 + dateTime.Minute(); + break; + default: + mins = dateTime.Hour() * 60 + dateTime.Minute(); + break; + } + + iLastAutoUpdate = iLastAutoUpdate - TTimeIntervalMinutes(mins % iFreq); +} diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/recenturlstore/BWINSCW/RecentUrlStoreU.def --- a/browserutilities/recenturlstore/BWINSCW/RecentUrlStoreU.def Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/recenturlstore/BWINSCW/RecentUrlStoreU.def Thu Aug 27 07:44:59 2009 +0300 @@ -3,5 +3,5 @@ ?DeleteData@CRecentUrlStore@@QAEXABVTDesC16@@@Z @ 2 NONAME ; void CRecentUrlStore::DeleteData(class TDesC16 const &) ?GetData@CRecentUrlStore@@QAEHAAVCDesC16Array@@0ABVTDesC16@@@Z @ 3 NONAME ; int CRecentUrlStore::GetData(class CDesC16Array &, class CDesC16Array &, class TDesC16 const &) ?NewL@CRecentUrlStore@@SAPAV1@XZ @ 4 NONAME ; class CRecentUrlStore * CRecentUrlStore::NewL(void) - ?SaveData@CRecentUrlStore@@QAEXABVTDesC16@@0@Z @ 5 NONAME ; void CRecentUrlStore::SaveData(class TDesC16 const &, class TDesC16 const &) + ?SaveDataL@CRecentUrlStore@@QAEXABVTDesC16@@0@Z @ 5 NONAME ; void CRecentUrlStore::SaveData(class TDesC16 const &, class TDesC16 const &) diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/recenturlstore/EABI/RecentUrlStoreU.def --- a/browserutilities/recenturlstore/EABI/RecentUrlStoreU.def Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/recenturlstore/EABI/RecentUrlStoreU.def Thu Aug 27 07:44:59 2009 +0300 @@ -2,7 +2,7 @@ _ZN15CRecentUrlStore10DeleteDataERK7TDesC16 @ 1 NONAME _ZN15CRecentUrlStore4NewLEv @ 2 NONAME _ZN15CRecentUrlStore7GetDataER12CDesC16ArrayS1_RK7TDesC16 @ 3 NONAME - _ZN15CRecentUrlStore8SaveDataERK7TDesC16S2_ @ 4 NONAME + _ZN15CRecentUrlStore9SaveDataLERK7TDesC16S2_ @ 4 NONAME _ZN15CRecentUrlStore9ClearDataEv @ 5 NONAME _ZTI15CRecentUrlStore @ 6 NONAME ; ## _ZTV15CRecentUrlStore @ 7 NONAME ; ## diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/recenturlstore/RecentUrlSrc/RecentUrlStore.cpp --- a/browserutilities/recenturlstore/RecentUrlSrc/RecentUrlStore.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/browserutilities/recenturlstore/RecentUrlSrc/RecentUrlStore.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -140,56 +140,52 @@ void CRecentUrlStore::GetDataL (RDbNamedDatabase& aDataBase, CDesCArray& aUrls, CDesCArray& aTitles, const TDesC& aUrl) { - - TInt rowCount(0); - - // select values from the database filtered by url - if (aUrl.Length()) - { - HBufC* domain = aUrl.AllocLC(); - domain->Des().LowerCase(); - iSQLStatement.Format(KSQLSelect, domain, domain); - CleanupStack::PopAndDestroy(); - } - else - { - iSQLStatement.Format(KSQLSelectAll); - } - + // shouldn't happen but if it's too long just skip it! + if ( aUrl.Length() <= KUrlSize) + { + TInt rowCount(0); - RDbView view; - - TInt err = view.Prepare(aDataBase, TDbQuery(iSQLStatement)); - if (err == KErrNone) - { - err = view.EvaluateAll(); - if (err == KErrNone) - { - view.FirstL(); - // loop through rows and build the list - while (view.AtRow() && rowCount++ < KMaxRows) - { - view.GetL(); - aUrls.AppendL(view.ColDes(KUrlCol)); - aTitles.AppendL(view.ColDes(KTitleCol)); - view.NextL(); - } - /* - * This loop will keep the number of rows in the database at a reasonable size by - * deleting old rows (deletes rows beyond KMaxRows). Should be at most 1 row deleted. - * Its more efficiant to delete it here than in the SaveData because in this function - * we already have the list and know its size - */ - while (view.AtRow()) - { - view.GetL(); - iSQLStatement.Format(KSQLDelete, &aUrl); - aDataBase.Execute(iSQLStatement); - view.NextL(); - } - } - } - view.Close(); + // select values from the database filtered by url + if (aUrl.Length()) + { + HBufC* domain = aUrl.AllocLC(); + domain->Des().LowerCase(); + iSQLStatement.Format(KSQLSelect, domain, domain); + CleanupStack::PopAndDestroy(); + } + else + { + iSQLStatement.Format(KSQLSelectAll); + } + + RDbView view; + CleanupClosePushL( view ); + User::LeaveIfError( view.Prepare(aDataBase, TDbQuery(iSQLStatement)) ); + User::LeaveIfError( view.EvaluateAll() ); + view.FirstL(); + // loop through rows and build the list + while (view.AtRow() && rowCount++ < KMaxRows) + { + view.GetL(); + aUrls.AppendL(view.ColDes(KUrlCol)); + aTitles.AppendL(view.ColDes(KTitleCol)); + view.NextL(); + } + /* + * This loop will keep the number of rows in the database at a reasonable size by + * deleting old rows (deletes rows beyond KMaxRows). Should be at most 1 row deleted. + * Its more efficiant to delete it here than in the SaveData because in this function + * we already have the list and know its size + */ + while (view.AtRow()) + { + view.GetL(); + iSQLStatement.Format(KSQLDelete, &aUrl); + aDataBase.Execute(iSQLStatement); + view.NextL(); + } + CleanupStack::PopAndDestroy( &view ); + } } //----------------------------------------------------------------------------- @@ -197,68 +193,69 @@ // Deletes a single row from the database. //----------------------------------------------------------------------------- EXPORT_C void CRecentUrlStore::DeleteData (const TDesC& aUrl) - { - RDbNamedDatabase dataBase; - if (OpenDatabase(dataBase) == KErrNone) - { - iSQLStatement.Format(KSQLDelete, &aUrl); - dataBase.Execute(iSQLStatement); - dataBase.Close(); - } - } + { + // shouldn't happen but if it's too long just skip it! + if ( aUrl.Length() <= KUrlSize) + { + RDbNamedDatabase dataBase; + if (OpenDatabase(dataBase) == KErrNone) + { + iSQLStatement.Format(KSQLDelete, &aUrl); + dataBase.Execute(iSQLStatement); + dataBase.Close(); + } + } + } //----------------------------------------------------------------------------- // CRecentUrlStore::SaveDataL // Save the url in store. //----------------------------------------------------------------------------- -EXPORT_C void CRecentUrlStore::SaveData (const TDesC& aUrl, const TDesC& aTitle) +EXPORT_C void CRecentUrlStore::SaveDataL (const TDesC& aUrl, const TDesC& aTitle) { - RDbNamedDatabase dataBase; - TInt urlLength (aUrl.Length()); - + TInt urlLength (aUrl.Length()); // shouldn't happen but if it's too long for the data store just skip it! - if (urlLength > KUrlSize) + if (urlLength <= KUrlSize) { - return; - } - - if (OpenDatabase(dataBase) == KErrNone) - { - // find the point where the domain starts and ends - TInt domainLength(urlLength); - TInt domainStart(0); - - TInt startPos = aUrl.Find(KDomainDelim); - if (startPos != KErrNotFound) + RDbNamedDatabase dataBase; + CleanupClosePushL( dataBase ); + if (OpenDatabase(dataBase) == KErrNone) { - domainStart = startPos + (KDomainDelim().Length()); // first char after delim - TInt len = aUrl.Right(urlLength - domainStart).Find(KDomainDelim); - if (len > 0) // ignore delim following delim. we don't want an empty string + // find the point where the domain starts and ends + TInt domainLength(urlLength); + TInt domainStart(0); + + TInt startPos = aUrl.Find(KDomainDelim); + if (startPos != KErrNotFound) { - domainLength = len; - } - else - { - domainLength -= domainStart; + domainStart = startPos + (KDomainDelim().Length()); // first char after delim + TInt len = aUrl.Right(urlLength - domainStart).Find(KDomainDelim); + if (len > 0) // ignore delim following delim. we don't want an empty string + { + domainLength = len; + } + else + { + domainLength -= domainStart; + } } - } - - // make sure it's not too big for the data store - domainLength = (domainLength > KDomainSize) ? KDomainSize : domainLength; - TInt titleLength = (aTitle.Length() > KTitleSize) ? KTitleSize : aTitle.Length(); + + // make sure it's not too big for the data store + domainLength = (domainLength > KDomainSize) ? KDomainSize : domainLength; + TInt titleLength = (aTitle.Length() > KTitleSize) ? KTitleSize : aTitle.Length(); + + HBufC* domain = aUrl.Mid(domainStart,domainLength).AllocLC(); + domain->Des().LowerCase(); + HBufC* title = aTitle.Left(titleLength).AllocLC(); + + // delete and re-insert + iSQLStatement.Format(KSQLDelete, &aUrl); + dataBase.Execute(iSQLStatement); + iSQLStatement.Format(KSQLInsert, domain, &aUrl, title); + dataBase.Execute(iSQLStatement); - HBufC* domain = aUrl.Mid(domainStart,domainLength).AllocLC(); - domain->Des().LowerCase(); - HBufC* title = aTitle.Left(titleLength).AllocLC(); - - // delete and re-insert - iSQLStatement.Format(KSQLDelete, &aUrl); - dataBase.Execute(iSQLStatement); - iSQLStatement.Format(KSQLInsert, domain, &aUrl, title); - CleanupStack::PopAndDestroy(2); // domain, title - - dataBase.Execute(iSQLStatement); - dataBase.Close(); + CleanupStack::PopAndDestroy(3, &dataBase ); + } } } @@ -279,34 +276,27 @@ //----------------------------------------------------------------------------- void CRecentUrlStore::DeleteOldRowsL (RDbNamedDatabase& aDataBase) { - TInt rowCount(0); - iSQLStatement.Format(KSQLSelectAll); RDbView view; + CleanupClosePushL( view ); - TInt err = view.Prepare(aDataBase, TDbQuery(iSQLStatement)); - if (err == KErrNone) - { - err = view.EvaluateAll(); - if (err == KErrNone) - { - view.FirstL(); - // loop through rows we want to keep - while (view.AtRow() && rowCount++ < KMaxRows) - { - view.NextL(); - } - // delete the rows that are old - while (view.AtRow()) - { - view.DeleteL(); - view.NextL(); - } - } - } - view.Close(); + User::LeaveIfError( view.Prepare(aDataBase, TDbQuery(iSQLStatement))); + User::LeaveIfError( view.EvaluateAll() ); + view.FirstL(); + // loop through rows we want to keep + while (view.AtRow() && rowCount++ < KMaxRows) + { + view.NextL(); + } + // delete the rows that are old + while (view.AtRow()) + { + view.DeleteL(); + view.NextL(); + } + CleanupStack::PopAndDestroy( &view ); } //----------------------------------------------------------------------------- diff -r 10e98eab6f85 -r a359256acfc6 browserutilities/webutils/conf/webutils.confml Binary file browserutilities/webutils/conf/webutils.confml has changed diff -r 10e98eab6f85 -r a359256acfc6 codhandler/codeng/inc/CodParser.h --- a/codhandler/codeng/inc/CodParser.h Fri Jul 03 15:54:40 2009 +0100 +++ b/codhandler/codeng/inc/CodParser.h Thu Aug 27 07:44:59 2009 +0300 @@ -26,7 +26,7 @@ #include // FORWARD DECLARATION - +class CMediaObjectData; class CCodData; // CLASS DECLARATION @@ -82,7 +82,7 @@ * Parse one line. * @return ETrue if more lines to go, EFalse if done. */ - TBool AttrLineL(); + TBool AttrLineL(CMediaObjectData *& aMediaObject); /** * Parse an attribute name. Empty token sets error. diff -r 10e98eab6f85 -r a359256acfc6 codhandler/codeng/inc/DownloadDataClient.h --- a/codhandler/codeng/inc/DownloadDataClient.h Fri Jul 03 15:54:40 2009 +0100 +++ b/codhandler/codeng/inc/DownloadDataClient.h Thu Aug 27 07:44:59 2009 +0300 @@ -221,6 +221,12 @@ */ void SetPausable( TBool aPausable ); + /** + * Set StatusCode attribute. + * @param aStatusCode. + * @return void. + */ + void SetStatusCode( TInt aStatusCode ); private: // implementation details /** diff -r 10e98eab6f85 -r a359256acfc6 codhandler/codeng/src/CodEngBase.cpp --- a/codhandler/codeng/src/CodEngBase.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/codhandler/codeng/src/CodEngBase.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -1838,24 +1838,6 @@ #endif } -#ifdef __SYNCML_DM_FOTA - if ( fota ) - { - // Transient FOTA session is used to check store space -> waste. - // Pre-allocate FOTA saver to avoid this (??) makes the saver's - // lifespan hard to follow, error-prone. TODO (??) - CLOG(( ECodEng, 2, _L(" FOTA check (%d)"), size )); - RFotaEngineSession fotaEng; - CleanupClosePushL( fotaEng ); - fotaEng.OpenL(); - if ( !fotaEng.IsPackageStoreSizeAvailable( size ) ) - { - User::Leave( KErrCodInsufficientSpace ); - } - CleanupStack::PopAndDestroy( &fotaEng ); - } -#endif /*def __SYNCML_DM_FOTA */ - //When reached here, it is assured that capability check is done successfully //for the active download. //Content type check is done for this track @@ -1880,7 +1862,7 @@ } // DD1 and DD2 cases - if (( aType.Find( KOma2TriggerContentType ) != KErrNotFound) || ( aType.Find( KDd2DataType ) != KErrNotFound )|| ( aType.Find( KOma1WbxmlRoContentType ) != KErrNotFound )) + if (( aType.Find( KOma2TriggerContentType ) != KErrNotFound) || ( aType.Find( KDd2DataType ) != KErrNotFound )|| ( aType.Find( KOma1WbxmlRoContentType ) != KErrNotFound )|| ( aType.Find( KOma1XmlRoContentType ) != KErrNotFound )) { iSaver = CRoapSaver::NewL( aType, iRoapData, iProgress, KRoapProgressMax, (*iData)[iData->ActiveDownload()]->iTempPath, (*iData)[iData->ActiveDownload()]->iRootPath, KNullDesC()); iSaver->SetObserver( iObserver ); @@ -2697,6 +2679,7 @@ for (TInt type = 0; type < objMedia->TypesCount(); ++type) aMOData->AddTypeL( objMedia->Types().MdcaPoint(type) ); + aMOData->SetStatusCode( objMedia->iStatusCode ); } //------------------------------------------------------------------------ diff -r 10e98eab6f85 -r a359256acfc6 codhandler/codeng/src/CodParser.cpp --- a/codhandler/codeng/src/CodParser.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/codhandler/codeng/src/CodParser.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -67,13 +67,14 @@ iBuf = &aBuf; iCurP = iBuf->Ptr(); iEndP = iCurP + iBuf->Length(); + CMediaObjectData *mediaObject = CMediaObjectData::NewL(); // Processing lines (attribute and value) until there is more lines to read. - while ( AttrLineL() ) + while ( AttrLineL(mediaObject) ) { // Some compilers require empty controlled statement block instead of // just a semicolon. } - + iData->AppendMediaObjectL( mediaObject ); #ifdef __TEST_COD_LOG TPtrC ptr16; TPtrC8 ptr8; @@ -113,7 +114,7 @@ // TCodParser::AttrLineL() // --------------------------------------------------------- // -TBool TCodParser::AttrLineL() +TBool TCodParser::AttrLineL(CMediaObjectData *& aMediaObject) { SkipWhiteSpace(); // Skip lines which contain only WS and LF at the end. while ( IsEndOfLine() ) @@ -131,7 +132,7 @@ { if ( Colon() ) { - ok = iData->SetNameL( AttrValue() ); + ok = aMediaObject->SetNameL( AttrValue() ); EndOfLine(); } break; @@ -151,7 +152,7 @@ { if ( Colon() ) { - ok = iData->SetDescriptionL( AttrValue() ); + ok = aMediaObject->SetDescriptionL( AttrValue() ); EndOfLine(); } break; @@ -166,7 +167,7 @@ TLex lex( AttrValue() ); if ( !lex.Val( size ) ) { - iData->SetSize( size ); + aMediaObject->SetSize( size ); } else { @@ -181,7 +182,7 @@ { if ( Colon() ) { - ok = iData->SetInstallNotifyL( AttrValue() ); + ok = aMediaObject->SetInstallNotifyL( AttrValue() ); EndOfLine(); } break; @@ -211,7 +212,7 @@ { if ( Colon() ) { - ok = iData->SetInfoUrlL( AttrValue() ); + ok = aMediaObject->SetInfoUrlL( AttrValue() ); EndOfLine(); } break; @@ -221,7 +222,7 @@ { if ( Colon() ) { - ok = iData->SetPriceL( AttrValue() ); + ok = aMediaObject->SetPriceL( AttrValue() ); EndOfLine(); } break; @@ -231,7 +232,25 @@ { if ( Colon() ) { - ok = iData->SetIconL( AttrValue() ); + ok = aMediaObject->SetIconL( AttrValue() ); + EndOfLine(); + } + break; + } + case ECodType: + { + if ( Colon() ) + { + ok = aMediaObject->SetTypeL( AttrValue() ); + EndOfLine(); + } + break; + } + case ECodUrl: + { + if ( Colon() ) + { + ok = aMediaObject->SetUrlL( AttrValue() ); EndOfLine(); } break; diff -r 10e98eab6f85 -r a359256acfc6 codhandler/codeng/src/DownloadDataClient.cpp --- a/codhandler/codeng/src/DownloadDataClient.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/codhandler/codeng/src/DownloadDataClient.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -235,6 +235,14 @@ { iResult = aResult; } +// --------------------------------------------------------- +// CMediaDataClient::SetStatusCode() +// --------------------------------------------------------- +// +void CMediaDataClient::SetStatusCode( TInt aStatusCode ) + { + iStatusCode = aStatusCode; + } // --------------------------------------------------------- // CMediaDataClient::SetRedirUrlL() @@ -504,6 +512,8 @@ // iPausable aStream.WriteInt32L(iPausable); + // iStatusCode + aStream.WriteInt32L(iStatusCode); } void CMediaDataClient::InternalizeL(RReadStream& /*aStream*/) diff -r 10e98eab6f85 -r a359256acfc6 codhandler/codeng/src/FotaSaver.cpp --- a/codhandler/codeng/src/FotaSaver.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/codhandler/codeng/src/FotaSaver.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -139,8 +139,8 @@ // // There is a safety upper bound on the transaction size, that is already // applied. See SetMaxSize(). - - if( iType != TDataType( (*aData[aData.ActiveDownload()]).Type() ) ) + + if( iType.Des8().Find( (*aData[aData.ActiveDownload()]).Type() ) == KErrNotFound ) { CLOG(( ECodEng, 4, _L(" content-type mismatch") )); User::Leave( KErrCodAttributeMismatch ); diff -r 10e98eab6f85 -r a359256acfc6 codhandler/codeng/src/HttpLoader.cpp --- a/codhandler/codeng/src/HttpLoader.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/codhandler/codeng/src/HttpLoader.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -1731,7 +1731,12 @@ } TInt size (iSaver->DownloadedFileSize()); - + if( iSaver->DataType().Des8().Find( KFotaPackageDataType ) != KErrNotFound ) + { + iCodEng->UpdateDownloadedSize( size ); + IncProgressL(size); + } + if( size <= 0 ) { // no bytes have been downloaded yet diff -r 10e98eab6f85 -r a359256acfc6 codhandler/codui/group/CodUi.mmp --- a/codhandler/codui/group/CodUi.mmp Fri Jul 03 15:54:40 2009 +0100 +++ b/codhandler/codui/group/CodUi.mmp Thu Aug 27 07:44:59 2009 +0300 @@ -69,6 +69,7 @@ LIBRARY eikdlg.lib LIBRARY eikctl.lib LIBRARY cone.lib +LIBRARY sysutil.lib LIBRARY eikcore.lib LIBRARY euser.lib LIBRARY etext.lib diff -r 10e98eab6f85 -r a359256acfc6 codhandler/codui/src/CodDialog.cpp --- a/codhandler/codui/src/CodDialog.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/codhandler/codui/src/CodDialog.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -24,6 +24,8 @@ #include "CodDialog.h" #include "CodLogger.h" #include +#include + #ifndef RD_MULTIPLE_DRIVE _LIT(KBackSlash,"\\"); #endif @@ -107,23 +109,33 @@ } User::LeaveIfError( PathInfo::GetRootPath( aRootPath, drive ) ); #else - TBuf driveList; - TInt drive( EDriveC ); - - if( repository->Get(KBrowserDrivePrefListForDownloadedContent, driveList) == KErrNone ) - { - TPtrC drives(driveList); - TInt err(KErrNone); - for( TInt i = 0; i < drives.Length(); i = i + 2 ) - { - err = fs.CharToDrive( drives[i], drive ); - if (err == KErrNone) - break; - } - TDriveUnit driveUnit(drive); - aRootPath = driveUnit.Name(); - aRootPath.Append(KBackSlash); - } + TBool mmcOk = EFalse; + TRAP_IGNORE( mmcOk = !SysUtil::MMCSpaceBelowCriticalLevelL + ( &fs, 0 ); ) + if(!mmcOk) + { + CLOG(( 2, _L("void CodDialog::GetRootPathL No mmc") )); + TDriveUnit driveUnit(EDriveC); + aRootPath = driveUnit.Name(); + aRootPath.Append(KBackSlash); + + } + else + { + CLOG(( 2, _L("void CodDialog::GetRootPathL No mmc") )); + TVolumeInfo volInfoC; + TVolumeInfo volInfoE; + fs.Volume(volInfoC,EDriveC); + fs.Volume(volInfoE,EDriveE); + TInt64 freeC = volInfoC.iFree;//free memory available in that drive + TInt64 freeE = volInfoE.iFree; + + TDriveUnit driveUnit(freeC>=freeE?EDriveC:EDriveE); + aRootPath = driveUnit.Name(); + aRootPath.Append(KBackSlash); + } + + #endif fs.Close(); CleanupStack::PopAndDestroy(repository); diff -r 10e98eab6f85 -r a359256acfc6 codhandler/roapapp/src/RoapAppUi.cpp --- a/codhandler/roapapp/src/RoapAppUi.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/codhandler/roapapp/src/RoapAppUi.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -983,4 +983,3 @@ CLOG(( 2, _L("<- CRoapAppUi::HandleDMgrEventL") )); } - diff -r 10e98eab6f85 -r a359256acfc6 web_plat/browser_platform_api/group/bld.inf --- a/web_plat/browser_platform_api/group/bld.inf Fri Jul 03 15:54:40 2009 +0100 +++ b/web_plat/browser_platform_api/group/bld.inf Thu Aug 27 07:44:59 2009 +0300 @@ -23,8 +23,18 @@ PRJ_EXPORTS ../inc/Browser_platform_variant.hrh MW_LAYER_PLATFORM_EXPORT_PATH(Browser_platform_variant.hrh) + #ifdef BRDO_ADDED_EXPORT_LOCATION ../inc/Browser_platform_variant.hrh BRDO_ADDED_EXPORT_LOCATION(Browser_platform_variant.hrh) #endif +#ifdef __PLATFORM_VERSION_50_TUBE__ +../inc/Browser_platform_variant.hrh /epoc32/include/oem/Browser_platform_variant.hrh +../inc/Browser_platform_variant.hrh /epoc32/include/oem/platform/mw/Browser_platform_variant.hrh +#endif + +#ifdef __PLATFORM_VERSION_50__ +../inc/Browser_platform_variant.hrh /epoc32/include/oem/Browser_platform_variant.hrh +#endif + PRJ_MMPFILES diff -r 10e98eab6f85 -r a359256acfc6 web_plat/browser_platform_api/inc/Browser_platform_variant.hrh --- a/web_plat/browser_platform_api/inc/Browser_platform_variant.hrh Fri Jul 03 15:54:40 2009 +0100 +++ b/web_plat/browser_platform_api/inc/Browser_platform_variant.hrh Thu Aug 27 07:44:59 2009 +0300 @@ -26,35 +26,58 @@ #ifndef BROWSER_PLATFORM_VARIANT_HRH #define BROWSER_PLATFORM_VARIANT_HRH - /* * Establish which platform we are building on. * If required, un-comment correct platform macro as * described below * */ - +/* +* =================== +* S60 3.23 Gadget, etc.. +* =================== +*/ #if defined(__S60_32__) // // this is the only supported platform that comes with unambiguous platform version flag #define __PLATFORM_VERSION_32__ -// -#else + +/* +* =================== +* S60 5.0 Tube, Alvin, Ivalo, Saga, etc. +* 5.0/5250 platforms +* =================== +*/ +#elif defined(__S60_50__) // manually edit the following lines to enable definition for // whichever platform is in use -// -// un-comment following line for 5.0/5250 platforms -//#define __PLATFORM_VERSION_50__ -// +// un-comment following line for 5.0/5250 platforms running on products similar on Tube and Alvin +// #define __PLATFORM_VERSION_50_TUBE__ + +// un-comment following line for 5.0/5250 platforms for Ivalo and Saga +// #define __PLATFORM_VERSION_50__ + +/* +* =================== +* S60 5.1 Corolla, etc. +* =================== +*/ +// #elif defined(__S60_51__) // un-comment following line for 5.1/TB9.1 platforms -#define __PLATFORM_VERSION_51__ -// +//#define __PLATFORM_VERSION_51__ + +/* +* =================== +* S60 5.2 Vasco, etc. +* =================== +*/ +// #elif defined(__S60_52__) + // un-comment following line for 5.2/TB9.2 platforms -//#define __PLATFORM_VERSION_52__ + #define __PLATFORM_VERSION_52__ // #endif - /* * * Define Browser Version @@ -65,7 +88,6 @@ #define BRDO_APP_VERSION_MINOR 2 #define BRDO_APP_VERSION BRDO_APP_VERSION_MAJOR##_##BRDO_APP_VERSION_MINOR - /* * * Define feature flags @@ -120,6 +142,11 @@ // Additional export location - to adapt to new header export location #undef BRDO_ADDED_EXPORT_LOCATION +// Platform contains new Symbian Libxml implementation +#undef BRDO_SYMBIAN_LIBXML_FF + +// Enable/Disable compilation of some of Search Integration specific code +#define BRDO_SEARCH_INTEGRATION_FF /* * =================== @@ -128,12 +155,6 @@ */ #if defined(__PLATFORM_VERSION_32__) -// Defines Language InterWork and SAPI availability -#undef BRDO_LIW_FF - -// Defines if SecurityManager component is present -#undef BRDO_WRT_SECURITY_MGR_FF - // Defines touch screen capability #undef BRDO_TOUCH_ENABLED_FF @@ -142,25 +163,104 @@ // Defines Direct File IO support in RFile ( EFileWriteDirectIO ) #undef BRDO_RFILE_WRITE_DIRECT_IO_FF + +// Defines use of GestureHelper library #undef BRDO_USE_GESTURE_HELPER +// Defines WRT widgets feature to publish on homescreen #undef BRDO_WRT_HS_FF // Gallery App is present #define BRDO_APP_GALLERY_SUPPORTED_FF +// Disable compilation of some of Search Integration specific code +#undef BRDO_SEARCH_INTEGRATION_FF + // Missing from 3.23 platform_paths.hrh // Location, where the middleware layer localization .loc file should be exported +#if __GNUC__ >= 3 +#define MW_LAYER_LOC_EXPORT_PATH(exported) MW_LAYER_PUBLIC_EXPORT_PATH(exported) +#else #define MW_LAYER_LOC_EXPORT_PATH(exported) MW_LAYER_PUBLIC_EXPORT_PATH(##exported) +#endif // Location, where the middleware layer localization .loc file should be exported +#if __GNUC__ >= 3 +#define APP_LAYER_LOC_EXPORT_PATH(exported) APP_LAYER_PUBLIC_EXPORT_PATH(exported) +#else #define APP_LAYER_LOC_EXPORT_PATH(exported) APP_LAYER_PUBLIC_EXPORT_PATH(##exported) +#endif +#if __GNUC__ >= 3 +#define BRDO_ADDED_EXPORT_LOCATION(exported) MW_LAYER_DOMAIN_EXPORT_PATH(../platform/mw/exported) +#else +#define BRDO_ADDED_EXPORT_LOCATION(exported) MW_LAYER_DOMAIN_EXPORT_PATH(../platform/mw/##exported) +#endif + +#define APP_LAYER_LIBC_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(libc) +#define APP_LAYER_ECOM_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(ecom) +#define APP_LAYER_HTTP_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(http) +#define APP_LAYER_CONNECT_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(connect) +#define APP_LAYER_SWI_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(swi) +#define APP_LAYER_OSKERNEL_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(kernel) +#define APP_LAYER_PUSH_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(push) +#define APP_LAYER_STDAPIS_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(stdapis) + +#define MW_LAYER_LIBC_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(libc) +#define MW_LAYER_ECOM_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(ecom) +#define MW_LAYER_HTTP_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(http) +#define MW_LAYER_CONNECT_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(connect) +#define MW_LAYER_SWI_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(swi) +#define MW_LAYER_OSKERNEL_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(kernel) +#define MW_LAYER_PUSH_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(push) +#define MW_LAYER_STDAPIS_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(stdapis) /* * =================== -* S60 5.0 +* S60 5.0 PF5250 / Tube / Alvin +* =================== +*/ +#elif defined(__PLATFORM_VERSION_50_TUBE__) + +// Defines must accumulate versions. ie for 5.01 you must define BRDO_BROWSER_50_FF and BRDO_BROWSER_501_FF(To be reviewed) +// The assumption is that anything that worked in 3.2 will work in 5.0 and 5.01. For anything doesn't work +// in 3.2 but works in 5.0 and above, that code should be behind the BRDO_BROWSER_50_FF flag. +#define BRDO_BROWSER_50_FF + +// Defines WRT widgets feature to publish on homescreen +#undef BRDO_WRT_HS_FF + +// Disable compilation of some of Search Integration specific code +#undef BRDO_SEARCH_INTEGRATION_FF + +#if __GNUC__ >= 3 +#define BRDO_ADDED_EXPORT_LOCATION(exported) MW_LAYER_DOMAIN_EXPORT_PATH(../../platform/mw/exported) +#else +#define BRDO_ADDED_EXPORT_LOCATION(exported) MW_LAYER_DOMAIN_EXPORT_PATH(../../platform/mw/##exported) +#endif + +#define APP_LAYER_LIBC_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(../libc) +#define APP_LAYER_ECOM_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(../ecom) +#define APP_LAYER_HTTP_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(../http) +#define APP_LAYER_CONNECT_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(../connect) +#define APP_LAYER_SWI_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(../swi) +#define APP_LAYER_OSKERNEL_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(../kernel) +#define APP_LAYER_PUSH_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(../push) +#define APP_LAYER_STDAPIS_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(../stdapis) + +#define MW_LAYER_LIBC_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(../libc) +#define MW_LAYER_ECOM_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(../ecom) +#define MW_LAYER_HTTP_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(../http) +#define MW_LAYER_CONNECT_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(../connect) +#define MW_LAYER_SWI_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(../swi) +#define MW_LAYER_OSKERNEL_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(../kernel) +#define MW_LAYER_PUSH_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(../push) +#define MW_LAYER_STDAPIS_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(../stdapis) + +/* +* =================== +* S60 5.0 PF5250+ / Ivalo / Saga * =================== */ #elif defined(__PLATFORM_VERSION_50__) @@ -194,7 +294,6 @@ #define MW_LAYER_PUSH_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(../push) #define MW_LAYER_STDAPIS_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(../stdapis) - /* * =================== * S60 5.1 @@ -223,7 +322,6 @@ #define MW_LAYER_PUSH_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(push) #define MW_LAYER_STDAPIS_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(stdapis) - /* * =================== * S60 5.2 @@ -236,7 +334,8 @@ #define BRDO_BROWSER_52_FF // BrDo MultipartParser not used from S60 5.2 onward -//#undef BRDO_MULTIPART_PARSER_FF - TODO: un-comment this line for week21 release +// un-comment this line for week21 release +#undef BRDO_MULTIPART_PARSER_FF #define APP_LAYER_LIBC_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(libc) #define APP_LAYER_ECOM_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(ecom) @@ -256,11 +355,11 @@ #define MW_LAYER_PUSH_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(push) #define MW_LAYER_STDAPIS_SYSTEMINCLUDE SYSTEMINCLUDE OS_LAYER_PUBLIC_EXPORT_PATH(stdapis) +// Platform contains new Symbian Libxml implementation +#define BRDO_SYMBIAN_LIBXML_FF #endif // PLATFORM VERSION ID's - - // Generic run-time definitions -- see WmlBrowserBuild.h for similar feature related definitions // Browser Update - Independent Application Delivery diff -r 10e98eab6f85 -r a359256acfc6 web_plat/cod_handler_api/inc/HttpDownloadData.h --- a/web_plat/cod_handler_api/inc/HttpDownloadData.h Fri Jul 03 15:54:40 2009 +0100 +++ b/web_plat/cod_handler_api/inc/HttpDownloadData.h Thu Aug 27 07:44:59 2009 +0300 @@ -264,6 +264,11 @@ */ inline TPtrC TempFilename() const { return *iTempFilename; } + /** + * Gets the StatusCode of Media Object + * @ return iStatusCode + */ + inline TInt StatusCode () const { return iStatusCode; } public: // Setters /** @@ -403,6 +408,12 @@ */ virtual void SetPausable( TBool aPausable ) = 0; + /** + * Set StatusCode attribute. + * @param aStatusCode. + * @return void. + */ + virtual void SetStatusCode( TInt aStatusCode ) = 0; protected: // data HBufC* iName; ///< Media-Name. Owned. @@ -424,6 +435,7 @@ TInt iGlobalErrorId; ///< Global Error Id. TBool iPausable; ///< Is Media-Download Pausable? HBufC* iTempFilename; ///< Media Temp Filename. + TInt iStatusCode; }; diff -r 10e98eab6f85 -r a359256acfc6 web_plat/recent_url_store_api/inc/RecentUrlStore.h --- a/web_plat/recent_url_store_api/inc/RecentUrlStore.h Fri Jul 03 15:54:40 2009 +0100 +++ b/web_plat/recent_url_store_api/inc/RecentUrlStore.h Thu Aug 27 07:44:59 2009 +0300 @@ -77,7 +77,7 @@ /** * Save the url and title in store. */ - IMPORT_C void SaveData (const TDesC& aUrl, const TDesC& aTitle); + IMPORT_C void SaveDataL (const TDesC& aUrl, const TDesC& aTitle); /** * Clear the saved data diff -r 10e98eab6f85 -r a359256acfc6 web_plat/widget_registry_api/inc/WidgetRegistryConstants.h --- a/web_plat/widget_registry_api/inc/WidgetRegistryConstants.h Fri Jul 03 15:54:40 2009 +0100 +++ b/web_plat/widget_registry_api/inc/WidgetRegistryConstants.h Thu Aug 27 07:44:59 2009 +0300 @@ -132,7 +132,13 @@ EWidgetPropertyIdCount, // must be at end of properties EWidgetPropertyIdInvalid = 1000 // must be after EWidgetPropertyIdCount }; - + +enum TWidgetBlanketPermissionState + { + EBlanketUnknown = 0, + EBlanketTrue, + EBlanketFalse + }; typedef RArray RUidArray; diff -r 10e98eab6f85 -r a359256acfc6 web_pub/browser_control_api/inc/BrCtlDefs.h --- a/web_pub/browser_control_api/inc/BrCtlDefs.h Fri Jul 03 15:54:40 2009 +0100 +++ b/web_pub/browser_control_api/inc/BrCtlDefs.h Thu Aug 27 07:44:59 2009 +0300 @@ -773,7 +773,8 @@ EWidgetIdentifier = 0, EWidgetBundleId, EWidgetBasePath, - EWidgetPublishState + EWidgetPublishState, + EWidgetNetworkState }; /** diff -r 10e98eab6f85 -r a359256acfc6 web_pub/browser_plugin_api/inc/npapi.h --- a/web_pub/browser_plugin_api/inc/npapi.h Fri Jul 03 15:54:40 2009 +0100 +++ b/web_pub/browser_plugin_api/inc/npapi.h Thu Aug 27 07:44:59 2009 +0300 @@ -48,6 +48,8 @@ #ifndef _NPAPI_H_ #define _NPAPI_H_ +#define GENERIC_CONTEXTS + #ifdef INCLUDE_JAVA #include "jri.h" /* Java Runtime Interface */ #else @@ -410,9 +412,73 @@ #endif /* XP_MACOSX */ /* Get the id of the currently connected access point */ - NPNNetworkAccess + NPNNetworkAccess, + NPNVGenericParameter } NPNVariable; +#ifdef GENERIC_CONTEXTS + +union NPN_GenericParam { + + NPN_GenericParam(int aIntValue) + :intValue(aIntValue) + { + + } + + NPN_GenericParam(bool aBoolValue) + :boolValue(aBoolValue) + { + + } + + NPN_GenericParam(const TDesC& aStrValue) + :strValue(aStrValue) + { + + } + + NPN_GenericParam(void* aVoidValue) + :voidValue(aVoidValue) + { + + } + int intValue; + bool boolValue; + const TDesC& strValue; + void* voidValue; +}; + + +typedef struct NPN_GenericElement{ + + NPN_GenericElement(const TDesC& aElementId, int aElementValue) + :genericElementId(aElementId), genericElementValue(aElementValue) + { + + } + + NPN_GenericElement(const TDesC& aElementId, bool aElementValue) + :genericElementId(aElementId), genericElementValue(aElementValue) + { + + } + + NPN_GenericElement(const TDesC& aElementId, void* aElementValue) + :genericElementId(aElementId), genericElementValue(aElementValue) + { + + } + + NPN_GenericElement(const TDesC& aElementId, const TDesC& aElementValue) + :genericElementId(aElementId), genericElementValue(aElementValue) + { + + } + const TDesC& genericElementId; + NPN_GenericParam genericElementValue; +} GenericEntry; +#endif /* * The type of a NPWindow - it specifies the type of the data structure * returned in the window field. diff -r 10e98eab6f85 -r a359256acfc6 web_pub/download_mgr_ui_api/inc/CDownloadMgrUiUserInteractions.h --- a/web_pub/download_mgr_ui_api/inc/CDownloadMgrUiUserInteractions.h Fri Jul 03 15:54:40 2009 +0100 +++ b/web_pub/download_mgr_ui_api/inc/CDownloadMgrUiUserInteractions.h Thu Aug 27 07:44:59 2009 +0300 @@ -189,6 +189,11 @@ * Schedule a postponed download for running. */ void SchedulePostponedDownloadL(); + + /** + * To Set the flag when progressive play is Launched + */ + inline void SetProgressiveDownloadLaunched( TBool aProgressiveDownloadLaunched ) {iProgressiveDownloadLaunched = aProgressiveDownloadLaunched; } public: // Functions from CDownloadMgrUiBase @@ -301,6 +306,8 @@ CAsyncEventHandlerArray* iEventHandlerArray; ///< Owned. TBool iDlgActive; + + TBool iProgressiveDownloadLaunched; private: // Friend classes diff -r 10e98eab6f85 -r a359256acfc6 web_pub/settings_api/inc/BrowserUiSDKCRKeys.h --- a/web_pub/settings_api/inc/BrowserUiSDKCRKeys.h Fri Jul 03 15:54:40 2009 +0100 +++ b/web_pub/settings_api/inc/BrowserUiSDKCRKeys.h Thu Aug 27 07:44:59 2009 +0300 @@ -130,6 +130,25 @@ // Valid values: 0 = off 1 = on const TUint32 KBrowserNGPageOverview = 0x0000002E; +// Valid values for KBrowserNGHomepageType +enum TBrowserCenRepHomePageTypeValue +{ + EBrowserCenRepAccessPoint = 0, // AccessPoint + EBrowserCenRepUserDefinedHomePage = 1, // User defined home page address + EBrowserCenRepCurrentURL = 2, // Current URL + EBrowserCenRepBookmarks = 3 // Bookmarks +}; + +// Integer type value to indicate what type of Home Page +// should be launched when "Home" option is activated. +// Valid values: +// AccessPoint = 0, +// User defined home page address = 1, +// Current URL = 2, +// Bookmarks = 3 +// Enums for these valid values are as defined in TBrowserCenRepHomePageTypeValue +const TUint32 KBrowserNGHomepageType = 0x00000031; + // Mime types for HTTP accept header. // Any String value const TUint32 KBrowserNGMimeTypes = 0x00000032; diff -r 10e98eab6f85 -r a359256acfc6 webengine/device/inc/Device.h --- a/webengine/device/inc/Device.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/device/inc/Device.h Thu Aug 27 07:44:59 2009 +0300 @@ -35,10 +35,42 @@ class MDeviceBinding; class ServiceObject; - class DevicePrivate; + class Device; + + class DevicePrivateBase + { + public: + DevicePrivateBase(); + virtual ~DevicePrivateBase(); + void AddChild( DevicePrivateBase* aValue ); + void RemoveChild( DevicePrivateBase* aValue ); + void SetParent( DevicePrivateBase* aValue ); + private: + TBool m_isDeleting; + DevicePrivateBase* m_parent; + RPointerArray* m_children; + }; + + class DevicePrivate : public DevicePrivateBase + { + friend class Device; + friend class DeviceFunc; + public: + DevicePrivate(Device* jsobj); + ~DevicePrivate(); + void SetUid( const TUint& aValue); + + private: + MDeviceBinding* m_deviceBinding; // Owned + Identifier m_propName; + ExecState* m_exec; // not owned + Device* m_jsobj; // not owned + }; + class Device: public JSObject { + friend class DevicePrivate; friend class DeviceFunc; public: // constructor and destructor @@ -92,8 +124,15 @@ * @return boolean * @since 5.0 */ - const bool valid() const { return m_valid; } + const TBool valid() const { return m_valid; } + /** + * getServiceData + * @return DevicePrivateBase* + * @since 7.x + */ + DevicePrivateBase* getDeviceData() { return m_privateData; } + static const ClassInfo info; /** @@ -118,28 +157,12 @@ * @since 5.0 **/ void SetUid( const TUint& aValue); + + MDeviceBinding* GetDeviceBinding(); private: DevicePrivate* m_privateData; // private object to hold data - bool m_valid; // object is valid or not - }; - - class DevicePrivate - { - friend class Device; - friend class DeviceFunc; - public: - DevicePrivate(); - ~DevicePrivate() { Close(); } - void Close(); - void SetUid( const TUint& aValue); - - private: - MDeviceBinding* m_deviceBinding; // Owned - Identifier m_propName; - RPointerArray* m_serviceObjArray; // owned - ExecState* m_exec; // not owned - + TBool m_valid; // object is valid or not }; class DeviceFunc : public JSObject diff -r 10e98eab6f85 -r a359256acfc6 webengine/device/inc/DeviceBinding.h --- a/webengine/device/inc/DeviceBinding.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/device/inc/DeviceBinding.h Thu Aug 27 07:44:59 2009 +0300 @@ -23,6 +23,8 @@ #include #include +class CRTSecMgrScriptSession; + namespace KJS { class ServiceEventHandler; @@ -53,6 +55,7 @@ const Identifier& prop ) = 0; virtual JSValue* ListProviders( ExecState* exec, const List& args ) = 0; virtual void SetUid ( const TUint& aValue) = 0; + virtual CRTSecMgrScriptSession* GetSecuritySession () = 0; }; } diff -r 10e98eab6f85 -r a359256acfc6 webengine/device/inc/DeviceBridge.h --- a/webengine/device/inc/DeviceBridge.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/device/inc/DeviceBridge.h Thu Aug 27 07:44:59 2009 +0300 @@ -50,6 +50,7 @@ inline virtual ~MDeviceBridge() {}; inline virtual void SetUid( const TUint& aValue) = 0; virtual void Clear() = 0; + inline virtual void* GetSecuritySession() = 0; }; /** @@ -96,6 +97,8 @@ */ void SetUid( const TUint& aValue); void Clear(); + + void* GetSecuritySession(); private: diff -r 10e98eab6f85 -r a359256acfc6 webengine/device/inc/DeviceLiwBinding.h --- a/webengine/device/inc/DeviceLiwBinding.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/device/inc/DeviceLiwBinding.h Thu Aug 27 07:44:59 2009 +0300 @@ -99,7 +99,7 @@ * @since 5.0 **/ JSValue* LiwGenericParamList2JsArray( ExecState* exec, - CLiwGenericParamList* liwList ); + CLiwGenericParamList* liwList, TBool managed = EFalse ); /** * Convert Unload service provider @@ -114,6 +114,11 @@ * @since 5.0 **/ void SetUid( const TUint& aValue); + + CRTSecMgrScriptSession* GetSecuritySession () + { + return m_scriptSession; + } private: @@ -160,7 +165,14 @@ **/ TBool JsVal2LiwVariant( ExecState* exec, JSValue* value, TLiwVariant& variant ); - +#ifdef SECURITYMANAGER_PROMPT_ENHANCEMENT + /** + * Set Widget Display Name + * @return none + * @since 5.0 + **/ + void SetAppName(); +#endif private: CLiwServiceHandler* m_serviceHandler; // Owned diff -r 10e98eab6f85 -r a359256acfc6 webengine/device/inc/DeviceLiwInterface.h --- a/webengine/device/inc/DeviceLiwInterface.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/device/inc/DeviceLiwInterface.h Thu Aug 27 07:44:59 2009 +0300 @@ -20,18 +20,34 @@ #define _KJS_LIWIINTERFACE_H_ #include +#include "Device.h" namespace KJS { class MDeviceBinding; class MDevicePeer; class ServiceEventHandler; - class DeviceLiwInterfacePrivate; + class DeviceLiwInterface; class DeviceLiwResult; + + class DeviceLiwInterfacePrivate : public DevicePrivateBase + { + friend class DeviceLiwInterface; + friend class DeviceLiwInterfaceFunc; + public: + DeviceLiwInterfacePrivate(DeviceLiwInterface* jsobj, MDeviceBinding* deviceBinding, MDevicePeer* devicePeer); + ~DeviceLiwInterfacePrivate(); + MDeviceBinding* m_deviceBinding; // not owned + MDevicePeer* m_devicePeer; // owned + Identifier m_interfaceName; + ExecState* m_exec; // not owned + DeviceLiwInterface* m_jsobj; // not owned + }; class DeviceLiwInterface : public JSObject { - friend class DeviceLiwInterfaceFunc; + friend class DeviceLiwInterfacePrivate; + friend class DeviceLiwInterfaceFunc; public: // constructor and destructor /** @@ -82,14 +98,20 @@ /** * Close **/ - void Close(ExecState* exec); + void Close(); /** * isValid */ - bool isValid() const { return m_valid; } + TBool isValid() const { return m_valid; } - + /** + * getInterfaceData + * @return DevicePrivateBase* + * @since 7.x + */ + DevicePrivateBase* getInterfaceData() { return m_privateData; } + /** * IsRunningCallBack */ @@ -106,26 +128,10 @@ private: DeviceLiwInterfacePrivate* m_privateData; // private object to hold data - bool m_valid; // object is valid or not + TBool m_valid; // object is valid or not }; - class DeviceLiwInterfacePrivate - { - friend class DeviceLiwInterface; - friend class DeviceLiwInterfaceFunc; - public: - DeviceLiwInterfacePrivate(MDeviceBinding* deviceBinding, MDevicePeer* devicePeer); - ~DeviceLiwInterfacePrivate() { Close(); } - void Close(); - MDeviceBinding* m_deviceBinding; // not owned - MDevicePeer* m_devicePeer; // owned - Identifier m_interfaceName; - RPointerArray* m_resultObjArray;// owned - ExecState* m_exec; // not owned - }; - - class DeviceLiwInterfaceFunc : public JSObject { public: // constructor and destructor diff -r 10e98eab6f85 -r a359256acfc6 webengine/device/inc/DeviceLiwIterable.h --- a/webengine/device/inc/DeviceLiwIterable.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/device/inc/DeviceLiwIterable.h Thu Aug 27 07:44:59 2009 +0300 @@ -21,6 +21,7 @@ // INCLUDES #include +#include "Device.h" /** * DeviceLiwIterable @@ -31,9 +32,25 @@ namespace KJS { class CDeviceLiwBinding; - class DeviceLiwIterablePrivate; + class DeviceLiwIterable; + + class DeviceLiwIterablePrivate : public DevicePrivateBase + { + friend class DeviceLiwIterable; + friend class DeviceLiwIterableFunc; + public: + DeviceLiwIterablePrivate(DeviceLiwIterable* jsobj, const CLiwIterable* m_iterable, CDeviceLiwBinding* liwBinding); + ~DeviceLiwIterablePrivate(); + CDeviceLiwBinding* m_liwBinding; // not Owned + Identifier m_propName; + CLiwIterable* m_iterable; // not owned + ExecState* m_exec; // not owned + DeviceLiwIterable* m_jsobj; // not owned + }; + class DeviceLiwIterable : public JSObject { + friend class DeviceLiwIterablePrivate; friend class DeviceLiwIterableFunc; public: // constructor and destructor @@ -81,14 +98,21 @@ * @return boolean * @since 5.0 */ - const bool isValid() const { return m_valid; } + const TBool isValid() const { return m_valid; } /** + * getIterableData + * @return DevicePrivateBase* + * @since 7.x + */ + DevicePrivateBase* getIterableData() { return m_privateData; } + + /** * close jsobject array * @return * @since 5.0 **/ - void Close(ExecState* exec , bool unmark); + void Close(); static const ClassInfo info; @@ -109,22 +133,7 @@ private: DeviceLiwIterablePrivate* m_privateData; // private object to hold data - bool m_valid; // object is valid or not - }; - - class DeviceLiwIterablePrivate - { - friend class DeviceLiwIterable; - friend class DeviceLiwIterableFunc; - public: - DeviceLiwIterablePrivate(const CLiwIterable* m_iterable, CDeviceLiwBinding* liwBinding); - ~DeviceLiwIterablePrivate() { Close(); } - void Close(); - CDeviceLiwBinding* m_liwBinding; // not Owned - Identifier m_propName; - CLiwIterable* m_iterable; // not owned - ExecState* m_exec; // not owned - RPointerArray* m_jsobjArray; // owned + TBool m_valid; // object is valid or not }; class DeviceLiwIterableFunc : public JSObject diff -r 10e98eab6f85 -r a359256acfc6 webengine/device/inc/DeviceLiwMap.h --- a/webengine/device/inc/DeviceLiwMap.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/device/inc/DeviceLiwMap.h Thu Aug 27 07:44:59 2009 +0300 @@ -21,6 +21,7 @@ // INCLUDES #include +#include "Device.h" /** * Device @@ -33,10 +34,24 @@ namespace KJS { class CDeviceLiwBinding; - class DeviceLiwMapPrivate; + class DeviceLiwMap; + + class DeviceLiwMapPrivate : public DevicePrivateBase + { + friend class DeviceLiwMap; + friend class DeviceLiwMapFunc; + public: + DeviceLiwMapPrivate(DeviceLiwMap* jsobj, const CLiwMap* liwMap, CDeviceLiwBinding* liwBinding); + ~DeviceLiwMapPrivate(); + CDeviceLiwBinding* m_liwBinding; // not Owned + Identifier m_propName; + CLiwMap* m_liwMap; // not owned + DeviceLiwMap* m_jsobj; // not owned + }; + class DeviceLiwMap: public JSObject { - + friend class DeviceLiwMapPrivate; public: // constructor and destructor /** @@ -82,14 +97,21 @@ * @return boolean * @since 5.0 */ - const bool isValid() const { return m_valid; } - + const TBool isValid() const { return m_valid; } + + /** + * getMapData + * @return DevicePrivateBase* + * @since 7.x + */ + DevicePrivateBase* getMapData() { return m_privateData; } + /** * close jsobject array * @return * @since 5.0 **/ - void Close(ExecState* exec, bool unmark ); + void Close(); /** * toString @@ -107,22 +129,9 @@ private: DeviceLiwMapPrivate* m_privateData; // private object to hold data - bool m_valid; // object is valid or not + TBool m_valid; // object is valid or not }; - class DeviceLiwMapPrivate - { - friend class DeviceLiwMap; - friend class DeviceLiwMapFunc; - public: - DeviceLiwMapPrivate(const CLiwMap* liwMap, CDeviceLiwBinding* liwBinding); - ~DeviceLiwMapPrivate() { Close(); } - void Close(); - CDeviceLiwBinding* m_liwBinding; // not Owned - Identifier m_propName; - CLiwMap* m_liwMap; // not owned - }; - class DeviceLiwMapFunc : public JSObject { public: // constructor and destructor diff -r 10e98eab6f85 -r a359256acfc6 webengine/device/inc/DeviceLiwResult.h --- a/webengine/device/inc/DeviceLiwResult.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/device/inc/DeviceLiwResult.h Thu Aug 27 07:44:59 2009 +0300 @@ -21,6 +21,7 @@ // INCLUDES #include +#include "Device.h" /** * Device @@ -32,10 +33,22 @@ namespace KJS { - class DeviceLiwResultPrivate; + class DeviceLiwResult; + + class DeviceLiwResultPrivate : public DevicePrivateBase + { + friend class DeviceLiwResult; + friend class DeviceLiwResultFunc; + public: + DeviceLiwResultPrivate(DeviceLiwResult* jsobj); + ~DeviceLiwResultPrivate(); + Identifier m_propName; + DeviceLiwResult* m_jsobj; // not owned + }; + class DeviceLiwResult: public JSObject { - + friend class DeviceLiwResultPrivate; public: // constructor and destructor /** @@ -81,21 +94,21 @@ * @return boolean * @since 5.0 */ - const bool isValid() const { return m_valid; } + const TBool isValid() const { return m_valid; } + + /** + * getResultData + * @return DevicePrivateBase* + * @since 7.x + */ + DevicePrivateBase* getResultData() { return m_privateData; } /** * close jsobject array * @return * @since 5.0 **/ - void Close(ExecState* exec, bool unmark ); - - /** - * close jsobject array - * @return - * @since 5.0 - **/ - void quickClose(); + void Close(); static const ClassInfo info; @@ -115,21 +128,10 @@ private: DeviceLiwResultPrivate* m_privateData; // private object to hold data - bool m_valid; // bject is valid or not + TBool m_valid; // bject is valid or not }; - - class DeviceLiwResultPrivate - { - friend class DeviceLiwResult; - friend class DeviceLiwResultFunc; - public: - DeviceLiwResultPrivate(); - ~DeviceLiwResultPrivate() { Close(); } - void Close(); - Identifier m_propName; - }; class DeviceLiwResultFunc : public JSObject { diff -r 10e98eab6f85 -r a359256acfc6 webengine/device/inc/ServiceObject.h --- a/webengine/device/inc/ServiceObject.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/device/inc/ServiceObject.h Thu Aug 27 07:44:59 2009 +0300 @@ -35,10 +35,24 @@ class ServiceEventHandler; class MDeviceBinding; class ServiceObjectFunc; - class ServiceObjectPrivate; + class ServiceObject; + class ServiceObjectPrivate : public DevicePrivateBase + { + friend class ServiceObject; + friend class ServiceObjectFunc; + public: + ServiceObjectPrivate(ServiceObject* jsobj, HBufC8* svcName, MDeviceBinding* deviceBinding ); + ~ServiceObjectPrivate(); + MDeviceBinding* m_deviceBinding; // Not owned + Identifier m_propName; + HBufC8* m_svcName; // owned + ServiceObject* m_jsobj; + }; + class ServiceObject : public JSObject { + friend class ServiceObjectPrivate; friend class ServiceObjectFunc; public: // constructor and destructor @@ -84,7 +98,14 @@ /** * isValid */ - bool isValid() const { return m_valid; } + TBool isValid() const { return m_valid; } + + /** + * getServiceData + * @return DevicePrivateBase* + * @since 7.x + */ + DevicePrivateBase* getServiceData() { return m_privateData; } /** * Get class info @@ -103,29 +124,15 @@ virtual UString toString( ExecState* exec ) const; public: - void Close( ExecState* exec, bool unmark ); + void Close(); enum { close }; private: ServiceObjectPrivate* m_privateData; // private object to hold data - bool m_valid; // object is valid or not + TBool m_valid; // object is valid or not }; - - class ServiceObjectPrivate - { - friend class ServiceObject; - friend class ServiceObjectFunc; - public: - ServiceObjectPrivate(HBufC8* svcName, MDeviceBinding* deviceBinding ); - ~ServiceObjectPrivate() { Close(); } - void Close(); - MDeviceBinding* m_deviceBinding; // Not owned - Identifier m_propName; - HBufC8* m_svcName; // owned - bool isClosing; - }; class ServiceObjectFunc : public JSObject { diff -r 10e98eab6f85 -r a359256acfc6 webengine/device/src/Device.cpp --- a/webengine/device/src/Device.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/device/src/Device.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -29,7 +29,7 @@ using namespace KJS; const ClassInfo Device::info = { "Device", 0, 0, 0 }; -const TInt INIT_SO_ARRAY_SIZE = 10; // initial service object array +const TInt INIT_ARRAY_SIZE = 10; // initial service object array // ============================= LOCAL FUNCTIONS =============================== /* @@ -49,11 +49,11 @@ Device::Device( ExecState* exec ) : JSObject() { - m_privateData = new DevicePrivate(); + m_privateData = new DevicePrivate(this); if (!m_privateData || !m_privateData->m_deviceBinding ) - m_valid = false; + m_valid = EFalse; else - m_valid = true; + m_valid = ETrue; } @@ -75,6 +75,10 @@ // void Device::Close() { + if ( !m_valid ) + return; + + m_valid = EFalse; delete m_privateData; m_privateData = NULL; } @@ -107,6 +111,9 @@ // ---------------------------------------------------------------------------- bool Device::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { + if ( !m_valid ) + return false; + m_privateData->m_exec = exec; m_privateData->m_propName = propertyName; const HashEntry* entry = Lookup::findEntry(&DeviceTable, propertyName); @@ -127,6 +134,9 @@ // ---------------------------------------------------------------------------- JSValue* Device::getValueProperty(ExecState *exec, int token) const { + if ( !m_valid ) + return jsUndefined(); + switch( token ) { case getServiceObject: @@ -139,35 +149,96 @@ } // --------------------------------------------------------------------------- +// DevicePrivateBase constructor +// +// --------------------------------------------------------------------------- +DevicePrivateBase::DevicePrivateBase() + { + m_parent = NULL; + m_isDeleting = EFalse; + TRAP_IGNORE( + m_children = new RPointerArray( INIT_ARRAY_SIZE );) + } + +// --------------------------------------------------------------------------- +// DevicePrivateBase destructor +// +// --------------------------------------------------------------------------- +DevicePrivateBase::~DevicePrivateBase() + { + m_isDeleting = ETrue; + // 1. remove self from the parent + if ( m_parent ) + { + m_parent->RemoveChild(this); + } + + // 2. delete all the children + for ( int i = 0; i < m_children->Count(); i++ ) + { + delete (*m_children)[i]; + } + + // 3. delete array + m_children->Close(); + delete m_children; + } + +// --------------------------------------------------------------------------- +// DevicePrivateBase setParent +// +// --------------------------------------------------------------------------- +void DevicePrivateBase::SetParent( DevicePrivateBase* aValue ) + { + m_parent = aValue; + } + +// --------------------------------------------------------------------------- +// DevicePrivateBase add child into list +// +// --------------------------------------------------------------------------- +void DevicePrivateBase::AddChild( DevicePrivateBase* aValue ) + { + m_children->Append( aValue ); + } + +// --------------------------------------------------------------------------- +// DevicePrivateBase add child into list +// +// --------------------------------------------------------------------------- +void DevicePrivateBase::RemoveChild( DevicePrivateBase* aValue ) + { + if ( m_isDeleting ) + return; + + TInt index = m_children->Find( aValue ); + if ( index != KErrNotFound ) + m_children->Remove( index ); + } + +// --------------------------------------------------------------------------- // DevicePrivate constructor // // --------------------------------------------------------------------------- -DevicePrivate::DevicePrivate() +DevicePrivate::DevicePrivate( Device* jsobj ) { - m_deviceBinding = NULL; + m_deviceBinding = NULL; TRAP_IGNORE( - m_serviceObjArray = new RPointerArray( INIT_SO_ARRAY_SIZE ); m_deviceBinding = CDeviceLiwBinding::NewL(); + m_jsobj = jsobj; m_exec = NULL;) } // --------------------------------------------------------------------------- -// DevicePrivate Close +// DevicePrivate destructor // // --------------------------------------------------------------------------- -void DevicePrivate::Close() +DevicePrivate::~DevicePrivate() { - if ( m_serviceObjArray ) - { - // close all the service objects created for this device - for (int i = 0; i < m_serviceObjArray->Count(); i++) - { - (*m_serviceObjArray)[i]->Close( m_exec, true ); - } - m_serviceObjArray->Close(); - delete m_serviceObjArray; - m_serviceObjArray = NULL; - } + // invalid the Device + if (m_jsobj) + m_jsobj->m_valid = EFalse; + delete m_deviceBinding; m_deviceBinding = NULL; } @@ -249,7 +320,10 @@ ServiceObject *so = new ServiceObject( exec, svcName, m_deviceBinding ); if ( so != NULL ) { - (static_cast(thisObj))->m_privateData->m_serviceObjArray->Append( so ); + DevicePrivateBase* devData = (static_cast(thisObj))->getDeviceData(); + DevicePrivateBase* soData = so->getServiceData(); + soData->SetParent( devData ); + devData->AddChild( soData ); ret = so; } } @@ -262,6 +336,11 @@ return ret; } +MDeviceBinding* Device::GetDeviceBinding() +{ + return m_privateData->m_deviceBinding; +} + //END OF FILE diff -r 10e98eab6f85 -r a359256acfc6 webengine/device/src/DeviceBridge.cpp --- a/webengine/device/src/DeviceBridge.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/device/src/DeviceBridge.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -21,6 +21,7 @@ #include #include "Device.h" #include "DeviceBridge.h" +#include "DeviceBinding.h" using namespace KJS; // ============================ LOCAL FUNCTIONS =============================== @@ -106,6 +107,20 @@ if(m_device) m_device->SetUid( aValue); } + + +void* TDeviceBridge::GetSecuritySession() + { + if( m_device && (m_device->GetDeviceBinding())) + { + return static_cast(m_device->GetDeviceBinding()->GetSecuritySession()); + } + else + { + return NULL; + } + } + //END OF FILE diff -r 10e98eab6f85 -r a359256acfc6 webengine/device/src/DeviceLiwBinding.cpp --- a/webengine/device/src/DeviceLiwBinding.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/device/src/DeviceLiwBinding.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -109,7 +109,7 @@ // we need to keep main session allive, to keep sub session m_secMgr = CRTSecManager::NewL(); - + CTrustInfo* trust = CTrustInfo::NewLC(); // TODO: in future, to support blanket permission, @@ -123,10 +123,12 @@ { User::Leave( KErrGeneral ); } +#ifdef SECURITYMANAGER_PROMPT_ENHANCEMENT + m_scriptSession->SetPromptOption(RTPROMPTUI_PROVIDER); // This is for setting the new prompting method +#endif CleanupStack::PopAndDestroy( trust ); } - // ---------------------------------------------------------------------------- // CDeviceLiwBinding::~CDeviceLiwBinding // Default destructor @@ -141,7 +143,7 @@ delete m_critArr; delete m_serviceHandler; delete m_scriptSession; - delete m_secMgr; + delete m_secMgr; } @@ -188,7 +190,7 @@ item->SetServiceClass( TUid::Uid( KLiwClassBase ) ); RCriteriaArray crit_arr; crit_arr.AppendL( item ); - + CleanupStack::Pop(item); // item // "Attach" runtime to service @@ -214,14 +216,14 @@ case SAPIPROMPTLESS : load_err = m_serviceHandler->AttachL( crit_arr ); break; - case SAPIACCESSDENIED : + case SAPIACCESSDENIED : load_err = KLiwSecurityAccessCheckFailed; break; default : load_err = KLiwSecurityAccessCheckFailed; break; } - + User::LeaveIfError(widgetregistry.Disconnect()); CleanupStack::PopAndDestroy(); //widgetregistry // hard coded for now since the definition of TLiwLoadStatus is not exposed to common dir yet @@ -230,7 +232,7 @@ error = KErrNone; // normalize the error m_critArr->AppendL( item ); } - else + else { error = load_err; // pass on the TLiwLoadStatus delete item; @@ -481,7 +483,7 @@ callBack ); User::UnMarkCleanupStack(____t); inps->Reset(); - rval = LiwGenericParamList2JsArray( exec, outps ); + rval = LiwGenericParamList2JsArray( exec, outps, ETrue ); outps->Reset(); CleanupStack::PopAndDestroy( oper ); // map CleanupStack::Pop();// outps @@ -901,7 +903,9 @@ jsList.append( jsNumber( variant.AsMap()->Count() ) ); JSObject * rval = new DeviceLiwMap(exec->lexicalInterpreter()->builtinArray()->construct( exec, jsList ), variant.AsMap(), this); - + + DevicePrivateBase* pMapData = (static_cast (rval))->getMapData(); + for ( TInt i = 0; i < variant.AsMap()->Count(); i++ ) { TBuf8 name; @@ -910,9 +914,24 @@ if ( variant.AsMap()->AtL( i, name ) ) { variant.AsMap()->FindL( name, v ); + JSValue* jsval = LiwVariant2JsVal( exec, v ); rval->put( exec, - Identifier( ( const char* ) name.PtrZ() ), - LiwVariant2JsVal( exec, v ) ); + Identifier( ( const char* ) name.PtrZ() ), + jsval ); + if ( v.TypeId() == EVariantTypeIterable ) + { + DeviceLiwIterable* itObj = static_cast (jsval); + DevicePrivateBase* itData = itObj->getIterableData(); + itData->SetParent( pMapData ); + pMapData->AddChild( itData ); + } + else if ( v.TypeId() == EVariantTypeMap ) + { + DeviceLiwMap* mapObj = static_cast (jsval); + DevicePrivateBase* mapData = mapObj->getMapData(); + mapData->SetParent( pMapData ); + pMapData->AddChild( mapData ); + } } }); // No error processing @@ -1051,7 +1070,7 @@ // JSValue* CDeviceLiwBinding::LiwGenericParamList2JsArray( ExecState* exec, - CLiwGenericParamList* aLiwList ) + CLiwGenericParamList* aLiwList, TBool managed ) { // the output param list should not be empty, if it is, return an undefined js obj. if ( aLiwList->Count() == 0 ) @@ -1064,11 +1083,31 @@ JSObject * rval = new DeviceLiwResult(exec->lexicalInterpreter()->builtinArray()->construct( exec, jsList )); + DevicePrivateBase* retData =(static_cast (rval))->getResultData(); + for ( TInt i = 0; i < aLiwList->Count(); i++ ) { TBuf8 name( (*aLiwList)[i].Name() ); - rval->put( exec, Identifier( (const char*) name.PtrZ() ), - LiwVariant2JsVal( exec, (*aLiwList)[i].Value() ) ); //??? should call AtL? + JSValue* jsval = LiwVariant2JsVal( exec, (*aLiwList)[i].Value() ); + // connect DeviceLiwResult to DeviceLiwIterable + if ( managed ) + { + if ( (*aLiwList)[i].Value().TypeId() == EVariantTypeIterable ) + { + DeviceLiwIterable* itObj = static_cast (jsval); + DevicePrivateBase* itData = itObj->getIterableData(); + itData->SetParent( retData ); + retData->AddChild( itData ); + } + else if ( (*aLiwList)[i].Value().TypeId() == EVariantTypeMap ) + { + DeviceLiwMap* mapObj = static_cast (jsval); + DevicePrivateBase* mapData = mapObj->getMapData(); + mapData->SetParent( retData ); + retData->AddChild( mapData ); + } + } + rval->put( exec, Identifier( (const char*) name.PtrZ() ), jsval); //??? should call AtL? } return rval; @@ -1084,7 +1123,42 @@ void CDeviceLiwBinding::SetUid( const TUint& aValue) { m_Uid.iUid = aValue; +#ifdef SECURITYMANAGER_PROMPT_ENHANCEMENT + SetAppName(); +#endif } +#ifdef SECURITYMANAGER_PROMPT_ENHANCEMENT +// ---------------------------------------------------------------------------- +// CDeviceLiwBinding::SetAppName +// Sets the widget display name +// +// ---------------------------------------------------------------------------- +// +void CDeviceLiwBinding::SetAppName() + { + RWidgetRegistryClientSession widgetregistry; + TRAP_IGNORE( + TInt ret = widgetregistry.Connect(); + if ( ret == KErrNone || ret == KErrAlreadyExists ) + { + CleanupClosePushL( widgetregistry ); + } + else + { + User::Leave( ret ); + } + + CWidgetPropertyValue* displayname = widgetregistry.GetWidgetPropertyValueL(m_Uid, EBundleDisplayName ); + User::LeaveIfError(widgetregistry.Disconnect()); + CleanupStack::PopAndDestroy(); //widgetregistry + + if ( displayname && displayname->iType == EWidgetPropTypeString ) + { + m_scriptSession->SetApplicationNameL(*displayname); + } + ); + } +#endif // ---------------------------------------------------------------------------- // KJS::GetAsciiBufferL diff -r 10e98eab6f85 -r a359256acfc6 webengine/device/src/DeviceLiwInterface.cpp --- a/webengine/device/src/DeviceLiwInterface.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/device/src/DeviceLiwInterface.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -30,7 +30,6 @@ using namespace KJS; const ClassInfo DeviceLiwInterface::info = { "DeviceLiwInterface", 0, 0, 0 }; -const TInt INIT_RST_ARRAY_SIZE = 10; // initial result object array // ============================= LOCAL FUNCTIONS =============================== /* @@ -52,11 +51,14 @@ MDevicePeer* devicePeer ) : JSObject( exec->lexicalInterpreter()->builtinObjectPrototype() ) { - m_privateData = new DeviceLiwInterfacePrivate(deviceBinding, devicePeer); - if (!m_privateData || !m_privateData->m_devicePeer ) - m_valid = false; - else - m_valid = true; + m_valid = EFalse; + m_privateData = NULL; + if ( deviceBinding && devicePeer) + { + m_privateData = new DeviceLiwInterfacePrivate(this, deviceBinding, devicePeer); + if ( m_privateData ) + m_valid = ETrue; + } } // ---------------------------------------------------------------------------- @@ -66,7 +68,7 @@ // DeviceLiwInterface::~DeviceLiwInterface() { - delete m_privateData; + Close(); } // ---------------------------------------------------------------------------- @@ -74,16 +76,14 @@ // // ---------------------------------------------------------------------------- // -void DeviceLiwInterface::Close(ExecState* exec) +void DeviceLiwInterface::Close() { if(!m_valid) return; - // need exec to close other jsobject - m_privateData->m_exec = exec; + m_valid = EFalse; delete m_privateData; m_privateData = NULL; - m_valid = false; } // ---------------------------------------------------------------------------- @@ -211,37 +211,26 @@ // DeviceLiwInterfacePrivate constructor // // --------------------------------------------------------------------------- -DeviceLiwInterfacePrivate::DeviceLiwInterfacePrivate(MDeviceBinding* deviceBinding, MDevicePeer* devicePeer) +DeviceLiwInterfacePrivate::DeviceLiwInterfacePrivate(DeviceLiwInterface* jsobj, MDeviceBinding* deviceBinding, MDevicePeer* devicePeer) { TRAP_IGNORE( - m_resultObjArray = new RPointerArray( INIT_RST_ARRAY_SIZE ); m_deviceBinding = deviceBinding; m_devicePeer = devicePeer; m_exec = NULL; + m_jsobj = jsobj; ) } // --------------------------------------------------------------------------- -// DevicePrivate Close +// DevicePrivate destructor // // --------------------------------------------------------------------------- -void DeviceLiwInterfacePrivate::Close() - { - if ( m_resultObjArray && m_exec) - { - // close all the result objects created for this device - for (int i = 0; i < m_resultObjArray->Count(); i++) - { - (*m_resultObjArray)[i]->Close( m_exec, true ); - } - m_resultObjArray->Close(); - delete m_resultObjArray; - m_resultObjArray = NULL; - } - - m_deviceBinding = NULL; - m_exec = NULL; - +DeviceLiwInterfacePrivate:: ~DeviceLiwInterfacePrivate() + { + // invalid the DeviceLiwInterface + if (m_jsobj) + m_jsobj->m_valid = EFalse; + delete m_devicePeer; m_devicePeer = NULL; } @@ -304,7 +293,7 @@ { return throwError(exec, GeneralError, "Can not close interface object in callback function."); } - sapiif->Close(exec); + sapiif->Close(); return ret; } @@ -313,7 +302,10 @@ if(ret->isObject() && (static_cast (ret))->inherits( &KJS::DeviceLiwResult::info )) { // insert into jsobject array - sapiif->m_privateData->m_resultObjArray->Append(static_cast (ret)); + DevicePrivateBase* ifData = sapiif->getInterfaceData(); + DevicePrivateBase* retData =(static_cast (ret))->getResultData(); + retData->SetParent( ifData ); + ifData->AddChild( retData ); if ( aArgs.size() > 1 ) { bool ok; diff -r 10e98eab6f85 -r a359256acfc6 webengine/device/src/DeviceLiwIterable.cpp --- a/webengine/device/src/DeviceLiwIterable.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/device/src/DeviceLiwIterable.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -28,7 +28,6 @@ using namespace KJS; const ClassInfo DeviceLiwIterable::info = { "DeviceLiwIterable", 0, 0, 0 }; -const TInt INIT_JSOBJ_ARRAY_SIZE = 10; // initial jsobject array // ============================= LOCAL FUNCTIONS =============================== /* @begin DeviceLiwIterableTable 1 @@ -60,14 +59,14 @@ CLiwIterable* variant) : JSObject(exec->lexicalInterpreter()->builtinObjectPrototype() ) { - m_privateData = new DeviceLiwIterablePrivate(variant, binding); - if (!m_privateData || !m_privateData->m_jsobjArray ) - m_valid = false; - else - { - m_valid = true; - KJS::Collector::protect(this); - } + m_valid = EFalse; + m_privateData = NULL; + if ( binding && variant ) + { + m_privateData = new DeviceLiwIterablePrivate(this, variant, binding); + if ( m_privateData ) + m_valid = ETrue; + } } // ---------------------------------------------------------------------------- @@ -77,8 +76,7 @@ // DeviceLiwIterable::~DeviceLiwIterable() { - // only can be called by garbage collection after the - // DeviceLiwIterable::Close() was called + Close(); } // ---------------------------------------------------------------------------- @@ -86,30 +84,14 @@ // // ---------------------------------------------------------------------------- // -void DeviceLiwIterable::Close(ExecState* exec, bool unmark) +void DeviceLiwIterable::Close() { - // avoid double close - if(!m_valid) - { - if(unmark) - { - // unprotect this to allow the garbage collection to release this jsobject - KJS::Collector::unprotect(this); - } + if ( !m_valid ) return; - } - - // need exec to close other jsobject - m_privateData->m_exec = exec; + + m_valid = EFalse; delete m_privateData; m_privateData = NULL; - m_valid = false; - - if(unmark) - { - // unprotect this to allow the garbage collection to release this jsobject - KJS::Collector::unprotect(this); - } } // ---------------------------------------------------------------------------- @@ -216,13 +198,13 @@ // DeviceLiwIterablePrivate constructor // // --------------------------------------------------------------------------- -DeviceLiwIterablePrivate::DeviceLiwIterablePrivate(const CLiwIterable* liwIterable, CDeviceLiwBinding* liwBinding) +DeviceLiwIterablePrivate::DeviceLiwIterablePrivate(DeviceLiwIterable* jsobj, const CLiwIterable* liwIterable, CDeviceLiwBinding* liwBinding) { TRAP_IGNORE( m_liwBinding = liwBinding; - m_jsobjArray = new RPointerArray( INIT_JSOBJ_ARRAY_SIZE ); m_exec = NULL; m_iterable = (CLiwIterable*) liwIterable; + m_jsobj = jsobj; if ( m_iterable ) m_iterable->IncRef(); ) @@ -232,29 +214,11 @@ // DeviceLiwMapPrivate::Close // // --------------------------------------------------------------------------- -void DeviceLiwIterablePrivate::Close() +DeviceLiwIterablePrivate::~DeviceLiwIterablePrivate() { - // close the jsobject - if ( m_jsobjArray && m_exec ) - { - // close all the DeviceLiwMap objects and DeviceLiwIterable objects - for (int i = 0; i < m_jsobjArray->Count(); i++) - { - JSObject * jsobj = (*m_jsobjArray)[i]; - if (jsobj->inherits( &DeviceLiwIterable::info )) - { - (static_cast(jsobj))->Close(m_exec, true); - } - else if (jsobj->inherits( &DeviceLiwMap::info )) - { - (static_cast(jsobj))->Close(m_exec, true); - } - } - m_jsobjArray->Close(); - delete m_jsobjArray; - m_jsobjArray = NULL; - m_exec = NULL; - } + // invalid the DeviceLiwIterable + if (m_jsobj) + m_jsobj->m_valid = EFalse; // release the map if ( m_iterable ) @@ -323,13 +287,19 @@ if(rval->isObject()) { JSObject* obj = static_cast (rval); - if(obj->inherits( &KJS::DeviceLiwIterable::info ) || obj->inherits( &KJS::DeviceLiwMap::info )) + DevicePrivateBase* thisData = it->getIterableData(); + DevicePrivateBase* childData = NULL; + if ( obj->inherits( &KJS::DeviceLiwIterable::info ) ) + childData = (static_cast (obj))->getIterableData(); + else if ( obj->inherits( &KJS::DeviceLiwMap::info ) ) + childData = (static_cast (obj))->getMapData(); + + if ( childData ) { - // insert into jsobject array - it->m_privateData->m_jsobjArray->Append(obj); + childData->SetParent( thisData ); + thisData->AddChild( childData ); } - } - + } vv.Reset(); } } @@ -337,7 +307,7 @@ it->m_privateData->m_iterable->Reset(); } else if ( m_func == DeviceLiwIterable::close ){ - it->Close(exec, false); + it->Close(); } return rval; } diff -r 10e98eab6f85 -r a359256acfc6 webengine/device/src/DeviceLiwMap.cpp --- a/webengine/device/src/DeviceLiwMap.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/device/src/DeviceLiwMap.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -47,19 +47,16 @@ DeviceLiwMap::DeviceLiwMap( JSValue* proto, const CLiwMap* liwMap, CDeviceLiwBinding* liwBinding) : JSObject(proto) { - m_privateData = new DeviceLiwMapPrivate(liwMap, liwBinding); - if (!m_privateData ) - m_valid = false; - else - { - m_valid = true; - // protect this object - KJS::Collector::protect(this); - } + m_valid = EFalse; + m_privateData = NULL; + if (liwMap && liwBinding ) + { + m_privateData = new DeviceLiwMapPrivate(this, liwMap, liwBinding); + if ( m_privateData ) + m_valid = ETrue; + } } - - // ---------------------------------------------------------------------------- // DeviceLiwMap::~DeviceLiwMap // @@ -67,8 +64,7 @@ // DeviceLiwMap::~DeviceLiwMap() { - // only can be called by garbage collection after the - // DeviceLiwMap::Close() was called + Close(); } // ---------------------------------------------------------------------------- @@ -76,53 +72,14 @@ // // ---------------------------------------------------------------------------- // -void DeviceLiwMap::Close( ExecState* exec, bool unmark ) +void DeviceLiwMap::Close() { - // avoid double close - if(!m_valid) - { - if(unmark) - { - // unprotect this to allow the garbage collection to release this jsobject - KJS::Collector::unprotect(this); - } + if ( !m_valid ) return; - } - if (exec) - { - PropertyNameArray propertyNames; - this->getPropertyNames( exec, propertyNames ); - unsigned size = static_cast(propertyNames.size()); - - for (unsigned i = 0; i < size; i++) - { - JSValue * jsvalue = this->get( exec, propertyNames[i] ); - if(jsvalue->isObject()) - { - JSObject * prop = jsvalue->toObject( exec ); - - if (prop->inherits( &DeviceLiwIterable::info )) - { - (static_cast(prop))->Close(exec, true); - } - else if (prop->inherits( &DeviceLiwMap::info )) - { - (static_cast(prop))->Close(exec, true); - } - } - } - } - + m_valid = EFalse; delete m_privateData; m_privateData = NULL; - m_valid = false; - - if(unmark) - { - // unprotect this to allow the garbage collection to release this jsobject - KJS::Collector::unprotect(this); - } } // ---------------------------------------------------------------------------- @@ -253,11 +210,12 @@ // DeviceLiwMapPrivate constructor // // --------------------------------------------------------------------------- -DeviceLiwMapPrivate::DeviceLiwMapPrivate(const CLiwMap* liwMap, CDeviceLiwBinding* liwBinding) +DeviceLiwMapPrivate::DeviceLiwMapPrivate(DeviceLiwMap* jsobj, const CLiwMap* liwMap, CDeviceLiwBinding* liwBinding) { TRAP_IGNORE( m_liwBinding = liwBinding; m_liwMap = (CLiwMap*) liwMap; + m_jsobj = jsobj; if ( m_liwMap ) m_liwMap->IncRef(); ) @@ -267,10 +225,12 @@ // DeviceLiwMapPrivate::Close // // --------------------------------------------------------------------------- -void DeviceLiwMapPrivate::Close() +DeviceLiwMapPrivate::~DeviceLiwMapPrivate() { - m_liwBinding = NULL; - + // invalid the DeviceLiwMap + if (m_jsobj) + m_jsobj->m_valid = EFalse; + // release the map if ( m_liwMap ) { @@ -278,7 +238,7 @@ m_liwMap = NULL; } } - + // ---------------------------------------------------------------------------- // DeviceLiwMapFunc::DeviceLiwMapFunc // @@ -297,17 +257,18 @@ // JSValue* DeviceLiwMapFunc::callAsFunction(ExecState* exec, JSObject *thisObj, const List& aArgs ) { - if (!thisObj->inherits(&DeviceLiwMap::info)) { - return throwError(exec, GeneralError); + if (!thisObj->inherits(&DeviceLiwMap::info)) + { + return throwError(exec, GeneralError); } - DeviceLiwMap *map = static_cast(thisObj); + DeviceLiwMap *map = static_cast(thisObj); - if ( m_func == DeviceLiwMap::close ) - { - map->Close(exec, false); - } - return jsUndefined(); + if ( m_func == DeviceLiwMap::close ) + { + map->Close(); + } + return jsUndefined(); } //END OF FILE diff -r 10e98eab6f85 -r a359256acfc6 webengine/device/src/DeviceLiwPeer.cpp --- a/webengine/device/src/DeviceLiwPeer.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/device/src/DeviceLiwPeer.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -60,6 +60,8 @@ delete m_serviceName; m_callbackArray->ResetAndDestroy(); m_callbackArray->Close(); + delete m_callbackArray; + m_callbackArray = NULL; m_interface->Close(); m_interface = NULL; // in majority cases, the interface close methods delete them selves. } @@ -126,7 +128,7 @@ List params; JSLock::lock(); JSValue* vEventParams = m_binding->LiwGenericParamList2JsArray( - m_globalExecState, &eventParamList ); + m_globalExecState, &eventParamList, ETrue ); JSLock::unlock(); params.append( jsNumber( cmdId ) ); params.append( jsNumber( eventId ) ); diff -r 10e98eab6f85 -r a359256acfc6 webengine/device/src/DeviceLiwResult.cpp --- a/webengine/device/src/DeviceLiwResult.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/device/src/DeviceLiwResult.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -48,15 +48,10 @@ DeviceLiwResult::DeviceLiwResult( JSValue* proto) : JSObject(proto) { - m_privateData = new DeviceLiwResultPrivate(); - if (!m_privateData) - m_valid = false; - else - { - m_valid = true; - // protect this object - KJS::Collector::protect(this); - } + m_valid = EFalse; + m_privateData = new DeviceLiwResultPrivate(this); + if ( m_privateData ) + m_valid = ETrue; } // ---------------------------------------------------------------------------- @@ -66,75 +61,21 @@ // DeviceLiwResult::~DeviceLiwResult() { - // only can be called by garbage collection after the - // DeviceLiwResult::Close() was called + Close(); } // ---------------------------------------------------------------------------- // DeviceLiwResult::Close // // ---------------------------------------------------------------------------- -void DeviceLiwResult::Close( ExecState* exec, bool unmark ) +void DeviceLiwResult::Close() { - - // avoid double close if(!m_valid) - { - if(unmark) - { - // unprotect this to allow the garbage collection to release this jsobject - KJS::Collector::unprotect(this); - } return; - } - - // close thDeviceLiwIterable - if ( exec ) - { - PropertyNameArray propertyNames; - this->getPropertyNames( exec, propertyNames ); - unsigned size = static_cast(propertyNames.size()); - - for (unsigned i = 0; i < size; i++) - { - JSValue * jsvalue = this->get( exec, propertyNames[i] ); - if(jsvalue->isObject()) - { - JSObject * prop = jsvalue->toObject( exec ); - if (prop && prop->inherits( &DeviceLiwIterable::info )) - { - (static_cast(prop))->Close(exec, true); - } - } - } - } - + + m_valid = EFalse; delete m_privateData; m_privateData = NULL; - m_valid = false; - - if(unmark) - { - // unprotect this to allow the garbage collection to release this jsobject - KJS::Collector::unprotect(this); - } - } - -// ---------------------------------------------------------------------------- -// DeviceLiwResult::QuickClose -// -// ---------------------------------------------------------------------------- -void DeviceLiwResult::quickClose() - { - if(!m_valid) - return - - delete m_privateData; - m_privateData = NULL; - m_valid = false; - - // unprotect this to allow the garbage collection to release this jsobject - KJS::Collector::unprotect(this); } // ---------------------------------------------------------------------------- @@ -238,18 +179,20 @@ // DeviceLiwIterablePrivate constructor // // --------------------------------------------------------------------------- -DeviceLiwResultPrivate::DeviceLiwResultPrivate() +DeviceLiwResultPrivate::DeviceLiwResultPrivate(DeviceLiwResult* jsobj) { - // currently, do nothing + m_jsobj = jsobj; } // --------------------------------------------------------------------------- // DeviceLiwMapPrivate::Close // // --------------------------------------------------------------------------- -void DeviceLiwResultPrivate::Close() +DeviceLiwResultPrivate::~DeviceLiwResultPrivate() { - // currently, do nothing + // invalid the DeviceLiwResult + if (m_jsobj) + m_jsobj->m_valid = EFalse; } // ---------------------------------------------------------------------------- @@ -278,7 +221,7 @@ if ( m_func == DeviceLiwResult::close ) { - result->Close(exec, false); + result->Close(); } return jsUndefined(); } diff -r 10e98eab6f85 -r a359256acfc6 webengine/device/src/ServiceObject.cpp --- a/webengine/device/src/ServiceObject.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/device/src/ServiceObject.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -47,17 +47,14 @@ MDeviceBinding* deviceBinding) : JSObject( exec->lexicalInterpreter()->builtinObjectPrototype() ) { - m_privateData = new ServiceObjectPrivate(svcName, deviceBinding); - if (m_privateData && m_privateData->m_deviceBinding) - { - m_valid = true; - // protect this object - KJS::Collector::protect(this); - } - else - { - m_valid = false; - } + m_valid = EFalse; + m_privateData = NULL; + if ( deviceBinding ) + { + m_privateData = new ServiceObjectPrivate(this, svcName, deviceBinding); + if ( m_privateData ) + m_valid = ETrue; + } } @@ -69,59 +66,22 @@ // ---------------------------------------------------------------------------- ServiceObject::~ServiceObject() { - // only can be called by garbage collection after the - // ServiceObject::Close() was called + Close(); } // ---------------------------------------------------------------------------- // ServiceObject::Close // // ---------------------------------------------------------------------------- -void ServiceObject::Close( ExecState* exec, bool unmark ) +void ServiceObject::Close() { // avoid double close - if(!m_valid) - { - if(unmark) - { - // unprotect this to allow the garbage collection to release this jsobject - KJS::Collector::unprotect(this); - } + if ( !m_valid ) return; - } - - // set isClosing flag to true - m_privateData->isClosing = true; - - if ( exec ) - { - PropertyNameArray propertyNames; - this->getPropertyNames( exec, propertyNames ); - unsigned size = static_cast(propertyNames.size()); - for (unsigned i = 0; i < size; i++) - { - JSValue * jsvalue = this->get( exec, propertyNames[i] ); - if(jsvalue->isObject()) - { - JSObject * prop = jsvalue->toObject( exec ); - if (prop->inherits( &DeviceLiwInterface::info )) - { - (static_cast(prop))->Close(exec); - } - } - } - } - + m_valid = EFalse; delete m_privateData; - m_privateData = NULL; - m_valid = false; - - if(unmark) - { - // unprotect this to allow the garbage collection to release this jsobject - KJS::Collector::unprotect(this); - } + m_privateData = NULL; } // ---------------------------------------------------------------------------- @@ -164,13 +124,13 @@ m_privateData->m_propName = propertyName; JSValue* val = getDirect( propertyName ); - // if the property is an interface and interface is closed + // if the property is an interface which has been closed bool need_recreate = false; if ( val && val->isObject() && val->toObject(exec)->inherits( &KJS::DeviceLiwInterface::info ) ) { DeviceLiwInterface* interface = static_cast(val); - if ( !interface->isValid() && !m_privateData->isClosing) + if ( !interface->isValid() ) { need_recreate = true; } @@ -183,14 +143,16 @@ // 1.3 check prototypes JSObject *proto = static_cast(this->prototype()); - while (!proto->isNull() && proto->isObject()) { + while (!proto->isNull() && proto->isObject()) + { if (proto->getOwnPropertySlot(exec, propertyName, slot)) return true; proto = static_cast(proto->prototype()); } } - + + // Create an interface for me, please! // Store the interface in the object so we get the same one each time. JSValue* resultVal = m_privateData->m_deviceBinding->CreateInterface( exec, m_privateData->m_svcName, m_privateData->m_propName ); @@ -200,6 +162,11 @@ else { JSValue* s = resultVal->toObject(exec)->get( exec, m_privateData->m_propName ); + DeviceLiwInterface* ifObj = static_cast(s); + DevicePrivateBase* ifData = ifObj->getInterfaceData(); + DevicePrivateBase* soData = this->getServiceData(); + ifData->SetParent( soData ); + soData->AddChild( ifData ); this->putDirect( propertyName, s, DontDelete|ReadOnly ); } @@ -210,7 +177,7 @@ if(jsobj->inherits( &KJS::DeviceLiwResult::info )) { DeviceLiwResult* result = static_cast(jsobj); - result->quickClose(); + result->Close(); } } } @@ -317,7 +284,7 @@ { return throwError(exec, GeneralError, "Can not close service object in callback function."); } - so->Close( exec, false ); + so->Close(); } return ret; } @@ -326,24 +293,28 @@ // DeviceLiwMapPrivate constructor // // --------------------------------------------------------------------------- -ServiceObjectPrivate::ServiceObjectPrivate(HBufC8* svcName, MDeviceBinding* deviceBinding ) +ServiceObjectPrivate::ServiceObjectPrivate(ServiceObject* jsobj, HBufC8* svcName, MDeviceBinding* deviceBinding ) { - m_svcName = svcName; - m_deviceBinding = deviceBinding; - isClosing = false; + m_svcName = svcName; + m_deviceBinding = deviceBinding; + m_jsobj = jsobj; } // --------------------------------------------------------------------------- -// DeviceLiwMapPrivate::Close +// DeviceLiwMapPrivate::destructor // // --------------------------------------------------------------------------- -void ServiceObjectPrivate::Close() +ServiceObjectPrivate::~ServiceObjectPrivate() { + // invalid the ServiceObject + if (m_jsobj) + m_jsobj->m_valid = EFalse; + m_deviceBinding->UnloadServiceProvider(KWildChar(), m_svcName->Des()); m_deviceBinding = NULL; delete m_svcName; - m_svcName = NULL; + m_svcName = NULL; } //END OF FILE diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/DerivedSources/WebCore/CharsetData.cpp --- a/webengine/osswebengine/DerivedSources/WebCore/CharsetData.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/DerivedSources/WebCore/CharsetData.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -140,6 +140,16 @@ { "ucs-2-big", KCharacterSetIdentifierUnicodeBig }, { "ucs-2-little", KCharacterSetIdentifierUnicodeLittle }, { "iscii", 0x1027508E }, + { "euc-kr", 0x2000E526 }, + { "csEUCKR", 0x2000E526 }, + { "ko", 0x200113CD }, + { "ks_c_5601-1987", 0x200113CD }, + { "iso-ir-149", 0x200113CD }, + { "ks_c_5601-1989", 0x200113CD }, + { "ksc_5601", 0x200113CD }, + { "csksc56011987", 0x200113CD }, + { "ms949", 0x200100FF }, + { "cp949", 0x200100FF }, { 0, 0 } }; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/DerivedSources/WebCore/HTMLNames.cpp --- a/webengine/osswebengine/DerivedSources/WebCore/HTMLNames.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/DerivedSources/WebCore/HTMLNames.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -35,7 +35,6 @@ #endif #include "HTMLNames.h" - #include "StaticConstructors.h" namespace WebCore { namespace HTMLNames { @@ -1251,11 +1250,29 @@ void remove() { +#ifndef __WINSCW__ + if( initialized ) { + size_t num(0); + QualifiedName** array = getHTMLTags(&num); + for( int i=0; i~QualifiedName(); + } + array = getHTMLAttrs(&num); + for( int i=0; i~QualifiedName(); + } + } +#endif //__WINSCW__ xhtmlNSString = ""; aTagString = ""; abbrTagString = ""; - acronymTagString = ""; addressTagString = ""; appletTagString = ""; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/DerivedSources/WebCore/XMLNames.cpp --- a/webengine/osswebengine/DerivedSources/WebCore/XMLNames.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/DerivedSources/WebCore/XMLNames.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -26,7 +26,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #include "config.h" #ifdef AVOID_STATIC_CONSTRUCTORS #define DOM_XMLNAMES_HIDE_GLOBALS 1 @@ -48,13 +47,12 @@ DEFINE_GLOBAL(QualifiedName, langAttr, nullAtom, "lang", xmlNamespaceURI); DEFINE_GLOBAL(QualifiedName, spaceAttr, nullAtom, "space", xmlNamespaceURI); -static bool initialized = false; -// Attributes -static const char *xmlNSString = "http://www.w3.org/XML/1998/namespace"; -static const char *baseAttrString = "base"; -static const char *langAttrString = "lang"; -static const char *spaceAttrString = "space"; - +static bool initialized = false; +// Attributes +static const char *xmlNSString = "http://www.w3.org/XML/1998/namespace"; +static const char *baseAttrString = "base"; +static const char *langAttrString = "lang"; +static const char *spaceAttrString = "space"; WebCore::QualifiedName** getXMLAttrs(size_t* size) { @@ -86,20 +84,23 @@ new ((void*)&spaceAttr) QualifiedName(nullAtom, spaceAttrString, xmlNS); } -void remove() -{ +void remove() +{ +#ifndef __WINSCW__ if( initialized ) { - xmlNamespaceURI.~AtomicString(); - baseAttr.~QualifiedName(); - langAttr.~QualifiedName(); - spaceAttr.~QualifiedName(); + ((AtomicString*)&xmlNamespaceURI)->~AtomicString(); + ((QualifiedName*)&baseAttr)->~QualifiedName(); + ((QualifiedName*)&langAttr)->~QualifiedName(); + ((QualifiedName*)&spaceAttr)->~QualifiedName(); } - xmlNSString = ""; - baseAttrString = ""; - langAttrString = ""; - spaceAttrString = ""; - initialized = false; -} +#endif // __WINSCW__ + + xmlNSString = ""; + baseAttrString = ""; + langAttrString = ""; + spaceAttrString = ""; + initialized = false; +} } } diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/DerivedSources/WebCore/kjs_navigator.lut.h --- a/webengine/osswebengine/DerivedSources/WebCore/kjs_navigator.lut.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/DerivedSources/WebCore/kjs_navigator.lut.h Thu Aug 27 07:44:59 2009 +0300 @@ -1,32 +1,39 @@ -/* Automatically generated from /cygdrive/x/tot/WebCore/bindings/js/kjs_navigator.cpp using /cygdrive/x/tot/WebCore/../JavaScriptCore/kjs/create_hash_table. DO NOT EDIT ! */ +/* Automatically generated from kjs_navigator.cpp using create_hash_table. DO NOT EDIT ! */ + +#include "lookup.h" namespace KJS { static const struct HashEntry NavigatorTableEntries[] = { - { "appVersion", Navigator::AppVersion, DontDelete|ReadOnly, 0, &NavigatorTableEntries[17] }/* 737224111 */ , - { "appCodeName", Navigator::AppCodeName, DontDelete|ReadOnly, 0, &NavigatorTableEntries[16] }/* 2036402863 */ , + { "appName", Navigator::AppName, DontDelete|ReadOnly, 0, 0 }/* 1928575421 */ , { 0, 0, 0, 0, 0 }, - { "javaEnabled", Navigator::JavaEnabled, DontDelete|Function, 0, 0 }/* 3101780464 */ , - { "productSub", Navigator::ProductSub, DontDelete|ReadOnly, 0, 0 }/* 2097335881 */ , - { "language", Navigator::Language, DontDelete|ReadOnly, 0, &NavigatorTableEntries[13] }/* 389985029 */ , - { "appName", Navigator::AppName, DontDelete|ReadOnly, 0, &NavigatorTableEntries[14] }/* 1928575421 */ , - { "vendorSub", Navigator::VendorSub, DontDelete|ReadOnly, 0, 0 }/* 2200565686 */ , + { "plugins", Navigator::_Plugins, DontDelete|ReadOnly, 0, 0 }/* 3805841733 */ , + { "appVersion", Navigator::AppVersion, DontDelete|ReadOnly, 0, 0 }/* 737224111 */ , + { "NetworkNotAllowed", Navigator::NetworkNotAllowed, DontDelete|ReadOnly, 0, 0 }/* 1135189233 */ , + { "mimeTypes", Navigator::_MimeTypes, DontDelete|ReadOnly, 0, &NavigatorTableEntries[19] }/* 541397713 */ , + { "vendorSub", Navigator::VendorSub, DontDelete|ReadOnly, 0, &NavigatorTableEntries[20] }/* 2200565686 */ , + { 0, 0, 0, 0, 0 }, + { "onLine", Navigator::Online, DontDelete|ReadOnly, 0, 0 }/* 3891351994 */ , + { "platform", Navigator::Platform, DontDelete|ReadOnly, 0, 0 }/* 1656147642 */ , { 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, + { "NetworkAccessAllowed", Navigator::NetworkAccessAllowed, DontDelete|ReadOnly, 0, 0 }/* 2231046963 */ , + { "appCodeName", Navigator::AppCodeName, DontDelete|ReadOnly, 0, &NavigatorTableEntries[17] }/* 2036402863 */ , + { "NetworkAccessible", Navigator::NetworkAccessible, DontDelete|ReadOnly, 0, 0 }/* 3337096018 */ , + { "language", Navigator::Language, DontDelete|ReadOnly, 0, &NavigatorTableEntries[18] }/* 389985029 */ , + { "productSub", Navigator::ProductSub, DontDelete|ReadOnly, 0, 0 }/* 2097335881 */ , { "vendor", Navigator::Vendor, DontDelete|ReadOnly, 0, 0 }/* 4183282360 */ , - { 0, 0, 0, 0, 0 }, - { "mimeTypes", Navigator::_MimeTypes, DontDelete|ReadOnly, 0, 0 }/* 541397713 */ , - { "userAgent", Navigator::UserAgent, DontDelete|ReadOnly, 0, &NavigatorTableEntries[15] }/* 1491767165 */ , - { "platform", Navigator::Platform, DontDelete|ReadOnly, 0, 0 }/* 1656147642 */ , - { "plugins", Navigator::_Plugins, DontDelete|ReadOnly, 0, 0 }/* 3805841733 */ , + { "userAgent", Navigator::UserAgent, DontDelete|ReadOnly, 0, 0 }/* 1491767165 */ , { "product", Navigator::Product, DontDelete|ReadOnly, 0, 0 }/* 3666888811 */ , - { "cookieEnabled", Navigator::CookieEnabled, DontDelete|ReadOnly, 0, 0 }/* 2175375748 */ + { "cookieEnabled", Navigator::CookieEnabled, DontDelete|ReadOnly, 0, 0 }/* 2175375748 */ , + { "javaEnabled", Navigator::JavaEnabled, DontDelete|Function, 0, 0 }/* 3101780464 */ }; -const struct HashTable NavigatorTable = { 2, 18, NavigatorTableEntries, 13 }; +const struct HashTable NavigatorTable = { 2, 21, NavigatorTableEntries, 17 }; } // namespace +#include "lookup.h" + namespace KJS { static const struct HashEntry PluginsTableEntries[] = { @@ -38,6 +45,8 @@ } // namespace +#include "lookup.h" + namespace KJS { static const struct HashEntry MimeTypesTableEntries[] = { @@ -48,6 +57,8 @@ } // namespace +#include "lookup.h" + namespace KJS { static const struct HashEntry PluginTableEntries[] = { @@ -62,6 +73,8 @@ } // namespace +#include "lookup.h" + namespace KJS { static const struct HashEntry MimeTypeTableEntries[] = { diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/DerivedSources/WebCore/kjs_window.lut.h --- a/webengine/osswebengine/DerivedSources/WebCore/kjs_window.lut.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/DerivedSources/WebCore/kjs_window.lut.h Thu Aug 27 07:44:59 2009 +0300 @@ -67,7 +67,7 @@ { "onmousemove", Window::Onmousemove, DontDelete, 0, &WindowTableEntries[122] }/* 1053316302 */ , { "onmouseout", Window::Onmouseout, DontDelete, 0, 0 }/* 708315430 */ , { 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, + { "ononline", Window::Ononline, DontDelete, 0, 0 }/* 1415647862 */ , { "btoa", Window::BToA, DontDelete|Function, 1, &WindowTableEntries[119] }/* 3147832331 */ , { 0, 0, 0, 0, 0 }, { "onload", Window::Onload, DontDelete, 0, 0 }/* 3960668140 */ , @@ -124,19 +124,20 @@ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, - { "setTimeout", Window::SetTimeout, DontDelete|Function, 2, &WindowTableEntries[127] }/* 3937824660 */ , + { "setTimeout", Window::SetTimeout, DontDelete|Function, 2, &WindowTableEntries[128] }/* 3937824660 */ , { "onabort", Window::Onabort, DontDelete, 0, 0 }/* 495556821 */ , { "onkeydown", Window::Onkeydown, DontDelete, 0, &WindowTableEntries[123] }/* 118358195 */ , - { "onmousewheel", Window::OnWindowMouseWheel, DontDelete, 0, &WindowTableEntries[128] }/* 2004718922 */ , - { "onreset", Window::Onreset, DontDelete, 0, 0 }/* 2148355157 */ , + { "onmousewheel", Window::OnWindowMouseWheel, DontDelete, 0, &WindowTableEntries[129] }/* 2004718922 */ , + { "onreset", Window::Onreset, DontDelete, 0, &WindowTableEntries[127] }/* 2148355157 */ , { "onresize", Window::Onresize, DontDelete, 0, 0 }/* 4050308757 */ , { "onsearch", Window::Onsearch, DontDelete, 0, 0 }/* 2178040503 */ , { "onselect", Window::Onselect, DontDelete, 0, 0 }/* 2628083475 */ , + { "onoffline", Window::Onoffline, DontDelete, 0, 0 }/* 3213228680 */ , { "DOMException", Window::DOMException, DontDelete, 0, 0 }/* 2633742454 */ , { "XMLHttpRequest", Window::XMLHttpRequest, DontDelete, 0, 0 }/* 760114463 */ }; -const struct HashTable WindowTable = { 2, 129, WindowTableEntries, 119 }; +const struct HashTable WindowTable = { 2, 130, WindowTableEntries, 119 }; } // namespace diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/JavaScriptCore/bindings/npruntime.h --- a/webengine/osswebengine/JavaScriptCore/bindings/npruntime.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/JavaScriptCore/bindings/npruntime.h Thu Aug 27 07:44:59 2009 +0300 @@ -75,7 +75,7 @@ #ifndef __SYMBIAN32__ #ifdef __S60_32__ -#include +#include #else #include #endif //__S60_32__ @@ -85,7 +85,7 @@ #else // Not __SYMBIAN32__ #ifdef __S60_32__ -#include +#include #else #include #endif //__S60_32__ diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/MemoryManager/Group/MemMan.mmp --- a/webengine/osswebengine/MemoryManager/Group/MemMan.mmp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/MemoryManager/Group/MemMan.mmp Thu Aug 27 07:44:59 2009 +0300 @@ -29,6 +29,8 @@ UID 0x1000008D 0x10281B6D //MACRO OOM_LOGGING +//MACRO DL_CHUNK_MEM_DEBUG + MACRO USE_FAST_MALLOC MACRO NOKIA_CHANGES MACRO __NEW_ALLOCATOR__ diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/MemoryManager/Inc/DLA.h --- a/webengine/osswebengine/MemoryManager/Inc/DLA.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/MemoryManager/Inc/DLA.h Thu Aug 27 07:44:59 2009 +0300 @@ -616,6 +616,8 @@ struct malloc_tree_chunk* child[2]; struct malloc_tree_chunk* parent; bindex_t index; + size_t pageout; /* chunk pageout flag */ + size_t npages; /* chunk pageout size */ }; typedef struct malloc_tree_chunk tchunk; @@ -652,10 +654,10 @@ struct malloc_state { binmap_t smallmap; binmap_t treemap; - size_t dvsize; + size_t dvsize; // unused size_t topsize; TUint8* least_addr; - mchunkptr dv; + mchunkptr dv; // unused mchunkptr top; size_t trim_check; size_t magic; @@ -1045,4 +1047,46 @@ unsigned size; }; /******CODE TO SUPORT SLAB ALLOCATOR******/ + + /****** COMMON DEFS CHUNK PAGE MAP/UNMAP *****/ +#define CHUNK_PAGEOUT_THESHOLD (12*1024U) +#define CHUNK_PAGE_OUT_FLAG (98989U) +#define tchunk_page_align(p) (char*)page_align((size_t)(p) + sizeof(tchunk) + TOP_FOOT_SIZE) +#define address_offset(HIGH, LOW) (size_t)((char*)(HIGH) - (char*)(LOW)) + +/* tree_malloc_chunk pageout header operations */ +#define set_tchunk_mem_pageout(TP, NPAGES) \ + { (TP)->pageout = CHUNK_PAGE_OUT_FLAG; (TP)->npages = (NPAGES); } +#define reset_tchunk_mem_pageout(TP) \ + { (TP)->pageout = 0; (TP)->npages = 0; } +#define page_not_in_memory(P, S) \ + ( !is_small(S) && ( (((tchunkptr)(P))->pageout==CHUNK_PAGE_OUT_FLAG)?1:0 ) ) + + +#ifdef DL_CHUNK_MEM_DEBUG +#define ASSERT_RCHUNK_SIZE() \ + {RChunk rchunk; rchunk.SetHandle(iChunkHandle); assert(iChunkSize == rchunk.Size());} +#define TRACE_DL_CHUNK_MAP(c_addr, csize, page_addr, page_size) \ + MEM_LOGF(_L8("DL_CHUNK_MAP$$:: chunk_addr=%x, chunk_size=%d, page_addr=%x, page_size=%d"), c_addr, csize, page_addr, (page_size)); +#define TRACE_DL_CHUNK_UNMAP(c_addr, csize, page_addr, page_size) \ + MEM_LOGF(_L8("DL_CHUNK_UNMAP:: chunk_addr=%x, chunk_size=%d, page_addr=%x, page_size=%d"), c_addr, csize, page_addr, (page_size)); +#else +#define ASSERT_RCHUNK_SIZE() +#define TRACE_DL_CHUNK_MAP(c_addr, csize, p_addr, psize) +#define TRACE_DL_CHUNK_UNMAP(c_addr, csize, p_addr, psize) +#endif + +#ifdef OOM_LOGGING +#define TRACE_UNMAPPED_CHUNK(SZ) \ + iUnmappedChunkSize += (SZ); +#define MEM_DUMP_OOM_LOGS(NB, MSG) \ + MEM_LOG(MSG); \ + C_LOG(MSG); \ + dump_heap_logs(NB) +#else +#define MEM_DUMP_OOM_LOGS(NB, MSG) +#define TRACE_UNMAPPED_CHUNK(SZ) +#endif + + /****** COMMON DEFS PAGE MAP/UNMAP *****/ #endif/*__DLA__*/ diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/MemoryManager/Inc/MemoryLogger.h --- a/webengine/osswebengine/MemoryManager/Inc/MemoryLogger.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/MemoryManager/Inc/MemoryLogger.h Thu Aug 27 07:44:59 2009 +0300 @@ -30,6 +30,7 @@ _LIT( KMEMLogDir, "WebCore"); _LIT( KMEMLogFile, "Memory.log"); +_LIT( KChunkLogFile, "freechunks.log"); _LIT8( KFuncMemLogBegin, "BEGIN: %S @ %S/%d InSize -> %d" ); _LIT8( KFuncMemLogEnd, "END: Peek -> %d Diff -> %d Accumulated Peek -> %d" ); _LIT8( KTab, "\t" ); @@ -38,6 +39,8 @@ #define MEM_LOG(a) { _LIT8(temp, a); RFileLogger::Write(KMEMLogDir, KMEMLogFile, EFileLoggingModeAppend, temp); } #define MEM_LOGF FPrint +#define C_LOG(a) { _LIT8(temp, a); RFileLogger::Write(KMEMLogDir, KChunkLogFile, EFileLoggingModeAppend, temp); } +#define C_LOGF FPrint2 // FUNCTION DECLARATIONS @@ -48,6 +51,13 @@ RFileLogger::WriteFormat(KMEMLogDir, KMEMLogFile, EFileLoggingModeAppend, aFmt, list); } +inline void FPrint2(const TRefByValue aFmt, ...) +{ + VA_LIST list; + VA_START(list,aFmt); + RFileLogger::WriteFormat(KMEMLogDir, KChunkLogFile, EFileLoggingModeAppend, aFmt, list); +} + // CLASS DECLARATION /** @@ -117,8 +127,10 @@ loggers[ i ]->_accum += _peek; } #else // OOM_LOGGING -#define MEM_LOG {} -#define MEM_LOGF {} +#define MEM_LOG(a) +#define MEM_LOGF +#define C_LOG(a) +#define C_LOGF #endif #endif diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/MemoryManager/Inc/MemoryPool.h --- a/webengine/osswebengine/MemoryManager/Inc/MemoryPool.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/MemoryManager/Inc/MemoryPool.h Thu Aug 27 07:44:59 2009 +0300 @@ -356,6 +356,9 @@ TUint PostCheck(); TUint FreeMemory( TFreeMem& aFree ); void RestoreRescueBuffer(); +#ifdef OOM_LOGGING + void DumpHeapLogs(); +#endif private: void InitLocal(); diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/MemoryManager/Inc/SymbianDlHeap.h --- a/webengine/osswebengine/MemoryManager/Inc/SymbianDlHeap.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/MemoryManager/Inc/SymbianDlHeap.h Thu Aug 27 07:44:59 2009 +0300 @@ -178,12 +178,12 @@ /*MACROS converted functions*/ static inline void unlink_first_small_chunk(mstate M,mchunkptr B,mchunkptr P,bindex_t& I); static inline void insert_small_chunk(mstate M,mchunkptr P, size_t S); - static inline void insert_chunk(mstate M,mchunkptr P,size_t S); + static inline void insert_chunk(mstate M,mchunkptr P,size_t S,size_t NPAGES); static inline void unlink_large_chunk(mstate M,tchunkptr X); static inline void unlink_small_chunk(mstate M, mchunkptr P,size_t S); static inline void unlink_chunk(mstate M, mchunkptr P, size_t S); static inline void compute_tree_index(size_t S, bindex_t& I); - static inline void insert_large_chunk(mstate M,tchunkptr X,size_t S); + static inline void insert_large_chunk(mstate M,tchunkptr X,size_t S,size_t NPAGES); static inline void replace_dv(mstate M, mchunkptr P, size_t S); static inline void compute_bit2idx(binmap_t X,bindex_t& I); /*MACROS converted functions*/ @@ -247,7 +247,39 @@ void paged_free(void* p); void* paged_reallocate(void* p, unsigned size); pagecell* paged_descriptor(const void* p) const ; -private: + + /* Dl heap log dump functions*/ +#ifdef OOM_LOGGING + void dump_heap_logs(size_t fail_size); + void dump_dl_free_chunks(); + void dump_large_chunk(mstate m, tchunkptr t); + size_t iUnmappedChunkSize; +#endif +private: + /* Dubug checks for chunk page support*/ +#ifdef DL_CHUNK_MEM_DEBUG +#define do_chunk_page_release_check(p, psize, fm, mem_released) debug_chunk_page_release_check(p, psize, fm, mem_released) +#define do_check_large_chunk_access(p, psize) debug_check_large_chunk_access(p, psize) +#define do_check_small_chunk_access(p, psize) debug_check_small_chunk_access(p, psize) +#define do_check_any_chunk_access(p, psize) debug_check_any_chunk_access(p, psize) + void debug_check_large_chunk_access(tchunkptr p, size_t psize); + void debug_check_small_chunk_access(mchunkptr p, size_t psize); + void debug_check_any_chunk_access(mchunkptr p, size_t psize); + void debug_chunk_page_release_check(mchunkptr p, size_t psize, mstate fm, int mem_released); +#else +#define do_chunk_page_release_check(p, psize, fm, mem_released) +#define do_check_large_chunk_access(p, psize) +#define do_check_small_chunk_access(p, psize) +#define do_check_any_chunk_access(p, psize) +#endif + + /* Chunk page release mechanism support */ + TInt map_chunk_pages(tchunkptr p, size_t psize); + TInt unmap_chunk_pages(tchunkptr p, size_t psize, size_t prev_npages); + TInt map_chunk_pages_partial(tchunkptr tp, size_t psize, tchunkptr r, size_t rsize); + TInt sys_trim_partial(mstate m, mchunkptr prev, size_t psize, size_t prev_npages); + size_t free_chunk_threshold; + // paged allocator structures enum {npagecells=4}; pagecell pagelist[npagecells]; // descriptors for page-aligned large allocations diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/MemoryManager/Src/MemoryPool.cpp --- a/webengine/osswebengine/MemoryManager/Src/MemoryPool.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/MemoryManager/Src/MemoryPool.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -620,30 +620,38 @@ // except at process end. } -const TInt KMaxHeapSize = 0x2000000; //32MB -const TInt KHeapGrowSize = 0x10000; //64KB +#ifdef __WINSCW__ +const TInt KMaxHeapSize = 0x2000000; // 32MB, on emulator +#else +const TInt KMaxHeapSize = 0x4000000; // 64MB, on hardware +#endif + +const TInt KHeapGrowSize = 0x10000; // 64KB TBool CNewSymbianHeapPool::Create() { // need to know system page size TInt page_size; UserHal::PageSizeInBytes(page_size); - - // Create the thread's heap chunk. - // - // The chunk needs reserve enough address space for twice the maximum allocation - // The heap object is instantiated exactly half way up the chunk, and initially is provided just 1 page of memory - // This memory can be committed as part of the call to creat the chunk - // - TInt maxChunkSize = 2 * KMaxHeapSize; - TInt offset = KMaxHeapSize; + + TInt maxmem = 0; + HAL::Get(HALData::EMemoryRAM, maxmem); + TInt maxHeapSize = Min(maxmem, KMaxHeapSize); + + /* Create the thread's heap chunk. + * The chunk needs reserve enough address space for twice the maximum allocation + * The heap object is instantiated exactly half way up the chunk, and initially is provided just 1 page of memory + * This memory can be committed as part of the call to creat the chunk + */ + TInt maxChunkSize = 2 * maxHeapSize; + TInt offset = maxHeapSize; TInt minLength = page_size; RChunk c; TInt r = c.CreateDisconnectedLocal(offset, offset+minLength, maxChunkSize, EOwnerProcess); if (r!=KErrNone) return EFalse; - iAlloc = new (c.Base() + offset) RSymbianDLHeap(c.Handle(), offset, minLength, KMaxHeapSize, KHeapGrowSize, 8, EFalse /* not single threaded! */); + iAlloc = new (c.Base() + offset) RSymbianDLHeap(c.Handle(), offset, minLength, maxHeapSize, KHeapGrowSize, 8, EFalse /* not single threaded! */); iAlloc->iHandles = &iAlloc->iChunkHandle; iAlloc->iHandleCount = 2; // chunk handle now 'owned' by iAlloc @@ -655,5 +663,12 @@ return CMemoryPool::Create(); } +#ifdef OOM_LOGGING +void CNewSymbianHeapPool::DumpHeapLogs() + { + iAlloc->dump_heap_logs(0); + iAlloc->dump_dl_free_chunks(); + } +#endif #endif // END OF FILE diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/MemoryManager/Src/SymbianDLAllocatorWrapper.cpp --- a/webengine/osswebengine/MemoryManager/Src/SymbianDLAllocatorWrapper.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/MemoryManager/Src/SymbianDLAllocatorWrapper.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -31,6 +31,9 @@ RSymbianDlAllocatorWrapper::~RSymbianDlAllocatorWrapper() { +#ifdef OOM_LOGGING + iPool->DumpHeapLogs(); +#endif } TAny* RSymbianDlAllocatorWrapper::Alloc(TInt aSize) diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/MemoryManager/Src/heap.cpp --- a/webengine/osswebengine/MemoryManager/Src/heap.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/MemoryManager/Src/heap.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -29,6 +29,7 @@ #ifdef __NEW_ALLOCATOR__ +#include "MemoryLogger.h" #include "SymbianDLHeap.h" _LIT(KDLHeapPanicCategory, "DL Heap"); @@ -46,6 +47,205 @@ #undef UEXPORT_C #define UEXPORT_C + +/* Purpose: Map chunk memory pages from system RAM + * Arguments: tp - tchunkptr in which memmory should be mapped + * psize - incoming tchunk size + * Return: KErrNone if successful, else KErrNoMemory + * Note: + */ +TInt RSymbianDLHeap::map_chunk_pages(tchunkptr tp, size_t psize) +{ + if(page_not_in_memory(tp, psize)) { + char *a_addr = tchunk_page_align(tp); + size_t npages = tp->npages; + +#ifdef OOM_LOGGING + // check that npages matches the psize + size_t offset = address_offset(a_addr,tp); + if(offset < psize && (psize - offset) >= mparams.page_size ) + { + size_t tpages = ( psize - offset) >> pageshift; + if(tpages != tp->npages) //assert condition + MEM_LOG("CHUNK_PAGE_ERROR:map_chunk_pages, error in npages"); + } + else + MEM_LOG("CHUNK_PAGE_ERROR::map_chunk_pages: - Incorrect page-in-memmory flag"); +#endif + + if(map(a_addr, npages*mparams.page_size)) { + TRACE_DL_CHUNK_MAP(tp, psize, a_addr, npages*mparams.page_size); + ASSERT_RCHUNK_SIZE(); + TRACE_UNMAPPED_CHUNK(-1*npages*mparams.page_size); + return KErrNone; + } + else { + MEM_LOGF(_L8("CHUNK_PAGE_ERROR:: map_chunk_pages - Failed to Commit RAM, page_addr=%x, npages=%d, chunk_size=%d"), a_addr, npages, psize); + MEM_DUMP_OOM_LOGS(psize, "RSymbianDLHeap::map_chunk_pages - Failed to Commit RAM"); + return KErrNoMemory; + } + } + return KErrNone; +} + +/* Purpose: Map partial chunk memory pages from system RAM + * Arguments: tp - tchunkptr in which memmory should be mapped + * psize - incoming tchunk size + * r - remainder chunk pointer + * rsize - remainder chunk size + * Return: Number of unmapped pages from remainder chunk if successful (0 or more), else KErrNoMemory + * Note: Remainder chunk should be large enough to be mapped out (checked before invoking this function) + * pageout headers will be set from insert_large_chunk(), not here. + */ +TInt RSymbianDLHeap::map_chunk_pages_partial(tchunkptr tp, size_t psize, tchunkptr r, size_t rsize) +{ + if(page_not_in_memory(tp, psize)) { + size_t npages = tp->npages; // total no of pages unmapped in this chunk + char *page_addr_map = tchunk_page_align(tp); // address to begin page map + char *page_addr_rem = tchunk_page_align(r); // address in remainder chunk to remain unmapped + assert(address_offset(page_addr_rem, r) < rsize); + size_t npages_map = address_offset(page_addr_rem, page_addr_map) >> pageshift; // no of pages to be mapped + if(npages_map > 0) { + if(map(page_addr_map, npages_map*mparams.page_size)) { + TRACE_DL_CHUNK_MAP(tp, psize, page_addr_map, npages_map*mparams.page_size); + ASSERT_RCHUNK_SIZE(); + TRACE_UNMAPPED_CHUNK(-1*npages_map*mparams.page_size); + return (npages - npages_map); + } + else { + MEM_LOGF(_L8("CHUNK_PAGE_ERROR:: map_chunk_pages_partial - Failed to Commit RAM, page_addr=%x, npages=%d, chunk_size=%d"), page_addr_map, npages_map, psize); + MEM_DUMP_OOM_LOGS(psize, "RSymbianDLHeap::map_chunk_pages_partial - Failed to Commit RAM"); + return KErrNoMemory; + } + } + else { + // map not needed, first page is already mapped + return npages; + } + } + + return 0; +} + + +/* Purpose: Release (unmap) chunk memory pages to system RAM + * Arguments: tp - tchunkptr from which memmory may be released + * psize - incoming tchunk size + * prev_npages - number of pages that has been already unmapped from this chunk + * Return: total number of pages that has been unmapped from this chunk (new unmapped pages + prev_npages) + * Note: pageout headers will be set from insert_large_chunk(), not here. + */ +TInt RSymbianDLHeap::unmap_chunk_pages(tchunkptr tp, size_t psize, size_t prev_npages) +{ + size_t npages = 0; + char *a_addr = tchunk_page_align(tp); + size_t offset = address_offset(a_addr,tp); + if(offset < psize && (psize - offset) >= mparams.page_size) + { /* check for new pages to decommit */ + npages = ( psize - offset) >> pageshift; + if(npages > prev_npages) { + unmap(a_addr, npages*mparams.page_size); // assuming kernel takes care of already unmapped pages + TRACE_DL_CHUNK_UNMAP(tp, psize, a_addr, npages*mparams.page_size); + iChunkSize += prev_npages*mparams.page_size; //adjust actual chunk size + ASSERT_RCHUNK_SIZE(); + TRACE_UNMAPPED_CHUNK((npages-prev_npages)*mparams.page_size); + assert((a_addr + npages*mparams.page_size - 1) < (char*)next_chunk(tp)); + } + } + +#ifdef OOM_LOGGING + if(npages && (npages < prev_npages)) + MEM_LOG("CHUNK_PAGE_ERROR:unmap_chunk_pages, error in npages"); + if(npages > prev_npages) { + /* check that end of decommited address lie within this chunk */ + if((a_addr + npages*mparams.page_size - 1) >= (char*)next_chunk(tp)) + MEM_LOG("CHUNK_PAGE_ERROR:unmap_chunk_pages, error chunk boundary"); + } +#endif +#ifdef DL_CHUNK_MEM_DEBUG + mchunkptr next = next_chunk(tp); + do_check_any_chunk_access(next, chunksize(next)); + if(!npages) do_check_any_chunk_access((mchunkptr)tp, psize); +#endif + + return (npages); +} + +/* Purpose: Unmap all pages between previously unmapped and end of top chunk + and reset top to beginning of prev chunk + * Arguments: fm - global malloc state + * prev - previous chunk which has unmapped pages + * psize - size of previous chunk + * prev_npages - number of unmapped pages from previous chunk + * Return: nonzero if sucessful, else 0 + * Note: + */ +TInt RSymbianDLHeap::sys_trim_partial(mstate m, mchunkptr prev, size_t psize, size_t prev_npages) +{ + size_t released = 0; + size_t extra = 0; + if (is_initialized(m)) { + psize += m->topsize; + char *a_addr = tchunk_page_align(prev); // includes space for TOP footer + size_t addr_offset = address_offset(a_addr, prev); + assert(addr_offset > TOP_FOOT_SIZE); //always assert? + assert((char*)iTop >= a_addr); //always assert? + if((char*)iTop > a_addr) + extra = address_offset(iTop, a_addr); + +#ifdef OOM_LOGGING + if ((char*)iTop < a_addr) + MEM_LOGF(_L8("RSymbianDLHeap::sys_trim_partial - incorrect iTop value, top=%x, iTop=%x"), m->top, iTop); +#endif + msegmentptr sp = segment_holding(m, (TUint8*)prev); + if (!is_extern_segment(sp)) { + if (is_mmapped_segment(sp)) { + if (HAVE_MMAP && sp->size >= extra && !has_segment_link(m, sp)) { /* can't shrink if pinned */ + size_t newsize = sp->size - extra; + /* Prefer mremap, fall back to munmap */ + if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) || + (CALL_MUNMAP(sp->base + newsize, extra) == 0)) { + released = extra; + } + } + } + else if (HAVE_MORECORE) { + if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */ + extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - mparams.granularity; + ACQUIRE_MORECORE_LOCK(m); + { + /* Make sure end of memory is where we last set it. */ + TUint8* old_br = (TUint8*)(CALL_MORECORE(0)); + if (old_br == sp->base + sp->size) { + TUint8* rel_br = (TUint8*)(CALL_MORECORE(-extra)); + TUint8* new_br = (TUint8*)(CALL_MORECORE(0)); + if (rel_br != CMFAIL && new_br < old_br) + released = old_br - new_br; + } + } + RELEASE_MORECORE_LOCK(m); + } + } + + if (released != 0) { + TRACE_DL_CHUNK_UNMAP(prev, psize, a_addr, released); + iChunkSize += prev_npages*mparams.page_size; // prev_unmapped was already unmapped + TRACE_UNMAPPED_CHUNK(-1*prev_npages*mparams.page_size); + ASSERT_RCHUNK_SIZE(); + sp->size -= released; + m->footprint -= released; + } + + /* reset top to prev chunk */ + init_top(m, prev, addr_offset - TOP_FOOT_SIZE); + check_top_chunk(m, m->top); + } + + // DL region not initalized, do not reset top here + return (released != 0)? 1 : 0; +} + + UEXPORT_C RSymbianDLHeap::RSymbianDLHeap(TInt aMaxLength, TInt aAlign, TBool aSingleThread) // constructor for a fixed heap. Just use DL allocator :iMinLength(aMaxLength), iMaxLength(aMaxLength), iOffset(0), iGrowBy(0), iChunkHandle(0), @@ -84,7 +284,7 @@ if (aMinLength == aMaxLength) Init(0, 0, 0); else - Init(0x3fff, 16, 0x10000); // all slabs, page {64KB}, trim {64KB} + Init(0x3fff, 15, 0x10000); // all slabs, page {32KB}, trim {64KB} // Init(0xabe, 16, iPageSize*4); // slabs {48, 40, 32, 24, 20, 16, 12}, page {64KB}, trim {16KB} } @@ -112,6 +312,10 @@ /*10-1K,11-2K,12-4k,13-8K,14-16K,15-32K,16-64K*/ paged_init(aPagePower); + +#ifdef OOM_LOGGING + iUnmappedChunkSize = 0; +#endif } UEXPORT_C RSymbianDLHeap::SCell* RSymbianDLHeap::GetAddress(const TAny* aCell) const @@ -163,6 +367,9 @@ else { addr = paged_allocate(aSize); + if(!addr) { // paged_allocator failed, try in dlmalloc + addr = dlmalloc(aSize); + } } Unlock(); @@ -417,18 +624,35 @@ t = leftmost_child(t); } /* If dv is a better fit, return 0 so malloc will use it */ - if (v != 0 && rsize < (size_t)(m->dvsize - nb)) { + if (v != 0) { if (RTCHECK(ok_address(m, v))) { /* split */ mchunkptr r = chunk_plus_offset(v, nb); assert(chunksize(v) == rsize + nb); + + /* check for chunk memory page-in */ + size_t npages_out = 0; + if(page_not_in_memory(v, chunksize(v))) { + if(!is_small(rsize) && rsize>=CHUNK_PAGEOUT_THESHOLD) { + // partial chunk page mapping + TInt result = map_chunk_pages_partial(v, chunksize(v), (tchunkptr)r, rsize); + if (result < 0) return 0; // Failed to Commit RAM + else npages_out = (size_t)result; + } + else { + // full chunk page map needed + TInt err = map_chunk_pages(v, chunksize(v)); + if(err != KErrNone) return 0; // Failed to Commit RAM + } + } + if (RTCHECK(ok_next(v, r))) { unlink_large_chunk(m, v); - if (rsize < MIN_CHUNK_SIZE) + if (rsize < free_chunk_threshold) // exaust if less than slab threshold set_inuse_and_pinuse(m, v, (rsize + nb)); else { set_size_and_pinuse_of_inuse_chunk(m, v, nb); set_size_and_pinuse_of_free_chunk(r, rsize); - insert_chunk(m, r, rsize); + insert_chunk(m, r, rsize, npages_out); } return chunk2mem(v); } @@ -460,14 +684,21 @@ if (RTCHECK(ok_address(m, v))) { mchunkptr r = chunk_plus_offset(v, nb); assert(chunksize(v) == rsize + nb); + + /* check for chunk memory page-in */ + if(page_not_in_memory(v, chunksize(v))) { + TInt err = map_chunk_pages(v, chunksize(v)); + if(err != KErrNone) return 0; // Failed to Commit RAM + } + if (RTCHECK(ok_next(v, r))) { unlink_large_chunk(m, v); - if (rsize < MIN_CHUNK_SIZE) + if (rsize < free_chunk_threshold) // exaust if less than slab threshold set_inuse_and_pinuse(m, v, (rsize + nb)); else { set_size_and_pinuse_of_inuse_chunk(m, v, nb); set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(m, r, rsize); + insert_chunk(m, r, rsize, 0); } return chunk2mem(v); } @@ -515,7 +746,7 @@ if (oldsize >= nb) { /* already big enough */ size_t rsize = oldsize - nb; newp = oldp; - if (rsize >= MIN_CHUNK_SIZE) { + if (rsize >= free_chunk_threshold) { mchunkptr remainder = chunk_plus_offset(newp, nb); set_inuse(m, newp, nb); set_inuse(m, remainder, rsize); @@ -833,6 +1064,8 @@ } } /*need to check this*/ + MEM_DUMP_OOM_LOGS(nb, "sys_alloc:: FAILED to get more memory"); + //errno = -1; return 0; } @@ -883,12 +1116,12 @@ } -inline void RSymbianDLHeap::insert_chunk(mstate M,mchunkptr P,size_t S) +inline void RSymbianDLHeap::insert_chunk(mstate M,mchunkptr P,size_t S,size_t NPAGES) { if (is_small(S)) insert_small_chunk(M, P, S); else{ - tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); + tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S, NPAGES); } } @@ -896,6 +1129,7 @@ { tchunkptr XP = X->parent; tchunkptr R; + reset_tchunk_mem_pageout(X); // clear chunk pageout flag if (X->bk != X) { tchunkptr F = X->fd; R = X->bk; @@ -1016,7 +1250,7 @@ /* ------------------------- Operations on trees ------------------------- */ /* Insert chunk into tree */ -inline void RSymbianDLHeap::insert_large_chunk(mstate M,tchunkptr X,size_t S) +inline void RSymbianDLHeap::insert_large_chunk(mstate M,tchunkptr X,size_t S,size_t NPAGES) { tbinptr* H; bindex_t I; @@ -1024,6 +1258,10 @@ H = treebin_at(M, I); X->index = I; X->child[0] = X->child[1] = 0; + + if(NPAGES) { set_tchunk_mem_pageout(X, NPAGES) } + else { reset_tchunk_mem_pageout(X) } + if (!treemap_is_marked(M, I)) { mark_treemap(M, I); *H = X; @@ -1157,7 +1395,7 @@ size_t psize = csp - old_top; mchunkptr tn = chunk_plus_offset(q, psize); set_free_with_pinuse(q, psize, tn); - insert_chunk(m, q, psize); + insert_chunk(m, q, psize, 0); } check_top_chunk(m, m->top); @@ -1184,20 +1422,20 @@ q->head = tsize | PINUSE_BIT; check_top_chunk(m, q); } - else if (oldfirst == m->dv) { - size_t dsize = m->dvsize += qsize; - m->dv = q; - set_size_and_pinuse_of_free_chunk(q, dsize); - } else { if (!cinuse(oldfirst)) { size_t nsize = chunksize(oldfirst); + + /* check for chunk memory page-in */ + if(page_not_in_memory(oldfirst, nsize)) + map_chunk_pages((tchunkptr)oldfirst, nsize); //Err Ignored, branch not reachable. + unlink_chunk(m, oldfirst, nsize); oldfirst = chunk_plus_offset(oldfirst, nsize); qsize += nsize; } set_free_with_pinuse(q, qsize, oldfirst); - insert_chunk(m, q, qsize); + insert_chunk(m, q, qsize, 0); check_free_chunk(m, q); } @@ -1321,14 +1559,9 @@ /* Can unmap if first chunk holds entire segment and not pinned */ if (!cinuse(p) && (TUint8*)p + psize >= base + size - TOP_FOOT_SIZE) { tchunkptr tp = (tchunkptr)p; + size_t npages_out = tp->npages; assert(segment_holds(sp, (TUint8*)sp)); - if (p == m->dv) { - m->dv = 0; - m->dvsize = 0; - } - else { - unlink_large_chunk(m, tp); - } + unlink_large_chunk(m, tp); if (CALL_MUNMAP(base, size) == 0) { released += size; m->footprint -= size; @@ -1337,7 +1570,7 @@ sp->next = next; } else { /* back out if cannot unmap */ - insert_large_chunk(m, tp, psize); + insert_large_chunk(m, tp, psize, npages_out); } } } @@ -1404,18 +1637,12 @@ Basic algorithm: If a small request (< 256 bytes minus per-chunk overhead): 1. If one exists, use a remainderless chunk in associated smallbin. - (Remainderless means that there are too few excess bytes to - represent as a chunk.) - 2. If it is big enough, use the dv chunk, which is normally the - chunk adjacent to the one used for the most recent small request. - 3. If one exists, split the smallest available chunk in a bin, - saving remainder in dv. + (Remainderless means that there are too few excess bytes to represent as a chunk.) + 2. If one exists, split the smallest available chunk in a bin, saving remainder in bin. 4. If it is big enough, use the top chunk. 5. If available, get memory from system and use it Otherwise, for a large request: - 1. Find the smallest available binned chunk that fits, and use it - if it is better fitting than dv chunk, splitting if necessary. - 2. If better fitting than any binned chunk, use the dv chunk. + 1. Find the smallest available binned chunk that fits, splitting if necessary. 3. If it is big enough, use the top chunk. 4. If request size >= mmap threshold, try to directly mmap this chunk. 5. If available, get memory from system and use it @@ -1443,9 +1670,7 @@ mem = chunk2mem(p); check_malloced_chunk(gm, mem, nb); goto postaction; - } - - else if (nb > gm->dvsize) { + } else { if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ mchunkptr b, p, r; size_t rsize; @@ -1459,25 +1684,24 @@ unlink_first_small_chunk(gm, b, p, i); rsize = small_index2size(i) - nb; /* Fit here cannot be remainderless if 4byte sizes */ - if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) + if (rsize < free_chunk_threshold) set_inuse_and_pinuse(gm, p, small_index2size(i)); else { set_size_and_pinuse_of_inuse_chunk(gm, p, nb); r = chunk_plus_offset(p, nb); set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(gm, r, rsize); + insert_chunk(gm, r, rsize, 0); } mem = chunk2mem(p); check_malloced_chunk(gm, mem, nb); goto postaction; } - else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) { check_malloced_chunk(gm, mem, nb); goto postaction; } } - } + } /* else - large alloc request */ else if (bytes >= MAX_REQUEST) nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ else { @@ -1488,27 +1712,7 @@ } } - if (nb <= gm->dvsize) { - size_t rsize = gm->dvsize - nb; - mchunkptr p = gm->dv; - if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ - mchunkptr r = gm->dv = chunk_plus_offset(p, nb); - gm->dvsize = rsize; - set_size_and_pinuse_of_free_chunk(r, rsize); - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - } - else { /* exhaust dv */ - size_t dvs = gm->dvsize; - gm->dvsize = 0; - gm->dv = 0; - set_inuse_and_pinuse(gm, p, dvs); - } - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if (nb < gm->topsize) { /* Split top */ + if (nb < gm->topsize) { /* Split top */ size_t rsize = gm->topsize -= nb; mchunkptr p = gm->top; mchunkptr r = gm->top = chunk_plus_offset(p, nb); @@ -1524,6 +1728,13 @@ postaction: POSTACTION(gm); +#ifdef DL_CHUNK_MEM_DEBUG + if(mem) { + mchunkptr pp = mem2chunk(mem); + do_check_any_chunk_access(pp, chunksize(pp)); + } +#endif + return mem; } @@ -1539,6 +1750,8 @@ if (mem != 0) { + size_t unmapped_pages = 0; + int prev_chunk_unmapped = 0; mchunkptr p = mem2chunk(mem); #if FOOTERS mstate fm = get_mstate_for(p); @@ -1565,41 +1778,23 @@ { prevsize &= ~IS_MMAPPED_BIT; psize += prevsize + MMAP_FOOT_PAD; - /*TInt tmp = TOP_FOOT_SIZE; - TUint8* top = (TUint8*)fm->top + fm->topsize + 40; - if((top == (TUint8*)p)&& fm->topsize > 4096) - { - fm->topsize += psize; - msegmentptr sp = segment_holding(fm, (TUint8*)fm->top); - sp->size+=psize; - if (should_trim(fm, fm->topsize)) - sys_trim(fm, 0); - goto postaction; - } - else*/ - { if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) fm->footprint -= psize; goto postaction; - } } else { mchunkptr prev = chunk_minus_offset(p, prevsize); + if(page_not_in_memory(prev, prevsize)) { + prev_chunk_unmapped = 1; + unmapped_pages = ((tchunkptr)prev)->npages; + } + psize += prevsize; p = prev; if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ - if (p != fm->dv) - { - unlink_chunk(fm, p, prevsize); - } - else if ((next->head & INUSE_BITS) == INUSE_BITS) - { - fm->dvsize = psize; - set_free_with_pinuse(p, psize, next); - goto postaction; - } + unlink_chunk(fm, p, prevsize); } else goto erroraction; @@ -1611,43 +1806,49 @@ if (!cinuse(next)) { /* consolidate forward */ if (next == fm->top) - { - size_t tsize = fm->topsize += psize; - fm->top = p; - p->head = tsize | PINUSE_BIT; - if (p == fm->dv) - { - fm->dv = 0; - fm->dvsize = 0; + { + if(prev_chunk_unmapped) { // previous chunk is unmapped + /* unmap all pages between previously unmapped and end of top chunk + and reset top to beginning of prev chunk - done in sys_trim_partial() */ + sys_trim_partial(fm, p, psize, unmapped_pages); + do_check_any_chunk_access(fm->top, fm->topsize); + goto postaction; } - if (should_trim(fm, tsize)) - sys_trim(fm, 0); - goto postaction; - } - else if (next == fm->dv) - { - size_t dsize = fm->dvsize += psize; - fm->dv = p; - set_size_and_pinuse_of_free_chunk(p, dsize); - goto postaction; + else { // forward merge to top + size_t tsize = fm->topsize += psize; + fm->top = p; + p->head = tsize | PINUSE_BIT; + if (should_trim(fm, tsize)) + sys_trim(fm, 0); + do_check_any_chunk_access(fm->top, fm->topsize); + goto postaction; + } } else { - size_t nsize = chunksize(next); + size_t nsize = chunksize(next); + int next_chunk_unmapped = 0; + if( page_not_in_memory(next, nsize) ) { + next_chunk_unmapped = 1; + unmapped_pages += ((tchunkptr)next)->npages; + } + psize += nsize; unlink_chunk(fm, next, nsize); set_size_and_pinuse_of_free_chunk(p, psize); - if (p == fm->dv) - { - fm->dvsize = psize; - goto postaction; - } } } else set_free_with_pinuse(p, psize, next); - insert_chunk(fm, p, psize); + + /* check if chunk memmory can be released */ + size_t npages_out = 0; + if(!is_small(psize) && psize>=CHUNK_PAGEOUT_THESHOLD) + npages_out = unmap_chunk_pages((tchunkptr)p, psize, unmapped_pages); + + insert_chunk(fm, p, psize, npages_out); check_free_chunk(fm, p); + do_chunk_page_release_check(p, psize, fm, npages_out); goto postaction; } } @@ -1959,6 +2160,8 @@ } sizemap[sz>>2] = ix; } + + free_chunk_threshold = pad_request(slab_threshold); } void* RSymbianDLHeap::slab_allocate(slabset& ss) @@ -2109,7 +2312,6 @@ TInt r = chunk.Commit(iOffset + ptrdiff(p, this),sz); if (r < 0) return 0; - ASSERT(p = offset(this, r - iOffset)); iChunkSize += sz; return p; } @@ -2267,4 +2469,162 @@ } } +/* Only for debugging purpose - start*/ +#ifdef DL_CHUNK_MEM_DEBUG +void RSymbianDLHeap::debug_check_small_chunk_access(mchunkptr p, size_t psize) +{ + size_t sz = chunksize(p); + char ch = *((char*)chunk_plus_offset(p, psize-1)); +} + +void RSymbianDLHeap::debug_check_any_chunk_access(mchunkptr p, size_t psize) +{ + if(p==0 || psize==0) return; + + mchunkptr next = chunk_plus_offset(p, psize); + char* t = (char*)chunk_plus_offset(p, mparams.page_size); + char ch = *((char*)p); + while((size_t)t<(size_t)next) + { + ch = *t; + t = (char*)chunk_plus_offset(t, mparams.page_size); + }; +} + +void RSymbianDLHeap::debug_check_large_chunk_access(tchunkptr p, size_t psize) +{ + mchunkptr next = chunk_plus_offset(p, psize); + char* t = (char*)chunk_plus_offset(p, mparams.page_size); + char ch = *((char*)p); + while((size_t)t<(size_t)next) + { + ch = *t; + t = (char*)chunk_plus_offset(t, mparams.page_size); + }; +} + +void RSymbianDLHeap::debug_chunk_page_release_check(mchunkptr p, size_t psize, mstate fm, int mem_released) +{ + if(mem_released) + { + if(!page_not_in_memory(p, psize) ) + MEM_LOG("CHUNK_PAGE_ERROR::dlfree, error - page_in_mem flag is corrupt"); + if(chunk_plus_offset(p, psize) > fm->top) + MEM_LOG("CHUNK_PAGE_ERROR: error Top chunk address invalid"); + if(fm->dv >= p && fm->dv < chunk_plus_offset(p, psize)) + MEM_LOG("CHUNK_PAGE_ERROR: error DV chunk address invalid"); + } +} #endif + +#ifdef OOM_LOGGING +#include +void RSymbianDLHeap::dump_large_chunk(mstate m, tchunkptr t) { + tchunkptr u = t; + bindex_t tindex = t->index; + size_t tsize = chunksize(t); + bindex_t idx; + compute_tree_index(tsize, idx); + + size_t free = 0; + int nfree = 0; + do + { /* traverse through chain of same-sized nodes */ + if (u->child[0] != 0) + { + dump_large_chunk(m, u->child[0]); + } + + if (u->child[1] != 0) + { + dump_large_chunk(m, u->child[1]); + } + + free += chunksize(u); + nfree++; + u = u->fd; + } + while (u != t); + C_LOGF(_L8("LARGE_BIN,%d,%d,%d"), tsize, free, nfree); +} + +void RSymbianDLHeap::dump_dl_free_chunks() +{ + C_LOG(""); + C_LOG("------------ dump_dl_free_chunks start -------------"); + C_LOG("BinType,BinSize,FreeSize,FreeCount"); + + // dump small bins + for (int i = 0; i < NSMALLBINS; ++i) + { + sbinptr b = smallbin_at(gm, i); + unsigned int empty = (gm->smallmap & (1 << i)) == 0; + int nfree = 0; + if (!empty) + { + int nfree = 0; + size_t free = 0; + mchunkptr p = b->bk; + size_t size = chunksize(p); + for (; p != b; p = p->bk) + { + free += chunksize(p); + nfree++; + } + + C_LOGF(_L8("SMALL_BIN,%d,%d,%d"), size, free, nfree); + } + } + + // dump large bins + for (int i = 0; i < NTREEBINS; ++i) + { + tbinptr* tb = treebin_at(gm, i); + tchunkptr t = *tb; + int empty = (gm->treemap & (1 << i)) == 0; + if (!empty) + dump_large_chunk(gm, t); + } + + C_LOG("------------ dump_dl_free_chunks end -------------"); + C_LOG(""); + } + +void RSymbianDLHeap::dump_heap_logs(size_t fail_size) +{ + MEM_LOG(""); + if (fail_size) { + MEM_LOG("MEMDEBUG::RSymbianDLHeap OOM Log dump *************** start"); + MEM_LOGF(_L8("Failing to alloc size: %d"), fail_size); + } + else + MEM_LOG("MEMDEBUG::RSymbianDLHeap Log dump *************** start"); + + TInt dl_chunk_size = ptrdiff(iTop,iBase); + TInt slabp_chunk_size = iChunkSize + iUnmappedChunkSize - dl_chunk_size; + TInt freeMem = 0; + HAL::Get(HALData::EMemoryRAMFree, freeMem); + MEM_LOGF(_L8("System Free RAM Size: %d"), freeMem); + MEM_LOGF(_L8("Allocator Commited Chunk Size: %d"), iChunkSize); + MEM_LOGF(_L8("DLHeap Arena Size=%d"), dl_chunk_size); + MEM_LOGF(_L8("DLHeap unmapped chunk size: %d"), iUnmappedChunkSize); + MEM_LOGF(_L8("Slab-Page Allocator Chunk Size=%d"), slabp_chunk_size); + + mallinfo info = dlmallinfo(); + TUint heapAlloc = info.uordblks; + TUint heapFree = info.fordblks; + MEM_LOGF(_L8("DLHeap allocated size: %d"), heapAlloc); + MEM_LOGF(_L8("DLHeap free size: %d"), heapFree); + + if (fail_size) { + MEM_LOG("MEMDEBUG::RSymbianDLHeap OOM Log dump *************** end"); + }else { + MEM_LOG("MEMDEBUG::RSymbianDLHeap Log dump *************** end"); + } + MEM_LOG(""); +} + +#endif +/* Only for debugging purpose - end*/ + +#endif diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/bindings/js/kjs_events.cpp --- a/webengine/osswebengine/WebCore/bindings/js/kjs_events.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/bindings/js/kjs_events.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -145,6 +145,39 @@ } } +void JSAbstractEventListener::handleNetworkStateEvent(int param) +{ + JSObject* listener = listenerObj(); + if (!listener) + return; + + Window* window = windowObj(); + if (!window) + return; + + Frame *frame = window->impl()->frame(); + if (!frame) + return; + KJSProxy* proxy = frame->scriptProxy(); + if (!proxy) + return; + + JSLock lock; + + ScriptInterpreter* interpreter = proxy->interpreter(); + ExecState* exec = interpreter->globalExec(); + + List args; + if ( param != -1 ) + args.append( jsNumber(param) ); + JSValue* retval = listener->call(exec, window, args); + + if (exec->hadException()) + exec->clearException(); + + JSLock::unlock(); +} + bool JSAbstractEventListener::isHTMLEventListener() const { return m_html; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/bindings/js/kjs_events.h --- a/webengine/osswebengine/WebCore/bindings/js/kjs_events.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/bindings/js/kjs_events.h Thu Aug 27 07:44:59 2009 +0300 @@ -41,6 +41,7 @@ JSAbstractEventListener(bool html = false); virtual void handleEvent(Event*, bool isWindowEvent); + virtual void handleNetworkStateEvent(int param); virtual bool isHTMLEventListener() const; virtual KJS::JSObject* listenerObj() const = 0; virtual KJS::Window* windowObj() const = 0; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/bindings/js/kjs_navigator.cpp --- a/webengine/osswebengine/WebCore/bindings/js/kjs_navigator.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/bindings/js/kjs_navigator.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -155,7 +155,7 @@ const ClassInfo Navigator::info = { "Navigator", 0, &NavigatorTable, 0 }; /* -@begin NavigatorTable 13 +@begin NavigatorTable 17 appCodeName Navigator::AppCodeName DontDelete|ReadOnly appName Navigator::AppName DontDelete|ReadOnly appVersion Navigator::AppVersion DontDelete|ReadOnly @@ -170,6 +170,10 @@ vendorSub Navigator::VendorSub DontDelete|ReadOnly cookieEnabled Navigator::CookieEnabled DontDelete|ReadOnly javaEnabled Navigator::JavaEnabled DontDelete|Function 0 + NetworkNotAllowed Navigator::NetworkNotAllowed DontDelete|ReadOnly + NetworkAccessAllowed Navigator::NetworkAccessAllowed DontDelete|ReadOnly + NetworkAccessible Navigator::NetworkAccessible DontDelete|ReadOnly + onLine Navigator::Online DontDelete|ReadOnly @end */ KJS_IMPLEMENT_PROTOTYPE_FUNCTION(NavigatorFunc) @@ -217,6 +221,14 @@ return new MimeTypes(exec); case CookieEnabled: return jsBoolean(cookiesEnabled()); + case NetworkNotAllowed: + return jsNumber(m_frame->loader()->widgetNetworkConstants(0)); + case NetworkAccessAllowed: + return jsNumber(m_frame->loader()->widgetNetworkConstants(1)); + case NetworkAccessible: + return jsNumber(m_frame->loader()->widgetNetworkConstants(2)); + case Online: + return jsNumber(m_frame->loader()->widgetNetworkState()); } return 0; } diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/bindings/js/kjs_navigator.h --- a/webengine/osswebengine/WebCore/bindings/js/kjs_navigator.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/bindings/js/kjs_navigator.h Thu Aug 27 07:44:59 2009 +0300 @@ -37,7 +37,8 @@ virtual const ClassInfo* classInfo() const { return &info; } static const ClassInfo info; enum { AppCodeName, AppName, AppVersion, Language, UserAgent, Platform, - _Plugins, _MimeTypes, Product, ProductSub, Vendor, VendorSub, CookieEnabled, JavaEnabled }; + _Plugins, _MimeTypes, Product, ProductSub, Vendor, VendorSub, CookieEnabled, JavaEnabled, + NetworkNotAllowed, NetworkAccessAllowed, NetworkAccessible, Online }; WebCore::Frame *frame() const { return m_frame; } private: WebCore::Frame *m_frame; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/bindings/js/kjs_window.cpp --- a/webengine/osswebengine/WebCore/bindings/js/kjs_window.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/bindings/js/kjs_window.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -210,6 +210,8 @@ onsubmit Window::Onsubmit DontDelete onunload Window::Onunload DontDelete onbeforeunload Window::Onbeforeunload DontDelete + ononline Window::Ononline DontDelete + onoffline Window::Onoffline DontDelete # -- Constructors -- DOMException Window::DOMException DontDelete Image Window::Image DontDelete @@ -626,6 +628,10 @@ return getListener(exec, beforeunloadEvent); case Onunload: return getListener(exec, unloadEvent); + case Ononline: + return getListener(exec, ononlineEvent); + case Onoffline: + return getListener(exec, onofflineEvent); } ASSERT(0); return jsUndefined(); @@ -846,6 +852,14 @@ if (isSafeScript(exec)) setListener(exec, unloadEvent, value); return; + case Ononline: + if (isSafeScript(exec)) + setListener(exec, ononlineEvent, value); + return; + case Onoffline: + if (isSafeScript(exec)) + setListener(exec, onofflineEvent, value); + return; default: break; } diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/bindings/js/kjs_window.h --- a/webengine/osswebengine/WebCore/bindings/js/kjs_window.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/bindings/js/kjs_window.h Thu Aug 27 07:44:59 2009 +0300 @@ -162,7 +162,7 @@ Onmousemove, Onmouseout, Onmouseover, Onmouseup, OnWindowMouseWheel, Onreset, Onresize, Onscroll, Onsearch, Onselect, Onsubmit, Onunload, - Onbeforeunload, + Onbeforeunload, Ononline, Onoffline, // Constructors DOMException, Image, Option, XMLHttpRequest, diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/config.h --- a/webengine/osswebengine/WebCore/config.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/config.h Thu Aug 27 07:44:59 2009 +0300 @@ -100,7 +100,9 @@ #define WTF_USE_NPOBJECT 1 #undef WIN32 #undef _WIN32 +#ifdef __WINSCW__ #undef AVOID_STATIC_CONSTRUCTORS +#endif // __WINSCW__ #define USE_SYSTEM_MALLOC 1 #define U_HAVE_INT8_T 0 #define U_HAVE_INT16_T 0 diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/css/MediaFeatureNames.cpp --- a/webengine/osswebengine/WebCore/css/MediaFeatureNames.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/css/MediaFeatureNames.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -37,9 +37,10 @@ CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(DEFINE_MEDIAFEATURE_GLOBAL) #undef DEFINE_MEDIAFEATURE_GLOBAL +static bool initialized; + void init() { - static bool initialized; if (!initialized) { // Use placement new to initialize the globals. @@ -51,5 +52,18 @@ } } +void remove() +{ + if( initialized ) { + #define DESTROY_GLOBAL(name, str) delete ((AtomicString*)&name##MediaFeature)->impl(); + CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(DESTROY_GLOBAL) + #undef DESTROY_GLOBAL + AtomicString::remove(); + + initialized = false; + } + +} //remove() + } // namespace MediaFeatureNames } // namespace WebCore diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/css/MediaFeatureNames.h --- a/webengine/osswebengine/WebCore/css/MediaFeatureNames.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/css/MediaFeatureNames.h Thu Aug 27 07:44:59 2009 +0300 @@ -62,6 +62,7 @@ #endif void init(); + void remove(); } // namespace MediaFeatureNames } // namespace WebCore diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/dom/Document.cpp --- a/webengine/osswebengine/WebCore/dom/Document.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/dom/Document.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -253,16 +253,13 @@ DeprecatedPtrList* Document::changedDocuments = 0; -struct cleanupChangedDocuments { - ~cleanupChangedDocuments() { +void cleanupChangedDocuments() { if(Document::changedDocuments) { delete Document::changedDocuments; Document::changedDocuments = NULL; } - } -}; -static cleanupChangedDocuments deleteChangedDocuments; +} // FrameView might be 0 Document::Document(DOMImplementation* impl, Frame* frame, bool isXHTML) @@ -2468,6 +2465,19 @@ (*it)->listener()->handleEvent(evt, true); } +void Document::handleNetworkEvent(const AtomicString &eventType, int param) +{ + if (m_windowEventListeners.isEmpty()) + return; + + // if any html event listeners are registered on the window, then dispatch them here + RegisteredEventListenerList listenersCopy = m_windowEventListeners; + RegisteredEventListenerList::iterator it = listenersCopy.begin(); + + for (; it != listenersCopy.end(); ++it) + if ((*it)->eventType() == eventType && !(*it)->removed()) + (*it)->listener()->handleNetworkStateEvent(param); +} void Document::defaultEventHandler(Event *evt) { diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/dom/Document.h --- a/webengine/osswebengine/WebCore/dom/Document.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/dom/Document.h Thu Aug 27 07:44:59 2009 +0300 @@ -40,6 +40,7 @@ #include namespace WebCore { + void cleanupChangedDocuments(); class AXObjectCache; class Attr; @@ -489,6 +490,7 @@ virtual void defaultEventHandler(Event*); void handleWindowEvent(Event*, bool useCapture); + void handleNetworkEvent(const AtomicString &eventType, int param); void setHTMLWindowEventListener(const AtomicString &eventType, PassRefPtr); EventListener* getHTMLWindowEventListener(const AtomicString &eventType); void removeHTMLWindowEventListener(const AtomicString &eventType); diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/dom/EventListener.h --- a/webengine/osswebengine/WebCore/dom/EventListener.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/dom/EventListener.h Thu Aug 27 07:44:59 2009 +0300 @@ -31,6 +31,7 @@ public: virtual ~EventListener() { } virtual void handleEvent(Event*, bool isWindowEvent) = 0; + virtual void handleNetworkStateEvent(int param) { } virtual bool isHTMLEventListener() const { return false; } }; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/dom/EventNames.cpp --- a/webengine/osswebengine/WebCore/dom/EventNames.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/dom/EventNames.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -35,9 +35,10 @@ DEFINE_GLOBAL(AtomicString, name##Event, #name) DOM_EVENT_NAMES_FOR_EACH(DEFINE_EVENT_GLOBAL) +static bool initialized = false; + void init() { - static bool initialized; if (!initialized) { // Use placement new to initialize the globals. @@ -48,4 +49,16 @@ } } +void remove() +{ + if( initialized ) { + #define DESTROY_GLOBAL(name) delete ((AtomicString*)&name##Event)->impl(); + DOM_EVENT_NAMES_FOR_EACH(DESTROY_GLOBAL) + AtomicString::remove(); + + initialized = false; + } + +} //remove() + } } diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/dom/EventNames.h --- a/webengine/osswebengine/WebCore/dom/EventNames.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/dom/EventNames.h Thu Aug 27 07:44:59 2009 +0300 @@ -73,6 +73,8 @@ macro(textInput) \ macro(unload) \ macro(zoom) \ + macro(ononline) \ + macro(onoffline) \ \ macro(DOMActivate) \ macro(DOMAttrModified) \ @@ -98,6 +100,7 @@ void init(); + void remove(); } } #endif diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/dom/StyledElement.cpp --- a/webengine/osswebengine/WebCore/dom/StyledElement.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/dom/StyledElement.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -71,22 +71,20 @@ static MappedAttributeDecls* mappedAttributeDecls = 0; -struct mappedAttributeCleaner { - ~mappedAttributeCleaner() { - if( mappedAttributeDecls ) { - MappedAttributeDeclsIterator end = mappedAttributeDecls->end(); - for (MappedAttributeDeclsIterator it = mappedAttributeDecls->begin(); it != end; ++it) - { - MappedAttributeKey* obj = (*it).first; - delete obj; - } - mappedAttributeDecls->clear(); - delete mappedAttributeDecls; - mappedAttributeDecls = 0; - } +void mappedAttributeCleaner() +{ + if( mappedAttributeDecls ) { + MappedAttributeDeclsIterator end = mappedAttributeDecls->end(); + for (MappedAttributeDeclsIterator it = mappedAttributeDecls->begin(); it != end; ++it) + { + MappedAttributeKey* obj = (*it).first; + delete obj; + } + mappedAttributeDecls->clear(); + delete mappedAttributeDecls; + mappedAttributeDecls = 0; } -}; -struct mappedAttributeCleaner mappedAttribute; +} CSSMappedAttributeDeclaration* StyledElement::getMappedAttributeDecl(MappedAttributeEntry entryType, Attribute* attr) { diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/dom/StyledElement.h --- a/webengine/osswebengine/WebCore/dom/StyledElement.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/dom/StyledElement.h Thu Aug 27 07:44:59 2009 +0300 @@ -30,6 +30,8 @@ namespace WebCore { +void mappedAttributeCleaner(); + class CSSMappedAttributeDeclaration; class MappedAttribute; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/editing/TextIterator.cpp --- a/webengine/osswebengine/WebCore/editing/TextIterator.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/editing/TextIterator.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -1068,7 +1068,11 @@ // -------- CircularSearchBuffer::CircularSearchBuffer(const String& s, bool isCaseSensitive) +#if PLATFORM(SYMBIAN) + : m_target(isCaseSensitive ? s : s.lower()) +#else : m_target(isCaseSensitive ? s : s.foldCase()) +#endif , m_isCaseSensitive(isCaseSensitive) , m_characterBuffer(m_target.length()) , m_isCharacterStartBuffer(m_target.length()) @@ -1098,7 +1102,11 @@ const int maxFoldedCharacters = 16; // sensible maximum is 3, this should be more than enough UChar foldedCharacters[maxFoldedCharacters]; bool error; +#if PLATFORM(SYMBIAN) + int numFoldedCharacters = toLower(foldedCharacters, maxFoldedCharacters, &c, 1, &error); +#else int numFoldedCharacters = foldCase(foldedCharacters, maxFoldedCharacters, &c, 1, &error); +#endif ASSERT(!error); ASSERT(numFoldedCharacters); ASSERT(numFoldedCharacters <= maxFoldedCharacters); diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/html/HTMLElementFactory.cpp --- a/webengine/osswebengine/WebCore/html/HTMLElementFactory.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/html/HTMLElementFactory.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -396,16 +396,16 @@ gFunctionMap->set(tag.localName().impl(), func); } -struct cleanupFuncMap { - ~cleanupFuncMap() { - if( gFunctionMap ) { - gFunctionMap->clear(); - delete gFunctionMap; - gFunctionMap=0; - } +void cleanupFuncMap() +{ + if( gFunctionMap ) { + gFunctionMap->clear(); + delete gFunctionMap; + gFunctionMap=0; + } -}; -static cleanupFuncMap cleanup; +} + static void createFunctionMap() { // Create the table. diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/html/HTMLElementFactory.h --- a/webengine/osswebengine/WebCore/html/HTMLElementFactory.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/html/HTMLElementFactory.h Thu Aug 27 07:44:59 2009 +0300 @@ -27,6 +27,8 @@ namespace WebCore { +void cleanupFuncMap(); + class AtomicString; class Document; class Element; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/html/HTMLMetaElement.cpp --- a/webengine/osswebengine/WebCore/html/HTMLMetaElement.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/html/HTMLMetaElement.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -70,9 +70,12 @@ String str = name(); if(!str.isEmpty()) { String v = content(); + Frame* frame = document()->frame(); + // frame null check added for fix of bug AJPA-7SWFS2, JS Document doesnot have frame assosicated so check has + // been added to avoid unnecessary metadata notification. //Inform the bridge about this meta value; - if (inDocument()) { - static_cast(document()->frame()->bridge())->notifyMetaData(str,v); + if (inDocument() && frame != NULL) { + static_cast(frame->bridge())->notifyMetaData(str,v); } } #endif diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/html/HTMLParser.cpp --- a/webengine/osswebengine/WebCore/html/HTMLParser.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/html/HTMLParser.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -122,6 +122,9 @@ , m_reportErrors(reportErrors) , m_handlingResidualStyleAcrossBlocks(false) , inStrayTableContent(0) +#if PLATFORM(SYMBIAN) + ,m_scriptSupported(true) +#endif { } diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/html/HTMLTokenizer.cpp --- a/webengine/osswebengine/WebCore/html/HTMLTokenizer.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/html/HTMLTokenizer.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -1597,6 +1597,9 @@ inWrite = wasInWrite; m_state = state; + // Flush remaining text if doing a document.write. + if (!appendData && buffer && !m_state.hasTagState()) + processToken(); if (noMoreData && !inWrite && !state.loadingExtScript() && !m_executingScript && !m_timer.isActive()) { end(); // this actually causes us to be deleted diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/loader/CachedImage.cpp --- a/webengine/osswebengine/WebCore/loader/CachedImage.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/loader/CachedImage.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -23,6 +23,9 @@ #include "config.h" #include "CachedImage.h" +#include "StaticObjectsContainer.h" +#include "ResourceLoaderDelegate.h" +#include "HttpCacheManager.h" #include "BitmapImage.h" #include "Cache.h" @@ -191,10 +194,31 @@ // received all the data or the size is known. Each chunk from the // network causes observers to repaint, which will force that chunk // to decode. - if (sizeAvailable || allDataReceived) { - if (m_image->isNull()) { - // FIXME: I'm not convinced this case can even be hit. + if (allDataReceived) { + if (!m_image || !sizeAvailable || m_image->isNull()) { + // This case is hit under OOM and lower layer is unable to set sizeAvailable = true + // even when allDataReceived is True. error(); +#if PLATFORM(SYMBIAN) + TBool found( EFalse ); + CHttpCacheManager* cacheManager = WebCore::StaticObjectsContainer::instance()->resourceLoaderDelegate()->httpSessionManager()->cacheManager(); + if ( cacheManager ) + { + // call cache manager to check for url in cache + TPtrC ptr = url().des(); + HBufC8* aUrl = HBufC8::New(ptr.Length()); + if ( aUrl ) + { + aUrl->Des().Copy(ptr); + found = cacheManager->Find( *aUrl ); + if ( found ) + { + cacheManager->RemoveL(*aUrl); + } + delete aUrl; + } + } +#endif if (inCache()) cache()->remove(this); return; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/loader/DocLoader.cpp --- a/webengine/osswebengine/WebCore/loader/DocLoader.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/loader/DocLoader.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -118,9 +118,32 @@ return cache()->requestUserCSSStyleSheet(this, url, charset); } +/* DocLoader::requestScript + * + * If we've been given the charset, just pass it on. + * Otherwise, get it from the enclosing frame. + * + * Notes: + * + * o We do this because some oddly-programmed web pages + * and/or servers deliver JavaScript that doesn't bear + * any obvious character set selection but the intended + * character set isn't the ISO-Latin-1 that will later + * be defaulted-in. + * + * o We don't conditionalize this code for S60/Symbian + * because it should be either benign or even helpful + * to the other platforms as well. + * + */ + CachedScript* DocLoader::requestScript(const String& url, const String& charset) { - return static_cast(requestResource(CachedResource::Script, url, charset)); + + if (!!charset) + return static_cast(requestResource(CachedResource::Script, url, charset)); + else + return static_cast(requestResource(CachedResource::Script, url, frame()->loader()->encoding() )); } #if ENABLE(XSLT) diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/loader/FrameLoader.cpp --- a/webengine/osswebengine/WebCore/loader/FrameLoader.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/loader/FrameLoader.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -3149,6 +3149,16 @@ return m_client->userAgent(url); } +TInt FrameLoader::widgetNetworkConstants(TInt aId) +{ + return m_client->widgetNetworkConstants(aId); +} + +TInt FrameLoader::widgetNetworkState() +{ + return m_client->widgetNetworkState(); +} + void FrameLoader::tokenizerProcessedData() { ASSERT(m_frame->page()); diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/loader/FrameLoader.h --- a/webengine/osswebengine/WebCore/loader/FrameLoader.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/loader/FrameLoader.h Thu Aug 27 07:44:59 2009 +0300 @@ -338,6 +338,8 @@ void handledOnloadEvents(); String userAgent(const KURL&) const; + TInt widgetNetworkConstants(TInt aId); + TInt widgetNetworkState(); Widget* createJavaAppletWidget(const IntSize&, Element*, const HashMap& args); diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/loader/FrameLoaderClient.h --- a/webengine/osswebengine/WebCore/loader/FrameLoaderClient.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/loader/FrameLoaderClient.h Thu Aug 27 07:44:59 2009 +0300 @@ -191,6 +191,8 @@ virtual void setTitle(const String& title, const KURL&) = 0; virtual String userAgent(const KURL&) = 0; + virtual TInt widgetNetworkConstants(TInt aId) = 0; + virtual TInt widgetNetworkState() = 0; virtual void saveDocumentViewToCachedPage(CachedPage*) = 0; virtual bool canCachePage() const = 0; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/loader/icon/IconDatabase.cpp --- a/webengine/osswebengine/WebCore/loader/icon/IconDatabase.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/loader/icon/IconDatabase.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -92,10 +92,13 @@ } #endif +static IconDatabaseClient* defaultClientObj; static IconDatabaseClient* defaultClient() { - static IconDatabaseClient* defaultClient = new IconDatabaseClient(); - return defaultClient; + if( !defaultClientObj ) { + defaultClientObj = new IconDatabaseClient(); + } + return defaultClientObj; } IconDatabase* iconDatabase() @@ -250,12 +253,15 @@ } m_retainedPageURLs.clear(); - delete m_client; - delete sharedIconDatabase; m_syncLock.~Mutex(); m_urlAndIconLock.~Mutex(); m_pendingSyncLock.~Mutex(); m_pendingReadingLock.~Mutex(); + + delete m_client; + defaultClientObj = NULL; + delete sharedIconDatabase; + sharedIconDatabase = NULL; #endif } diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/page/EventHandler.cpp --- a/webengine/osswebengine/WebCore/page/EventHandler.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/page/EventHandler.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -1469,11 +1469,6 @@ keyDownEvent.setIsAutoRepeat(false); bool result = !node->dispatchKeyEvent(keyDownEvent); - - //***** FL added from r12765 *****// - if (initialKeyEvent.isKeyDown()) - return result; - //**********// // Focus may have change during the keyDown handling, so refetch node node = eventTargetNodeForDocument(m_frame->document()); diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/page/symbian/WebCoreFrameBridge.cpp --- a/webengine/osswebengine/WebCore/page/symbian/WebCoreFrameBridge.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/page/symbian/WebCoreFrameBridge.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -282,6 +282,13 @@ sizeMultiplier = StaticObjectsContainer::instance()->screenResolution() == ELowScreenResolution ? KDefaultLowResFontMultiplier : KDefaultFontMultiplier; } +#if PLATFORM(SYMBIAN) + TLanguage uilang = User::Language(); + if(uilang == ELangKorean) + { + sizeMultiplier = 100; + } +#endif if (control(m_frame)->settings()) sizeMultiplier = textMultiplier(control(m_frame)->settings()->brctlSetting(TBrCtlDefs::ESettingsFontSize), sizeMultiplier); return sizeMultiplier; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/DeprecatedString.cpp --- a/webengine/osswebengine/WebCore/platform/DeprecatedString.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/DeprecatedString.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -117,21 +117,6 @@ DeprecatedStringData *DeprecatedString::shared_null = 0; DeprecatedStringData **DeprecatedString::shared_null_handle = 0; -void DeprecatedString::deleteSharedNull() - { - delete shared_null; - shared_null=0; - freeHandle(shared_null_handle); - } - -struct cleanupSharedNull { - ~cleanupSharedNull() - { - DeprecatedString::deleteSharedNull(); - } -}; -struct cleanupSharedNull cleanSharedNull; - // ------------------------------------------------------------------------- // Utility functions // ------------------------------------------------------------------------- diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/FontCache.cpp --- a/webengine/osswebengine/WebCore/platform/FontCache.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/FontCache.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -104,23 +104,21 @@ static FontPlatformDataCache* gFontPlatformDataCache = 0; -struct cleanupFontDataCache { - ~cleanupFontDataCache() { - if( gFontPlatformDataCache ) - { - FontPlatformDataCacheIterator end = gFontPlatformDataCache->end(); - for (FontPlatformDataCacheIterator it = gFontPlatformDataCache->begin(); it != end; ++it) - { - FontPlatformData* obj = (*it).second; - delete obj; - } - gFontPlatformDataCache->clear(); - delete gFontPlatformDataCache; - gFontPlatformDataCache=0; - } +void cleanupFontDataCache() +{ + if( gFontPlatformDataCache ) + { + FontPlatformDataCacheIterator end = gFontPlatformDataCache->end(); + for (FontPlatformDataCacheIterator it = gFontPlatformDataCache->begin(); it != end; ++it) + { + FontPlatformData* obj = (*it).second; + delete obj; + } + gFontPlatformDataCache->clear(); + delete gFontPlatformDataCache; + gFontPlatformDataCache=0; } -}; -static cleanupFontDataCache cleanFontDataCache; +} static const AtomicString& alternateFamilyName(const AtomicString& familyName) { diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/FontCache.h --- a/webengine/osswebengine/WebCore/platform/FontCache.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/FontCache.h Thu Aug 27 07:44:59 2009 +0300 @@ -37,6 +37,7 @@ namespace WebCore { +void cleanupFontDataCache(); class AtomicString; class FontData; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/MimeTypeRegistry.cpp --- a/webengine/osswebengine/WebCore/platform/MimeTypeRegistry.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/MimeTypeRegistry.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -45,26 +45,24 @@ static WTF::HashSet* supportedImageMIMETypes; static WTF::HashSet* supportedNonImageMIMETypes; -struct cleanupMimeTypes { - ~cleanupMimeTypes() { - if( supportedImageResourceMIMETypes ) { - supportedImageResourceMIMETypes->clear(); - delete supportedImageResourceMIMETypes; - supportedImageResourceMIMETypes = 0; - } - if( supportedImageMIMETypes ) { - supportedImageMIMETypes->clear(); - delete supportedImageMIMETypes; - supportedImageMIMETypes = 0; - } - if( supportedNonImageMIMETypes ) { - supportedNonImageMIMETypes->clear(); - delete supportedNonImageMIMETypes; - supportedNonImageMIMETypes = 0; - } +void cleanupMimeTypes() +{ + if( supportedImageResourceMIMETypes ) { + supportedImageResourceMIMETypes->clear(); + delete supportedImageResourceMIMETypes; + supportedImageResourceMIMETypes = 0; } -}; -struct cleanupMimeTypes cleanMimeTypes; + if( supportedImageMIMETypes ) { + supportedImageMIMETypes->clear(); + delete supportedImageMIMETypes; + supportedImageMIMETypes = 0; + } + if( supportedNonImageMIMETypes ) { + supportedNonImageMIMETypes->clear(); + delete supportedNonImageMIMETypes; + supportedNonImageMIMETypes = 0; + } +} #if PLATFORM(CG) extern String getMIMETypeForUTI(const String& uti); diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/MimeTypeRegistry.h --- a/webengine/osswebengine/WebCore/platform/MimeTypeRegistry.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/MimeTypeRegistry.h Thu Aug 27 07:44:59 2009 +0300 @@ -33,6 +33,8 @@ namespace WebCore { +void cleanupMimeTypes(); + class MIMETypeRegistry { public: static String getMIMETypeForExtension(const String& ext); diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/PlatformKeyboardEvent.h --- a/webengine/osswebengine/WebCore/platform/PlatformKeyboardEvent.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/PlatformKeyboardEvent.h Thu Aug 27 07:44:59 2009 +0300 @@ -59,7 +59,11 @@ class PlatformKeyboardEvent { public: +#if PLATFORM(SYMBIAN) + String text() const; +#elif String text() const { return m_text; } +#endif //PLATFORM(SYMBIAN) String unmodifiedText() const { return m_unmodifiedText; } String keyIdentifier() const { return m_keyIdentifier; } bool isKeyUp() const { return m_isKeyUp; } @@ -96,6 +100,7 @@ #if PLATFORM(SYMBIAN) PlatformKeyboardEvent(TKeyEvent, TEventCode, bool forceAutoRepeat = false ); TKeyEvent symbianEvent() const { return m_symbianEvent; } + bool isNaviKey(TUint code) const; #endif private: String m_text; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/SharedTimer.h --- a/webengine/osswebengine/WebCore/platform/SharedTimer.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/SharedTimer.h Thu Aug 27 07:44:59 2009 +0300 @@ -40,6 +40,7 @@ void stopSharedTimer(); #if PLATFORM(SYMBIAN) + void initSharedTimer(); void shutdownSharedTimer(); #endif } diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/StaticConstructors.h --- a/webengine/osswebengine/WebCore/platform/StaticConstructors.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/StaticConstructors.h Thu Aug 27 07:44:59 2009 +0300 @@ -38,6 +38,6 @@ #else // Define an correctly-sized array of pointers to avoid static initialization. // Use an array of pointers instead of an array of char in case there is some alignment issue. -#define DEFINE_GLOBAL(type, name, ...) \ +#define DEFINE_GLOBAL(type, name, args...) \ void * name[(sizeof(type) + sizeof(void *) - 1) / sizeof(void *)]; #endif diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/TextEncoding.cpp --- a/webengine/osswebengine/WebCore/platform/TextEncoding.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/TextEncoding.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -161,53 +161,98 @@ return *this; } +static TextEncoding* globalASCIIEncoding; const TextEncoding& ASCIIEncoding() { - static TextEncoding globalASCIIEncoding("ASCII"); - return globalASCIIEncoding; + if( !globalASCIIEncoding ) { + globalASCIIEncoding = new TextEncoding("ASCII"); + } + return *globalASCIIEncoding; } +static TextEncoding* globalLatin1Encoding; const TextEncoding& Latin1Encoding() { - static TextEncoding globalLatin1Encoding("Latin-1"); - return globalLatin1Encoding; + if( !globalLatin1Encoding ) { + globalLatin1Encoding = new TextEncoding("Latin-1"); + } + return *globalLatin1Encoding; } +static TextEncoding* globalUTF16BigEndianEncoding; const TextEncoding& UTF16BigEndianEncoding() { - static TextEncoding globalUTF16BigEndianEncoding("UTF-16BE"); - return globalUTF16BigEndianEncoding; + if( !globalUTF16BigEndianEncoding ) { + globalUTF16BigEndianEncoding = new TextEncoding("UTF-16BE"); + } + return *globalUTF16BigEndianEncoding; } +static TextEncoding* globalUTF16LittleEndianEncoding; const TextEncoding& UTF16LittleEndianEncoding() { - static TextEncoding globalUTF16LittleEndianEncoding("UTF-16LE"); - return globalUTF16LittleEndianEncoding; + if( !globalUTF16LittleEndianEncoding ) { + globalUTF16LittleEndianEncoding = new TextEncoding("UTF-16LE"); + } + return *globalUTF16LittleEndianEncoding; +} + +static TextEncoding* globalUTF32BigEndianEncoding; +const TextEncoding& UTF32BigEndianEncoding() +{ + if( !globalUTF32BigEndianEncoding ) { + globalUTF32BigEndianEncoding = new TextEncoding("UTF-32BE"); + } + return *globalUTF32BigEndianEncoding; } -const TextEncoding& UTF32BigEndianEncoding() +static TextEncoding* globalUTF32LittleEndianEncoding; +const TextEncoding& UTF32LittleEndianEncoding() { - static TextEncoding globalUTF32BigEndianEncoding("UTF-32BE"); - return globalUTF32BigEndianEncoding; + if( !globalUTF32LittleEndianEncoding ) { + globalUTF32LittleEndianEncoding = new TextEncoding("UTF-32LE"); + } + return *globalUTF32LittleEndianEncoding; } -const TextEncoding& UTF32LittleEndianEncoding() +static TextEncoding* globalUTF8Encoding; +const TextEncoding& UTF8Encoding() { - static TextEncoding globalUTF32LittleEndianEncoding("UTF-32LE"); - return globalUTF32LittleEndianEncoding; + if( !globalUTF8Encoding ) { + globalUTF8Encoding = new TextEncoding("UTF-8"); + } + return *globalUTF8Encoding; } - -const TextEncoding& UTF8Encoding() +static TextEncoding* globalWindowsLatin1Encoding; +const TextEncoding& WindowsLatin1Encoding() { - static TextEncoding globalUTF8Encoding("UTF-8"); - return globalUTF8Encoding; + if( !globalWindowsLatin1Encoding ) { + globalWindowsLatin1Encoding = new TextEncoding("WinLatin-1"); + } + return *globalWindowsLatin1Encoding; } -const TextEncoding& WindowsLatin1Encoding() -{ - static TextEncoding globalWindowsLatin1Encoding("WinLatin-1"); - return globalWindowsLatin1Encoding; +void deleteTextEncodings() { + + // Delete all encodings and set to NULL + delete globalASCIIEncoding; + globalASCIIEncoding = NULL; + delete globalLatin1Encoding; + globalLatin1Encoding = NULL; + delete globalUTF16BigEndianEncoding; + globalUTF16BigEndianEncoding = NULL; + delete globalUTF16LittleEndianEncoding; + globalUTF16LittleEndianEncoding = NULL; + delete globalUTF32BigEndianEncoding; + globalUTF32BigEndianEncoding = NULL; + delete globalUTF32LittleEndianEncoding; + globalUTF32LittleEndianEncoding = NULL; + delete globalUTF8Encoding; + globalUTF8Encoding = NULL; + delete globalWindowsLatin1Encoding; + globalWindowsLatin1Encoding = NULL; + } } // namespace WebCore diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/TextEncoding.h --- a/webengine/osswebengine/WebCore/platform/TextEncoding.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/TextEncoding.h Thu Aug 27 07:44:59 2009 +0300 @@ -64,7 +64,8 @@ const TextEncoding& UTF32LittleEndianEncoding(); const TextEncoding& UTF8Encoding(); const TextEncoding& WindowsLatin1Encoding(); - + void deleteTextEncodings(); + } // namespace WebCore #endif // TextEncoding_h diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/TextEncodingRegistry.cpp --- a/webengine/osswebengine/WebCore/platform/TextEncodingRegistry.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/TextEncodingRegistry.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -251,10 +251,16 @@ #if PLATFORM(SYMBIAN) void deleteEncodingMaps() { - delete textEncodingNameMap; - textEncodingNameMap = NULL; - delete textCodecMap; - textCodecMap = NULL; + if( textEncodingNameMap ) { + textEncodingNameMap->clear(); + delete textEncodingNameMap; + textEncodingNameMap = NULL; + } + if( textCodecMap ) { + textCodecMap->clear(); + delete textCodecMap; + textCodecMap = NULL; + } didExtendTextCodecMaps = false; } #endif diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/graphics/ImageSource.h --- a/webengine/osswebengine/WebCore/platform/graphics/ImageSource.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/graphics/ImageSource.h Thu Aug 27 07:44:59 2009 +0300 @@ -79,7 +79,7 @@ bool initialized() const; - void setData(SharedBuffer* data, bool allDataReceived); + void setDataL(SharedBuffer* data, bool allDataReceived); bool isSizeAvailable(); IntSize size() const; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/graphics/symbian/ImageSourceSymbian.cpp --- a/webengine/osswebengine/WebCore/platform/graphics/symbian/ImageSourceSymbian.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/graphics/symbian/ImageSourceSymbian.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -101,7 +101,7 @@ { return m_mimeType; } -void ImageSource::setData(SharedBuffer* data, bool allDataReceived) +void ImageSource::setDataL(SharedBuffer* data, bool allDataReceived) { // Make the decoder by sniffing the bytes. // This method will examine the data and instantiate an instance of the appropriate decoder plugin. @@ -110,11 +110,11 @@ if( !allDataReceived ) return; if( !m_decoder ) // sync decoding if no observer is passed - TRAP_IGNORE( m_decoder = CAnimationDecoder::NewL( NULL ) ); + m_decoder = CAnimationDecoder::NewL( NULL ); if( m_decoder ) { TPtrC8 ptr( (const TUint8*)data->data(), data->size() ); TPtrC16 ptr16(m_mimeType.des()); - TRAP_IGNORE( m_decoder->OpenL( ptr, &ptr16, ETrue ) ); + m_decoder->OpenL( ptr, &ptr16, ETrue ); } } diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/graphics/symbian/ImageSymbian.cpp --- a/webengine/osswebengine/WebCore/platform/graphics/symbian/ImageSymbian.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/graphics/symbian/ImageSymbian.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -25,6 +25,7 @@ */ #include "config.h" +#include "ImageSymbian.h" #include "BitmapImage.h" #include "FloatRect.h" #include "ImageObserver.h" @@ -183,8 +184,13 @@ // Feed all the data we've seen so far to the image decoder. m_allDataReceived = allDataReceived; - m_source.setData(m_data.get(), allDataReceived); - + TRAPD(oomErr, m_source.setDataL(m_data.get(), allDataReceived)); + if (oomErr == KErrNoMemory) + { + //We are OOM, this should be reported as an error and image load + // must be stopped. + return false; + } // Image properties will not be available until the first frame of the file // reaches kCGImageStatusIncomplete. return isSizeAvailable(); @@ -368,13 +374,11 @@ #endif static HBufC* iconFileNameBuf = NULL; -struct cleanupIconFileName { - ~cleanupIconFileName() { + +void cleanupIconFileName() { delete iconFileNameBuf; iconFileNameBuf = NULL; - } -}; -struct cleanupIconFileName cleanIconFileName; +} TPtrC iconFileName() { diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/graphics/symbian/ImageSymbian.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/osswebengine/WebCore/platform/graphics/symbian/ImageSymbian.h Thu Aug 27 07:44:59 2009 +0300 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#ifndef IMAGESYMBIAN_H +#define IMAGESYMBIAN_H + +namespace WebCore { + +void cleanupIconFileName(); + +}; + +#endif //IMAGESYMBIAN_H diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/network/symbian/HttpConnUtils.cpp --- a/webengine/osswebengine/WebCore/platform/network/symbian/HttpConnUtils.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/network/symbian/HttpConnUtils.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -372,6 +372,19 @@ HttpFilterCommonStringsExt::GetTable()); break; } + case EEucKr: + { + charsetHdr = aStringPool.StringF(HttpFilterCommonStringsExt::EEucKr, + HttpFilterCommonStringsExt::GetTable()); + break; + } + + case EKsc5601: + { + charsetHdr = aStringPool.StringF(HttpFilterCommonStringsExt::EKsc5601, + HttpFilterCommonStringsExt::GetTable()); + break; + } case EIso2022Jp: // This value can be in the settings only if Japanese is supported, no variation needed { charsetHdr = aStringPool.StringF(HttpFilterCommonStringsExt::EIso2022Jp, diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/network/symbian/HttpDefs.h --- a/webengine/osswebengine/WebCore/platform/network/symbian/HttpDefs.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/network/symbian/HttpDefs.h Thu Aug 27 07:44:59 2009 +0300 @@ -53,6 +53,8 @@ EEucJp, EIso2022Jp, EWindows874, + EEucKr, + EKsc5601, EDummyLast }; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/network/symbian/HttpRequestHeaderManager.cpp --- a/webengine/osswebengine/WebCore/platform/network/symbian/HttpRequestHeaderManager.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/network/symbian/HttpRequestHeaderManager.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -147,8 +147,8 @@ const TStringTable& stringTable = m_Session.GetTable(); TPtrC8 acceptMimeTypes; HBufC8* tmpBuf = NULL; - CleanupStack::PushL(tmpBuf); - // + TInt pushCounter( 0 ); + if(aRequest.mainLoad()) { acceptMimeTypes.Set(*TopLevelAcceptStringL(aRequest)); } else { @@ -159,6 +159,8 @@ if(reqMimeTypes.Length() > 0) { // WebCore has set accept MIME type - leave alone tmpBuf = HBufC8::NewL(reqMimeTypes.Length()); + CleanupStack::PushL(tmpBuf); + ++pushCounter; tmpBuf->Des().Copy(reqMimeTypes); acceptMimeTypes.Set(*tmpBuf); } else { @@ -166,11 +168,11 @@ acceptMimeTypes.Set(KStarSlashStar8); } } - // RStringF str = m_StringPool.OpenFStringL(acceptMimeTypes); CleanupClosePushL(str); + ++pushCounter; aHeaders.SetFieldL(m_StringPool.StringF(HTTP::EAccept, stringTable), str); - CleanupStack::PopAndDestroy(2); // str, tmpBuf + CleanupStack::PopAndDestroy(pushCounter); } // ----------------------------------------------------------------------------- diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/network/symbian/HttpSessionManager.cpp --- a/webengine/osswebengine/WebCore/platform/network/symbian/HttpSessionManager.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/network/symbian/HttpSessionManager.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -115,7 +115,6 @@ THTTPHdrVal enableTranspHndlrPriority(strP.StringF(HTTP::EEnableTranspHndlrPriority, RHTTPSession::GetTable())); connInfo.SetPropertyL(strP.StringF(HTTP::ETranspHndlrPriority, RHTTPSession::GetTable()), enableTranspHndlrPriority); - strP.OpenL( HttpFilterCommonStringsExt::GetTable() ); strP.OpenL( HttpFilterCommonStringsExt::GetLanguageTable() ); strP.OpenL( HttpFilterCommonStringsAddition::GetTable() ); diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/network/symbian/HttpSessionManager.h --- a/webengine/osswebengine/WebCore/platform/network/symbian/HttpSessionManager.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/network/symbian/HttpSessionManager.h Thu Aug 27 07:44:59 2009 +0300 @@ -43,7 +43,7 @@ class SelfDownloadContentHandler; const int KHttpMaxConnectionNum = 7; -const int KHttpMaxTransactionNumPerConnection = 5; +const int KHttpMaxTransactionNumPerConnection = 2; const int KHttpBatchingBuffSize = 2*1400; const int KHttpReceiveBuffSize = 32*1024; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/network/symbian/HttpUiCallbacks.cpp --- a/webengine/osswebengine/WebCore/platform/network/symbian/HttpUiCallbacks.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/network/symbian/HttpUiCallbacks.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -48,6 +48,7 @@ { m_error = KErrNone; m_scheduler = NULL; + m_brctl = NULL; } HttpUiCallbacks::~HttpUiCallbacks() @@ -56,6 +57,12 @@ m_scheduler->Cancel(); delete m_scheduler; } + m_brctl = NULL; +} + +void HttpUiCallbacks::SetBrowserControl(CBrCtl* aBrctl) +{ + m_brctl = aBrctl; } TInt HttpUiCallbacks::handleErrorCb(TAny* aPtr) @@ -79,7 +86,14 @@ { TInt error = KErrNone; if( aConnectionPtr && aSockSvrHandle && aNewConn ){ - TRAP(error, brctl()->brCtlSpecialLoadObserver()->NetworkConnectionNeededL(aConnectionPtr, aSockSvrHandle, aNewConn, aBearerType)); + if(m_brctl && m_brctl->webView()->widgetExtension()){ + TRAP(error, m_brctl->brCtlSpecialLoadObserver()->NetworkConnectionNeededL(aConnectionPtr, aSockSvrHandle, aNewConn, aBearerType)); + } + else + { + TRAP(error, brctl()->brCtlSpecialLoadObserver()->NetworkConnectionNeededL(aConnectionPtr, aSockSvrHandle, aNewConn, aBearerType)); + } + if( error == KErrNone && *aConnectionPtr ) { RConnection* connPtr = REINTERPRET_CAST( RConnection*, *aConnectionPtr ); TConnectionInfoBuf connInfoBuf; @@ -195,7 +209,12 @@ event = TBrCtlDefs::EEventSecureItemInNonSecurePage; break; } - + case EReEnteringSecurePage: + { + resId = 0; + event = TBrCtlDefs::EEventEnteringSecurePage; + break; + } default: { resId = 0; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/network/symbian/HttpUiCallbacks.h --- a/webengine/osswebengine/WebCore/platform/network/symbian/HttpUiCallbacks.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/network/symbian/HttpUiCallbacks.h Thu Aug 27 07:44:59 2009 +0300 @@ -40,6 +40,7 @@ ERedirectConfirmation, ERepostConfirmation, ESecureItemInNonSecurePage, + EReEnteringSecurePage, // add new items here EEnterStatusNone }; @@ -147,7 +148,8 @@ */ virtual void HandleDownloadEventL(TUint aTransactionID, TBrCtlDownloadEvent aDownloadEvent, - TUint aValue) {} + TUint aValue) {} + void SetBrowserControl(CBrCtl* aBrctl) ; private: void handleError(); @@ -165,6 +167,7 @@ private: // data CPeriodic* m_scheduler; int m_error; + CBrCtl* m_brctl; }; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/network/symbian/PostDataItem.cpp --- a/webengine/osswebengine/WebCore/platform/network/symbian/PostDataItem.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/network/symbian/PostDataItem.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -111,7 +111,7 @@ // FileDataItem::~FileDataItem() { - if(m_fileLocked) { + if(m_fileLocked && m_fileSize > 0 ) { m_file.UnLock(0, m_fileSize); } m_file.Close(); @@ -132,8 +132,11 @@ // size of the file User::LeaveIfError(m_file.Open(rfs, fileName->Des(), EFileRead | EFileShareReadersOnly)); User::LeaveIfError(m_file.Size(m_fileSize)); + if (m_fileSize > 0) + { User::LeaveIfError(m_file.Lock(0, m_fileSize)); m_fileLocked = ETrue; + } CleanupStack::PopAndDestroy();// fileName } diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/network/symbian/ResourceHandleManagerSymbian.cpp --- a/webengine/osswebengine/WebCore/platform/network/symbian/ResourceHandleManagerSymbian.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/network/symbian/ResourceHandleManagerSymbian.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -40,15 +40,13 @@ static CResourceHandleManager* s_self = 0; -struct cleanupHandleManager { - ~cleanupHandleManager() { - if(s_self){ - delete s_self; - s_self = 0; - } +void cleanupHandleManager() +{ + if(s_self){ + delete s_self; + s_self = 0; } -}; -static cleanupHandleManager deleteResourceHandleManager; +} CResourceHandleManager::CResourceHandleManager() { diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/network/symbian/ResourceHandleManagerSymbian.h --- a/webengine/osswebengine/WebCore/platform/network/symbian/ResourceHandleManagerSymbian.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/network/symbian/ResourceHandleManagerSymbian.h Thu Aug 27 07:44:59 2009 +0300 @@ -25,6 +25,8 @@ namespace WebCore { +void cleanupHandleManager(); + struct ResourceRequest; class ResourceResponse; @@ -47,8 +49,6 @@ private: CResourceHandleManager(); - - }; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/network/symbian/ResourceLoaderDelegate.cpp --- a/webengine/osswebengine/WebCore/platform/network/symbian/ResourceLoaderDelegate.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/network/symbian/ResourceLoaderDelegate.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -85,6 +85,8 @@ if (r.mainLoad() && frame == frame->page()->mainFrame() && err != KErrNone && err != KErrCancel) { m_httpSessionManager.uiCallback()->reportError(mapHttpErrors(err)); } + CBrCtl* brctl = control(frame); + m_httpSessionManager.uiCallback()->SetBrowserControl(brctl); return connection; } @@ -169,62 +171,70 @@ HttpUiCallbacks::TEnterStatus enterStatus = HttpUiCallbacks::EEnterStatusNone; bool ret = true; - if (brctl->settings()->brctlSetting(TBrCtlDefs::ESettingsSecurityWarnings)) { - TUriParser8 parser; - bool secureUrl = false; - bool currentSecureUrl = false; - if (parser.Parse(request.url().des()) == KErrNone) { - TPtrC8 scheme = parser.Extract( EUriScheme ); - secureUrl = scheme.CompareF(KHttps) == 0; + TUriParser8 secureUrlParser; + TUriParser8 currentSecureUrlParser; + bool secureUrl = false; + bool currentSecureUrl = false; + if (secureUrlParser.Parse(request.url().des()) == KErrNone) { + TPtrC8 scheme = secureUrlParser.Extract( EUriScheme ); + secureUrl = scheme.CompareF(KHttps) == 0; + } + if (frame->loader() && frame->loader()->documentLoader()) { + TPtrC8 url = frame->loader()->documentLoader()->URL().des(); + if (currentSecureUrlParser.Parse(url) == KErrNone) { + TPtrC8 scheme = currentSecureUrlParser.Extract( EUriScheme ); + currentSecureUrl = scheme.CompareF(KHttps) == 0; } - if (frame->loader() && frame->loader()->documentLoader()) { - TPtrC8 url = frame->loader()->documentLoader()->URL().des(); - TUriParser8 parser; - if (parser.Parse(url) == KErrNone) { - TPtrC8 scheme = parser.Extract( EUriScheme ); - currentSecureUrl = scheme.CompareF(KHttps) == 0; + } + if (request.mainLoad()) { + if (!frame->ownerElement()) { + if (currentSecureUrl) { + if (!secureUrl) { + // secure -> non secure + if (request.httpMethod() == "POST") { + enterStatus = HttpUiCallbacks::ESubmittingToNonSecurePage; + } + else { + enterStatus = HttpUiCallbacks::EExitingSecurePage; + } + } // if (!secureUrl) + else { + // secure -> secure + if( secureUrlParser.Extract(EUriHost).Compare( + currentSecureUrlParser.Extract(EUriHost)) ) { + enterStatus = HttpUiCallbacks::EEnteringSecurePage; + } + else { + enterStatus = HttpUiCallbacks::EReEnteringSecurePage; + } + } + } // if (currentSecureUrl) + else { + if (secureUrl) { + // non secure -> secure + enterStatus = HttpUiCallbacks::EEnteringSecurePage; + } } - } - if (request.mainLoad()) { - if (!frame->ownerElement()) { - if (currentSecureUrl) { - if (!secureUrl) { - // secure -> non secure - if (request.httpMethod() == "POST") { - enterStatus = HttpUiCallbacks::ESubmittingToNonSecurePage; - } - else { - enterStatus = HttpUiCallbacks::EExitingSecurePage; - } - } // if (!secureUrl) + } // if (!frame->ownerElement()) + } + else + { + if (currentSecureUrl) { + if (!secureUrl) { + // Ask once per page. If we already asked, just use the previous user decision + if (topDocumentLoader->userWasAskedToLoadNonSecureItem()) { + ret = topDocumentLoader->userAgreedToLoadNonSecureItem(); } else { - if (secureUrl) { - // non secure -> secure - enterStatus = HttpUiCallbacks::EEnteringSecurePage; - } - } // if (currentSecureUrl) - } // if (!frame->ownerElement()) - } - else - { - if (currentSecureUrl) { - if (!secureUrl) { - // Ask once per page. If we already asked, just use the previous user decision - if (topDocumentLoader->userWasAskedToLoadNonSecureItem()) { - ret = topDocumentLoader->userAgreedToLoadNonSecureItem(); - } - else { - enterStatus = HttpUiCallbacks::ESomeItemsNotSecure; - } - } - } - else { - if (secureUrl) { - enterStatus = HttpUiCallbacks::ESecureItemInNonSecurePage; + enterStatus = HttpUiCallbacks::ESomeItemsNotSecure; } } } + else { + if (secureUrl) { + enterStatus = HttpUiCallbacks::ESecureItemInNonSecurePage; + } + } } if (enterStatus != HttpUiCallbacks::EEnterStatusNone) { int err = m_httpSessionManager.uiCallback()->aboutToLoadPage(brctl, enterStatus); diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/symbian/FontSymbian.cpp --- a/webengine/osswebengine/WebCore/platform/symbian/FontSymbian.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/symbian/FontSymbian.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -34,6 +34,8 @@ namespace WebCore { +const UChar UnicodeZeroWidthSpace = 0x200b; + static void notSupported() { __ASSERT_ALWAYS( 0, User::Panic( _L("Font:"), 1 ) ); } void Font::drawGlyphs(GraphicsContext* graphicsContext, const FontData* font, const GlyphBuffer& glyphBuffer, @@ -111,6 +113,13 @@ // word spacing bitgc.SetWordJustification(m_wordSpacing*numSpaces + style.padding(), numSpaces); +#if PLATFORM(SYMBIAN) + TLanguage uilang = User::Language(); + if(uilang == ELangKorean) + { + startPos.iY -= 1; + } +#endif // see if we need a temporary buffer if( indexOfFirstNonRegularSpace > -1 || isSmallCaps() || style.rtl()){ HBufC* text = 0; @@ -129,7 +138,9 @@ if (indexOfFirstNonRegularSpace > -1) { for(; indexOfFirstNonRegularSpacecreateFormFillPopup(font->Font()); } if (!m_popup) { diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/symbian/PlatformKeyEventSymbian.cpp --- a/webengine/osswebengine/WebCore/platform/symbian/PlatformKeyEventSymbian.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/symbian/PlatformKeyEventSymbian.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -23,6 +23,7 @@ #include #include #include +#include namespace WebCore { @@ -660,10 +661,8 @@ PlatformKeyboardEvent::PlatformKeyboardEvent( TKeyEvent event, TEventCode eventCode, bool forceAutoRepeat ) : m_keyIdentifier(KeyIdentifierForKeyEvent(event.iCode)) - , m_isKeyUp( eventCode == EEventKeyUp ) - //***** FL added from r12765 *****// - , m_isKeyDown( eventCode == EEventKeyDown ) - //**********// + , m_isKeyUp( eventCode == EEventKeyUp || eventCode == EEventUser + 2) + , m_isKeyDown( eventCode == EEventKeyDown || eventCode == EEventUser + 1 ) , m_autoRepeat(event.iRepeats>0 || forceAutoRepeat ) , m_WindowsKeyCode(WindowsKeyCodeForKeyEvent(event)) , m_shiftKey( event.iModifiers & EModifierShift ) @@ -674,8 +673,11 @@ { TText c = event.iCode; + if (eventCode == EEventUser + 1 || eventCode == EEventUser + 2) { + m_symbianEvent.iCode = 0; + } m_text = String(TPtrC(&c,1)); - m_unmodifiedText = String(TPtrC(&c,1));; // ### FIXME should do something else + m_unmodifiedText = String(TPtrC(&c,1)); // ### FIXME should do something else // Turn 0x7F into 8, because backspace needs to always be 8. if (m_text == "\x7F") @@ -694,5 +696,31 @@ } } +String PlatformKeyboardEvent::text() const +{ + return m_text; } + +bool PlatformKeyboardEvent::isNaviKey(TUint code) const +{ + return ( code == EKeyUpArrow // North + || code == EStdKeyUpArrow // : + || code == EKeyRightUpArrow // Northeast + || code == EStdKeyDevice11 // : + || code == EKeyRightArrow // East + || code == EStdKeyRightArrow // : + || code == EKeyRightDownArrow // Southeast + || code == EStdKeyDevice12 // : + || code == EKeyDownArrow // South + || code == EStdKeyDownArrow // : + || code == EKeyLeftDownArrow // Southwest + || code == EStdKeyDevice13 // : + || code == EKeyLeftArrow // West + || code == EStdKeyLeftArrow // : + || code == EKeyLeftUpArrow // Northwest + || code == EStdKeyDevice10 ); // : +} + +} + diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/symbian/PopupMenuSymbian.cpp --- a/webengine/osswebengine/WebCore/platform/symbian/PopupMenuSymbian.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/symbian/PopupMenuSymbian.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -36,6 +36,7 @@ #include #include +const TInt KDefaultSize(1); namespace WebCore { static void ResetAndDestroy(TAny *aPtr); @@ -60,8 +61,9 @@ WebView* wv = kit(v->frame()->page()); MBrCtlDialogsProvider* dialogs = wv->brCtl()->brCtlDialogsProvider(); int size = client()->listSize(); - CArrayFix* options = new CArrayFixFlat(size); - RPointerArray items(size); + CArrayFix* options = + new CArrayFixFlat((size>0) ? size : KDefaultSize); + RPointerArray items((size>0) ? size : KDefaultSize); CleanupStack::PushL(TCleanupItem(&ResetAndDestroy,&items)); for (int i = 0; i < size; i++) { @@ -97,7 +99,6 @@ m_popupClient->valueChanged(newIndex); } delete options; - } void PopupMenu::hide() diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/symbian/SharedTimerSymbian.cpp --- a/webengine/osswebengine/WebCore/platform/symbian/SharedTimerSymbian.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/symbian/SharedTimerSymbian.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -118,4 +118,9 @@ stopSharedTimer(); } +void initSharedTimer() + { + shutdownInProgress = false; + } + } diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/symbian/StaticObjectsContainer.cpp --- a/webengine/osswebengine/WebCore/platform/symbian/StaticObjectsContainer.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/symbian/StaticObjectsContainer.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -35,6 +35,7 @@ #include "WebCannedImages.h" #include "OOMHandler.h" #include "SharedTimer.h" +#include "TextEncoding.h" #include "TextEncodingRegistry.h" #include "CSSStyleSelector.h" #include "RenderStyle.h" @@ -43,10 +44,22 @@ #include "StreamingTextCodecSymbian.h" #include "HTMLNames.h" #include "XMLNames.h" +#include "MediaFeatureNames.h" +#include "EventNames.h" #include "FontCache.h" #include "RenderThemeSymbian.h" #include "qualifiedname.h" #include "XMLTokenizer.h" +#include "Document.h" +#include "StyleElement.h" +#include "bidi.h" +#include "RenderBox.h" +#include "FontCache.h" +#include "MIMETypeRegistry.h" +#include "ImageSymbian.h" +#include "ResourceHandleManagerSymbian.h" +#include "TextBreakIteratorSymbian.h" +#include "HTMLElementFactory.h" #include #include "WidgetEngineBridge.h" @@ -97,6 +110,7 @@ } } m_oomHandler = new OOMHandler(); + initSharedTimer(); } StaticObjectsContainer::~StaticObjectsContainer() @@ -120,12 +134,29 @@ gInstance = NULL; deletePageStaticData(); CSSStyleSelector::deleteDefaultStyle(); + deleteTextEncodings(); deleteEncodingMaps(); RenderStyle::deleteDefaultRenderStyle(); Cache::deleteStaticCache(); TextCodecSymbian::deleteStatAvailCharsets(); QualifiedName::cleanup(); XMLNames::remove(); + cleanupChangedDocuments(); + mappedAttributeCleaner(); + cleanupMidpoints(); + cleanOverridSizeMap(); + cleanupFontDataCache(); + cleanupMimeTypes(); + cleanupHandleManager(); + cleanupFuncMap(); + cleanupIconFileName(); + cleanupIterators(); + +#ifndef __WINSCW__ + WebCore::MediaFeatureNames::remove(); + WebCore::EventNames::remove(); +#endif // __WINSCW__ + // HTMLNames::remove() will destroy the AtomicString table // All other atomic string destruction must be done before this call // @@ -240,37 +271,23 @@ } #if defined(BRDO_LIW_FF) -MDeviceBridge* StaticObjectsContainer::getDeviceBridgeL() +RLibrary& StaticObjectsContainer::getDeviceBridgeLibL() { - MDeviceBridge* device(NULL); - if( !m_deviceLibrary.Handle() ) { _LIT( KDeviceDLLName, "jsdevice.dll" ); User::LeaveIfError( m_deviceLibrary.Load(KDeviceDLLName) ); } - - TLibraryFunction device_entry = m_deviceLibrary.Lookup(1); - if (device_entry) { - device = (MDeviceBridge*) device_entry(); - } - return device; + return m_deviceLibrary; } #endif -MWidgetEngineBridge* StaticObjectsContainer::getWidgetEngineBridgeL() +RLibrary& StaticObjectsContainer::getWidgetEngineBridgeLibL() { - MWidgetEngineBridge* widget(NULL); - if( !m_widgetLibrary.Handle() ) { _LIT( KBrowserWidgetEngineName, "widgetengine.dll" ); User::LeaveIfError( m_widgetLibrary.Load(KBrowserWidgetEngineName) ); } - - TLibraryFunction entry = m_widgetLibrary.Lookup(1); - if (entry) { - widget = (MWidgetEngineBridge*) entry(); - } - return widget; + return m_widgetLibrary; } CBrCtl* StaticObjectsContainer::brctl() const diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/symbian/StaticObjectsContainer.h --- a/webengine/osswebengine/WebCore/platform/symbian/StaticObjectsContainer.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/symbian/StaticObjectsContainer.h Thu Aug 27 07:44:59 2009 +0300 @@ -73,9 +73,9 @@ void setPluginFullscreen(bool val) { m_pluginFullscreen = val; } bool isPluginFullscreen() { return m_pluginFullscreen; } #if defined(BRDO_LIW_FF) - MDeviceBridge* getDeviceBridgeL(); + RLibrary& getDeviceBridgeLibL(); #endif - MWidgetEngineBridge* getWidgetEngineBridgeL(); + RLibrary& getWidgetEngineBridgeLibL(); RenderTheme* theme(); virtual ~StaticObjectsContainer(); diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/symbian/TextBreakIteratorSymbian.cpp --- a/webengine/osswebengine/WebCore/platform/symbian/TextBreakIteratorSymbian.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/symbian/TextBreakIteratorSymbian.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -21,7 +21,7 @@ * */ -#include "config.h" +#include "TextBreakIteratorSymbian.h" #include "TextBreakIterator.h" #include #include @@ -168,17 +168,15 @@ static WordBreakIteratorSymbian *wordIterator = 0; static CharBreakIteratorSymbian *charIterator = 0; static LineBreakIteratorSymbian *lineIterator = 0; -struct cleanupIterators { - ~cleanupIterators() { - delete wordIterator; - wordIterator = NULL; - delete charIterator; - charIterator = NULL; - delete lineIterator; - lineIterator = NULL; - } -}; -static cleanupIterators deleteBreakIterator; +void cleanupIterators() +{ + delete wordIterator; + wordIterator = NULL; + delete charIterator; + charIterator = NULL; + delete lineIterator; + lineIterator = NULL; +} TextBreakIterator* wordBreakIterator(const UChar* string, int length) { diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/symbian/TextBreakIteratorSymbian.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/osswebengine/WebCore/platform/symbian/TextBreakIteratorSymbian.h Thu Aug 27 07:44:59 2009 +0300 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#ifndef TEXTBREAKITERATORSYMBIAN_H +#define TEXTBREAKITERATORSYMBIAN_H + +#include "config.h" + +namespace WebCore { + + void cleanupIterators(); + +}; + +#endif //TEXTBREAKITERATORSYMBIAN_H diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/symbian/bitmap/AnimationDecoder.cpp --- a/webengine/osswebengine/WebCore/platform/symbian/bitmap/AnimationDecoder.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/symbian/bitmap/AnimationDecoder.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -41,6 +41,7 @@ } using namespace WebCore; +CSynDecodeThread *CAnimationDecoder::iSyncDecodeThread = NULL; // ============================ MEMBER FUNCTIONS =============================== // ----------------------------------------------------------------------------- @@ -55,7 +56,6 @@ , iCurLoopCount( -1 ) , iSyncBitmapHandle(-1) , iSyncMaskHandle(-1) - , iSyncDecodeThread(NULL) , iDecodeInProgress(ETrue) { if (CActiveScheduler::Current()) @@ -96,7 +96,6 @@ delete iDecoder, iDecoder = NULL; } - delete iSyncDecodeThread; iSyncDecodeThread = NULL; delete iAnimationBitmap, iAnimationBitmap = NULL; delete iDestination, iDestination = NULL; if(iDrmContent) @@ -115,23 +114,16 @@ iRawDataComplete = ETrue; delete iDestination; iDestination = NULL; - delete iSyncDecodeThread; - iSyncDecodeThread = NULL; - iSyncDecodeThread = CSynDecodeThread::NewL(); + if(!iSyncDecodeThread) { // first time, create decoder thread + iSyncDecodeThread = CSynDecodeThread::NewL(); + } - TRequestStatus status; - if (iSyncDecodeThread->Decode( aData, &status ) == KErrNone) { - User::WaitForRequest(status); - if( status == KErrNone ) { - iSyncDecodeThread->Handle(iSyncBitmapHandle, iSyncMaskHandle); - iSizeAvailable = ETrue; - } - } - if (!iSizeAvailable) { - delete iSyncDecodeThread; - iSyncDecodeThread = NULL; - } + if (iSyncDecodeThread->Decode(aData) == KErrNone) { + iSyncDecodeThread->Handle(iSyncBitmapHandle, iSyncMaskHandle); + Destination(); // duplicate bitmap handles + iSizeAvailable = ETrue; + } } CMaskedBitmap* CAnimationDecoder::Destination() @@ -151,8 +143,7 @@ iSyncBitmapHandle = -1; iSyncMaskHandle = -1; } - delete iSyncDecodeThread; - iSyncDecodeThread = NULL; + return iDestination; } //============================================================================= @@ -242,7 +233,7 @@ iRawDataComplete = aIsComplete; - if(iDecoder->ValidDecoder() && iDecoder->IsImageHeaderProcessingComplete()) + if(iDecoder && iDecoder->ValidDecoder() && iDecoder->IsImageHeaderProcessingComplete()) StartDecodingL(); else // remove me when incremental image rendering gets supported diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/symbian/bitmap/AnimationDecoder.h --- a/webengine/osswebengine/WebCore/platform/symbian/bitmap/AnimationDecoder.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/symbian/bitmap/AnimationDecoder.h Thu Aug 27 07:44:59 2009 +0300 @@ -224,7 +224,7 @@ TInt iSyncBitmapHandle; TBool iSyncMaskHandle; TBool iDecodeInProgress; - CSynDecodeThread* iSyncDecodeThread; + static CSynDecodeThread* iSyncDecodeThread; // sync decoder thread HBufC8* iDrmContent; }; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/symbian/bitmap/SyncDecodeThread.cpp --- a/webengine/osswebengine/WebCore/platform/symbian/bitmap/SyncDecodeThread.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/symbian/bitmap/SyncDecodeThread.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -40,6 +40,7 @@ TInt iMaskHandle; }; +enum DecoderState {ENewDecodeRequest, EDecodeInProgress, EDecoderIdle}; class CSynDecoder : public CActive { public: // Constructors and destructor @@ -47,25 +48,35 @@ virtual ~CSynDecoder(); public: - TInt Open(BmElem* aElem); + void Open(const TDesC8& aData, TRequestStatus *status); + void Lock() { iDecoderLock.Wait(); } + void Release() { iDecoderLock.Signal(); } private: // From base class CActive void DoCancel(); void RunL(); TInt RunError( TInt aError ); void SignalParent( TInt aError ); + void StartDecodeL(); + void SetIdle(); private: // Private constructors CSynDecoder(); - void ConstructL() {} + void ConstructL(); private: // Data - BmElem* iElem; // not owned - CImageDecoder* iDecoder; // owned - CMaskedBitmap* iBitmap; // owned + BmElem iElem; + CImageDecoder* iDecoder; + CMaskedBitmap* iBitmap; + RFastLock iDecoderLock; + DecoderState iDecodeState; + RThread syncThread; + +friend class CSynDecodeThread; }; // FORWARD DECLARATIONS +CSynDecoder *CSynDecodeThread::iSyncDecoder = NULL; // ============================= LOCAL FUNCTIONS =============================== @@ -80,6 +91,12 @@ CActiveScheduler::Add( this ); } +void CSynDecoder::ConstructL() +{ + User::LeaveIfError(iDecoderLock.CreateLocal()); + SetIdle(); +} + CSynDecoder* CSynDecoder::NewL() { CSynDecoder* self = new (ELeave) CSynDecoder(); @@ -94,46 +111,67 @@ Cancel(); delete iDecoder; delete iBitmap; + iDecoderLock.Close(); } // ----------------------------------------------------------------------------- -// OpenL +// Decode - Decode request submitted from client thread // ----------------------------------------------------------------------------- -TInt CSynDecoder::Open(BmElem* aElem) +void CSynDecoder::Open(const TDesC8& aData, TRequestStatus *status) +{ + iElem.iRequestStatus = status; + iElem.iData.Set(aData); + iElem.iParentThreadId = RThread().Id(); + iElem.iBitmapHandle = 0; + iElem.iMaskHandle = 0; + iDecodeState = ENewDecodeRequest; +} + +void CSynDecoder::SetIdle() { - iElem = aElem; - // reset decoder - TRAPD( err, - iDecoder = CImageDecoder::DataNewL(CEikonEnv::Static()->FsSession(), iElem->iData); - iBitmap = CMaskedBitmap::NewL(); - ); - if( err != KErrNone ) - return err; + iDecodeState = EDecoderIdle; + if(!IsActive()) { + iStatus = KRequestPending; + SetActive(); + } +} +void CSynDecoder::StartDecodeL() +{ + if(iDecoder) { + delete iDecoder; + iDecoder = NULL; + } + if(iBitmap) { + delete iBitmap; + iBitmap = NULL; + } + + iDecoder = CImageDecoder::DataNewL(CEikonEnv::Static()->FsSession(), iElem.iData); + iBitmap = CMaskedBitmap::NewL(); + TFrameInfo frameInfo = iDecoder->FrameInfo( 0 ); - + TInt err = KErrNone; if( frameInfo.iFlags & TFrameInfo::ETransparencyPossible ) { TDisplayMode maskmode = (frameInfo.iFlags & TFrameInfo::EAlphaChannel) ? EGray256 : EGray2; - err = iBitmap->Create( frameInfo.iOverallSizeInPixels, EColor64K, maskmode ); } else err = iBitmap->Create( frameInfo.iOverallSizeInPixels, EColor64K ); - // - if( err != KErrNone ) - return err; - // start decoding + User::LeaveIfError(err); + + // start decoding CFbsBitmap& dstBitmap = iBitmap->BitmapModifyable(); - CFbsBitmap& dstMask = iBitmap->MaskModifyable(); - + CFbsBitmap& dstMask = iBitmap->MaskModifyable(); if( ( frameInfo.iFlags & TFrameInfo::ETransparencyPossible ) && dstMask.Handle() ) iDecoder->Convert( &iStatus, dstBitmap, dstMask, 0 ); else { dstMask.Reset(); iDecoder->Convert( &iStatus, dstBitmap, 0 ); } + + iDecodeState = EDecodeInProgress; SetActive(); - return KErrNone; } // ----------------------------------------------------------------------------- @@ -143,25 +181,31 @@ { iDecoder->Cancel(); SignalParent( KErrCancel ); + SetIdle(); } // ----------------------------------------------------------------------------- // CSynDecoder::RunL // ----------------------------------------------------------------------------- void CSynDecoder::RunL() -{ - SignalParent( iStatus.Int() ); - - if( iStatus.Int() == KErrNone ) { - iElem->iBitmapHandle = iBitmap->Bitmap().Handle(); - iElem->iMaskHandle = iBitmap->Mask().Handle(); - - RThread self; - self.Suspend(); - self.Close(); - // destroy - CActiveScheduler::Stop(); - } +{ + switch(iDecodeState) + { + case ENewDecodeRequest: + StartDecodeL(); // start async decode + break; + case EDecodeInProgress: + if( iStatus.Int() == KErrNone ) { + iElem.iBitmapHandle = iBitmap->Bitmap().Handle(); + iElem.iMaskHandle = iBitmap->Mask().Handle(); + } + + SignalParent(iStatus.Int()); + SetIdle(); + break; + default: + SetIdle(); + } } // ----------------------------------------------------------------------------- @@ -169,7 +213,8 @@ // ----------------------------------------------------------------------------- TInt CSynDecoder::RunError(TInt aError) { - SignalParent( aError ); + SignalParent(aError); + SetIdle(); return KErrNone; } @@ -179,13 +224,11 @@ void CSynDecoder::SignalParent(TInt aError) { RThread parent; - parent.Open(iElem->iParentThreadId); - parent.RequestComplete(iElem->iRequestStatus, aError ); - parent.Close(); + parent.Open(iElem.iParentThreadId); + parent.RequestComplete(iElem.iRequestStatus, aError ); + parent.Close(); +} - if (aError != KErrNone) - CActiveScheduler::Stop(); -} CSynDecodeThread* CSynDecodeThread::NewL() { @@ -201,46 +244,45 @@ } CSynDecodeThread::~CSynDecodeThread() -{ - if(iUp) { - iDecoderThread.Resume(); - iDecoderThread.Kill(KErrNone); - iDecoderThread.Close(); - } - delete iElem; +{ + CActiveScheduler::Stop(); + iDecoderThread.Close(); +} + +void CSynDecodeThread::ConstructL() +{ + _LIT(KThreadName, "ImgDecoder"); + User::LeaveIfError(iDecoderThread.Create(KThreadName, CSynDecodeThread::ScaleInThread, KDefaultStackSize, KMinHeapSize, KMaxHeapSize, NULL)); + iDecoderThread.SetPriority(EPriorityMore); + TRequestStatus status = KRequestPending; + iDecoderThread.Rendezvous(status); + iDecoderThread.Resume(); + User::WaitForRequest(status); + User::LeaveIfError(status.Int()); } -void CSynDecodeThread::ConstructL() +TInt CSynDecodeThread::Decode(const TDesC8& aData) { -} - -TInt CSynDecodeThread::Decode(const TDesC8& aData, TRequestStatus* aRequestStatus) -{ - iElem = new (ELeave) BmElem; - iElem->iData.Set( aData ); - iElem->iParentThreadId = RThread().Id(); - iElem->iRequestStatus = aRequestStatus; + iSyncDecoder->Lock(); + + //notify decoder thread about new request + TRequestStatus status = KRequestPending; + iSyncDecoder->Open(aData, &status); + TRequestStatus *ps = &(iSyncDecoder->iStatus); + iDecoderThread.RequestComplete(ps, KErrNone); - TBuf<20> randName; - TTime t; - t.HomeTime(); - randName.Num( I64INT(t.Int64()) ); + //wait for decode complete + User::WaitForRequest(status); - TInt err = iDecoderThread.Create(randName, CSynDecodeThread::ScaleInThread, KDefaultStackSize, KMinHeapSize, KMaxHeapSize, iElem); - if (err==KErrNone) { - iUp = ETrue; - iDecoderThread.SetPriority(EPriorityMore); - *aRequestStatus = KRequestPending; - iDecoderThread.Resume(); - } - return err; + iSyncDecoder->Release(); + return status.Int(); } void CSynDecodeThread::Handle(TInt& aBitmapHandle, TInt& aMaskHandle) { - aBitmapHandle = iElem->iBitmapHandle; - aMaskHandle = iElem->iMaskHandle; + aBitmapHandle = iSyncDecoder->iElem.iBitmapHandle; + aMaskHandle = iSyncDecoder->iElem.iMaskHandle; } TInt CSynDecodeThread::ScaleInThread(TAny *aPtr) @@ -248,26 +290,23 @@ CTrapCleanup* cleanup = CTrapCleanup::New(); CActiveScheduler* as = new CActiveScheduler; CActiveScheduler::Install(as); - - CSynDecoder* decoder = NULL; - RFbsSession fbs; fbs.Connect(); - BmElem* elem = (BmElem*)aPtr; - TRAPD(err, decoder = CSynDecoder::NewL()); - - if (err == KErrNone && (err = decoder->Open(elem))== KErrNone ) - CActiveScheduler::Start(); - else { - RThread parent; - parent.Open(elem->iParentThreadId); - parent.RequestComplete(elem->iRequestStatus, err); - parent.Close(); + // start event loop + TRAPD(err, iSyncDecoder = CSynDecoder::NewL()); + if (err == KErrNone) { + // wait for decode request from client threads + RThread().Rendezvous(KErrNone); + CActiveScheduler::Start(); } - + else { + RThread().Rendezvous(err); + } + + // thread shutdown delete as; - delete decoder; + delete iSyncDecoder; delete cleanup; fbs.Disconnect(); return err; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/platform/symbian/bitmap/SyncDecodeThread.h --- a/webengine/osswebengine/WebCore/platform/symbian/bitmap/SyncDecodeThread.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/platform/symbian/bitmap/SyncDecodeThread.h Thu Aug 27 07:44:59 2009 +0300 @@ -25,6 +25,7 @@ class BmElem; class CMaskedBitmap; +class CSynDecoder; // CLASS DECLARATION /** * CSynDecodeThread @@ -43,7 +44,7 @@ public: - TInt Decode(const TDesC8& aData, TRequestStatus* aRequestStatus); + TInt Decode(const TDesC8& aData); void Handle( TInt& aBitmapHandle, TInt& aMaskHandle ); private: // Private constructors @@ -55,9 +56,8 @@ private: // Data // Image status & state - BmElem* iElem; RThread iDecoderThread; - TBool iUp; + static CSynDecoder* iSyncDecoder; }; #endif // SYNCDECODETHREAD_H diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/rendering/RenderBox.cpp --- a/webengine/osswebengine/WebCore/rendering/RenderBox.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/rendering/RenderBox.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -54,16 +54,14 @@ typedef WTF::HashMap OverrideSizeMap; static OverrideSizeMap* gOverrideSizeMap = 0; -struct cleanOverridSizeMap { - ~cleanOverridSizeMap() { - if( gOverrideSizeMap ) { - gOverrideSizeMap->clear(); - delete gOverrideSizeMap; - gOverrideSizeMap = 0; - } +void cleanOverridSizeMap() +{ + if( gOverrideSizeMap ) { + gOverrideSizeMap->clear(); + delete gOverrideSizeMap; + gOverrideSizeMap = 0; } -}; -struct cleanOverridSizeMap cleanOSizeMap; +} RenderBox::RenderBox(Node* node) : RenderObject(node) diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/rendering/RenderBox.h --- a/webengine/osswebengine/WebCore/rendering/RenderBox.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/rendering/RenderBox.h Thu Aug 27 07:44:59 2009 +0300 @@ -27,6 +27,8 @@ namespace WebCore { + void cleanOverridSizeMap(); + enum WidthType { Width, MinWidth, MaxWidth }; class RenderBox : public RenderObject { diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/rendering/bidi.cpp --- a/webengine/osswebengine/WebCore/rendering/bidi.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/rendering/bidi.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -95,18 +95,15 @@ static bool previousLineBrokeCleanly = true; static int numSpaces; -struct cleanupMidpoints { - ~cleanupMidpoints() { - if(smidpoints) - { - smidpoints->clear(); - delete smidpoints; - smidpoints = 0; - } - } -}; -static cleanupMidpoints deleteMidPoints; - +void cleanupMidpoints() +{ + if(smidpoints) + { + smidpoints->clear(); + delete smidpoints; + smidpoints = 0; + } +} static int getBPMWidth(int childValue, Length cssUnit) { diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebCore/rendering/bidi.h --- a/webengine/osswebengine/WebCore/rendering/bidi.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebCore/rendering/bidi.h Thu Aug 27 07:44:59 2009 +0300 @@ -34,6 +34,8 @@ class RenderObject; class InlineBox; +void cleanupMidpoints(); + struct BidiRun : BidiCharacterRun { BidiRun(int start, int stop, RenderObject* o, BidiContext* context, WTF::Unicode::Direction dir) : BidiCharacterRun(start, stop, context, dir) diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/formcontrols/WebFormFillPopup.cpp --- a/webengine/osswebengine/WebKit/s60/formcontrols/WebFormFillPopup.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/formcontrols/WebFormFillPopup.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -143,12 +143,8 @@ // y position TInt height = m_font->HeightInPixels()*KMaxNumToShow; - if (y + height > r.Height()) - y -= height; - else y += m_inputHeight; - //m_listBox->SetRect(TRect(TPoint(x, y), TSize(width, height))); SetRect(TRect(TPoint(x, y), TSize(width, height))); } } @@ -301,7 +297,9 @@ } void WebFormFillPopup::setLocationHintInDoc(const TRect& r, WebCore::Frame* frame) -{ +{ + if (!frame) + return; WebFrame* webFrame = kit(frame); // now lets reverse back to the root frame to figure out the screen position diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/group/browserengine/browserengine.mmp --- a/webengine/osswebengine/WebKit/s60/group/browserengine/browserengine.mmp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/group/browserengine/browserengine.mmp Thu Aug 27 07:44:59 2009 +0300 @@ -128,6 +128,8 @@ LIBRARY pbe.lib LIBRARY crypto.lib LIBRARY libpthread.lib +LIBRARY WidgetRegistryClient.lib + #ifdef BRDO_TOUCH_ENABLED_FF LIBRARY touchfeedback.lib #endif // BRDO_TOUCH_ENABLED_FF diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/group/common.mmpi --- a/webengine/osswebengine/WebKit/s60/group/common.mmpi Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/group/common.mmpi Thu Aug 27 07:44:59 2009 +0300 @@ -36,6 +36,7 @@ USERINCLUDE ../../../WebCore/bridge/symbian USERINCLUDE ../../../WebCore/platform USERINCLUDE ../../../WebCore/platform/symbian +USERINCLUDE ../../../WebCore/platform/graphics/symbian USERINCLUDE ../../../WebCore/platform/symbian/bitmap USERINCLUDE ../../../WebCore/loader/symbian USERINCLUDE ../../../WebCore/loader diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/misc/WebCharsetData.cpp --- a/webengine/osswebengine/WebKit/s60/misc/WebCharsetData.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/misc/WebCharsetData.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -67,6 +67,16 @@ {KCharacterSetIdentifierUnicodeBig, _S("ucs-2-big")}, {KCharacterSetIdentifierUnicodeLittle,_S("ucs-2-little")}, {0x1027508E, _S("iscii")}, + {0x2000E526, _S("euc-kr")}, + {0x2000E526, _S("csEUCKR")}, + {0x200113CD, _S("ko")}, + {0x200113CD, _S("ks_c_5601-1987")}, + {0x200113CD, _S("iso-ir-149")}, + {0x200113CD, _S("ks_c_5601-1989")}, + {0x200113CD, _S("ksc_5601")}, + {0x200113CD, _S("csksc56011987")}, + {0x200100FF, _S("ms949")}, + {0x200100FF, _S("cp949")}, {0, NULL} }; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/misc/WebTabbedNavigation.cpp --- a/webengine/osswebengine/WebKit/s60/misc/WebTabbedNavigation.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/misc/WebTabbedNavigation.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -107,6 +107,28 @@ StaticObjectsContainer::instance()->webCursor()->cursorUpdate(true); return true; } + // DOM can be changed so check if we are still inside the document + // If not reset tabbed navigation parameters to the closest point in document. + TSize contentSize = m_webView->mainFrame()->frameView()->contentSize(); + TPoint contentPos = m_webView->mainFrame()->frameView()->contentPos(); + TRect docRect = TRect(contentPos, contentSize - contentPos); + if (!docRect.Contains(m_focusPosition)) { + TInt viewW = m_webView->Rect().Width(); + TInt viewH = m_webView->Rect().Height(); + if (m_focusPosition.iX > contentSize.iWidth || + m_focusPosition.iX < contentPos.iX) { + m_focusPosition.iX = (horizontalDir == -1) ? contentPos.iX + viewW : contentPos.iX; + } + + if (m_focusPosition.iY > contentSize.iHeight || + m_focusPosition.iY < contentPos.iY) { + m_focusPosition.iY = (verticalDir == -1) ? contentPos.iY + viewH : contentPos.iY; + } + + m_selectedElementRect.SetRect(m_focusPosition.iX, m_focusPosition.iY, m_focusPosition.iX, m_focusPosition.iY); + m_node = NULL; + } + bool ret = m_firstNavigationOnPage; Frame* focusedFrame = m_webView->page()->focusController()->focusedFrame(); if (focusedFrame == NULL) focusedFrame = m_webView->page()->mainFrame(); @@ -188,7 +210,7 @@ f = f->tree()->traverseNext(); } // while ( f ) // Remember new selection - TPoint contentPos = m_webView->mainFrame()->frameView()->contentPos(); + contentPos = m_webView->mainFrame()->frameView()->contentPos(); if (selectedNode) { // Found an element to jump to m_selectedElementRect = selectedRect; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/misc/WebUtil.cpp --- a/webengine/osswebengine/WebKit/s60/misc/WebUtil.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/misc/WebUtil.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -152,7 +152,7 @@ // change to activated input box WebView* v = control(frame)->webView(); - if ((elType == TBrCtlDefs::EElementInputBox || elType == TBrCtlDefs::EElementTextAreaBox) && v && v->isEditable()) + if ((elType == TBrCtlDefs::EElementInputBox) && v && v->isEditable()) elType = TBrCtlDefs::EElementActivatedInputBox; return elType; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/plugins/NpnImplementation.cpp --- a/webengine/osswebengine/WebKit/s60/plugins/NpnImplementation.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/plugins/NpnImplementation.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -378,7 +378,17 @@ *((TInt*) aRetValue) = apId; break; - + case NPNVGenericParameter: { + PluginWin* pluginWin = (PluginWin*)aInstance->ndata; + if (pluginWin) { + void **v = (void **)aRetValue; + *v = pluginWin->pluginSkin()->genericElementArray(); + } + else { + err = NPERR_GENERIC_ERROR; + } + } + break; // for code consistency default: { *((TBool*) aRetValue) = EFalse; @@ -460,7 +470,8 @@ { PluginWin* pluginWin = (PluginWin*)aInstance->ndata; if (pluginWin) { - pluginWin->pluginDeactivate(); + TPoint* cursorPos = static_cast(aSetValue); + pluginWin->pluginDeactivate(*cursorPos); } } break; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/plugins/PluginHandler.cpp --- a/webengine/osswebengine/WebKit/s60/plugins/PluginHandler.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/plugins/PluginHandler.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -23,7 +23,7 @@ #include #include #include "config.h" -#include "..\..\bidi.h" +#include "../../bidi.h" // System includes #include @@ -586,12 +586,27 @@ // TInt PluginHandler::findPluginByExtension(const TDesC8& url) { + TInt idx = -1; + PluginInfo* pluginInfo = pluginInfoByExtention(url, &idx); + TInt ret = pluginInfo ? pluginInfo->m_handle : KErrNotFound; + return ret; +} + + +// ----------------------------------------------------------------------------- +// PluginHandler::pluginInfoByExtention +// aUrl - url that should be handle by plugin +// aExtIdx - return value of the index in the m_mimeFileExtensions for the extention +// returns a pointer to the PluginInfo object of the plugin that should handle aUrl +// ----------------------------------------------------------------------------- +PluginInfo* PluginHandler::pluginInfoByExtention(const TPtrC8& aUrl, TInt* aExtIdx) +{ LOAD_PLUGINS TInt pluginIndex; TInt extIndex; - TPtrC8 extPtr(url.Mid(url.LocateReverse('.') + 1)); + TPtrC8 extPtr(aUrl.Mid(aUrl.LocateReverse('.') + 1)); for (pluginIndex = 0; pluginIndex < m_pluginInfoArray.Count(); pluginIndex++) { for (extIndex = 0; @@ -599,12 +614,30 @@ m_mimeFileExtensions.Count(); extIndex++) { if (!m_pluginInfoArray[pluginIndex]->m_mimeFileExtensions[extIndex]->CompareF(extPtr)) { - return m_pluginInfoArray[pluginIndex]->m_handle; + *aExtIdx = extIndex; + return m_pluginInfoArray[pluginIndex]; } } } - return KErrNotFound; + return NULL; +} + + +// ----------------------------------------------------------------------------- +// PluginHandler::pluginMimeByExtention +// aUrl - url that should be handle by plugin +// returns pointer to mime type in m_mimeExtensionToTypeMap array +// ----------------------------------------------------------------------------- +HBufC* PluginHandler::pluginMimeByExtention(const TPtrC8& url) +{ + TInt idx = -1; + PluginInfo* pluginInfo = pluginInfoByExtention(url, &idx); + HBufC* mimeType = NULL; + if (pluginInfo && idx < pluginInfo->m_mimeExtensionToTypeMap.Count()) { + mimeType = pluginInfo->m_mimeExtensionToTypeMap[idx]; + } + return mimeType; } diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/plugins/PluginHandler.h --- a/webengine/osswebengine/WebKit/s60/plugins/PluginHandler.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/plugins/PluginHandler.h Thu Aug 27 07:44:59 2009 +0300 @@ -144,6 +144,8 @@ void setPluginToActivate(PluginSkin* pluginObj) {m_pluginToActivate = pluginObj; }; PluginSkin* activePlugin() { return m_activePlugin; }; void setActivePlugin(PluginSkin* pluginObj) { m_activePlugin = pluginObj; }; + HBufC* pluginMimeByExtention(const TPtrC8& url); + PluginInfo* pluginInfoByExtention(const TPtrC8& aUrl, TInt* aExtIdx); private: // New functions diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/plugins/PluginSkin.cpp --- a/webengine/osswebengine/WebKit/s60/plugins/PluginSkin.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/plugins/PluginSkin.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -16,6 +16,7 @@ */ //INCLUDES +#include #include "../../bidi.h" #include "PlatformString.h" #include @@ -48,6 +49,10 @@ #include #include #include +#include +#include "CString.h" +#include "WidgetExtension.h" +#include // CONSTANTS using namespace WebCore; @@ -72,6 +77,19 @@ const TUint KBorderWidthUnfocus( 0 ); const TUint KBorderWidthFocus( KHtml4cssPadding ); +_LIT(KBrowserMode,"BrowserMode"); +_LIT(KWidgetMode,"WidgetMode"); +_LIT(KUnknownMode, "UnKnownMode"); +_LIT(KApplicationId,"ApplicationId"); +_LIT(KSecMgrScriptSession,"SecMgrScriptSession"); +_LIT(KAllowNetworkAccess,"AllowNetworkAccess"); + + +#define KArraySize 3 + +const TInt32 KWidgetApplicationId = 0x10282822; +const TInt32 KBrowserApplicationId = 0x10008D39; + //MACROS //DATATYPES @@ -140,10 +158,79 @@ m_handle(-1), m_instance(0), m_pluginfuncs(0), - m_resized(false) + m_resized(false), + m_oldPos(TPoint(-1,-1)) { } + +void PluginSkin::addWidgetAttributesL() +{ + const TDesC& SecMgrScriptSession = KSecMgrScriptSession(); + RWidgetRegistryClientSession widgetregistry; + TInt ret = widgetregistry.Connect(); + if ( ret != KErrNone && ret != KErrAlreadyExists ) { + User::Leave( ret ); + } + else { + CleanupClosePushL( widgetregistry ); + } + + CBrCtl* brCtl = control(this->frame()); + WebView* view = brCtl->webView(); + CWidgetExtension* wdgtExt = view->widgetExtension(); + + if(wdgtExt){ + +#if defined(BRDO_LIW_FF) + void* scriptSession = wdgtExt->getSecuritySession(); + if ( !scriptSession ) { + User::Leave( KErrGeneral ); + } + + NPN_GenericElement ScriptSession(SecMgrScriptSession,scriptSession); + iGenericElementArray->AppendL(ScriptSession); +#endif + + TInt uid = wdgtExt->GetWidgetId(); + CWidgetPropertyValue* AccessValue = widgetregistry.GetWidgetPropertyValueL(TUid::Uid(uid), EAllowNetworkAccess ); + TInt networkAccess = *AccessValue; + const TDesC& allowNetworkAccess = KAllowNetworkAccess(); + NPN_GenericElement NetworkAccess(allowNetworkAccess,networkAccess); + iGenericElementArray->AppendL(NetworkAccess); + } + User::LeaveIfError(widgetregistry.Disconnect()); + CleanupStack::PopAndDestroy(); //widgetregistry +} + +const TDesC& PluginSkin::GetExecutionMode() +{ + TUid uid = RProcess().SecureId(); + if( uid.iUid == KWidgetApplicationId ){ + return KWidgetMode; + } + else if( uid.iUid == KBrowserApplicationId ){ + return KBrowserMode; + } + return KUnknownMode; + } + + void PluginSkin::setupGenericElementArrrayL() + { + iGenericElementArray = new (ELeave) RArray (KArraySize); + + const TDesC& appId = KApplicationId(); + const TDesC& executionMode = GetExecutionMode(); + + NPN_GenericElement ExecutionModeElement(appId,executionMode); + iGenericElementArray->AppendL(ExecutionModeElement); + + if(0 == executionMode.Compare(KWidgetMode())) { + addWidgetAttributesL(); + } + + } + // ---------------------------------------------------------------------------- // PluginSkin::ConstructL() // Second phase constructor for PluginSkin @@ -170,8 +257,18 @@ // Create the plugin if supported by platform PluginHandler* pluginHandler = WebCore::StaticObjectsContainer::instance()->pluginHandler(); - m_pluginSupported = pluginHandler->isSupported( mimeType.des(), url ); - + TPtrC mimeTypePtr; + if (mimeType.length() > 0) { + mimeTypePtr.Set(mimeType.des()); + m_pluginSupported = pluginHandler->isSupported( mimeTypePtr, url ); + } + else { + HBufC* ptr = pluginHandler->pluginMimeByExtention(url); + if (ptr) { + mimeTypePtr.Set(ptr->Des()); + } + m_pluginSupported = ((ptr != NULL) && (mimeTypePtr.Length() > 0)); + } if ( m_pluginSupported ) { @@ -193,10 +290,13 @@ TBuf16<4> value; value.Format( _L("%d"), m_frame->frameView()->topView()->accessPointId() ); m_attributeValues->AppendL( value ); + + setupGenericElementArrrayL(); + if(url.Length()) m_url = url.AllocL(); bool loadPluginContent = m_frame->frameView()->topView()->brCtl()->settings()->brctlSetting(TBrCtlDefs::ESettingsAutoLoadImages); - if((mimeType.des().Find(KContentTypeFlash) != KErrNotFound)) { + if((mimeTypePtr.Find(KContentTypeFlash) != KErrNotFound)) { loadPluginContent = loadPluginContent && !m_frame->frameView()->topView()->brCtl()->settings()->brctlSetting(TBrCtlDefs::ESettingsDisableFlash); m_flashContent = ETrue; } @@ -211,12 +311,11 @@ } } else { - TPtrC mimePtr(mimeType.des()); TPtrC8 urlPtr(url); HBufC8* mime = NULL; - mime = HBufC8::NewLC(mimePtr.Length()); - mime->Des().Copy(mimePtr); - createPluginWinL(urlPtr, mimePtr); + mime = HBufC8::NewLC(mimeTypePtr.Length()); + mime->Des().Copy(mimeTypePtr); + createPluginWinL(urlPtr, mimeTypePtr); loadPluginL(*mime); CleanupStack::PopAndDestroy(); // mime } @@ -258,6 +357,10 @@ } m_tempFilesArray.ResetAndDestroy(); + if (iGenericElementArray){ + iGenericElementArray->Close(); + delete iGenericElementArray; + } } void PluginSkin::Close() @@ -461,11 +564,11 @@ { m_active = ETrue; m_frame->frameView()->topView()->setFocusedElementType(TBrCtlDefs::EElementActivatedObjectBox); - // Set right soft key - m_frame->frameView()->topView()->brCtl()->updateDefaultSoftkeys(); pluginHandler->setActivePlugin(this); pluginHandler->setPluginToActivate(NULL); } + // Set right soft key + m_frame->frameView()->topView()->brCtl()->updateDefaultSoftkeys(); } else { @@ -636,13 +739,19 @@ // If the plugin content hasnt arrived yet or plugin is invalid, then return immediately if ( !m_pluginwin ) { return; - } + } TRect rect = m_rect; - TRect clipRect(frameVisibleRect()); - clipRect.Intersection(rect); - setClipRect(clipRect); - setPluginWinClipedRect(); + TPoint newPos = m_frame->frameView()->frameCoordsInViewCoords(rect.iTl); + TRect newViewport = m_frame->frameView()->topView()->DocumentViewport(); + if (m_oldPos != newPos || m_oldViewport != newViewport) { + m_oldPos = newPos; + m_oldViewport = newViewport; + TRect clipRect(frameVisibleRect()); + clipRect.Intersection(rect); + setClipRect(clipRect); + setPluginWinClipedRect(); + } } //------------------------------------------------------------------------------- @@ -796,9 +905,11 @@ int start_content = buffer.Find(KRequestEOH()); start_content = (start_content != KErrNotFound) ? start_content+ KRequestEOH().Length() : 0; - 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()); + 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()); request.setHTTPBody(fd); CleanupStack::PopAndDestroy(); // body } @@ -920,13 +1031,28 @@ { TRect fullRect(getPluginWinRect()); TRect clipRect(getClipRect()); - m_pluginwin->makeVisible((m_frame->frameView()->isVisible()) - && (m_frame->frameView()->rect().Intersects(fullRect)) - && (control(m_frame)->webView()->inPageViewMode() == EFalse)); - clipRect.Intersection(fullRect); - if (m_pluginwin && !m_pluginwin->isPluginInFullscreen() && - (m_pluginwin->Rect() != clipRect || m_pluginwin->isForceScroll())) { - m_pluginwin->SetRect(clipRect); + 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); + + if (m_pluginwin) { + m_pluginwin->makeVisible( isFrameVisible && !isPageViewMode && isPluginVisible); + if (!m_pluginwin->isPluginInFullscreen()) { + clipRect.Intersection(fullRect); + m_pluginwin->SetRect(clipRect); + } } } diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/plugins/PluginSkin.h --- a/webengine/osswebengine/WebKit/s60/plugins/PluginSkin.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/plugins/PluginSkin.h Thu Aug 27 07:44:59 2009 +0300 @@ -428,11 +428,17 @@ * @return Bool. */ TBool RunScript(); + RArray* genericElementArray(){ + return iGenericElementArray; + } private: // private member data void setPluginWinClipedRect(); TRect frameVisibleRect() const; void Close(); + const TDesC& GetExecutionMode(); + void setupGenericElementArrrayL(); + void addWidgetAttributesL(); // Window-owning CoeControl which wraps the CoeControl created by the plugin PluginWin* m_pluginwin; WebFrame* m_frame; // not owned @@ -464,6 +470,11 @@ RPointerArray m_JSUrls; WTF::HashSet m_streams; + + RArray* iGenericElementArray; + TPoint m_oldPos; + TRect m_oldViewport; + public: TInt m_handle; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/plugins/PluginStream.cpp --- a/webengine/osswebengine/WebKit/s60/plugins/PluginStream.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/plugins/PluginStream.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -282,6 +282,11 @@ fileExtPtr.Set(fileExtPtr.Left(i)); } + // remove any '/' at the end + if ( fileExtPtr[fileExtPtr.Length() - 1] == '/' ) { + fileExtPtr.Set(fileExtPtr.Left(fileExtPtr.Length() - 1)); + } + // Trim anything left of path, the last '/' // "http://www.xyz.com/flashy.swf" -> "flashy.swf" i = fileExtPtr.LocateReverse('/'); diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/plugins/PluginWin.cpp --- a/webengine/osswebengine/WebKit/s60/plugins/PluginWin.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/plugins/PluginWin.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -231,15 +231,33 @@ switch ( eventType ) { case EEventActivate: - if ( m_notifier ) - { - TPoint pt = StaticObjectsContainer::instance()->webCursor()->position() - Position(); - m_notifier->NotifyL( MPluginNotifier::EPluginActivated, (void*) &pt ); + { + WebCursor* cursor = StaticObjectsContainer::instance()->webCursor(); + CBrCtl* brCtl = control(m_pluginskin->frame()); + WebView* view = brCtl->webView(); + + if ( m_notifier ) + { + TPoint pt = TPoint(0,0); + if (cursor) { + pt = cursor->position() + view->PositionRelativeToScreen() - + m_control->PositionRelativeToScreen(); } + m_notifier->NotifyL( MPluginNotifier::EPluginActivated, (void*) &pt ); + cursor->cursorUpdate(EFalse); consumed = ETrue; setPluginFocusL( ETrue ); - break; + } + else + { + m_pluginskin->frame()->frameView()->topView()->setFocusedElementType(TBrCtlDefs::EElementBrokenImage); + cursor->cursorUpdate(ETrue); + consumed = EFalse; + setPluginFocusL( EFalse ); + } + break; + } case EEventDeactivate: if( m_notifier ) { @@ -366,17 +384,7 @@ rect = TRect(fv->viewCoordsInFrameCoords(Rect().iTl), fv->viewCoordsInFrameCoords(Rect().iBr)); rect = fv->toViewCoords(rect); rect.SetSize(m_bitmap->SizeInPixels()); // toViewCoords sometimes grows the rect by 1, which wil cause the bitmap to not draw - if (m_transparentPlugin) { - m_bitmapContextMask->SetBrushStyle( CGraphicsContext::ESolidBrush ); - m_bitmapContextMask->SetPenStyle( CGraphicsContext::ESolidPen ); - m_bitmapContextMask->SetPenColor( TRgb( 30, 30, 30 ) ); - m_bitmapContextMask->SetBrushColor( TRgb( 30, 30, 30 ) ); - m_bitmapContextMask->DrawRect(m_mask->SizeInPixels() ); - bitmapContext.DrawBitmapMasked(rect, m_bitmap, rect.Size(), m_mask, true); - } - else { - bitmapContext.DrawBitmap(rect, m_bitmap, rect.Size()); - } + bitmapContext.DrawBitmap(rect, m_bitmap, rect.Size()); } return KErrNone; } @@ -600,10 +608,20 @@ // Deactivate the plugin // ----------------------------------------------------------------------------- // -void PluginWin::pluginDeactivate() - { +void PluginWin::pluginDeactivate(const TPoint& aPosition) +{ m_pluginskin->deActivate(); + if (!m_pluginskin->isActive()) { + CBrCtl* brCtl = control(m_pluginskin->frame()); + WebView* view = brCtl->webView(); + TPoint pos = aPosition + m_control->PositionRelativeToScreen() - + view->PositionRelativeToScreen(); + WebCursor* cursor = StaticObjectsContainer::instance()->webCursor(); + TPoint offset = cursor->position() - pos; + cursor->offsetCursor( offset ); + cursor->cursorUpdate(ETrue); } +} // ----------------------------------------------------------------------------- // CPluginWin::HitRegionContains diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/plugins/PluginWin.h --- a/webengine/osswebengine/WebKit/s60/plugins/PluginWin.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/plugins/PluginWin.h Thu Aug 27 07:44:59 2009 +0300 @@ -340,7 +340,8 @@ * @since 3.1 * @return */ - void pluginDeactivate(); + void pluginDeactivate(const TPoint& aCurPosition); + /** * zoom on double tap on the plugin * Sets the cursor poistion diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/rom/webkit.iby --- a/webengine/osswebengine/WebKit/s60/rom/webkit.iby Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/rom/webkit.iby Thu Aug 27 07:44:59 2009 +0300 @@ -55,7 +55,9 @@ file=ABI_DIR\BUILD_DIR\MemMan.dll SHARED_LIB_DIR\MemMan.dll file=ABI_DIR\BUILD_DIR\WmlEngine.dll SHARED_LIB_DIR\WmlEngine.dll file=ABI_DIR\BUILD_DIR\BrowserCache.dll SHARED_LIB_DIR\BrowserCache.dll +#ifndef __S60_32__ file=ABI_DIR\BUILD_DIR\npscript.dll SHARED_LIB_DIR\npscript.dll +#endif ECOM_PLUGIN(MemoryPlugin.dll, memoryplugin.RSC) diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webcoresupport/WebEditorClient.cpp --- a/webengine/osswebengine/WebKit/s60/webcoresupport/WebEditorClient.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/webcoresupport/WebEditorClient.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -352,8 +352,7 @@ // previous char in secret text editor case EKeyF20: case EKeyBackspace: - frame->editor()->deleteWithDirection(SelectionController::BACKWARD, - CharacterGranularity, false, true); + handleDeleteText(frame); m_webView->fepTextEditor()->HandleUpdateCursor(); m_webView->fepTextEditor()->UpdateEditingMode(); event->setDefaultHandled(); @@ -476,7 +475,7 @@ if (m_webView->fepTextEditor()->DocumentLengthForFep() < m_webView->fepTextEditor()->DocumentMaximumLengthForFep()) { TText c = kevent->symbianEvent().iCode; - frame->editor()->insertTextWithoutSendingTextEvent(String(TPtrC(&c,1)), false); + handleInsertText(frame, String(TPtrC(&c,1))); m_webView->fepTextEditor()->UpdateEditingMode(); } m_webView->fepTextEditor()->HandleUpdateCursor(); @@ -629,3 +628,31 @@ { m_webView->setEditable(enabled); } + +//----------------------------------------------------------------------------- +// WebEditorClient::handleInsertText +//----------------------------------------------------------------------------- +void WebEditorClient::handleInsertText(Frame* frame, const String& text) +{ + if (!m_webView->fepTextEditor()->IsWapMaskedModeInput(frame)) { + frame->editor()->insertTextWithoutSendingTextEvent(text, false); + } + else { + m_webView->fepTextEditor()->HandleMaskedInsertText(frame, text); + } +} + +//----------------------------------------------------------------------------- +// WebEditorClient::handleDeleteText +//----------------------------------------------------------------------------- +void WebEditorClient::handleDeleteText(Frame* frame) +{ + if (!m_webView->fepTextEditor()->IsWapMaskedModeInput(frame)) { + frame->editor()->deleteWithDirection(SelectionController::BACKWARD, + CharacterGranularity, false, true); + } + else { + m_webView->fepTextEditor()->HandleMaskedDeleteText(frame); + } +} + diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webcoresupport/WebEditorClient.h --- a/webengine/osswebengine/WebKit/s60/webcoresupport/WebEditorClient.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/webcoresupport/WebEditorClient.h Thu Aug 27 07:44:59 2009 +0300 @@ -99,6 +99,10 @@ void setInputMethodState(bool enabled); private: + void handleInsertText(WebCore::Frame* frame, const WebCore::String& text); + void handleDeleteText(WebCore::Frame* frame); + +private: WebView* m_webView; }; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webcoresupport/WebFrameBridge.cpp --- a/webengine/osswebengine/WebKit/s60/webcoresupport/WebFrameBridge.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/webcoresupport/WebFrameBridge.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -45,6 +45,9 @@ WebFrameBridge::~WebFrameBridge() { m_webFrame.release(); + if (m_frame) + m_frame->setBridge(NULL); + } WebView* WebFrameBridge::webView() const diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webcoresupport/WebFrameLoaderClient.cpp --- a/webengine/osswebengine/WebKit/s60/webcoresupport/WebFrameLoaderClient.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/webcoresupport/WebFrameLoaderClient.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -57,6 +57,7 @@ #include "WebKitLogger.h" #include "PluginHandler.h" #include "MIMETypeRegistry.h" +#include "WidgetExtension.h" using namespace WebCore; using namespace HTMLNames; @@ -1276,6 +1277,28 @@ return m_webFrame->frameView()->topView()->userAgent(); } +TInt WebFrameLoaderClient::widgetNetworkConstants(TInt aId) +{ + CWidgetExtension* widgetExt = m_webFrame->frameView()->topView()->widgetExtension(); + if ( widgetExt ) { + return widgetExt->widgetNetworkConstants(aId); + } + + notImplemented(); + return 0; +} + +TInt WebFrameLoaderClient::widgetNetworkState() +{ + CWidgetExtension* widgetExt = m_webFrame->frameView()->topView()->widgetExtension(); + if ( widgetExt ) { + return widgetExt->widgetNetworkState(); + } + + notImplemented(); + return 0; +} + void WebFrameLoaderClient::saveDocumentViewToCachedPage(CachedPage*) { // cachedPage->setDocumentView([m_webFrame->_private->webFrameView documentView]); diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webcoresupport/WebFrameLoaderClient.h --- a/webengine/osswebengine/WebKit/s60/webcoresupport/WebFrameLoaderClient.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/webcoresupport/WebFrameLoaderClient.h Thu Aug 27 07:44:59 2009 +0300 @@ -156,6 +156,8 @@ virtual void setTitle(const WebCore::String& title, const WebCore::KURL&); virtual WebCore::String userAgent(const WebCore::KURL&); + virtual TInt widgetNetworkConstants(TInt aId); + virtual TInt widgetNetworkState(); virtual void saveDocumentViewToCachedPage(WebCore::CachedPage*); virtual bool canCachePage() const; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webview/BrCtl.cpp --- a/webengine/osswebengine/WebKit/s60/webview/BrCtl.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/webview/BrCtl.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -77,7 +77,10 @@ #include "focusController.h" #include "IconDatabase.h" #include "httpDownload.h" +#include "BrCtlSoftkeysObserverImpl.h" +#include "BrCtlSpecialLoadObserverImpl.h" #include "BrCtlLayoutObserverImpl.h" +#include "BrCtlWindowObserverImpl.h" #include "WidgetExtension.h" #include "PluginSkin.h" #include "HttpUiCallbacks.h" @@ -410,6 +413,7 @@ , m_suspendTimers(false) , m_wmlEngineInterface(NULL) , m_brCtlDownloadObserver(aBrCtlDownloadObserver) + , m_windoCloseTimer(NULL) { m_documentHeight = 0; m_displayHeight = 0; @@ -418,8 +422,11 @@ m_displayWidth = 0; m_displayPosX = 0; m_hasHorizontalScrollbar = false; + m_ownsSpecialLoadObserver = false; + m_ownsSoftkeysObserver = false; m_ownsLayoutObserver = false; m_ownsDialogsProvider = false; + m_ownsWindowObserver = false; } // ----------------------------------------------------------------------------- @@ -448,16 +455,42 @@ m_usrAgnt = CUserAgent::NewL(); + // Create and initialize the Special Load Observer + if (m_brCtlSpecialLoadObserver == NULL) + { + m_brCtlSpecialLoadObserver = new (ELeave) CBrCtlSpecialLoadObserver(); + m_ownsSpecialLoadObserver = true; + } + + + // Setup default support, if it wasn't passed into the constructor... + // Create and initialize the Softkey Observer + if (m_brCtlSoftkeysObserver == NULL) + { + m_brCtlSoftkeysObserver = new (ELeave) CBrCtlSoftkeysObserver(); + m_ownsSoftkeysObserver = true; + } + + // Create and initialize the Layout Observer if (m_brCtlLayoutObserver == NULL) { m_brCtlLayoutObserver = new (ELeave) CBrCtlLayoutObserver(); m_ownsLayoutObserver = true; } + // Create and initialize the Dialog Provider if (m_brCtlDialogsProvider == NULL) { m_brCtlDialogsProvider = CBrowserDialogsProvider::NewL(NULL); m_ownsDialogsProvider = true; } + + // window observer + if(m_brCtlWindowObserver == NULL) + { + m_brCtlWindowObserver = new (ELeave) CBrCtlWindowObserver(); + m_ownsWindowObserver = true; + } + LoadResourceFileL(); // Set the rect for BrowserControl (a CCoeControl). SetRect(aRect); @@ -478,7 +511,6 @@ iLoadEventObserversArray.Close(); iLoadEventObserversArray.Close(); m_stateChangeObserverArray.Close(); - m_commandObserverArray.ResetAndDestroy(); m_commandObserverArray.Close(); m_subscribeToItems.ResetAndDestroy(); m_subscribeToItems.Close(); @@ -489,6 +521,18 @@ delete m_historyHandler; delete m_settingsContainer; delete m_usrAgnt; + + if (m_ownsSpecialLoadObserver) { + delete (CBrCtlSpecialLoadObserver*)m_brCtlSpecialLoadObserver; + } + + if (m_ownsSoftkeysObserver) { + delete (CBrCtlSoftkeysObserver*)m_brCtlSoftkeysObserver; + } + + if (m_ownsWindowObserver) { + delete (CBrCtlWindowObserver*)m_brCtlWindowObserver; + } if (m_ownsLayoutObserver) { delete (CBrCtlLayoutObserver*)m_brCtlLayoutObserver; @@ -500,6 +544,11 @@ m_timer->Cancel(); delete m_timer; } + if (m_windoCloseTimer) { + m_windoCloseTimer->Cancel(); + delete m_windoCloseTimer; + } + if (m_dataLoadConsumer) { m_dataLoadConsumer->stopDataLoad(); endLoadData(); @@ -507,6 +556,9 @@ m_brCtlLayoutObserver = NULL; m_brCtlDialogsProvider = NULL; m_brCtlDownloadObserver = NULL; + m_brCtlWindowObserver = NULL; + m_brCtlSoftkeysObserver = NULL; + m_brCtlSpecialLoadObserver = NULL; UnloadDllWmlEngine(); @@ -545,6 +597,8 @@ UnloadDllWmlEngine(); } #endif + if (m_webView->formFillPopup() && m_webView->formFillPopup()->IsVisible()) + m_webView->formFillPopup()->handleCommandL(TBrCtlDefs::ECommandCancel); break; } } @@ -2036,13 +2090,19 @@ void CBrCtl::closeWindowSoon() { - m_timer = CPeriodic::NewL(CActive::EPriorityIdle); - m_timer->Start( 20, 0, TCallBack( &doCloseCb, this ) ); + if( m_windoCloseTimer ) { + m_windoCloseTimer->Cancel(); + } + else { + m_windoCloseTimer = CPeriodic::NewL(CActive::EPriorityIdle); + } + + m_windoCloseTimer->Start( 20, 0, TCallBack( &doCloseCb, this ) ); } void CBrCtl::doCloseWindowSoon() { - m_timer->Cancel(); + m_windoCloseTimer->Cancel(); if (brCtlWindowObserver()) TRAP_IGNORE(brCtlWindowObserver()->HandleWindowCommandL(KNullDesC(), ECloseWindow)); } diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webview/BrCtl.h --- a/webengine/osswebengine/WebKit/s60/webview/BrCtl.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/webview/BrCtl.h Thu Aug 27 07:44:59 2009 +0300 @@ -719,11 +719,15 @@ bool m_wmlUnloadPending; bool m_ownsLayoutObserver; bool m_ownsDialogsProvider; + bool m_ownsSpecialLoadObserver; + bool m_ownsSoftkeysObserver; + bool m_ownsWindowObserver; CPageScaler* m_wmlPageScaler; CWmlDispatcher* m_wmlDispatcher; RPointerArray m_wmlServiceOption; TBrCtlWmlServiceOption* m_firstPrevDoElement; - MBrCtlDownloadObserver* m_brCtlDownloadObserver; + MBrCtlDownloadObserver* m_brCtlDownloadObserver; + CPeriodic* m_windoCloseTimer; //new timer for managing browser window close }; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webview/BrCtlSoftkeysObserverImpl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/osswebengine/WebKit/s60/webview/BrCtlSoftkeysObserverImpl.h Thu Aug 27 07:44:59 2009 +0300 @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Handle softkeys updates +* +*/ + + + +#ifndef CRCTLSOFTKEYSOBSERVERIMPL_H +#define CRCTLSOFTKEYSOBSERVERIMPL_H + +// INCLUDES +#include + + +/** +* This observer is notified when the browser requests softkeys changes +* +* @lib BrowserEngine.lib +* @since 2.8 +*/ +class CBrCtlSoftkeysObserver: public CBase, public MBrCtlSoftkeysObserver + { + public: // From MBrCtlSoftkeysObserver + + /** + * Browser Control requests to update a softkey + * @since 2.8 + * @param aKeySoftkey Update the left softkey or the right softkey + * @param aLabel The label associated with the softkey update + * @param aCommandId The command to use if the softkey is selected by the user + * @param aBrCtlSoftkeyChangeReason The reason for the softkey change + * @return void + */ + virtual void UpdateSoftkeyL(TBrCtlKeySoftkey /*aKeySoftkey*/, + const TDesC& /*aLabel*/, + TUint32 /*aCommandId*/, + TBrCtlSoftkeyChangeReason /*aBrCtlSoftkeyChangeReason*/) {} + }; + +#endif // BRCTLSOFTKEYSOBSERVERIMPL_H + +// End of File diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webview/BrCtlSpecialLoadObserverImpl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/osswebengine/WebKit/s60/webview/BrCtlSpecialLoadObserverImpl.h Thu Aug 27 07:44:59 2009 +0300 @@ -0,0 +1,72 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Handle special load events such as network connection, deal with non-http or non-html requests +* +*/ + + + +#ifndef BRCTLSPECIALLOADOBSERVERIMPL_H +#define BRCTLSPECIALLOADOBSERVERIMPL_H + +// INCLUDES +#include + +/** +* This observer handles special load events such as network connection, deal with non-http(s) or non-html requests +* +* @lib BrowserEngine.lib +* @since 2.8 +*/ +//NONSHARABLE_CLASS(CBrCtlSpecialLoadObserver) : public CBase, public MBrCtlSpecialLoadObserver +class CBrCtlSpecialLoadObserver : public CBase, public MBrCtlSpecialLoadObserver + { + public: // From MBrCtlSpecialLoadObserver + /** + * Request to create a network connection. + * @since 2.8 + * @param aConnectionPtr A pointer to the new connection. If NULL, the proxy filter will automatically create a network connection + * @param aSockSvrHandle A handle to the socket server. + * @param aNewConn A flag if a new connection was created. If the connection is not new, proxy filter optimization will not read the proxy again from CommsBd + * @param aBearerType The bearer type of the new connection + * @return void + */ + virtual void NetworkConnectionNeededL(TInt* /*aConnectionPtr*/, + TInt* /*aSockSvrHandle*/, + TBool* /*aNewConn*/, + TApBearerType* /*aBearerType*/) {} + + /** + * Request the host applicaion to handle non-http request. + * @since 2.8 + * @param aUrl The non-http(s) or file URL + * @param aParamList Parameters to pass to the host application. Contain referer header. It could be NULL + * @return ETrue is handled by the host application. EFlase if not + */ + virtual TBool HandleRequestL(RArray* /*aTypeArray*/, CDesCArrayFlat* /*aDesArray*/) {return EFalse;} + + /** + * Request the host applicaion to handle downloads + * @since 2.8 + * @param aTypeArray array of download parameter types + * @param aDesArray array of values associated with the types in the type array + * @return ETrue is handled by the host application. EFlase if not + */ + virtual TBool HandleDownloadL(RArray* /*aTypeArray*/, + CDesCArrayFlat* /*aDesArray*/) {return EFalse;} + }; + +#endif // BRCTLSPECIALLOADOBSERVERIMPL_H + +// End of File diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webview/BrCtlWindowObserverImpl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/osswebengine/WebKit/s60/webview/BrCtlWindowObserverImpl.h Thu Aug 27 07:44:59 2009 +0300 @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Handle special load events such as network connection, deal with non-http or non-html requests +* +*/ + + + +#ifndef BRCTLWINDOWOBSERVERIMPL_H +#define BRCTLWINDOWOBSERVERIMPL_H + +// INCLUDES +#include + + +/** +* This observer handles special load events such as network connection, deal with non-http(s) or non-html requests +* +* @lib BrowserEngine.lib +* @since 2.8 +*/ +class CBrCtlWindowObserver : public CBase, public MBrCtlWindowObserver + { + public: // From MBrCtlWindowObserver + /** + * Request the host applicaion to open the URL in a new window + * @since 3.0 + * @param aUrl The Url of the request to be done in the new window + * @param aTargetName The name of the new window + * @param aUserInitiated ETrue if the new window is initiated by a user event (click) + * @param aReserved For future use + * @return Return Value is for future reference and is currently ignored + */ + virtual CBrCtlInterface* OpenWindowL(TDesC& /*aUrl*/, TDesC* /*aTargetName*/, + TBool /*aUserInitiated*/, TAny* /*aReserved*/) {return NULL;} + + /** + * Find a window by target name + * @since 3.0 + * @param aTargetName name of the window to find + * @return Return Value is the browser control associated with the window name + */ + virtual CBrCtlInterface* FindWindowL( const TDesC& /*aTargetName*/ ) const { return NULL; } + + /** + * Handle window events such as close/focus etc + * @since 3.0 + * @param aTargetName name of the window to send the event to + * @param aCommand Command to pass to the window + * @return void + */ + virtual void HandleWindowCommandL( const TDesC& /*aTargetName*/, TBrCtlWindowCommand /*aCommand*/ ) {} + + }; + +#endif // BRCTLWINDOWOBSERVERIMPL_H + +// End of File diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webview/WebCursor.cpp --- a/webengine/osswebengine/WebKit/s60/webview/WebCursor.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/webview/WebCursor.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -143,6 +143,13 @@ m_view = &view; TRAP_IGNORE( constructSpriteL() ); } + //switching between diffrent webviews, set current webview as the parent to m_sprite + if( m_sprite->Parent() != &view) + { + m_view = &view; + CCoeControl* parent = static_cast(m_view); + m_sprite->SetParent(parent); + } m_view = &view; setOpaqueUntil(KTransparencyTime); m_transcount = 0; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webview/WebFepTextEditor.cpp --- a/webengine/osswebengine/WebKit/s60/webview/WebFepTextEditor.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/webview/WebFepTextEditor.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -30,6 +30,7 @@ #include "WebFrame.h" #include "Page.h" #include "FocusController.h" +#include "WebFrameView.h" #include "Frame.h" #include "Editor.h" @@ -60,8 +61,8 @@ // ----------------------------------------------------------------------------- // CWebFepTextEditor -// -// +// +// // ----------------------------------------------------------------------------- CWebFepTextEditor::CWebFepTextEditor(WebView* aView) : m_webView(aView), @@ -83,8 +84,8 @@ // ----------------------------------------------------------------------------- // ~CWebFepTextEditor -// -// +// +// // ----------------------------------------------------------------------------- CWebFepTextEditor::~CWebFepTextEditor() { @@ -96,163 +97,164 @@ // ----------------------------------------------------------------------------- // CreateTextFormatMask -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::CreateTextFormatMask() { - if (!m_textFormatMask) { + if (!m_textFormatMask) { Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame(); if (frame && frame->document() && - frame->document()->focusedNode()) { - RenderStyle* s = frame->document()->focusedNode()->renderStyle(); - if (s && - (!s->wapInputFormat().isEmpty() || s->wapInputRequired())){ + frame->document()->focusedNode()) { + RenderStyle* s = frame->document()->focusedNode()->renderStyle(); + if (s && + (!s->wapInputFormat().isEmpty() || s->wapInputRequired())){ m_textFormatMask = new WebTextFormatMask(s->wapInputFormat(), s->wapInputRequired()); } } } -} +} // ----------------------------------------------------------------------------- // UpdateEditingMode -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::UpdateEditingMode() -{ +{ Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame(); if (frame) { - SelectionController* sc = frame->selectionController(); - if (sc && sc->isContentEditable() && sc->isInPasswordField()) { - - // Set the state as if it was the CEikSecretEditor - CAknEdwinState* state = static_cast(State(KNullUid)); - if (state) { - state->SetFlags( EAknEditorFlagNoLRNavigation | + Node *node = frame->document()->focusedNode(); + if (frame && frame->document() && node) { + if (node->hasTagName(HTMLNames::inputTag) + && (static_cast(node)->inputType() == HTMLInputElement::PASSWORD) + && !static_cast(node)->readOnly()) { + // Set the state as if it was the CEikSecretEditor + CAknEdwinState* state = static_cast(State(KNullUid)); + if (state) { + state->SetFlags( EAknEditorFlagNoLRNavigation | EAknEditorFlagLatinInputModesOnly | EAknEditorFlagNoT9 | EAknEditorFlagUseSCTNumericCharmap ); - - state->SetDefaultInputMode(EAknEditorSecretAlphaInputMode); - state->SetCurrentInputMode(EAknEditorSecretAlphaInputMode); - state->SetPermittedCases(EAknEditorLowerCase|EAknEditorUpperCase); - state->SetCurrentCase(EAknEditorLowerCase); - state->SetPermittedInputModes(EAknEditorSecretAlphaInputMode | EAknEditorNumericInputMode); - state->SetDefaultCase(EAknEditorLowerCase); - state->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG_LATIN_ONLY); - state->SetNumericKeymap(EAknEditorPlainNumberModeKeymap); - } - - } - else { - - CreateTextFormatMask(); - - TUint currentCase ( EAknEditorLowerCase ) ; - TUint permittedCase ( EAknEditorAllCaseModes ) ; - TUint inputMode( EAknEditorNullInputMode ); - TUint permittedInputModes( EAknEditorAllInputModes ); - TUint flags( EAknEditorFlagDefault ); - TUint numericKeyMap( EAknEditorStandardNumberModeKeymap ); - - if (GetStateFromFormatMask(currentCase, permittedCase, inputMode, permittedInputModes, flags, numericKeyMap)) { - UpdateFlagsState(flags); - UpdateInputModeState(inputMode, permittedInputModes, numericKeyMap); - UpdateCaseState(currentCase, permittedCase); + state->SetDefaultInputMode(EAknEditorSecretAlphaInputMode); + state->SetCurrentInputMode(EAknEditorSecretAlphaInputMode); + state->SetPermittedCases(EAknEditorLowerCase|EAknEditorUpperCase); + state->SetCurrentCase(EAknEditorLowerCase); + state->SetPermittedInputModes(EAknEditorSecretAlphaInputMode | EAknEditorNumericInputMode); + state->SetDefaultCase(EAknEditorLowerCase); + state->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG_LATIN_ONLY); + state->SetNumericKeymap(EAknEditorPlainNumberModeKeymap); + } } else { - CAknEdwinState* state = static_cast(State(KNullUid)); - if (state) { - state->SetPermittedInputModes(EAknEditorAllInputModes); - state->SetPermittedCases(EAknEditorAllCaseModes);//allow everything - } + CreateTextFormatMask(); + TUint currentCase ( EAknEditorLowerCase ) ; + TUint permittedCase ( EAknEditorAllCaseModes ) ; + TUint inputMode( EAknEditorNullInputMode ); + TUint permittedInputModes( EAknEditorAllInputModes ); + TUint flags( EAknEditorFlagDefault ); + TUint numericKeyMap( EAknEditorStandardNumberModeKeymap ); + + if (GetStateFromFormatMask(currentCase, permittedCase, inputMode, permittedInputModes, flags, numericKeyMap)) { + UpdateFlagsState(flags); + UpdateInputModeState(inputMode, permittedInputModes, numericKeyMap); + UpdateCaseState(currentCase, permittedCase); + } + else { + CAknEdwinState* state = static_cast(State(KNullUid)); + if (state) { + state->SetDefaultCase(EAknEditorLowerCase); + state->SetPermittedInputModes(EAknEditorAllInputModes); + state->SetPermittedCases(EAknEditorAllCaseModes);//allow everything + } + } } } } // End of if (frame) } - + // ----------------------------------------------------------------------------- // CancelEditingMode -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::CancelEditingMode() - { + { delete m_textFormatMask; m_textFormatMask = NULL; - delete m_inlineEditText; - m_inlineEditText = NULL; + delete m_inlineEditText; + m_inlineEditText = NULL; - UpdateFlagsState(EAknEditorFlagDefault); UpdateInputModeState(EAknEditorNullInputMode, EAknEditorAllInputModes,EAknEditorStandardNumberModeKeymap); - UpdateCaseState(EAknEditorLowerCase, EAknEditorAllCaseModes); - + UpdateFlagsState(EAknEditorFlagDefault); + UpdateCaseState(EAknEditorLowerCase, EAknEditorAllCaseModes); + CancelFepInlineEdit(); } - + // ----------------------------------------------------------------------------- // ActivatePenInputRequest -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::ActivatePenInputRequest() -{ - CAknEdwinState* state = static_cast(State(KNullUid)); - if ( state ) { +{ + CAknEdwinState* state = static_cast(State(KNullUid)); + if ( state ) { TRAP_IGNORE( state->ReportAknEdStateEventL(MAknEdStateObserver::EAknActivatePenInputRequest ) ); - } + } } // ----------------------------------------------------------------------------- // DeactivatePenInputRequest -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::DeactivatePenInputRequest() - { + { } // ----------------------------------------------------------------------------- // InputCapabilities -// -// +// +// // ----------------------------------------------------------------------------- -TCoeInputCapabilities CWebFepTextEditor::InputCapabilities() +TCoeInputCapabilities CWebFepTextEditor::InputCapabilities() { Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame(); if (frame) { SelectionController* sc = frame->selectionController(); - if (sc && sc->isContentEditable()) { + if (sc && sc->isContentEditable()) { // Set up the input capabilities, based on the box - TUint caps = TCoeInputCapabilities::ENavigation; - - if ( sc->isInPasswordField() ) { - caps |= TCoeInputCapabilities::ESecretText; + TUint caps = TCoeInputCapabilities::ENavigation; + + if ( sc->isInPasswordField() ) { + caps |= TCoeInputCapabilities::ESecretText; + UpdateFlagsState(EAknEditorFlagNoT9); } else { - - CAknEdwinState* state = static_cast(State(KNullUid)); - if ( state ) { + + CAknEdwinState* state = static_cast(State(KNullUid)); + if ( state ) { if ( state->PermittedInputModes() == EAknEditorNumericInputMode ) { caps |= (TCoeInputCapabilities::EWesternNumericIntegerPositive | - TCoeInputCapabilities::EWesternNumericIntegerNegative)| + TCoeInputCapabilities::EWesternNumericIntegerNegative)| TCoeInputCapabilities::EAllText; - } - else if ( state->PermittedInputModes() == EAknEditorTextInputMode ) { + } + else if ( state->PermittedInputModes() == EAknEditorTextInputMode ) { caps |= TCoeInputCapabilities::EWesternAlphabetic; } - else if ( state->PermittedInputModes() == (EAknEditorTextInputMode | EAknEditorNumericInputMode) ) { + else if ( state->PermittedInputModes() == (EAknEditorTextInputMode | EAknEditorNumericInputMode) ) { caps |= (TCoeInputCapabilities::EWesternNumericIntegerPositive | TCoeInputCapabilities::EWesternNumericIntegerNegative | TCoeInputCapabilities::EWesternAlphabetic); } else { - caps |= TCoeInputCapabilities::EAllText; - } + caps |= TCoeInputCapabilities::EAllText; + } } } @@ -270,7 +272,7 @@ // MObjectProvider callback method MopSupplyObject(). TCoeInputCapabilities inputCaps( caps, this, NULL, TUid::Uid(0x100056de), this ); inputCaps.SetObjectProvider( this ); - + return inputCaps; } } @@ -284,13 +286,13 @@ //////////////////////////////////////////////////////////////////////////////// -// from MCoeFepAwareTextEditor +// from MCoeFepAwareTextEditor // // ----------------------------------------------------------------------------- // StartFepInlineEditL -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::StartFepInlineEditL( const TDesC& aInitialInlineText, @@ -299,28 +301,28 @@ const MFormCustomDraw*, MFepInlineTextFormatRetriever&, MFepPointerEventHandlerDuringInlineEdit& /*aPointerEventHandlerDuringInlineEdit*/) -{ - CCoeEnv::Static()->ForEachFepObserverCall(FepObserverHandleStartOfTransactionL); - ClearInlineText(); - UpdateInlineText(aInitialInlineText); +{ + CCoeEnv::Static()->ForEachFepObserverCall(FepObserverHandleStartOfTransactionL); + ClearInlineText(); + UpdateInlineText(aInitialInlineText); } // ----------------------------------------------------------------------------- // UpdateFepInlineTextL -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::UpdateFepInlineTextL( const TDesC& aNewInlineText, TInt /*aPositionOfInsertionPointInInlineText*/ ) -{ - ClearInlineText(); - UpdateInlineText(aNewInlineText); +{ + ClearInlineText(); + UpdateInlineText(aNewInlineText); } // ----------------------------------------------------------------------------- // SetInlineEditingCursorVisibilityL -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::SetInlineEditingCursorVisibilityL(TBool /*aCursorVisibility*/) { @@ -328,8 +330,8 @@ // ----------------------------------------------------------------------------- // CancelFepInlineEdit -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::CancelFepInlineEdit() { @@ -337,8 +339,8 @@ // ----------------------------------------------------------------------------- // DocumentLengthForFep -// -// +// +// // ----------------------------------------------------------------------------- TInt CWebFepTextEditor::DocumentLengthForFep() const { @@ -358,23 +360,23 @@ } } - return length; + return length; } // ----------------------------------------------------------------------------- // DocumentMaximumLengthForFep -// -// +// +// // ----------------------------------------------------------------------------- TInt CWebFepTextEditor::DocumentMaximumLengthForFep() const -{ - TInt length = KMaxTInt; +{ + TInt length = KMaxTInt; Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame(); if (frame && frame->document() && frame->document()->focusedNode() && - frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag) ) { + frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag) ) { length = static_cast(frame->document()->focusedNode())->maxLength(); } @@ -388,34 +390,40 @@ // ----------------------------------------------------------------------------- // SetCursorSelectionForFepL -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::SetCursorSelectionForFepL(const TCursorSelection& aCursorSelection) -{ +{ // The other part of the rather hackish way to check if we are at the end of the editing field // see WebEditorClient::handleKeypress Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame(); - if ( frame ) { + if ( frame ) { SelectionController* sc = frame->selectionController(); Node* editNode = sc->base().node(); if ( IsTextAreaFocused() ) { + while(editNode && !editNode->isTextNode()){ + editNode = editNode->previousSibling(); + } TInt position( aCursorSelection.iAnchorPos ); TInt offset( 0 ); + TInt extentoffset = 0; if ( editNode ) { editNode = findTextNodeForCurPos( editNode, position ); - if ( aCursorSelection.iAnchorPos > position ) { - offset = aCursorSelection.iAnchorPos - position; - } - Position base( editNode, offset ); - Position extent( editNode, offset ); - sc->moveTo( base, extent, DOWNSTREAM ); + if(aCursorSelection.iAnchorPos >= position) { + offset = aCursorSelection.iAnchorPos - position; + extentoffset = aCursorSelection.iCursorPos - position; + } + extentoffset = extentoffset < 0 ? 0 : extentoffset; + Position base( editNode, offset ); + Position extent(editNode,extentoffset); + sc->moveTo( base, extent, DOWNSTREAM ); } } - else if ( editNode && editNode->isTextNode() ) { + else if ( editNode && editNode->isTextNode() ) { Position base( sc->baseNode(), aCursorSelection.iAnchorPos ); Position extent( sc->baseNode(), aCursorSelection.iCursorPos ); - sc->moveTo( base, extent, DOWNSTREAM ); + sc->moveTo( base, extent, DOWNSTREAM ); } HandleUpdateCursor(); } @@ -423,28 +431,31 @@ // ----------------------------------------------------------------------------- // GetCursorSelectionForFep -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::GetCursorSelectionForFep(TCursorSelection& aCursorSelection) const { aCursorSelection.SetSelection(0,0); - + Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame(); - if ( frame ) { + if ( frame ) { SelectionController* sc = frame->selectionController(); Node* editNode = sc->base().node(); if ( frame && frame->document()->focusedNode() ) { if ( IsTextAreaFocused() ) { + HTMLTextAreaElement* ie = static_cast(frame->document()->focusedNode()); + while(editNode && !editNode->isTextNode()) + editNode = editNode->previousSibling(); TInt len( 0 ); if ( editNode ) { - findPrevSiblingTextLen( editNode, len ); + findPrevSiblingTextLen( editNode, len ); } - aCursorSelection.SetSelection( sc->baseOffset() + len, - sc->extentOffset() + len ); + aCursorSelection.SetSelection( ((sc->baseOffset()+len > ie->value().length()) ? 0 : sc->baseOffset()+len), + ((sc->extentOffset()+len > ie->value().length()) ? 0 : sc->baseOffset()+len)); } else { - aCursorSelection.SetSelection(sc->baseOffset(), sc->extentOffset()); + aCursorSelection.SetSelection(sc->baseOffset(), sc->extentOffset()); } } } @@ -452,19 +463,19 @@ // ----------------------------------------------------------------------------- // GetEditorContentForFep -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::GetEditorContentForFep( TDes& aEditorContent, TInt aDocumentPosition, TInt aLengthToRetrieve ) const -{ +{ aEditorContent = KNullDesC; // KNullDesC has length 0 if (aLengthToRetrieve == 0) { return; } - + Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame(); if (frame && frame->document() && @@ -479,25 +490,25 @@ // Convert the newline to paragraph separator, because the FEP // input editors (vkb, etc) ignore newline String str(ie->value().substring(aDocumentPosition, aLengthToRetrieve)); - str.replace(EKeyLineFeed, CEditableText::EParagraphDelimiter); - aEditorContent = str; + str.replace(EKeyLineFeed, CEditableText::EParagraphDelimiter); + aEditorContent = str; } } } // ----------------------------------------------------------------------------- // GetFormatForFep -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::GetFormatForFep(TCharFormat& /*aFormat*/,TInt /*aDocumentPosition*/) const -{ +{ } // ----------------------------------------------------------------------------- // GetScreenCoordinatesForFepL -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::GetScreenCoordinatesForFepL(TPoint& aLeftSideOfBaseLine, TInt& aHeight, @@ -508,18 +519,18 @@ if (frame && frame->document() && frame->document()->focusedNode()){ - if ( frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag) || + if ( frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag) || frame->document()->focusedNode()->hasTagName(HTMLNames::textareaTag)){ - HTMLGenericFormElement* ie = static_cast(frame->document()->focusedNode()); + HTMLGenericFormElement* ie = static_cast(frame->document()->focusedNode()); SelectionController* sc = frame->selectionController(); int xPos(0); int yPos(0); if ( sc ){ - IntRect rect = sc->caretRect(); - xPos = rect.x(); - yPos = rect.y(); - yPos += m_webView->brCtl()->PositionRelativeToScreen().iY; - Node* editNode = sc->focusNode(); + IntRect rect = sc->caretRect(); + Node* editNode = sc->focusNode(); + TPoint viewPoint = kit(frame)->frameView()->frameCoordsInViewCoords(editNode->getRect().Rect().iBr); + xPos = viewPoint.iX; + yPos = viewPoint.iY; String str; if ( editNode && editNode->isTextNode() ) { @@ -531,14 +542,14 @@ if( position > 0 ){ word = str.left( position ); } - RenderStyle* s = frame->document()->focusedNode()->renderStyle(); + RenderStyle* s = frame->document()->focusedNode()->renderStyle(); PlatformFontCache* cache = StaticObjectsContainer::instance()->fontCache(); CFont* sFont = cache->zoomedFont( s->fontDescription(), cache->fontZoomFactor()); TInt sizePix = sFont->MeasureText( word.des() ); - xPos -= sizePix; - } + xPos -= sizePix; + } } - aLeftSideOfBaseLine.SetXY( xPos,yPos ); + aLeftSideOfBaseLine.SetXY( xPos,yPos ); } } aAscent = 0; @@ -547,23 +558,27 @@ // ----------------------------------------------------------------------------- // DoCommitFepInlineEditL -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::DoCommitFepInlineEditL() -{ - ClearInlineText(); +{ + ClearInlineText(); if (m_inlineEditText && DocumentLengthForFep() < DocumentMaximumLengthForFep()) { Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame(); if (frame){ - frame->editor()->insertTextWithoutSendingTextEvent(String(*m_inlineEditText), false); + if(IsWapMaskedModeInput(frame)) { + HandleMaskedInsertText(frame, (String(*m_inlineEditText))); + } + else { + frame->editor()->insertTextWithoutSendingTextEvent(String(*m_inlineEditText), false); + } } } - //delete the m_inlineEditText since text is commited - delete m_inlineEditText; - m_inlineEditText = NULL; + delete m_inlineEditText; + m_inlineEditText = NULL; HandleUpdateCursor(); UpdateEditingMode(); @@ -571,8 +586,8 @@ // ----------------------------------------------------------------------------- // Extension1 -// -// +// +// // ----------------------------------------------------------------------------- MCoeFepAwareTextEditor_Extension1* CWebFepTextEditor::Extension1(TBool& aSetToTrue) { @@ -582,31 +597,31 @@ // ----------------------------------------------------------------------------- // MCoeFepAwareTextEditor_Reserved_2 -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::MCoeFepAwareTextEditor_Reserved_2() { } - + //////////////////////////////////////////////////////////////////////////////// // from MCoeFepAwareTextEditor_Extension1 // ----------------------------------------------------------------------------- // SetStateTransferingOwnershipL -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::SetStateTransferingOwnershipL(CState* aState, TUid /*aTypeSafetyUid*/) { delete m_state; - m_state = aState; + m_state = aState; } // ----------------------------------------------------------------------------- // State -// -// +// +// // ----------------------------------------------------------------------------- MCoeFepAwareTextEditor_Extension1::CState* CWebFepTextEditor::State(TUid /*aTypeSafetyUid*/) { @@ -620,17 +635,17 @@ // ----------------------------------------------------------------------------- // StartFepInlineEditL -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::StartFepInlineEditL( - TBool& aSetToTrue, - const TCursorSelection& aCursorSelection, - const TDesC& aInitialInlineText, - TInt aPositionOfInsertionPointInInlineText, - TBool aCursorVisibility, - const MFormCustomDraw* aCustomDraw, - MFepInlineTextFormatRetriever& aInlineTextFormatRetriever, + TBool& aSetToTrue, + const TCursorSelection& aCursorSelection, + const TDesC& aInitialInlineText, + TInt aPositionOfInsertionPointInInlineText, + TBool aCursorVisibility, + const MFormCustomDraw* aCustomDraw, + MFepInlineTextFormatRetriever& aInlineTextFormatRetriever, MFepPointerEventHandlerDuringInlineEdit& aPointerEventHandlerDuringInlineEdit) { aSetToTrue=ETrue; @@ -640,8 +655,8 @@ // ----------------------------------------------------------------------------- // SetCursorType -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::SetCursorType(TBool& /*aSetToTrue*/, const TTextCursor& /*aTextCursor*/) { @@ -652,14 +667,14 @@ // ----------------------------------------------------------------------------- // IsValidCharacter -// -// +// +// // ----------------------------------------------------------------------------- TBool CWebFepTextEditor::IsValidCharacter(TInt aChar) { return ETrue; } - + //////////////////////////////////////////////////////////////////////////////// // from MObjectProvider @@ -677,7 +692,7 @@ return aId.Null(); } - + //////////////////////////////////////////////////////////////////////////////// // New public methods @@ -685,35 +700,35 @@ // ----------------------------------------------------------------------------- // UpdateFlagsState -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::UpdateFlagsState(TUint flags) -{ - CAknEdwinState* state = static_cast(State(KNullUid)); - +{ + CAknEdwinState* state = static_cast(State(KNullUid)); + if ( IsTextAreaFocused() ) { // If in a TextArea, allow "enter" key presses to be newline/paragraph - state->SetFlags( flags | EAknEditorFlagUseSCTNumericCharmap + state->SetFlags( flags | EAknEditorFlagUseSCTNumericCharmap | EAknEditorFlagAllowEntersWithScrollDown ); } else { state->SetFlags(flags | EAknEditorFlagUseSCTNumericCharmap); } - + state->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateFlagsUpdate); } // ----------------------------------------------------------------------------- // UpdateInputModeState -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::UpdateInputModeState(TUint inputMode, TUint permittedInputModes, TUint numericKeyMap) -{ +{ - CAknEdwinState* state = static_cast(State(KNullUid)); - + CAknEdwinState* state = static_cast(State(KNullUid)); + if (permittedInputModes != EAknEditorNumericInputMode) { EVariantFlag variant = AknLayoutUtils::Variant(); if (variant == EApacVariant) { @@ -721,64 +736,62 @@ EAknEditorHalfWidthTextInputMode | EAknEditorFullWidthTextInputMode | EAknEditorKatakanaInputMode | EAknEditorFullWidthKatakanaInputMode | EAknEditorHiraganaKanjiInputMode | EAknEditorHiraganaInputMode; - + } } - - state->SetDefaultInputMode(inputMode); - state->SetCurrentInputMode(inputMode); - state->SetPermittedInputModes(permittedInputModes); + + state->SetDefaultInputMode(inputMode); + state->SetCurrentInputMode(inputMode); + state->SetPermittedInputModes(permittedInputModes); state->SetNumericKeymap(static_cast(numericKeyMap)); - - state->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateInputModeUpdate); - + state->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateInputModeUpdate); } // ----------------------------------------------------------------------------- // UpdateCaseState -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::UpdateCaseState(TUint currentCase, TUint permittedCase) -{ - CAknEdwinState* state = static_cast(State(KNullUid)); +{ + CAknEdwinState* state = static_cast(State(KNullUid)); Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame(); if (frame){ if (frame->editor()->canEditRichly()) { - state->SetDefaultCase(EAknEditorTextCase); + state->SetDefaultCase(EAknEditorTextCase); } else { state->SetDefaultCase(currentCase); state->SetCurrentCase(currentCase); - state->SetPermittedCases(permittedCase); - } + state->SetPermittedCases(permittedCase); + } } - - state->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateCaseModeUpdate); + + state->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateCaseModeUpdate); } // ----------------------------------------------------------------------------- // HandleUpdateCursor // -// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::HandleUpdateCursor() { // ReportAknEdStateEventL, for events see aknedstsobs.h - // MAknEdStateObserver::EAknCursorPositionChanged - - CAknEdwinState* state = static_cast(State(KNullUid)); - if ( state ) { + // MAknEdStateObserver::EAknCursorPositionChanged + + CAknEdwinState* state = static_cast(State(KNullUid)); + if ( state ) { TRAP_IGNORE( state->ReportAknEdStateEventL( MAknEdStateObserver::EAknCursorPositionChanged ) ); } } // ----------------------------------------------------------------------------- // GetStateFromFormatMask -// -// +// +// // ----------------------------------------------------------------------------- bool CWebFepTextEditor::GetStateFromFormatMask(TUint& currentCase, TUint& permittedCase, @@ -787,31 +800,36 @@ TUint& flags, TUint& numericKeyMap) { - Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame(); + Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame(); if (frame && m_textFormatMask) { - - TInt cursorpos = DocumentLengthForFep(); - TInputFormatMaskType fm = m_textFormatMask->getInputFormatMaskType(frame, cursorpos); + TInt cursorpos = DocumentLengthForFep(); + TInputFormatMaskType fm = m_textFormatMask->getInputFormatMaskType(frame, cursorpos); + if (!cursorpos) { + while(fm == EStatic) { + fm = m_textFormatMask->getInputFormatMaskType(frame, ++cursorpos); + } + } + setSCTAvailability(true); switch( fm ) { case ELeUpSymPuc: //A any upper case letter or symbolic flags = EAknEditorFlagNoT9 | EAknEditorFlagFixedCase; - currentCase = EAknEditorUpperCase; - permittedCase = EAknEditorUpperCase; + currentCase = EAknEditorUpperCase; + permittedCase = EAknEditorUpperCase; inputMode = EAknEditorTextInputMode; permittedInputModes = EAknEditorTextInputMode; break; case ELeLoSymPuc: //a any lower case letter or symbolic flags = EAknEditorFlagNoT9 | EAknEditorFlagFixedCase; currentCase = EAknEditorLowerCase; - permittedCase= EAknEditorLowerCase; + permittedCase= EAknEditorLowerCase; inputMode = EAknEditorTextInputMode; permittedInputModes= EAknEditorTextInputMode; break; case ELeUpNumSymPuc: //X any upper case, number or symbolic flags = EAknEditorFlagNoT9 | EAknEditorFlagFixedCase; currentCase = EAknEditorUpperCase; - permittedCase= EAknEditorUpperCase; + permittedCase= EAknEditorUpperCase; inputMode = EAknEditorTextInputMode; permittedInputModes= EAknEditorTextInputMode; break; @@ -823,13 +841,15 @@ permittedInputModes= EAknEditorTextInputMode | EAknEditorNumericInputMode; break; case EAnyLow: //m any lower character can be changed to upper + flags = EAknEditorFlagNoT9; currentCase = EAknEditorLowerCase; permittedCase= EAknEditorAllCaseModes; inputMode = EAknEditorTextInputMode; permittedInputModes= EAknEditorAllInputModes; - break; + break; case EAnyUpper: //M any upper character can be changed to lower - currentCase = EAknEditorUpperCase; + flags = EAknEditorFlagNoT9; + currentCase = EAknEditorUpperCase; permittedCase= EAknEditorAllCaseModes; inputMode = EAknEditorTextInputMode; permittedInputModes= EAknEditorAllInputModes; @@ -838,36 +858,38 @@ flags = EAknEditorFlagNoT9; currentCase = EAknEditorUpperCase; permittedCase = EAknEditorAllCaseModes; - inputMode = EAknEditorNumericInputMode; - permittedInputModes= EAknEditorAllInputModes; + inputMode = EAknEditorNumericInputMode; + permittedInputModes= EAknEditorAllInputModes; break; case ENumChar: //N any number flags = EAknEditorFlagNoT9; currentCase = EAknEditorUpperCase; permittedCase = EAknEditorAllCaseModes; - inputMode = EAknEditorNumericInputMode; - permittedInputModes= EAknEditorNumericInputMode; + inputMode = EAknEditorNumericInputMode; + permittedInputModes= EAknEditorNumericInputMode; + numericKeyMap = EAknEditorPlainNumberModeKeymap; + setSCTAvailability(false); break; - case EStatic: + case EStatic: return EFalse; break; - case ENoFormat: + case ENoFormat: return EFalse; - break; + break; default: - return EFalse; - } - - return ETrue; + return EFalse; + } + + return ETrue; } - return EFalse; + return EFalse; } // ----------------------------------------------------------------------------- // validateTextFormat -// -// +// +// // ----------------------------------------------------------------------------- bool CWebFepTextEditor::validateTextFormat() { @@ -875,39 +897,39 @@ if (!frame || !frame->document()->focusedNode()) return true; - RenderStyle* s = frame->document()->focusedNode()->renderStyle(); - if (!m_textFormatMask) { + RenderStyle* s = frame->document()->focusedNode()->renderStyle(); + if (!m_textFormatMask) { return true; } - + Node* n = frame->document()->focusedNode(); if (n->hasTagName(HTMLNames::inputTag)) { HTMLInputElement* input = static_cast(n); WebTextFormatMask::ErrorBlock eb; CSSStyleDeclaration* style = input->style(); - ExceptionCode ec = 0; - - String inputColor = style->getPropertyValue(CSS_PROP_COLOR); + ExceptionCode ec = 0; + + String inputColor = style->getPropertyValue(CSS_PROP_COLOR); if ( inputColor.lower() != "red" ) { - m_inputTextColor = inputColor; + m_inputTextColor = inputColor; } - + if (!m_textFormatMask->checkText(input->value(), eb)) { style->setProperty(CSS_PROP_COLOR, "red", false, ec); return false; } - else + else { style->setProperty(CSS_PROP_COLOR, m_inputTextColor, false, ec); CancelEditingMode(); - return true; + return true; } } else if ( n->hasTagName(HTMLNames::textareaTag)) { CancelEditingMode(); } - + return true; } @@ -940,14 +962,14 @@ // ----------------------------------------------------------------------------- // SetAlignment // The EInputEditorAlignXXX flags are only supported in 5.0+ platforms -// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::SetAlignment(CAknExtendedInputCapabilities::TInputCapabilities aAlignment) { if ( !m_ExtendedInputCapabilities ) { return; } - + // Clear the old alignment TUint capabilities = m_ExtendedInputCapabilities->Capabilities(); capabilities &= ~( CAknExtendedInputCapabilities::KAknEditorAlignMask ); @@ -960,42 +982,47 @@ // ----------------------------------------------------------------------------- // UpdateInlineText -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::UpdateInlineText(const TDesC& aText) -{ - delete m_inlineEditText; - m_inlineEditText = NULL; - - if (DocumentLengthForFep() >= DocumentMaximumLengthForFep()) +{ + delete m_inlineEditText; + m_inlineEditText = NULL; + + if (DocumentLengthForFep() >= DocumentMaximumLengthForFep()) return; - m_inlineEditText = aText.Alloc(); - + m_inlineEditText = aText.Alloc(); + Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame(); - + if (!frame) return; - - + + RenderStyle* r = NULL; if ( Node *n = frame->selectionController()->selection().start().node() ) { r = n->renderStyle(); } - + bool textSecurity = r && r->textSecurity() != TSNONE; RefPtr oldStyle; - if (textSecurity) { + if (textSecurity) { oldStyle = frame->typingStyle(); RefPtr style = new CSSMutableStyleDeclaration; style->setProperty(CSS_PROP__WEBKIT_TEXT_SECURITY, CSS_VAL_NONE); frame->computeAndSetTypingStyle(style.get(), EditActionTyping); } - - frame->editor()->insertTextWithoutSendingTextEvent(String(*m_inlineEditText), false); - + + if(!DocumentLengthForFep() && IsWapMaskedModeInput(frame)) { + HandleMaskedInsertText(frame, String(*m_inlineEditText)); + } + else { + frame->editor()->insertTextWithoutSendingTextEvent(String(*m_inlineEditText), false); + } + if (textSecurity) { if (oldStyle) frame->setTypingStyle(oldStyle.get()); @@ -1006,16 +1033,16 @@ // ----------------------------------------------------------------------------- // ClearInlineText -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::ClearInlineText() { TInt oldlen = m_inlineEditText ? m_inlineEditText->Length() : 0; - TKeyEvent keyEvent = { EKeyBackspace, EKeyBackspace, 0, 0 }; + TKeyEvent keyEvent = { EKeyBackspace, EKeyBackspace, 0, 0 }; Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame(); - if (frame) { + if (frame) { while ( oldlen-- ) { frame->editor()->deleteWithDirection(SelectionController::BACKWARD, CharacterGranularity, false, true); @@ -1025,8 +1052,8 @@ // ----------------------------------------------------------------------------- // IsTextAreaFocused -// -// +// +// // ----------------------------------------------------------------------------- bool CWebFepTextEditor::IsTextAreaFocused() const { @@ -1037,85 +1064,85 @@ // ----------------------------------------------------------------------------- // CcpuIsFocused -// -// +// +// // ----------------------------------------------------------------------------- TBool CWebFepTextEditor::CcpuIsFocused() const { return ETrue; } - + // ----------------------------------------------------------------------------- // CcpuCanCut -// -// +// +// // ----------------------------------------------------------------------------- TBool CWebFepTextEditor::CcpuCanCut() const { TCursorSelection selection; - GetCursorSelectionForFep(selection); + GetCursorSelectionForFep(selection); return selection.Length(); } // ----------------------------------------------------------------------------- // CcpuCutL -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::CcpuCutL() { PlaceDataOnClipboardL(); TCursorSelection selection; - GetCursorSelectionForFep(selection); + GetCursorSelectionForFep(selection); } - + // ----------------------------------------------------------------------------- // CcpuCanCopy -// -// +// +// // ----------------------------------------------------------------------------- TBool CWebFepTextEditor::CcpuCanCopy() const { TCursorSelection selection; - GetCursorSelectionForFep(selection); + GetCursorSelectionForFep(selection); return selection.Length(); } - + // ----------------------------------------------------------------------------- // CcpuCopyL -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::CcpuCopyL() { PlaceDataOnClipboardL(); } - + // ----------------------------------------------------------------------------- // CcpuCanPaste -// -// +// +// // ----------------------------------------------------------------------------- TBool CWebFepTextEditor::CcpuCanPaste() const { TRAPD(err, DoCcpuCanPasteL()); return err == KErrNone; } - + // ----------------------------------------------------------------------------- // CcpuPasteL -// -// +// +// // ----------------------------------------------------------------------------- -void CWebFepTextEditor::CcpuPasteL() +void CWebFepTextEditor::CcpuPasteL() { - RetrieveDataFromClipboardL(); + RetrieveDataFromClipboardL(); } - + // ----------------------------------------------------------------------------- // DoCcpuCanPasteL -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::DoCcpuCanPasteL() const { @@ -1125,12 +1152,12 @@ if (streamId==KNullStreamId) User::Leave(KErrNotFound); CleanupStack::PopAndDestroy(); // allowedChars, cb -} - +} + // ----------------------------------------------------------------------------- // PlaceDataOnClipboardL -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::PlaceDataOnClipboardL() { @@ -1143,8 +1170,8 @@ // ----------------------------------------------------------------------------- // CopyToStoreL -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::CopyToStoreL(CStreamStore& aStore,CStreamDictionary& aDict) { @@ -1152,24 +1179,95 @@ return ; TCursorSelection selection; GetCursorSelectionForFep(selection); - + HBufC* buf = HBufC::NewLC(512); TPtr ptr(buf->Des()); - + GetEditorContentForFep(ptr,0,DocumentLengthForFep()); - CPlainText* text = CPlainText::NewL(CPlainText::EFlatStorage); - - text->InsertL(0,*buf); + CPlainText* text = CPlainText::NewL(CPlainText::EFlatStorage); + + text->InsertL(0,*buf); text->CopyToStoreL(aStore, aDict, selection.LowerPos(), selection.Length()); - + delete text; - CleanupStack::PopAndDestroy(); + CleanupStack::PopAndDestroy(); +} + +// ----------------------------------------------------------------------------- +// HandleMaskedInsertText +// +// +// ----------------------------------------------------------------------------- +void CWebFepTextEditor::HandleMaskedInsertText(WebCore::Frame *frame, const String& text) +{ + TInt pos = DocumentLengthForFep(); + if (!pos) { + while(m_textFormatMask->getInputFormatMaskType(frame, pos) == EStatic) { + MaskStatic* ms = static_cast(m_textFormatMask->getMask(pos)); + UChar mask(ms->getStatic()); + frame->editor()->insertTextWithoutSendingTextEvent(String(&mask,1), false); + ++pos; + } + frame->editor()->insertTextWithoutSendingTextEvent(text, false); + } + else { + frame->editor()->insertTextWithoutSendingTextEvent(text, false); + while(m_textFormatMask->getInputFormatMaskType(frame, ++pos) == EStatic) { + TCursorSelection selection; + GetCursorSelectionForFep(selection); + const TInt cursorPos=selection.LowerPos(); + if (cursorPos>=pos) { + MaskStatic* ms = static_cast(m_textFormatMask->getMask(pos)); + UChar mask(ms->getStatic()); + frame->editor()->insertTextWithoutSendingTextEvent(String(&mask,1), false); + } + } + } +} + +// ----------------------------------------------------------------------------- +// HandleMaskedDeleteText +// +// +// ----------------------------------------------------------------------------- +void CWebFepTextEditor::HandleMaskedDeleteText(WebCore::Frame* frame) +{ + TCursorSelection selection; + GetCursorSelectionForFep(selection); + TInt cursorPos=selection.LowerPos(); + + if (cursorPos == DocumentLengthForFep()) { + while (m_textFormatMask->getInputFormatMaskType(frame, --cursorPos) == EStatic) { + frame->editor()->deleteWithDirection(SelectionController::BACKWARD, + CharacterGranularity, false, true); + } + } + if (cursorPos >=0) + frame->editor()->deleteWithDirection(SelectionController::BACKWARD, + CharacterGranularity, false, true); +} + +// ----------------------------------------------------------------------------- +// IsWapMaskedModeInput +// +// +// ----------------------------------------------------------------------------- +bool CWebFepTextEditor::IsWapMaskedModeInput(WebCore::Frame* frame) +{ + bool maskedInput(false); + if (m_textFormatMask && frame->document() && frame->document()->focusedNode()) { + RenderStyle* s = frame->document()->focusedNode()->renderStyle(); + if (s && (!s->wapInputFormat().isEmpty() || s->wapInputRequired())){ + maskedInput = true; + } + } + return maskedInput; } // ----------------------------------------------------------------------------- // RetrieveDataFromClipboardL -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::RetrieveDataFromClipboardL() { @@ -1180,13 +1278,13 @@ User::LeaveIfError(err); TStreamId streamId=cb->StreamDictionary().At(KClipboardUidTypePlainText); PasteFromStoreL(cb->Store(), cb->StreamDictionary()); - CleanupStack::PopAndDestroy(); // cb + CleanupStack::PopAndDestroy(); // cb } - + // ----------------------------------------------------------------------------- // PasteFromStoreL -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::PasteFromStoreL(CStreamStore& aStore,CStreamDictionary& aDict) { @@ -1196,58 +1294,58 @@ TCursorSelection selection; GetCursorSelectionForFep(selection); const TInt cursorPos=selection.LowerPos(); - + HBufC* buf1 = HBufC::NewLC(512); TPtr ptr1(buf1->Des()); - - CPlainText* text = CPlainText::NewL(CPlainText::EFlatStorage); - - GetEditorContentForFep(ptr1,0,DocumentLengthForFep()); - + + CPlainText* text = CPlainText::NewL(CPlainText::EFlatStorage); + + GetEditorContentForFep(ptr1,0,DocumentLengthForFep()); + text->InsertL(0,*buf1); - + TInt charPasted = text->PasteFromStoreL(aStore,aDict,cursorPos); - + HBufC* buf = HBufC::NewLC(512); TPtr ptr(buf->Des()); - text->Extract(ptr,cursorPos,charPasted); - + text->Extract(ptr,cursorPos,charPasted); + //remove Paragraph Delimiter TInt position = ptr.Mid(0).LocateReverse(TChar(CEditableText::EParagraphDelimiter)); while (position != KErrNotFound ){ ptr.Delete( position, 1 ); position = ptr.Left(position).LocateReverse(TChar(CEditableText::EParagraphDelimiter)); - } - + } + Frame* frame = m_webView->page()->mainFrame(); frame = m_webView->page()->focusController()->focusedOrMainFrame(); frame->editor()->insertTextWithoutSendingTextEvent(String(ptr), false); - + delete text; CleanupStack::PopAndDestroy(2); } // ----------------------------------------------------------------------------- // EnableCcpu -// -// +// +// // ----------------------------------------------------------------------------- void CWebFepTextEditor::EnableCcpu(TBool aSupport) { CAknEdwinState* edwinState = static_cast(this->State(KNullUid)); if(aSupport) { - edwinState->SetCcpuState(this); + edwinState->SetCcpuState(this); } else { edwinState->SetCcpuState(NULL); - } + } } // ----------------------------------------------------------------------------- // findPrevSiblingTextLen -// +// // Walk the previous text nodes and add up the len of each text node, so we can // calculate the total length from first text node to current text node cursor // position. @@ -1295,7 +1393,7 @@ WebCore::Text* aText = (WebCore::Text*)aNode; str = aText->data(); len += str.length(); - if ( len >= aPos ) { + if ( len > aPos ) { // We found the text node at aPos, calculate the length of all // previous text nodes retNode = aNode; @@ -1307,3 +1405,23 @@ return retNode; } + +// ----------------------------------------------------------------------------- +// SetSCTAvailability +// +// Set availibility of the special character table. +// ----------------------------------------------------------------------------- +void CWebFepTextEditor::setSCTAvailability(bool aAvailable) +{ + if (m_ExtendedInputCapabilities) { + TUint capabilities = m_ExtendedInputCapabilities->Capabilities(); + if (!aAvailable) { + capabilities |= CAknExtendedInputCapabilities::EDisableSCT; + } + else { + capabilities &= ~(CAknExtendedInputCapabilities::EDisableSCT); + } + m_ExtendedInputCapabilities->SetCapabilities(capabilities); + } +} + diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webview/WebFepTextEditor.h --- a/webengine/osswebengine/WebKit/s60/webview/WebFepTextEditor.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/webview/WebFepTextEditor.h Thu Aug 27 07:44:59 2009 +0300 @@ -30,6 +30,7 @@ #include "PlatformString.h" #include "Node.h" +#include "Frame.h" #ifndef WEBFEPTEXTEDITOR_H #define WEBFEPTEXTEDITOR_H @@ -128,10 +129,14 @@ void RetrieveDataFromClipboardL(); void PasteFromStoreL(CStreamStore& aStore,CStreamDictionary& aDict); void CopyToStoreL(CStreamStore& aStore,CStreamDictionary& aDict); + void HandleMaskedInsertText(WebCore::Frame* frame, const String& text); + void HandleMaskedDeleteText(WebCore::Frame* frame); + bool IsWapMaskedModeInput(WebCore::Frame* frame); private: void findPrevSiblingTextLen(Node*, TInt&) const; Node* findTextNodeForCurPos(Node* aNode, TInt& aPos) const; + void setSCTAvailability(bool aAvailable); private: CState* m_state; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webview/WebFrame.cpp --- a/webengine/osswebengine/WebKit/s60/webview/WebFrame.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/webview/WebFrame.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -282,6 +282,7 @@ void WebFrame::notifyPluginsOfScrolling() { + setpluginToScroll(true); Frame* coreFrame = core(this); for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) { PassRefPtr objects = frame->document()->objects(); @@ -293,6 +294,7 @@ notifyPluginOfScrolling(n->renderer()); } + setpluginToScroll(false); } void WebFrame::notifyPluginOfScrolling(RenderObject* renderer) diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webview/WebFrame.h --- a/webengine/osswebengine/WebKit/s60/webview/WebFrame.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/webview/WebFrame.h Thu Aug 27 07:44:59 2009 +0300 @@ -108,6 +108,9 @@ bool executeScript(const WebCore::String& script); WebCore::Node* getClosestAnchorElement(const TPoint& pt, TPoint& newPos); + void setpluginToScroll(bool pluginScroll){m_pluginToScroll=pluginScroll;} + bool pluginToScroll(){return m_pluginToScroll;} + private: WebFrame(const WebFrame&); // not implemented WebFrame& operator=(const WebFrame&); // not implemented @@ -115,6 +118,7 @@ WebFrameView* m_view; // the frame view RefPtr m_loaderClient; // the loader client WebFrameBridge* m_bridge; // the bridge + bool m_pluginToScroll; }; // utility functions diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webview/WebPageZoomHandler.cpp --- a/webengine/osswebengine/WebKit/s60/webview/WebPageZoomHandler.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/webview/WebPageZoomHandler.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -89,6 +89,10 @@ if ( m_zoomSlider ) { + if( m_zoomSlider->IsVisible()) + { + m_zoomSlider->CloseVolumePopup(); + } delete m_zoomSlider; } } diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webview/WebTextFormatMask.cpp --- a/webengine/osswebengine/WebKit/s60/webview/WebTextFormatMask.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/webview/WebTextFormatMask.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -199,6 +199,20 @@ return (eb.m_start == -1); } +MaskBase* WebTextFormatMask::getMask(int aOffset) +{ + MaskBase* m = m_masks; + int i = 0; + while(m) { + if (i == aOffset) { + return m; + } + m = m->nextMask(); + ++i; + } + return NULL; +} + int WebTextFormatMask::getMultitude() { int count = 0; @@ -230,24 +244,6 @@ else if (i==aOffset) { TInputFormatMaskType ifmt = m->getInputFormatMaskType(); - if (ifmt == EStatic){ - MaskStatic* ms = static_cast(m); - if (ms) { - //make sure not to re-write the static text if it already exists - if (frame->document() && - frame->document()->focusedNode() && - frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag) ) { - - HTMLInputElement* ie = static_cast(frame->document()->focusedNode()); - int len = ie->value().length(); - - if (len<=aOffset) { - UChar c = ms->getStatic(); - frame->editor()->insertTextWithoutSendingTextEvent(String(&c,1), false); - } - } - } - } return ifmt; } m = m->nextMask(); diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webview/WebTextFormatMask.h --- a/webengine/osswebengine/WebKit/s60/webview/WebTextFormatMask.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/webview/WebTextFormatMask.h Thu Aug 27 07:44:59 2009 +0300 @@ -120,6 +120,7 @@ ~WebTextFormatMask(); bool checkText(const WebCore::String&, ErrorBlock&); + MaskBase* getMask(int aOffset); public: int getMultitude(); diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webview/WebView.cpp --- a/webengine/osswebengine/WebKit/s60/webview/WebView.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/webview/WebView.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -97,9 +97,10 @@ #include "WebPageFullScreenHandler.h" #include "eikon.hrh" #include "WebScrollbarDrawer.h" - +#include "EventNames.h" using namespace WebCore; +using namespace EventNames; const int KRepaintDelayLoading = 500*1000; // dont do repaints more often than this during loading (0.5s) const int KRepaintDelayComplete = 100*1000; // faster updates after load so dynamic scripts etc have better frame rate (0.1s) @@ -193,6 +194,7 @@ , m_ptrbuffer(0) , m_showCursor(false) , m_allowRepaints(true) +, m_prevEditMode(false) { } @@ -536,7 +538,8 @@ // draw to back buffer - + if(m_widgetextension && !IsVisible()) + return; if(!( m_widgetextension && m_widgetextension->IsWidgetPublising())) { mainFrame()->frameView()->draw( *m_webcorecontext, rect ); if ( zoomLevel < m_minZoomLevel ) zoomLevel = m_minZoomLevel; @@ -579,7 +582,8 @@ } layoutPending = false; } - if (!layoutPending) { + + if ( !layoutPending || !isLoading()) { bool needsDraw = false; m_repaints.Tidy(); for (int i=0; iSize(), StaticObjectsContainer::instance()->webSurface()->displayMode()); + if( m_widgetextension && m_widgetextension->IsWidgetPublising()) { + if ( snapshot.Handle() == 0) { + // Create bitmap only once + (snapshot).Create(m_brctl->Size(), StaticObjectsContainer::instance()->webSurface()->displayMode()); + } + CFbsBitmapDevice* device = CFbsBitmapDevice::NewL( &snapshot); + CleanupStack::PushL(device); + + WebCoreGraphicsContext* gc = WebCoreGraphicsContext::NewL( device, &snapshot, mainFrame()->frameView()); + CleanupStack::PushL(gc); + + if( snapshot.Handle() != 0 ) { + // Clear previous offscreen bitmap + // frameView->draw might clear the bitmap. + gc->gc().Clear(); + } + if (snapshot.SizeInPixels()!=m_brctl->Size()) { + snapshot.Resize(m_brctl->Size()); + } + mainFrame()->frameView()->draw( *gc, mainFrame()->frameView()->visibleRect() ); + + CleanupStack::PopAndDestroy(2); } - CFbsBitmapDevice* device = CFbsBitmapDevice::NewL( &snapshot); - CleanupStack::PushL(device); - - WebCoreGraphicsContext* gc = WebCoreGraphicsContext::NewL( device, &snapshot, mainFrame()->frameView()); - CleanupStack::PushL(gc); - - if( snapshot.Handle() != 0 ){ - // Clear previous offscreen bitmap - // frameView->draw might clear the bitmap. - gc->gc().Clear(); - } else if (snapshot.SizeInPixels()!=m_brctl->Size()){ - snapshot.Resize(m_brctl->Size()); - } - mainFrame()->frameView()->draw( *gc, mainFrame()->frameView()->visibleRect() ); - - CleanupStack::PopAndDestroy(2); } @@ -827,17 +834,21 @@ bool WebView::isNaviKey(const TKeyEvent& keyevent) { return ( keyevent.iCode == EKeyUpArrow // North + || keyevent.iCode == EStdKeyUpArrow // : || keyevent.iCode == EKeyRightUpArrow // Northeast - || keyevent.iCode == EStdKeyDevice11 // : Extra KeyEvent supports diagonal event simulator wedge + || keyevent.iCode == EStdKeyDevice11 // : || keyevent.iCode == EKeyRightArrow // East + || keyevent.iCode == EStdKeyRightArrow // : || keyevent.iCode == EKeyRightDownArrow // Southeast - || keyevent.iCode == EStdKeyDevice12 // : Extra KeyEvent supports diagonal event simulator wedge + || keyevent.iCode == EStdKeyDevice12 // : || keyevent.iCode == EKeyDownArrow // South + || keyevent.iCode == EStdKeyDownArrow // : || keyevent.iCode == EKeyLeftDownArrow // Southwest - || keyevent.iCode == EStdKeyDevice13 // : Extra KeyEvent supports diagonal event simulator wedge + || keyevent.iCode == EStdKeyDevice13 // : || keyevent.iCode == EKeyLeftArrow // West + || keyevent.iCode == EStdKeyLeftArrow // : || keyevent.iCode == EKeyLeftUpArrow // Northwest - || keyevent.iCode == EStdKeyDevice10); + || keyevent.iCode == EStdKeyDevice10 ); // : } bool WebView::handleEditable(const TKeyEvent& keyevent, TEventCode eventcode, Frame* frame ) @@ -908,11 +919,38 @@ } } +bool WebView::needDeactivateEditable(const TKeyEvent& keyevent, TEventCode eventcode) +{ + bool upOrDown = ((keyevent.iCode == EKeyDevice3) || + (keyevent.iCode == EKeyUpArrow) || + (keyevent.iCode == EStdKeyUpArrow) || + (keyevent.iCode == EKeyRightUpArrow) || + (keyevent.iCode == EKeyDownArrow) || + (keyevent.iCode == EStdKeyDownArrow) || + (keyevent.iCode == EKeyLeftDownArrow)); + bool inEditState = (m_isEditable && (m_focusedElementType == TBrCtlDefs::EElementActivatedInputBox)); + bool isSelectBoxActive = (m_focusedElementType == TBrCtlDefs::EElementSelectBox); + bool deactivateInputBox = (inEditState && upOrDown); + bool deactivateSelectBox = (isSelectBoxActive && isNaviKey(keyevent)); + + return deactivateInputBox || deactivateSelectBox; +} + + +bool WebView::deactivateEditable() +{ + setFocusNone(); + m_prevEditMode = true; + setEditable( EFalse ); + return true; +} + bool WebView::handleEventKeyL(const TKeyEvent& keyevent, TEventCode eventcode, Frame* frame) { WebCursor* cursor = StaticObjectsContainer::instance()->webCursor(); bool consumed = false; - + bool tabbedNavigation = (m_brctl->settings()->getNavigationType() == SettingsContainer::NavigationTypeTabbed); + bool navigationNone = (m_brctl->settings()->getNavigationType() == SettingsContainer::NavigationTypeNone); TKeyEvent oldKeyEvent(m_currentEventKey); oldKeyEvent.iCode = keyevent.iCode; TEventCode oldKeyCode = m_currentEventCode; @@ -920,20 +958,26 @@ m_currentEventKey = keyevent; m_currentEventCode = eventcode; - if (m_brctl->settings()->getNavigationType() == SettingsContainer::NavigationTypeNone) { + if (navigationNone) { consumed = handleInputElement(keyevent, eventcode, frame); if (!consumed) consumed = sendKeyEventToEngine(keyevent, eventcode, frame); } else { - if (keyevent.iCode == EKeyDevice3) { - // pass it to webcore - sendMouseEventToEngine(TPointerEvent::EButton1Down, - cursor->position(), frame); - - // mimic ccb's behavior of onFocus + if (needDeactivateEditable(keyevent, eventcode)) { + consumed = deactivateEditable(); + handleKeyNavigation(keyevent, eventcode, frame); + } + else if (keyevent.iCode == EKeyDevice3) { + sendMouseEventToEngine(TPointerEvent::EButton1Down, + cursor->position(), frame); + // mimic ccb's behavior of onFocus setFocusedNode(frame); - + if (oldKeyCode == EEventKeyDown && + (m_focusedElementType != TBrCtlDefs::EElementActivatedInputBox)){ + sendKeyEventToEngine(oldKeyEvent, EEventKeyDown, frame); + } + // Toolbar is activated on long key press only if the element // type is EElementNone during EEventKeyDown and EEventKey. // This prevents toolbar from popping up in DHTML pages. Also, @@ -947,32 +991,50 @@ consumed = true; } else if (isNaviKey(keyevent)) { - - if (oldKeyCode == EEventKeyDown){ - // Keydown event is automatically generated before each keypress event, but in this case - // we don't send a keypress event, so send a keydown event explicitly. - downEventConsumed = sendKeyEventToEngine(oldKeyEvent, EEventKeyDown, frame); - } - - - if (m_brctl->settings()->getNavigationType() == SettingsContainer::NavigationTypeTabbed) { - consumed = downEventConsumed || handleTabbedNavigation(keyevent, eventcode); - } - else { - consumed = handleKeyNavigation(keyevent, eventcode, frame); - } + consumed = handleNaviKeyEvent(oldKeyEvent, oldKeyCode, frame); } // if (m_brctl->settings()->getNavigationType() else { // Not an arrow key.. // activate hovered input element by just start typing - consumed = handleInputElement(keyevent, eventcode, frame); + consumed = !m_isEditable && handleInputElement(keyevent, eventcode, frame); } - if (!consumed && !(m_brctl->settings()->getNavigationType() == SettingsContainer::NavigationTypeTabbed && isNaviKey(keyevent))) { + if (!consumed && !(tabbedNavigation && isNaviKey(keyevent))) { consumed = sendKeyEventToEngine(keyevent, eventcode, frame); } } return consumed; } +bool WebView::handleNaviKeyEvent(const TKeyEvent& keyevent, TEventCode eventcode, Frame* frame) +{ + bool downEventConsumed = false; + bool consumed = false; + bool tabbedNavigation = (m_brctl->settings()->getNavigationType() == SettingsContainer::NavigationTypeTabbed); + /* + * For each platform keyDown event EventHandler::keEvent() generates + * keydown and keypress. + * For keypress event we need a char code and since we don't + * have it at the time of EEventKeyDown we pospond it until EEventKey + * and send it here. + */ + if (eventcode == EEventKeyDown){ + downEventConsumed = sendKeyEventToEngine(keyevent, EEventKeyDown, frame); + } + + if (m_isEditable && !downEventConsumed && m_webfeptexteditor->validateTextFormat()) { + setFocusNone(); + } + + if (tabbedNavigation) { + consumed = downEventConsumed || handleTabbedNavigation(m_currentEventKey, m_currentEventCode); + } + else { + consumed = (!m_isEditable && //avoid showing the cursor when we are in the input box + handleKeyNavigation(keyevent, eventcode, frame)) || + downEventConsumed; + } + return consumed; +} + bool WebView::handleInputElement(const TKeyEvent& keyevent, TEventCode eventcode, Frame* frame) { @@ -984,16 +1046,18 @@ } else if (m_focusedElementType == TBrCtlDefs::EElementSelectBox || m_focusedElementType == TBrCtlDefs::EElementSelectMultiBox) { - if (m_brctl->settings()->getNavigationType() != SettingsContainer::NavigationTypeNone || keyevent.iCode == EKeyDevice3) { + if (m_brctl->settings()->getNavigationType() != SettingsContainer::NavigationTypeNone || + keyevent.iCode == EKeyDevice3) { sendMousedEvent = true; } } if (sendMousedEvent) { sendMouseEventToEngine(TPointerEvent::EButton1Down, cursor->position(), frame); sendMouseEventToEngine(TPointerEvent::EButton1Up, cursor->position(), frame); - - if (m_focusedElementType == TBrCtlDefs::EElementInputBox || - m_focusedElementType == TBrCtlDefs::EElementTextAreaBox) { + + if (m_focusedElementType == TBrCtlDefs::EElementInputBox || + m_focusedElementType == TBrCtlDefs::EElementTextAreaBox || + m_focusedElementType == TBrCtlDefs::EElementActivatedInputBox) { if (!m_fepTimer) { m_fepTimer = new WebCore::Timer(this, &WebView::fepTimerFired); } @@ -1020,8 +1084,11 @@ if (!cursor->isVisible()) { cursor->cursorUpdate(true); } - - m_savedPosition = mainFrame()->frameView()->contentPos(); + + if(!pageView()) { + m_savedPosition = mainFrame()->frameView()->contentPos(); + } + cursor->scrollAndMoveCursor(keyevent.iCode, m_scrollingSpeed, fastscroll); updateScrollbars(); if (!fastscroll) { @@ -1059,26 +1126,29 @@ int vertical = 0; switch(keyevent.iCode) { case EKeyUpArrow: // North + case EStdKeyUpArrow: // : vertical = -1; break; case EKeyRightUpArrow: // Northeast - case EStdKeyDevice11: // : Extra KeyEvent supports diagonal event simulator wedge + case EStdKeyDevice11: // : vertical = -1; horizontal = +1; break; case EKeyRightArrow: // East + case EStdKeyRightArrow: // : horizontal = +1; break; case EKeyRightDownArrow: // Southeast - case EStdKeyDevice12: // : Extra KeyEvent supports diagonal event simulator wedge + case EStdKeyDevice12: // : vertical = +1; horizontal = +1; break; case EKeyDownArrow: // South + case EStdKeyDownArrow: // : vertical = +1; break; @@ -1089,6 +1159,7 @@ break; case EKeyLeftArrow: // West + case EStdKeyLeftArrow: // : horizontal = -1; break; @@ -1124,26 +1195,47 @@ } } m_pageScrollHandler->scrollbarDrawer()->fadeScrollbar(delay); - - if ( (keyevent.iScanCode == EStdKeyDevice3) || + TKeyEvent correctedKeyEvent(keyevent); + correctedKeyEvent.iCode = correctKeyCode(); + TEventCode eventCodeUp = eventcode; + TEventCode eventCodeDown = EEventKeyDown; + //If we adjusted iCode we have to reset it to 0 after we + //create PlatformKeyEventSymbian when we send the key event. + //Otherwise the character will be drawn twice - by fep editor and by + //WebEditorClient. These two custom eventcodes serves as indicator that + //PlatformKeyEventSymbian::m_symbianEvent.iCode nee to be reset to 0. + if (correctedKeyEvent.iCode != m_currentEventKey.iCode) { + eventCodeDown = (TEventCode)(EEventUser + 1); + eventCodeUp = (TEventCode)(EEventUser + 2); + } + + if ( (keyevent.iScanCode == EStdKeyDevice3) || (keyevent.iScanCode == EStdKeyEnter) ) { - // pass it to webcore - - if (m_focusedElementType == TBrCtlDefs::EElementInputBox || - m_focusedElementType == TBrCtlDefs::EElementTextAreaBox) { - setEditable(true); + // pass it to webcore + + if (( m_focusedElementType == TBrCtlDefs::EElementInputBox || + m_focusedElementType == TBrCtlDefs::EElementTextAreaBox) && + m_brctl->settings()->getNavigationType() == SettingsContainer::NavigationTypeTabbed ) { + if (!m_prevEditMode) { + setEditable(true); + } + else { + m_prevEditMode = false; + } } if (m_brctl->settings()->getNavigationType() != SettingsContainer::NavigationTypeNone) { - sendMouseEventToEngine(TPointerEvent::EButton1Up, cursor->position(), frame); + if (!sendKeyEventToEngine(correctedKeyEvent, eventcode, frame)) { + sendMouseEventToEngine(TPointerEvent::EButton1Up, cursor->position(), frame); + } consumed = true; } } if (!consumed) { - - TKeyEvent correctedKeyEvent(keyevent); - correctedKeyEvent.iCode = m_currentEventKey.iCode; - sendKeyEventToEngine(correctedKeyEvent, eventcode, frame); + if (m_currentEventCode == EEventKeyDown) { + sendKeyEventToEngine(correctedKeyEvent, eventCodeDown, frame); + } + sendKeyEventToEngine(correctedKeyEvent, eventCodeUp, frame); } m_currentEventKey = KNullKeyEvent; m_currentEventCode = EEventNull; @@ -1151,11 +1243,55 @@ } -bool WebView::sendKeyEventToEngine(const TKeyEvent& keyevent, +TUint WebView::correctKeyCode() +{ + TUint code = m_currentEventKey.iCode; + // if fep editor was invoked then it consume TKeyEvent and as + // result we have KeyEvent.iCode == 0. So we assume here that + // if element is editable and no iCode in KeyEvent then fep editor + // already put the right character into the input area and we can get + // the correct iCode from the last entered char. + if (m_isEditable && !m_currentEventKey.iCode && m_webfeptexteditor) { + TInt len = m_webfeptexteditor->DocumentLengthForFep(); + if (len > 0) { + TBuf<2> data; + m_webfeptexteditor->GetEditorContentForFep(data, len - 1, 1); + if (data.Length() > 0) { + code = data[0]; + } + } + } + + return code; +} + +bool WebView::sendKeyEventToEngine(const TKeyEvent& keyevent, TEventCode eventcode, Frame* frame) { + bool tabbedNavigation = (m_brctl->settings()->getNavigationType() == SettingsContainer::NavigationTypeTabbed); + Node* targetNode = frame->document()->focusedNode(); + bool hasOnKeyDown = false; + bool hasOnKeyUp = false; + bool hasOnKeyPress = false; + + for (Node* n = targetNode; n; n = n->parentNode()) { + EventTargetNode* tnode = static_cast(n); + hasOnKeyDown = tnode->getHTMLEventListener(keydownEvent); + hasOnKeyUp = tnode->getHTMLEventListener(keyupEvent); + hasOnKeyPress = tnode->getHTMLEventListener(keypressEvent); + if (hasOnKeyDown || hasOnKeyUp || hasOnKeyPress) { + break; + } + } + + + if (!m_isEditable && !(hasOnKeyDown || hasOnKeyUp || hasOnKeyPress)) { + frame->document()->setFocusedNode(NULL); + } bool consumed = frame->eventHandler()->keyEvent(PlatformKeyboardEvent(keyevent,eventcode)); - if (!consumed && eventcode == EEventKey && + frame->document()->setFocusedNode(targetNode); + + if (!consumed && eventcode == EEventKey && (m_brctl->capabilities() & TBrCtlDefs::ECapabilityAccessKeys)) { TKeyEvent ke = keyevent; TChar c(ke.iCode); @@ -1195,27 +1331,19 @@ if (!coreFrame) return EKeyWasNotConsumed; coreFrame = page()->focusController()->focusedOrMainFrame(); - - // edit events - if (m_isEditable) { - consumed = handleEditable(keyevent, eventcode, coreFrame); + + switch( eventcode ) { + case EEventKeyDown: + handleEventKeyDown(keyevent, eventcode, coreFrame); + break; + case EEventKey: + consumed = handleEventKeyL(keyevent, eventcode, coreFrame); + break; + case EEventKeyUp: + consumed = handleEventKeyUp(keyevent, eventcode, coreFrame); + break; } - - // scroll events - if (!consumed) { - switch( eventcode ) { - case EEventKeyDown: - handleEventKeyDown(keyevent, eventcode, coreFrame); - break; - case EEventKey: - if (keyevent.iScanCode != m_currentEventKey.iScanCode ) return EKeyWasNotConsumed; - consumed = handleEventKeyL(keyevent, eventcode, coreFrame); - break; - case EEventKeyUp: - consumed = handleEventKeyUp(keyevent, eventcode, coreFrame); - break; - } - } + return (consumed) ? EKeyWasConsumed : EKeyWasNotConsumed; } @@ -1235,12 +1363,7 @@ scrollDelta.iX *= 100; scrollDelta.iY *= 100; if (!inPageViewMode()) { - if (scrollDelta.iX == 0 && scrollDelta.iY == 0) { - m_pageScrollHandler->scrollbarDrawer()->drawScrollbar(this); - } - else { - m_pageScrollHandler->scrollbarDrawer()->drawScrollbar(this, scrollDelta); - } + m_pageScrollHandler->scrollbarDrawer()->drawScrollbar(this, scrollDelta); } } @@ -1254,6 +1377,7 @@ m_pageView = CPageView::NewL(*this); MakeVisible(EFalse); m_savedPosition = mainFrame()->frameView()->contentPos(); + m_pageViewStartPosition = m_savedPosition; m_brctl->reportStateChanged(TBrCtlDefs::EStateThumbnailView, ETrue); } } @@ -1276,7 +1400,7 @@ if ( m_brctl->capabilities() & TBrCtlDefs::ECapabilityWebKitLite ) return; if (m_pageView) { - mainFrame()->frameView()->scrollTo(m_savedPosition); + mainFrame()->frameView()->scrollTo(m_pageViewStartPosition); closePageView(); } } @@ -1545,6 +1669,8 @@ r.Grow(1, 1); m_repaints.AddRect(r); } + + region.Close(); } else { TRect r(to, bufSize); diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webview/WebView.h --- a/webengine/osswebengine/WebKit/s60/webview/WebView.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/webview/WebView.h Thu Aug 27 07:44:59 2009 +0300 @@ -22,7 +22,7 @@ // INCLUDES #include #include -#include "platform\Shared.h" +#include "platform/Shared.h" #include "BrCtlDefs.h" #include "PageScaler.h" #include "Timer.h" @@ -459,6 +459,11 @@ bool handleEventKeyUp(const TKeyEvent& keyevent, TEventCode eventcode, WebCore::Frame* frame); bool handleEditable(const TKeyEvent& keyevent, TEventCode eventcode, WebCore::Frame* frame ); bool isNaviKey(const TKeyEvent& keyevent); + bool needDeactivateEditable(const TKeyEvent& keyevent, TEventCode eventcode); + bool deactivateEditable(); + TUint correctKeyCode(); + bool handleNaviKeyEvent(const TKeyEvent& keyevent, TEventCode eventcode, WebCore::Frame* frame); + public: void sendMouseEventToEngine(TPointerEvent::TType eventType, TPoint pos, WebCore::Frame* frame); void fepTimerFired(WebCore::Timer*); @@ -504,6 +509,7 @@ bool m_inFindState; CPageView* m_pageView; TPoint m_savedPosition; // contentPosition + TPoint m_pageViewStartPosition; TPoint m_savedCursorPosition; HBufC* m_findKeyword; WebTabbedNavigation* m_tabbedNavigation; @@ -551,6 +557,7 @@ //Indicates any plugin is activated/deactivated bool m_showCursor; bool m_allowRepaints; + bool m_prevEditMode; }; #endif diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webview/WidgetExtension.cpp --- a/webengine/osswebengine/WebKit/s60/webview/WidgetExtension.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/webview/WidgetExtension.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -33,6 +33,8 @@ #include "BrCtl.h" #include "WebCursor.h" #include "SettingsContainer.h" +#include "Document.h" +#include "EventNames.h" // LOCAL FUNCTION PROTOTYPES @@ -63,6 +65,8 @@ m_webview(&aWebKitView), m_isWidgetPublishing ( false) { + m_topLevelLoadedpage = 0; + m_widgetNetState = ENetworkNotAllowed; } @@ -78,22 +82,38 @@ { if (!m_widgetengine) { - m_widgetengine = WebCore::StaticObjectsContainer::instance()->getWidgetEngineBridgeL(); + RLibrary& widgetLib = WebCore::StaticObjectsContainer::instance()->getWidgetEngineBridgeLibL(); + TLibraryFunction entry = widgetLib.Lookup(1); + if (entry) { + m_widgetengine = (MWidgetEngineBridge*) entry(); + } if(!m_widgetengine) { User::Leave(KErrNotFound); } m_widgetcallback = &aWidgetCallback; + if (m_widgetengine) { + AddJSExtension(_L("widget"),m_widgetengine->Widget(*m_widgetcallback, *this)); + AddJSExtension(_L("menu"),m_widgetengine->Menu(*m_widgetcallback, *this)); + AddJSExtension(_L("MenuItem"),m_widgetengine->MenuItem(*m_widgetcallback, *this)); + } #if defined(BRDO_LIW_FF) // device for SAPI - - m_deviceBridge = WebCore::StaticObjectsContainer::instance()->getDeviceBridgeL(); + RLibrary& deviceLib = WebCore::StaticObjectsContainer::instance()->getDeviceBridgeLibL(); + TLibraryFunction device_entry = deviceLib.Lookup(1); + if (device_entry) { + m_deviceBridge = (MDeviceBridge*) device_entry(); + } if (!m_deviceBridge) { User::Leave(KErrNotFound); } + if (m_deviceBridge) { + AddJSExtension(_L("device"), m_deviceBridge->Device(0)); + } + m_securitySession = m_deviceBridge->GetSecuritySession(); #endif if (m_webview && m_webview->page()) { @@ -153,6 +173,13 @@ void CWidgetExtension::SetParamL(TBrCtlDefs::TBrCtlWidgetParams aParam, TUint aValue) { + if ( aParam == TBrCtlDefs::EWidgetNetworkState ) + { + m_widgetNetState = (TNetworkState)aValue; + DispatchNetworkStateChangeEvent(); + return; + } + if ( aParam == TBrCtlDefs::EWidgetPublishState) { m_isWidgetPublishing = aValue; return ; @@ -228,12 +255,14 @@ void CWidgetExtension::windowObjectCleared() { - if (m_widgetengine) { - m_widgetengine->Clear(); - AddJSExtension(_L("widget"),m_widgetengine->Widget(*m_widgetcallback, *this)); - AddJSExtension(_L("menu"),m_widgetengine->Menu(*m_widgetcallback, *this)); - AddJSExtension(_L("MenuItem"),m_widgetengine->MenuItem(*m_widgetcallback, *this)); - } + m_topLevelLoadedpage++; + if (m_topLevelLoadedpage > 1) { + if (m_widgetengine) { + m_widgetengine->Clear(); + AddJSExtension(_L("widget"),m_widgetengine->Widget(*m_widgetcallback, *this)); + AddJSExtension(_L("menu"),m_widgetengine->Menu(*m_widgetcallback, *this)); + AddJSExtension(_L("MenuItem"),m_widgetengine->MenuItem(*m_widgetcallback, *this)); + } #if defined(BRDO_LIW_FF) if (m_deviceBridge) { @@ -243,6 +272,36 @@ } #endif } +} + +TInt CWidgetExtension::widgetNetworkConstants(TInt aId) + { + switch (aId) + { + case 0: + return ENetworkNotAllowed; + case 1: + return ENetworkAccessAllowed; + case 2: + return ENetworkAccessible; + default: + return 0; + } + } + +void CWidgetExtension::DispatchNetworkStateChangeEvent() +{ + if ( m_widgetNetState == ENetworkNotAllowed) + { + // fire offline event + m_webview->page()->mainFrame()->document()->handleNetworkEvent(WebCore::EventNames::onofflineEvent, -1); + } + else + { + // fire online event + m_webview->page()->mainFrame()->document()->handleNetworkEvent(WebCore::EventNames::ononlineEvent, (TInt)m_widgetNetState); + } +} //END OF FILE diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/WebKit/s60/webview/WidgetExtension.h --- a/webengine/osswebengine/WebKit/s60/webview/WidgetExtension.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/WebKit/s60/webview/WidgetExtension.h Thu Aug 27 07:44:59 2009 +0300 @@ -27,6 +27,13 @@ #include #include "WidgetEngineCallbacks.h" +enum TNetworkState + { + ENetworkNotAllowed = 0, + ENetworkAccessAllowed, + ENetworkAccessible + }; + // FUNCTION PROTOTYPES // FORWARD DECLARATION @@ -58,6 +65,8 @@ void SetParamL(TBrCtlDefs::TBrCtlWidgetParams aParam, TUint aValue); TBool HandleCommandL( TInt aCommandId ); TInt GetWidgetId(){ return iWidgetId;} + TInt widgetNetworkConstants( TInt aId ); + TInt widgetNetworkState() { return (TInt)m_widgetNetState; } public: void drawWidgetTransition(); @@ -68,11 +77,16 @@ bool IsWidgetPublising(){ return m_isWidgetPublishing;} void setNavigationType(const TDesC& aType); void windowObjectCleared(); +#if defined(BRDO_LIW_FF) + void* getSecuritySession(){ return m_securitySession; } +#endif + private: void AddJSExtension(const TDesC& id, void* obj); CWidgetExtension(WebView& aWebKitView); void ConstructL(MWidgetCallback& aWidgetCallback); + void DispatchNetworkStateChangeEvent(); WebView* m_webview; @@ -80,9 +94,12 @@ MWidgetCallback* m_widgetcallback; TInt iWidgetId; bool m_isWidgetPublishing; + int m_topLevelLoadedpage; + TNetworkState m_widgetNetState; #if defined(BRDO_LIW_FF) MDeviceBridge* m_deviceBridge; + void* m_securitySession; #endif }; diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/cache_check.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/osswebengine/cache/cache_check.pl Thu Aug 27 07:44:59 2009 +0300 @@ -0,0 +1,181 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of the License "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# +#!/usr/bin/perl + +#use Encode; + +# open index file +open INH,'<','\epoc32\winscw\c\system\cache\index.dat' or die "couldn't open index.dat"; +binmode INH; + +my @missing_files; +my @missing_urls; + +my @cache_uris; +my @cache_files; + +my @dir_items = GetDirContents(); +my @cache_content = ParseCacheIndex(); +my @extra_files; +GetExtraFiles(); + +$count = 0; +print "\n\nMissing Items:\n"; +foreach (@missing_files) { + print "$_ - $missing_urls[$count++]\n"; +} + +print "\n\nExtra Files:\n"; +foreach (@extra_files) { + print "$_\n"; +} + + + + +sub GetDirContents +{ + my @subdirectories = ( "0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f" ); + my @diritems = (); + $index=0; + foreach (@subdirectories) + { + opendir DIRHANDLE,"\\epoc32\\winscw\\c\\system\\cache\\@subdirectories[$index++]" or die "couldn't open cache directory"; + my @tmp = readdir DIRHANDLE; + push @diritems, @tmp; + } + + return @diritems; +} + +sub ParseCacheIndex +{ + $filenames; + $numEntries = GetNumEntries(); + + print "Index contains $numEntries items\n"; + + while($numEntries) + { + @urifilenamearray = GetNextFilename(); + print "@urifilenamearray[1] - @urifilenamearray[0]\n"; + push @filenames, @urifilenamearray[0]; + push @filenames, @urifilenamearray[1]; + $numEntries--; + CheckFilePresent(@urifilenamearray[1], @urifilenamearray[0]); + push @cache_files, @urifilenamearray[1]; + push @cache_urls, @urifilenamearray[0]; + } + + return @filenames; +} + +sub GetNumEntries +{ + read (INH, $buffer, 4); #throw away version number + read (INH, $buffer, 4); # read num of 16-bit chars in dir stub + $charcount = unpack("l",$buffer); + read (INH, $buffer, $charcount*2); #throw away dir stub + read (INH, $buffer, 4); # read entry count + $value = unpack("l",$buffer); + return $value; +} + +sub GetNextFilename +{ + my @return = (); + + read (INH, $buffer, 4); + # get URI + $stringlen = unpack("l",$buffer); + read (INH, $buffer, $stringlen); + + @return[0] = $buffer; +# print "$stringlen chars in URI:\n$buffer\n"; + + # get unicode filename +# read (INH, $buffer, 4); +# $stringlen = unpack("l", $buffer); + + $stringlen = 8; + my @filename_array = (); + if($stringlen) + { + # convert $buffer from unicode to ascii + while($stringlen) { + read (INH, $buffer, 2); + $string = unpack("a",$buffer); + #print "$string"; + push @filename_array, $string; + $stringlen--; + } + } + @return[1] = join '',@filename_array; + #print "\n\n"; + # gobble rest of item up to header data + read (INH, $buffer, 24); + + read (INH, $buffer, 4); + $stringlen = unpack("l",$buffer); + read (INH, $buffer, $stringlen); # throw away header data. + + return @return; +} + +sub CheckFilePresent() +{ + my $filename = $_[0]; + my $url = $_[1]; + + my $fqname = "\\epoc32\\winscw\\c\\system\\cache\\". (substr $filename, -1, 1) . "\\" . $filename; + + my $FILE; + open FILE, $fqname or MissingItem($filename, $url); +} + +sub MissingItem() +{ + push @missing_files, $_[0]; + push @missing_urls, $_[1]; +} + +sub GetExtraFiles() +{ + # dir_items contains list of all filenames in all directories. + my $dirnum = -1; + my @dirnames = ( "0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f" ); + + foreach $item (@dir_items) + { + my $match = 0; + if($item eq '.') + { + $dirnum++; + } + elsif($item ne '..') # filter out directories + { + foreach (@cache_files) + { + $match = 1 if($_ eq $item); + } + if($match == 0) + { + my $fqname = "\\epoc32\\winscw\\c\\system\\cache\\".@dirnames[$dirnum]."\\".$item; + push @extra_files, $fqname; + } + } + } +} \ No newline at end of file diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/conf/httpcachemanager.confml Binary file webengine/osswebengine/cache/conf/httpcachemanager.confml has changed diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/conf/httpcachemanager_101F8557.crml Binary file webengine/osswebengine/cache/conf/httpcachemanager_101F8557.crml has changed diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/filter_emulator_output.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/osswebengine/cache/filter_emulator_output.bat Thu Aug 27 07:44:59 2009 +0300 @@ -0,0 +1,18 @@ +@rem +@rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +@rem All rights reserved. +@rem This component and the accompanying materials are made available +@rem under the terms of the License "Eclipse Public License v1.0" +@rem which accompanies this distribution, and is available +@rem at the URL "http://www.eclipse.org/legal/epl-v10.html". +@rem +@rem Initial Contributors: +@rem Nokia Corporation - initial contribution. +@rem +@rem Contributors: +@rem +@rem Description: +@rem + +filter_log.pl %tmp%\epocwind.out log.txt" +log.txt diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/filter_log.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/osswebengine/cache/filter_log.pl Thu Aug 27 07:44:59 2009 +0300 @@ -0,0 +1,27 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of the License "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# +#!/usr/bin/perl + +open INH,"<",$ARGV[0]; +open OUTH,">",$ARGV[1]; + +foreach $line (){ + if($line =~ m/CACHEPOSTPONE:/) + { + print OUTH $line; + } +} + diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/group/BrowserCache.mmp --- a/webengine/osswebengine/cache/group/BrowserCache.mmp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/cache/group/BrowserCache.mmp Thu Aug 27 07:44:59 2009 +0300 @@ -47,6 +47,8 @@ SOURCE HttpCacheLookupTable.cpp SOURCE HttpCacheStreamHandler.cpp SOURCE HttpCacheUtil.cpp +SOURCE HttpCacheFileWriteHandler.cpp +SOURCE HttpCachePostponeWriteUtilities.cpp USERINCLUDE ../inc @@ -55,24 +57,26 @@ #ifndef __BROWSER_SDK MW_LAYER_SYSTEMINCLUDE -MW_LAYER_HTTP_SYSTEMINCLUDE -MW_LAYER_LIBC_SYSTEMINCLUDE #else -SYSTEMINCLUDE /epoc32/include /epoc32/include/oem -SYSTEMINCLUDE /epoc32/include/http /epoc32/include/libc +SYSTEMINCLUDE /epoc32/include /epoc32/include/oem #endif +SYSTEMINCLUDE /Epoc32/include/http +SYSTEMINCLUDE /Epoc32/include/libc + -LIBRARY ESTLIB.lib -LIBRARY http.lib -LIBRARY EFSRV.lib -LIBRARY bafl.lib -LIBRARY InetProtUtil.lib +LIBRARY ESTLIB.lib +LIBRARY http.lib +LIBRARY EFSRV.lib +LIBRARY bafl.lib +LIBRARY InetProtUtil.lib LIBRARY HttpFilterCommon.lib -LIBRARY euser.lib -LIBRARY estor.lib -LIBRARY centralrepository.lib -LIBRARY CenRepNotifHandler.lib -LIBRARY featmgr.lib -LIBRARY cone.lib // CoeControl +LIBRARY euser.lib +LIBRARY estor.lib +LIBRARY centralrepository.lib +LIBRARY CenRepNotifHandler.lib +LIBRARY featmgr.lib +LIBRARY hal.lib +LIBRARY memman.lib +LIBRARY cone.lib // CoeControl DEBUGLIBRARY flogger.lib diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/group/Bwinscw/BrowserCacheu.def --- a/webengine/osswebengine/cache/group/Bwinscw/BrowserCacheu.def Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/cache/group/Bwinscw/BrowserCacheu.def Thu Aug 27 07:44:59 2009 +0300 @@ -1,15 +1,15 @@ EXPORTS - ?AddHeaderL@CHttpCacheManager@@QAEHABVTDesC8@@00@Z @ 1 NONAME ; int CHttpCacheManager::AddHeaderL(class TDesC8 const &, class TDesC8 const &, class TDesC8 const &) - ?Find@CHttpCacheManager@@QAEHABVTDesC8@@@Z @ 2 NONAME ; int CHttpCacheManager::Find(class TDesC8 const &) - ?NewL@CHttpCacheManager@@SAPAV1@XZ @ 3 NONAME ; class CHttpCacheManager * CHttpCacheManager::NewL(void) - ?ReceivedResponseBodyDataL@CHttpCacheManager@@QAEXAAVRHTTPTransaction@@AAVMHTTPDataSupplier@@AAVTHttpCacheEntry@@@Z @ 4 NONAME ; void CHttpCacheManager::ReceivedResponseBodyDataL(class RHTTPTransaction &, class MHTTPDataSupplier &, class THttpCacheEntry &) - ?ReceivedResponseHeadersL@CHttpCacheManager@@QAEXAAVRHTTPTransaction@@AAVTHttpCacheEntry@@@Z @ 5 NONAME ; void CHttpCacheManager::ReceivedResponseHeadersL(class RHTTPTransaction &, class THttpCacheEntry &) - ?RemoveAllL@CHttpCacheManager@@QAEHXZ @ 6 NONAME ; int CHttpCacheManager::RemoveAllL(void) - ?RemoveL@CHttpCacheManager@@QAEHABVTDesC8@@@Z @ 7 NONAME ; int CHttpCacheManager::RemoveL(class TDesC8 const &) - ?RequestClosed@CHttpCacheManager@@QAEXPAVRHTTPTransaction@@AAVTHttpCacheEntry@@@Z @ 8 NONAME ; void CHttpCacheManager::RequestClosed(class RHTTPTransaction *, class THttpCacheEntry &) - ?RequestHeadersL@CHttpCacheManager@@QAEHAAVRHTTPTransaction@@AAVTHttpCacheEntry@@@Z @ 9 NONAME ; int CHttpCacheManager::RequestHeadersL(class RHTTPTransaction &, class THttpCacheEntry &) - ?RequestL@CHttpCacheManager@@QAEHAAVRHTTPTransaction@@W4TBrCtlCacheMode@TBrCtlDefs@@AAVTHttpCacheEntry@@@Z @ 10 NONAME ; int CHttpCacheManager::RequestL(class RHTTPTransaction &, enum TBrCtlDefs::TBrCtlCacheMode, class THttpCacheEntry &) - ?RequestNextChunkL@CHttpCacheManager@@QAEPAVHBufC8@@AAVRHTTPTransaction@@AAHAAVTHttpCacheEntry@@@Z @ 11 NONAME ; class HBufC8 * CHttpCacheManager::RequestNextChunkL(class RHTTPTransaction &, int &, class THttpCacheEntry &) - ?ResponseComplete@CHttpCacheManager@@QAEXAAVRHTTPTransaction@@AAVTHttpCacheEntry@@@Z @ 12 NONAME ; void CHttpCacheManager::ResponseComplete(class RHTTPTransaction &, class THttpCacheEntry &) - ?SaveL@CHttpCacheManager@@QAEHABVTDesC8@@000@Z @ 13 NONAME ; int CHttpCacheManager::SaveL(class TDesC8 const &, class TDesC8 const &, class TDesC8 const &, class TDesC8 const &) + ?AddHeaderL@CHttpCacheManager@@QAEHABVTDesC8@@00@Z @ 1 NONAME ; int CHttpCacheManager::AddHeaderL(class TDesC8 const &, class TDesC8 const &, class TDesC8 const &) + ?Find@CHttpCacheManager@@QAEHABVTDesC8@@@Z @ 2 NONAME ; int CHttpCacheManager::Find(class TDesC8 const &) + ?NewL@CHttpCacheManager@@SAPAV1@XZ @ 3 NONAME ; class CHttpCacheManager * CHttpCacheManager::NewL(void) + ?ReceivedResponseBodyDataL@CHttpCacheManager@@QAEXAAVRHTTPTransaction@@AAVMHTTPDataSupplier@@AAVTHttpCacheEntry@@@Z @ 4 NONAME ; void CHttpCacheManager::ReceivedResponseBodyDataL(class RHTTPTransaction &, class MHTTPDataSupplier &, class THttpCacheEntry &) + ?ReceivedResponseHeadersL@CHttpCacheManager@@QAEXAAVRHTTPTransaction@@AAVTHttpCacheEntry@@@Z @ 5 NONAME ; void CHttpCacheManager::ReceivedResponseHeadersL(class RHTTPTransaction &, class THttpCacheEntry &) + ?RemoveAllL@CHttpCacheManager@@QAEHXZ @ 6 NONAME ; int CHttpCacheManager::RemoveAllL(void) + ?RemoveL@CHttpCacheManager@@QAEHABVTDesC8@@@Z @ 7 NONAME ; int CHttpCacheManager::RemoveL(class TDesC8 const &) + ?RequestClosed@CHttpCacheManager@@QAEXPAVRHTTPTransaction@@AAVTHttpCacheEntry@@@Z @ 8 NONAME ; void CHttpCacheManager::RequestClosed(class RHTTPTransaction *, class THttpCacheEntry &) + ?RequestHeadersL@CHttpCacheManager@@QAEHAAVRHTTPTransaction@@AAVTHttpCacheEntry@@@Z @ 9 NONAME ; int CHttpCacheManager::RequestHeadersL(class RHTTPTransaction &, class THttpCacheEntry &) + ?RequestL@CHttpCacheManager@@QAEHAAVRHTTPTransaction@@W4TBrCtlCacheMode@TBrCtlDefs@@AAVTHttpCacheEntry@@@Z @ 10 NONAME ; int CHttpCacheManager::RequestL(class RHTTPTransaction &, enum TBrCtlDefs::TBrCtlCacheMode, class THttpCacheEntry &) + ?RequestNextChunkL@CHttpCacheManager@@QAEPAVHBufC8@@AAVRHTTPTransaction@@AAHAAVTHttpCacheEntry@@@Z @ 11 NONAME ; class HBufC8 * CHttpCacheManager::RequestNextChunkL(class RHTTPTransaction &, int &, class THttpCacheEntry &) + ?ResponseComplete@CHttpCacheManager@@QAEXAAVRHTTPTransaction@@AAVTHttpCacheEntry@@@Z @ 12 NONAME ; void CHttpCacheManager::ResponseComplete(class RHTTPTransaction &, class THttpCacheEntry &) + ?SaveL@CHttpCacheManager@@QAEHABVTDesC8@@000@Z @ 13 NONAME ; int CHttpCacheManager::SaveL(class TDesC8 const &, class TDesC8 const &, class TDesC8 const &, class TDesC8 const &) diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/group/bld.inf --- a/webengine/osswebengine/cache/group/bld.inf Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/cache/group/bld.inf Thu Aug 27 07:44:59 2009 +0300 @@ -11,18 +11,18 @@ * * Contributors: * -* Description: +* Description: * */ #include #include "../../../../web_plat/browser_platform_api/inc/Browser_platform_variant.hrh" PRJ_PLATFORMS -DEFAULT +DEFAULT PRJ_EXPORTS -../conf/httpcachemanager.confml MW_LAYER_CONFML(httpcachemanager.confml) +../conf/httpcachemanager.confml MW_LAYER_CONFML(httpcachemanager.confml) ../conf/httpcachemanager_101F8557.crml MW_LAYER_CRML(httpcachemanager_101F8557.crml) PRJ_MMPFILES diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/inc/HttpCacheEntry.h --- a/webengine/osswebengine/cache/inc/HttpCacheEntry.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/cache/inc/HttpCacheEntry.h Thu Aug 27 07:44:59 2009 +0300 @@ -21,10 +21,9 @@ // INCLUDES #include #include +#include "HttpCachePostponeWriteUtilities.h" // CONSTANTS -const TInt KBufferSize32k = 32768; -const TInt KBufferSizeZero = 0; // MACROS @@ -43,14 +42,14 @@ // CLASS DECLARATION /** -* -* @lib +* +* @lib * @since 3.1 */ -class CHttpCacheEntry : public CBase +class CHttpCacheEntry : public CBase, public MHttpCacheWriteSource { - public: // Constructors and destructor - + public: // Constructors and destructor + enum TCacheEntryState { ECacheUninitialized, @@ -64,245 +63,245 @@ /** * Two-phased constructor. * @since 3.1 - * @param - * @param + * @param + * @param * @return CHttpCacheEntry object. */ - static CHttpCacheEntry* NewL( const TDesC8& aUrl, + static CHttpCacheEntry* NewL( const TDesC8& aUrl, CHttpCacheEvictionHandler& aEvictionHandler ); /** * Two-phased constructor. * @since 3.1 - * @param - * @param + * @param + * @param * @return CHttpCacheEntry object. */ - static CHttpCacheEntry* NewLC( const TDesC8& aUrl, + static CHttpCacheEntry* NewLC( const TDesC8& aUrl, CHttpCacheEvictionHandler& aEvictionHandler ); - + /** * Destructor. */ virtual ~CHttpCacheEntry(); - + public: // new functions - - /** - * - * @since 3.1 - * @param - * @return - */ - void SetState( TCacheEntryState aState ); /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return + */ + void SetState( TCacheEntryState aState ); + + /** + * + * @since 3.1 + * @param + * @return */ inline TCacheEntryState State() { return iState; } /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ void SetFileNameL( const TFileName& aFileName ); /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ const TDesC& Filename() const { return *iFileName; } - + /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ inline const TDesC8& Url() const { return *iUrl; } - + /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ inline TInt64 LastAccessed() const { return iLastAccessed; } /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ void Accessed(); - + /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ inline TUint16 Ref() const { return iRef; } /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ inline TUint BodySize() const { return iBodySize; } /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ void SetBodySize( TUint aSize ); /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ inline TUint16 HeaderSize() const { return iHeaderSize; } /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ inline void SetHeaderSize( TUint16 aHeaderSize ) { iHeaderSize = aHeaderSize; } /** - * + * * @since 7.1 - * @param - * @return + * @param + * @return */ - inline RFile& HeaderFile() { return iHeaderFile; } - - /** - * - * @since 7.1 - * @param - * @return - */ - inline RFile& BodyFile() { return iBodyFile; } + void CreateHeaderBufferL( TInt aHeaderBufferSize ); /** - * + * * @since 7.1 - * @param - * @return + * @param + * @return */ - TPtr8 CacheBuffer(); - - /** - * - * @since 7.1 - * @param - * @return - */ - void SetCacheBufferL( TInt aCacheBufferSize ); + void CreateHeaderBufferL( const TDesC8& aHeaderData ); /** - * + * + * @since 7.1 + * @param + * @return + */ + TDesC8& HeaderData(); + + /** + * * @since 3.1 - * @param - * @return + * @param + * @return */ inline TBool Protected() const { return iProtected; } /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ void SetProtected(); /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ - TInt Internalize( RFileReadStream& aReadStream ); + TInt Internalize( RReadStream& aReadStream, const TDesC& aDirectory ); + + /** + * + * @since 7.1 + * @param + * @return + */ + void InternalizeL( RReadStream& aReadStream, const TDesC& aDirectory ); /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ - TInt Externalize( RFileWriteStream& aWriteStream ); + TInt Externalize( RWriteStream& aWriteStream, const TDesC& aDirectory ); /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return + */ + void ExternalizeL( RWriteStream& aWriteStream, const TDesC& aDirectory ); + + /** + * + * @since 3.1 + * @param + * @return */ void Accessed(TInt64 aLastAccessed, TUint16 aRef); /** - * + * * @since 7.1 - * @param - * @return + * @param + * @return */ inline TBool BodyFileDeleteNeeded() { return iBodyFileDeleteNeeded; } /** - * + * * @since 7.1 - * @param - * @return + * @param + * @return */ inline void SetBodyFileDeleteNeeded( TBool aBodyFileDeleteNeeded ) { iBodyFileDeleteNeeded = aBodyFileDeleteNeeded; } - /** - * - * @since 7.1 - * @param - * @return - */ - TBool CacheFilesOpened() { return iCacheFilesOpened; } + * + * @since 7.1 + * @param + * @return + * + */ + void UnsetEvictionCandidate() { iEvictionCandidate = EFalse; }; // this only exists because when EvictL removes an item from the eviction candidate list, it can't tell the entry that this has happened and so the entry then goes on to attempt to remove itself later when it's being deleted. - /** - * - * @since 7.1 - * @param - * @return - */ - void SetCacheFilesOpened( TBool aCacheFilesOpened ); - - public : + public : // support linked list static const TInt iOffset; private: - + /** * Construct. * @since 3.1 - * @param - * @param + * @param + * @param * @return CHttpCacheEntry object. */ CHttpCacheEntry( CHttpCacheEvictionHandler& aEvictionHandler ); @@ -310,7 +309,48 @@ /** * By default Symbian 2nd phase constructor is private. */ - void ConstructL( const TDesC8& aUrl ); + void ConstructL( const TDesC8& aUrl ); + + /** + * + * @since 7.1 + * @param + * @return + */ + void SetCacheBufferL( TInt aCacheBufferSize ); + + public: + // from MHttpCacheStreamWriteSource + virtual RFile& BodyFile(); + virtual void BodyWriteInProgress(); + virtual void BodyWriteComplete(); + virtual CSegmentedHeapBuffer& BodyData(); + + enum TWriteStateBits + { + EFileOk = 0x01, + EHeaderDataCached = 0x02, + ENewHeaderData = 0x04, + EBodyDataCached = 0x08, + EDelayedWriteAllowed = 0x10, + EDelayedWriteInProgress = 0x20, + EBodyDataPartiallyWritten = 0x40 + }; + + inline TBool FileOk() const { return (iWriteState & EFileOk); } + inline TBool BodyDataCached() const { return (iWriteState & EBodyDataCached); } + inline TBool DelayedWriteAllowed() const { return (iWriteState & EDelayedWriteAllowed); } + inline TBool DelayedWriteInProgress() const { return (iWriteState & EDelayedWriteInProgress); } + inline TBool BodyDataPartiallyWritten() const { return (iWriteState & EBodyDataPartiallyWritten); } + + inline void SetFileOk(TBool aBit) { (aBit ? iWriteState |= EFileOk : iWriteState &= ~EFileOk); } + void SetBodyDataCached(TBool aBit) { (aBit ? iWriteState |= EBodyDataCached : iWriteState &= ~EBodyDataCached); if(!aBit){ iCacheBuffer->Reset(); } } + void SetDelayedWriteAllowed(TBool aBit) { (aBit ? iWriteState |= EDelayedWriteAllowed : iWriteState &= ~EDelayedWriteAllowed); } + void SetDelayedWriteInProgress(TBool aBit) { (aBit ? iWriteState |= EDelayedWriteInProgress : iWriteState &= ~EDelayedWriteInProgress); } + void SetBodyDataPartiallyWritten(TBool aBit){ (aBit ? iWriteState |= EBodyDataPartiallyWritten : iWriteState &= ~EBodyDataPartiallyWritten); } + + void WriteBodyDataAsync(TRequestStatus& aStatus); + void CancelBodyWrite(); private: // Data @@ -339,15 +379,17 @@ // TBool iBodyFileDeleteNeeded; // - RFile iHeaderFile; // owned - // RFile iBodyFile; // owned // - HBufC8* iCacheBuffer; // owned - // ETrue if files open (and attached to StreamHandler) for read/write - TBool iCacheFilesOpened; + CSegmentedHeapBuffer* iCacheBuffer; //owned + // + HBufC8* iHeaderBuffer; // owned + // TWriteStateBits + TUint32 iWriteState; + // + CHttpCacheEntryAsyncWriteHelper* iWriteHelper; //owned }; #endif // CHTTPCACHEENTRY_H - + // End of File diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/inc/HttpCacheEvictionHandler.h --- a/webengine/osswebengine/cache/inc/HttpCacheEvictionHandler.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/cache/inc/HttpCacheEvictionHandler.h Thu Aug 27 07:44:59 2009 +0300 @@ -11,7 +11,7 @@ * * Contributors: * -* Description: Definition of CHttpCacheEvictionHandler +* Description: Definition of CHttpCacheEvictionHandler * */ @@ -38,77 +38,77 @@ // CLASS DECLARATION /** -* -* @lib +* +* @lib * @since 3.1 */ class CHttpCacheEvictionHandler : public CBase { - public: // Constructors and destructor + public: // Constructors and destructor /** * Two-phased constructor. * @since 3.1 - * @param - * @param + * @param + * @param * @return CHttpCacheEvictionHandler object. */ static CHttpCacheEvictionHandler* NewL(); - + /** * Destructor. */ virtual ~CHttpCacheEvictionHandler(); - + public: // new functions - + /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ - void Insert( CHttpCacheEntry& aCacheEntry ); + void Insert( CHttpCacheEntry& aCacheEntry ); /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ - void Accessed( CHttpCacheEntry& aCacheEntry ); + void Accessed( CHttpCacheEntry& aCacheEntry ); /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ - void Remove( CHttpCacheEntry& aCacheEntry ); + void Remove( CHttpCacheEntry& aCacheEntry ); /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ void RemoveAll(); /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ CArrayPtrFlat* EvictL( TInt aSpaceNeeded ); private: - + /** * Construct. * @since 3.1 - * @param - * @param + * @param + * @param * @return CHttpCacheEvictionHandler object. */ CHttpCacheEvictionHandler(); @@ -116,57 +116,57 @@ /** * By default Symbian 2nd phase constructor is private. */ - void ConstructL(); + void ConstructL(); private: /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ TBucket* Bucket( TInt aBucketIndex ); /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ TInt BucketIndex( TInt aSizeFrequencyValue ); /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ TBool ItemIsInBucket( TInt aBucketIndex, const CHttpCacheEntry& aCacheEntry ); /** - * + * * @since 3.1 - * @param - * @return + * @param + * @return */ TInt FastLog2( TUint aNum ); /** * Used for debugging * @since 3.1 - * @param - * @return + * @param + * @return */ void LogBuckets(); private: // Data - // array of 5 buckets each bucket is a linked list of + // array of 5 buckets each bucket is a linked list of // cached items CArrayPtrFlat* iBuckets; // owned }; #endif // CHTTPCACHEEVICTIONHANDLER_H - + // End of File diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/inc/HttpCacheFileWriteHandler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/osswebengine/cache/inc/HttpCacheFileWriteHandler.h Thu Aug 27 07:44:59 2009 +0300 @@ -0,0 +1,192 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CHttpCacheFileWriteHandler +* +*/ + +#ifndef CHTTPCACHEFILEWRITEHANDLER_H +#define CHTTPCACHEFILEWRITEHANDLER_H + +// INCLUDES +#include +#include +#include "HttpCacheHandler.h" +#include "MemoryManager.h" + +// CONSTANTS + +// MACROS + +// DATA TYPES + +// FUNCTION PROTOTYPES +class CAsyncFileWriter; +class CHttpCacheWriteTimeout; + +// FORWARD DECLARATIONS + +// CLASS DECLARATION + +/** +* +* @lib +* @since 5.0 +*/ +NONSHARABLE_CLASS(CHttpCacheFileWriteHandler) : public CActive, public MMemoryCollector + { + public: // Constructors and destructor + + /** + * Two-phased constructor. + * @since 5.0 + * @param + * @param + * @return CacheFileWriteHandler object. + */ + static CHttpCacheFileWriteHandler* NewL(CHttpCacheHandler* aManager, CHttpCacheStreamHandler* aStreamHandler, RFs& aRfs, const TInt aWriteTimeout); + + /** + * Destructor. + */ + virtual ~CHttpCacheFileWriteHandler(); + + public: // From MMemoryCollector + /** + * Collect free memory, this function is called when allocation from + * System heap fails + * @since 3.1 + * @param amount of memory needs to be collected + * @return amount of memory collected + */ + virtual TUint Collect(TUint aRequired); + + /** + * restore the entity controlled memory collector when there is enough memory + * System heap fails + * @since 3.1 + * @param + * @return + */ + virtual void Restore(); + + /** + * Priority of this collector, 0 - lowest, 10 - highest; + * the lower the priority, the earlier this collector is executed. + * @since 3.1 + * @param + * @return + */ + virtual TOOMPriority Priority(); + + /** + * + * @since 7.1 + * @param + * @return + */ + TBool IsCacheEntryPostponed(const CHttpCacheEntry* aEntry); + + public: // new functions + enum TAddStatus { + EAddedOk, + EBodySmallerThanThreshold, + ENotEnoughFreeMemory, + ECheckReturn + }; + + /** + * Add a cache entry to write out when possible + * + */ + TInt AddEntry(TAddStatus& aAddStatus, CHttpCacheEntry *aEntry); + + /** + * Remove a stream entry from the list + */ + CHttpCacheEntry* RemoveEntry(CHttpCacheEntry *aEntry); + + /** + * Remove all stream entries from the list + */ + void RemoveAll(); + + /** + * Emergency method if memory is short - write everything + * to disk *now* and wait for it. Or maybe just dump it all + * and delete the headers... + */ + void DumpAllObjects(); + + /** + * Signal called by the timer callback to indicate that we + * should begin writing out the cached data. + */ + void BeginWriting(); + + private: + + /** + * Construct. + * @since 5.0 + * @param + * @param + * @return CacheFileWriteHandler object. + */ + CHttpCacheFileWriteHandler(CHttpCacheHandler* aHandler, CHttpCacheStreamHandler* aStreamHandler, RFs& aRfs); + + /** + * By default Symbian 2nd phase constructor is private. + */ + void ConstructL(const TInt aWriteTimeout); + + /** + * from CActive + */ + void DoCancel(); + + /** + * from CActive + */ + void RunL(); + + void ContinueFlushing(); + + void OutputQueueContentToDebug(); + + // sort by size function for arrays of CHttpCacheEntry objects. + static TInt CompareHttpCacheEntrySize( const CHttpCacheEntry& aFirst, const CHttpCacheEntry& aSecond ); + void CollectMemory( TUint aRequired ); + + /** + * Callback function for timer to activate writing. + */ + static TInt WriteTimeout(TAny* aParam); + + private: // Data + CHttpCacheHandler* iCacheHandler; + CHttpCacheStreamHandler* iCacheStreamHandler; + TInt iFreeRamThreshold; + TInt iImmediateWriteThreshold; + TBool iLowMemoryState; + RFs iFs; + CHttpCacheWriteTimeout* iWaitTimer; + // objects in this array are not owned. + RPointerArray iObjectQueue; + // contains a pointer to the object that flush was called for + CHttpCacheEntry* iObjectFlushing; + }; + +#endif // CHttpCacheFileWriteHandler_H + +// End of File diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/inc/HttpCacheHandler.h --- a/webengine/osswebengine/cache/inc/HttpCacheHandler.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/cache/inc/HttpCacheHandler.h Thu Aug 27 07:44:59 2009 +0300 @@ -21,7 +21,7 @@ // INCLUDES #include #include -#include +#include #include // CONSTANTS @@ -44,9 +44,106 @@ class CHttpCacheEvictionHandler; class THttpCacheEntry; class CHttpCacheObserver; +class CHttpCacheFileWriteHandler; // CLASS DECLARATION +NONSHARABLE_CLASS( THttpCachePostponeParameters ) + { + public: + THttpCachePostponeParameters(); + + TBool iEnabled; + TInt iFreeRamThreshold; + TInt iImmediateWriteThreshold; + TInt iWriteTimeout; + }; + +NONSHARABLE_CLASS( TCompressedEntry ) + { + public: + ~TCompressedEntry() { if(!IsCompressed()) delete iName.iNameAsHBuf; }; + static TCompressedEntry *NewL( const TEntry& aEntry ); + + private: + TCompressedEntry(){}; + void ConstructL( const TEntry& aEntry ); + enum { + EFilenameStoredAsUint32 = 0x01 + }; + + public: + TBool IsCompressed() { return (iFlags && TCompressedEntry::EFilenameStoredAsUint32); }; + static TBool ConvertANameToUint32( const TDesC& aName, TUint32& aConverted); + static TInt ConvertAsciiToIntSingleHexDigit(const TUint16& aDigitChar); + TUint32 GetSize() { return iSize; }; + HBufC* GetNameL(); + TUint32 GetCompressedName() { return iName.iNameAsUint32; }; + + private: + TUint32 iFlags; + TUint32 iSize; + union { + TUint32 iNameAsUint32; + HBufC* iNameAsHBuf; + }iName; + }; + +NONSHARABLE_CLASS( CCustomCacheDirList ) : public CBase + { + public: + static CCustomCacheDirList* NewL(CDir *aSrc); + ~CCustomCacheDirList() { iDirList.ResetAndDestroy(); }; + + public: + TBool ValidateCacheEntryL( const CHttpCacheEntry& aEntry ); + TInt Count(); + HBufC* NameAtL( TInt aIndex ); + + private: + CCustomCacheDirList(); + void ConstructL(CDir *aSrc); + + private: + RPointerArray iDirList; + }; + +NONSHARABLE_CLASS( CCacheDirectoryFiles ) : public CBase + { + public: + static CCacheDirectoryFiles* NewL(RFs aRfs, const TDesC& aDir); + static CCacheDirectoryFiles* NewLC(RFs aRfs, const TDesC& aDir); + + public: + /* + * Check to see if the entry passed in has a valid file in the directory listing + * returns ETrue if file present and size matches entry + * otherwise EFalse. + * Removes matching files from stored list. + */ + TBool ValidateEntryL(const CHttpCacheEntry& aEntry); + + /* + * Delete any files in the stored list from the filesystem + * Intended to be called after you have validated all the entries + * against the list - the content of the list will now only be the + * orphan files in the cache subdirectories. + * IMPORTANT: only call this once you've looked at all your entries. + */ + void RemoveLeftoverFilesL(); + + private: + CCacheDirectoryFiles(RFs aRfs, const TDesC& aDir) : iRfs(aRfs), iDir(aDir) {}; + ~CCacheDirectoryFiles(); + void ConstructL(); + + private: + RFs iRfs; + const TDesC& iDir; + + RPointerArray iDirContent; + }; + /** * * @lib @@ -63,10 +160,11 @@ * @param * @return CacheHandler object. */ - static CHttpCacheHandler* NewL( TInt aSize, + static CHttpCacheHandler* NewL( TInt aSize, const TDesC& aDirectory, const TDesC& aIndexFile, - TInt aCriticalLevel ); + TInt aCriticalLevel, + const THttpCachePostponeParameters& aPostpone); /** * Destructor. @@ -145,8 +243,8 @@ * @param * @return */ - TInt CHttpCacheHandler::ListFiles(RPointerArray& aFilenameList); - + TInt ListFiles(RPointerArray& aFilenameList); + /** * * @since 3.1 @@ -198,6 +296,15 @@ */ void UpdateLookupTable(); + /** + * + * @since 3.1 + * @param + * @param + * @return + */ + void SaveLookupTableL(); + private: /** @@ -212,7 +319,7 @@ /** * By default Symbian 2nd phase constructor is private. */ - void ConstructL( const TDesC& aDirectory, const TDesC& aIndexFile, TInt aCriticalLevel); + void ConstructL( const TDesC& aDirectory, const TDesC& aIndexFile, TInt aCriticalLevel, const THttpCachePostponeParameters& aPostpone); private: // @@ -277,15 +384,6 @@ * @param * @return */ - void SaveLookupTableL(); - - /** - * - * @since 3.1 - * @param - * @param - * @return - */ void OpenLookupTableL(); /** @@ -316,6 +414,22 @@ */ TBool SaveBuffer( CHttpCacheEntry& aEntry, const TDesC8& aBuffer, TBool aBody = EFalse ); + /** + * + * @since 7.1 + * @param + * @return + */ + void GenerateValidationFilename(TDes& aFilename, const TDesC& aIndexFilename) const; + + /** + * + * @since 7.1 + * @param + * @return + */ + void ValidateCacheEntriesL(); + private: // Data // hash table for cache entries @@ -332,8 +446,10 @@ HBufC* iIndexFile; // owned // Observing changes in cache CHttpCacheObserver* iHttpCacheObserver; // owned - // An opened and configured file server session - RFs iRfs; + // An opened and configured file server session + RFs iRfs; + // + CHttpCacheFileWriteHandler* iPostponeHandler; // owned }; #endif // CHTTPCACHEHANDLER_H diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/inc/HttpCacheLookupTable.h --- a/webengine/osswebengine/cache/inc/HttpCacheLookupTable.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/cache/inc/HttpCacheLookupTable.h Thu Aug 27 07:44:59 2009 +0300 @@ -38,7 +38,11 @@ class CHttpCacheStreamHandler; // CLASS DECLARATION - +struct THttpCacheLookupTableEntryIterator + { + TInt iPos; + TInt iCount; + }; /** * * @lib @@ -47,7 +51,7 @@ class CHttpCacheLookupTable : public CBase { public: // Constructors and destructor - + /** * Two-phased constructor. * @since 3.1 @@ -56,14 +60,14 @@ * @return CHttpCacheLookupTable object. */ static CHttpCacheLookupTable* NewL( CHttpCacheEvictionHandler& aEvictionHandler, CHttpCacheStreamHandler& aStreamHandler ); - + /** * Destructor. */ virtual ~CHttpCacheLookupTable(); - + public: // new functions - + /** * * @since 3.1 @@ -71,7 +75,7 @@ * @return */ CHttpCacheEntry* InsertL( const TDesC8& aUrl ); - + /** * * @since 3.1 @@ -79,7 +83,7 @@ * @return */ CHttpCacheEntry* Find( const TDesC8& aUrl ); - + /** * * @since 3.1 @@ -87,15 +91,7 @@ * @return */ TInt Remove( const TDesC8& aUrl ); - - /** - * - * @since 3.1 - * @param - * @return - */ - TInt RemoveByPosition( TInt aPos ); - + /** * * @since 3.1 @@ -103,7 +99,7 @@ * @return */ TInt RemoveAll(); - + /** * * @since 7.1 @@ -111,7 +107,7 @@ * @return */ TInt CHttpCacheLookupTable::ListFiles( RPointerArray& aFilenameList ); - + /** * * @since 3.1 @@ -119,7 +115,7 @@ * @return */ const CArrayPtrFlat& Entries() const { return *iEntries; } - + /** * * @since 3.1 @@ -127,23 +123,23 @@ * @return */ void EraseCacheEntry( const TDesC8& aUrl ); - + /** * * @since 3.1 * @param * @return */ - void InternalizeL( RFileReadStream& aReadStream, const TDesC& aDirectory ); - + void InternalizeL( RReadStream& aReadStream, const TDesC& aDirectory ); + /** * * @since 3.1 * @param * @return */ - void ExternalizeL( RFileWriteStream& aWriteStream ); - + void ExternalizeL( RWriteStream& aWriteStream, const TDesC& aDirectory ); + /** * * @since 3.1 @@ -151,17 +147,25 @@ * @return */ void MergeL( CHttpCacheLookupTable* aHttpCacheLookupTable, RFs aRfs ); - + /** - * - * @since 7.1 - * @param - * @return - */ - void FindCacheEntryIndex( const CHttpCacheEntry& aCacheEntry, TInt* aIndex ); + * + * @since 7.1 + * @param + * @return + */ + void BeginEntryIteration(THttpCacheLookupTableEntryIterator& aIter); + + /** + * + * @since 7.1 + * @param + * @return + */ + const CHttpCacheEntry* NextEntry(THttpCacheLookupTableEntryIterator& aIter); private: - + /** * Construct. * @since 3.1 @@ -170,14 +174,14 @@ * @return CHttpCacheLookupTable object. */ CHttpCacheLookupTable( CHttpCacheEvictionHandler& aEvictionHandler, CHttpCacheStreamHandler& aStreamHandler ); - + /** * By default Symbian 2nd phase constructor is private. */ void ConstructL(); - + private: // - + /** * * @since 3.1 @@ -185,7 +189,7 @@ * @return */ TInt InsertL( CHttpCacheEntry* aCacheEntry ); - + /** * * @since 3.1 @@ -193,7 +197,7 @@ * @return */ TInt Probe( const TDesC8& aKey, TBool aInsert ); - + /** * * @since 3.1 @@ -201,7 +205,7 @@ * @return */ TInt HashUrl( const TDesC8& aUrl ); - + /** * * @since 3.1 @@ -209,7 +213,7 @@ * @return */ void ReHashL(); - + /** * * @since 3.1 @@ -217,7 +221,7 @@ * @return */ TUint NextPrime( TUint aNum ); - + /** * * @since 3.1 @@ -225,7 +229,7 @@ * @return */ void Erase( TInt aPos ); - + /** * * @since 3.1 @@ -233,7 +237,7 @@ * @return */ TBool Valid( TInt aPos ); - + /** * * @since 3.1 @@ -241,7 +245,7 @@ * @return */ TBool Empty( TInt aPos ); - + /** * * @since 3.1 @@ -249,7 +253,7 @@ * @return */ TBool Deleted( TInt aPos ); - + /** * * @since 3.1 @@ -257,7 +261,7 @@ * @return */ void SetDeleted( TInt aPos ); - + /** * * @since 3.1 @@ -265,9 +269,9 @@ * @return */ TBool BoundaryCheck( TInt aPos ); - + private: // Data - + // hash table for cache entries CArrayPtrFlat* iEntries; // number of entries in the hashtable @@ -277,7 +281,7 @@ // CHttpCacheStreamHandler* iStreamHandler; // not owned }; - + #endif // CHTTPCACHELOOKUPTABLE_H - + // End of File diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/inc/HttpCacheManager.h --- a/webengine/osswebengine/cache/inc/HttpCacheManager.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/cache/inc/HttpCacheManager.h Thu Aug 27 07:44:59 2009 +0300 @@ -39,6 +39,7 @@ class CRepository; class RHTTPTransaction; class MHTTPDataSupplier; +class CHttpCacheFileWriteHandler; // CLASS DECLARATION @@ -223,8 +224,8 @@ * @param * @return */ - void RemoveOrphanedFilesL(); - + void RemoveOrphanedFilesL(); + /** * * @since 3.1 @@ -240,8 +241,8 @@ * @param * @return */ - TBool VSSRequestCheck( const RHTTPTransaction& aTrans, - const RHTTPHeaders& aHttpHeader, const TDesC8& aUrl ); + TBool VSSRequestCheckL( const RHTTPTransaction& aTrans, + const RHTTPHeaders& aHttpHeader, const TDesC8& aUrl ); /** * * @since 3.1 @@ -254,14 +255,14 @@ private: // Data CHttpCacheHandler* iCache; // owned - - TPath iCacheFolder; - + + TPath iCacheFolder; + CHttpCacheHandler* iOperatorCache; // owned // CHttpCacheHandler* iphoneSpecificCache; // owned // - + CHttpCacheFileWriteHandler* iFileWriteHandler; // owned HBufC8* iOpDomain; // owned // @@ -281,4 +282,4 @@ #endif // CHttpCacheManager_H -// End of File \ No newline at end of file +// End of File diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/inc/HttpCachePostponeWriteUtilities.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/osswebengine/cache/inc/HttpCachePostponeWriteUtilities.h Thu Aug 27 07:44:59 2009 +0300 @@ -0,0 +1,210 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CHttpCachePostponeWriteUtilities +* +*/ + +#ifndef CHTTPCACHEPOSTPONEWRITEUTILS_H +#define CHTTPCACHEPOSTPONEWRITEUTILS_H + +// INCLUDES +#include +#include +#include + +// CONSTANTS + +// MACROS +#define CACHE_POSTPONE_DEBUG_PRINT +// DATA TYPES + +// FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS +class CHttpCacheEntry; +class RFileWriteStream; +class RFileReadStream; +class CHttpCacheFileWriteHandler; +class CHttpCacheHandler; +class MHttpCacheWriteSource; + +/* + * CHttpCacheEntryAsyncWriteHelper is responsible for asynchronously writing out the data from a CHttpCacheStreamEntry object. + * + * It is used in CHttpCacheHandler::FlushAsync() to provide the async write capability. + * + * At creation, it begins to write the first segment of body data. As each segment completes, the next is written. + * Once the body data is written, the headers are written and the status from the header write is returned to the observer. + */ +NONSHARABLE_CLASS(CHttpCacheEntryAsyncWriteHelper) : public CActive + { +public: + virtual ~CHttpCacheEntryAsyncWriteHelper(); + + static CHttpCacheEntryAsyncWriteHelper* NewL(MHttpCacheWriteSource* aSource, TRequestStatus& aStatus); + TInt GetResult(); // KRequestPending, or a completion code. + +private: + CHttpCacheEntryAsyncWriteHelper(TRequestStatus& aStatus, MHttpCacheWriteSource* aSource, TInt aPriority = EPriorityNormal); + + virtual void DoCancel(); + virtual void RunL(); + + void ConstructL(); + void WriteNextBodyBlock(); + +private: + const TRequestStatus& iSignalStatus; + MHttpCacheWriteSource* iSource; + TInt iBodyPart; + TBool iDone; + }; + + + +/* + * CSegmentedHeapBuffer is a simple segmented buffer. You can add data progressively and storage will + * be automatically provided. + * + * When creating one of these, you provide aBufferSize which is the segment size and aCompressGranularity which is the + * multiple which is used to determine if the final block should be shrunk when Compress() is called. + */ +NONSHARABLE_CLASS(CSegmentedHeapBuffer) : public CBase + { +public: + virtual ~CSegmentedHeapBuffer(); + /* + * aBufferSize is the size of each segment used for storage. + * aCompressGranularity is the multiple used when Compress()ing the last block. + */ + static CSegmentedHeapBuffer * NewL(TInt aBufferSize = 32768, TInt aCompressGranularity = 4096); + + /* + * @since 5.0 + * @param aRemainder [out] - returns the amount of data not consumed from aDes. + * @param aDes [in] - the data to append. + * @return void + * Add some data to the buffer. + * + * This function will append the data from aDes in chunks of iBufferSize. + * aRemainder will normally be zero after completion of this call, however if AppendL + * does leave, then aRemainder will tell you how many bytes from aDes have not been consumed. + * This is intended for calling code to cope in the case where the buffer cannot be extended (KErrNoMemory) + * to contain the whole descriptor. Calling code can take remedial action and know exactly how much data + * is left to handle. + */ + void AppendL(TInt& aRemainder, const TDesC8& aDes); + + /* + * @since 5.0 + * @param aSegment [in & out] - in -> the segment to address, out -> next segment. + * @return Segment data descriptor. + * + * Access data in the buffer. + * + * Simply returns descriptor giving access to the desired segment. + * Normal usage is to call with aSegment initialised to zero. + * Repeated calls with same aSegment will result in iterator behaviour. + * Do not call past number of available segments as returned by Count() - this will result in a panic from + * addressing past the end of the RPointerArray. + */ + TPtrC8 GetSegmentData(TInt& aSegment); + + /* + * @since 5.0 + * @param aSegment [in] - the segment to free. + * @return void + * + * Release data in the buffer. + * + * Frees the requested segment without changing segment numbering and order. + */ + void ReleaseSegmentData(const TInt aSegment); + + TInt Length(); // amount of data stored + TInt SpareCapacity(); // spare space in last block + TInt Count(); // number of blocks + + void Compress(); // release space at end of last block. + void Reset(); // release all allocated storage +private: + void ConstructL(); + CSegmentedHeapBuffer(TInt aBufferSize, TInt aCompressGranularity); + +private: + const TInt iBufferSize; + const TInt iCompressGranularity; + RPointerArray iBufferList; + }; +// CLASS DECLARATION + + +NONSHARABLE_CLASS(MHttpCacheWriteSource) + { +public: + virtual RFile& BodyFile() = 0; + virtual void BodyWriteInProgress() = 0; + virtual void BodyWriteComplete() = 0; + virtual CSegmentedHeapBuffer& BodyData() = 0; + }; + +// calls the given function when the preset timer expires. +NONSHARABLE_CLASS(CHttpCacheWriteTimeout) : public CActive + { + public: + // Cancel and destroy + ~CHttpCacheWriteTimeout (); + + // Two-phased constructor. + static CHttpCacheWriteTimeout* NewL (const TInt aTimeout); + + // Two-phased constructor. + static CHttpCacheWriteTimeout* NewLC (const TInt aTimeout); + + public: + // New functions + // Function for making the initial request + void Start(TCallBack aCallbackFn, TAny *aToken); + + private: + // C++ constructor + CHttpCacheWriteTimeout (const TInt aTimeout); + + // Second-phase constructor + void ConstructL (); + + private: + // From CActive + // Handle completion + void RunL (); + + // How to cancel me + void DoCancel (); + + // Override to handle leaves from RunL(). Default implementation causes + // the active scheduler to panic. + TInt RunError (TInt aError); + + private: + TInt iTimeout; + RTimer iTimer; // Provides async timing service + TCallBack iCallbackFn; + TAny *iToken; + }; + + + +#endif // CHTTPCACHEPOSTPONEWRITEUTILS_H + +// End of File diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/inc/HttpCacheStreamHandler.h --- a/webengine/osswebengine/cache/inc/HttpCacheStreamHandler.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/cache/inc/HttpCacheStreamHandler.h Thu Aug 27 07:44:59 2009 +0300 @@ -11,7 +11,7 @@ * * Contributors: * -* Description: Definition of CHttpCacheStreamHandler +* Description: Definition of CHttpCacheStreamHandler * */ @@ -19,9 +19,11 @@ #define CHTTPCACHESTREAMHANDLER_H // INCLUDES + #include #include #include +#include "HttpCacheHandler.h" // CONSTANTS @@ -35,6 +37,8 @@ class CHttpCacheEntry; class RFileWriteStream; class RFileReadStream; +class CHttpCacheFileWriteHandler; +class CSegmentedHeapBuffer; // CLASS DECLARATION @@ -54,7 +58,7 @@ * @param * @return CHttpCacheStreamHandler object. */ - static CHttpCacheStreamHandler* NewL( const TDesC& aDirectory, TInt aCriticalLevel ); + static CHttpCacheStreamHandler* NewL( const TDesC& aDirectory, TInt aCriticalLevel, RFs& aRFs ); /** * Destructor. @@ -63,6 +67,8 @@ public: // new functions + void InitialiseCacheEntryL(CHttpCacheEntry& aCacheEntry); + /** * * @since 3.1 @@ -85,23 +91,7 @@ * @param * @return */ - TBool AttachL( CHttpCacheEntry& aCacheEntry ); - - /** - * - * @since 3.1 - * @param - * @return - */ - void Detach( CHttpCacheEntry& aCacheEntry ); - - /** - * - * @since 3.1 - * @param - * @return - */ - void EraseCacheFile( CHttpCacheEntry& aCacheEntry ); + void Erase( CHttpCacheEntry& aCacheEntry ); /** * @@ -160,20 +150,36 @@ TBool Flush( CHttpCacheEntry& aCacheEntry ); /** - * - * @since 3.1 + * FlushL + * @since 7.1 + * @param + * @return + */ + TBool FlushL( CHttpCacheEntry& aCacheEntry ); + + /** + * FlushAsync + * @since 7.1 * @param * @return */ - TBool OpenCacheFiles( CHttpCacheEntry& aCacheEntry ); + TBool FlushAsync( CHttpCacheEntry& aCacheEntry , TRequestStatus& aStatus); /** * - * @since 3.1 + * @since 7.1 * @param * @return */ - TBool CreateNewFilesL( CHttpCacheEntry& aCacheEntry ); + TBool OpenBodyFile( CHttpCacheEntry& aCacheEntry ); + + /** + * + * @since 7.1 + * @param + * @return + */ + TBool CreateNewBodyFile( CHttpCacheEntry& aCacheEntry ); private: @@ -184,7 +190,7 @@ * @param * @return CacheHandler object. */ - CHttpCacheStreamHandler(); + CHttpCacheStreamHandler(RFs& aRFs); /** * By default Symbian 2nd phase constructor is private. @@ -200,7 +206,7 @@ * @return */ TBool IsDiskSpaceAvailable( TInt aContentSize ); - + /** * * @since 7.1 @@ -212,7 +218,7 @@ private: // Data // - RFs iRfs; // owned + RFs iRfs; // attached entries CArrayPtrFlat* iActiveEntries; // owned // diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/inc/HttpCacheUtil.h --- a/webengine/osswebengine/cache/inc/HttpCacheUtil.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/cache/inc/HttpCacheUtil.h Thu Aug 27 07:44:59 2009 +0300 @@ -45,12 +45,18 @@ ELogFileErrorCode }; -const TInt KCacheVersionNumber = 1; +const TInt KCacheVersionNumber = 2; // changed on-disk format //make 16 subdirectories named 0 through F for organizing cached files const TUint32 KCacheSubdirCount = 16; +// The subdirectory name is calculated in HttpCacheUtil::GenerateNameLC() +const TUint32 KSubdirNameLength = 2; +// The filename is calculated in HttpCacheUtil::GenerateNameLC() +const TUint32 KFilenameLength = 8; _LIT( KHttpCacheHeaderExt, ".h" ); -//#define __CACHELOG__ +#ifdef _DEBUG +#define __CACHELOG__ +#endif // MACROS @@ -147,7 +153,7 @@ * @return */ static TCacheLoadMethod MethodFromStr( RStringF aMethodStr, RStringPool aStrP ); - + /** * * @since 3.1 @@ -204,7 +210,7 @@ * @return */ static void GetHeaderFileName( const TDesC& aBodyFileName, TDes& aHeaderFileName ); - + /** * * @since 3.1 @@ -256,6 +262,14 @@ static void WriteLog( TInt aLogLevel, TPtrC aBuf, TInt aAny = 0xffff ); /** + * expects a format string in aBuf, plus arguments... + * @since 7.1 + * @param + * @return + */ + static void WriteFormatLog( TInt aLogLevel, TRefByValue aBuf, ... ); + + /** * * @since 7.1 * @param diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/src/HttpCacheEntry.cpp --- a/webengine/osswebengine/cache/src/HttpCacheEntry.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/cache/src/HttpCacheEntry.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -28,6 +28,8 @@ // CONSTANTS const TInt CHttpCacheEntry::iOffset = _FOFF( CHttpCacheEntry, iSqlQueLink ); +const TInt KBufferSize32k = 32768; +const TInt KBufferGranularity4k = 4096; // MACROS @@ -63,7 +65,8 @@ void CHttpCacheEntry::ConstructL( const TDesC8& aUrl ) { iUrl = aUrl.AllocL(); - iFileName = KNullDesC().AllocL(); + iHeaderBuffer = KNullDesC8().AllocL(); + iCacheBuffer = CSegmentedHeapBuffer::NewL( KBufferSize32k, KBufferGranularity4k ); } // ----------------------------------------------------------------------------- @@ -111,16 +114,14 @@ } // Close files, this will commit changes - if ( iCacheFilesOpened ) - { - iHeaderFile.Close(); - iBodyFile.Close(); - } + iBodyFile.Close(); // Clean up our memory delete iUrl; delete iFileName; + delete iHeaderBuffer; delete iCacheBuffer; + delete iWriteHelper; } // ----------------------------------------------------------------------------- @@ -150,7 +151,7 @@ { delete iFileName; iFileName = NULL; - + iFileName = aFileName.AllocL(); } @@ -221,47 +222,80 @@ // // ----------------------------------------------------------------------------- // -TInt CHttpCacheEntry::Internalize( RFileReadStream& aReadStream ) +TInt CHttpCacheEntry::Internalize( RReadStream& aReadStream, const TDesC& aDirectory ) + { + TRAPD( err, InternalizeL( aReadStream, aDirectory ) ); + return err; + } + +// ----------------------------------------------------------------------------- +// CHttpCacheEntry::InternalizeL +// +// ----------------------------------------------------------------------------- +// +void CHttpCacheEntry::InternalizeL( RReadStream& aReadStream, const TDesC& aDirectory ) { // url length - TRAPD( err, - TInt len; - - // url length - len = aReadStream.ReadInt32L(); - delete iUrl; - iUrl=NULL; - iUrl = HBufC8::NewL( len ); - TPtr8 ptr8( iUrl->Des() ); - // url - aReadStream.ReadL( ptr8, len ); - - // filename length - len = aReadStream.ReadInt32L(); - HBufC* filename = HBufC::NewLC( len ); - TPtr ptr( filename->Des() ); - // url - aReadStream.ReadL( ptr, len ); - // - SetFileNameL( filename->Des() ); - // - CleanupStack::PopAndDestroy(); // filename - // la - TReal64 la; - la = aReadStream.ReadReal64L(); - iLastAccessed = la; - // ref - iRef = aReadStream.ReadUint32L(); - // size - iBodySize = aReadStream.ReadUint32L( ); - // size - iHeaderSize = aReadStream.ReadUint32L( ); - // protected - iProtected = aReadStream.ReadInt32L(); - // - SetState( ECacheComplete ); - ); // end of TRAPD + TInt len; + len = aReadStream.ReadInt32L(); + delete iUrl; + iUrl=NULL; + iUrl = HBufC8::NewL( len ); + TPtr8 ptr8( iUrl->Des() ); + // url + aReadStream.ReadL( ptr8, len ); + + // calculate full path and filename length + // aDirectory/ + "x/xxxxxxxx" : note aDirectory has trailing '/' + len = aDirectory.Length() + KSubdirNameLength + KFilenameLength; + HBufC* filename = HBufC::NewLC( len ); + TPtr ptr( filename->Des() ); + + // Read max char length of filename. + // NOTE: The filename and filename length is calculated by the code in + // HttpCacheUtil::GenerateNameLC. The sub directory is the same as the + // last char of the filename, e.g. ..\A\0123DCBA + TBuf uniqueFilename; + aReadStream.ReadL( uniqueFilename , KFilenameLength ); + TPtrC uniqueSubDir = uniqueFilename.Right(1); + // assemble path and filename + ptr.Format(_L("%S%S\\%S"), &aDirectory, &uniqueSubDir, &uniqueFilename); + // + SetFileNameL( filename->Des() ); + // + CleanupStack::PopAndDestroy(); // filename + // la + TReal64 la; + la = aReadStream.ReadReal64L(); + iLastAccessed = la; + // ref + iRef = aReadStream.ReadUint32L(); + // size + iBodySize = aReadStream.ReadUint32L( ); + // size + iHeaderSize = aReadStream.ReadUint32L( ); + // protected + iProtected = aReadStream.ReadInt32L(); + // header data + delete iHeaderBuffer; + iHeaderBuffer = NULL; + len = aReadStream.ReadInt32L(); + iHeaderBuffer = HBufC8::NewL(len); + TPtr8 header_ptr( iHeaderBuffer->Des() ); + aReadStream.ReadL( header_ptr, len ); + // + SetState( ECacheComplete ); + } + +// ----------------------------------------------------------------------------- +// CHttpCacheEntry::Externalize +// +// ----------------------------------------------------------------------------- +// +TInt CHttpCacheEntry::Externalize( RWriteStream& aWriteStream, const TDesC& aDirectory ) + { + TRAPD( err, ExternalizeL( aWriteStream, aDirectory ) ); return err; } @@ -270,30 +304,33 @@ // // ----------------------------------------------------------------------------- // -TInt CHttpCacheEntry::Externalize( RFileWriteStream& aWriteStream ) +void CHttpCacheEntry::ExternalizeL( RWriteStream& aWriteStream, const TDesC& aDirectory ) { - TRAPD( err, - // url length - aWriteStream.WriteInt32L( iUrl->Length() ); - // url - aWriteStream.WriteL( iUrl->Des() ); - // filename length - aWriteStream.WriteInt32L( iFileName->Length() ); - // filename - aWriteStream.WriteL( iFileName->Des() ); - // la - aWriteStream.WriteReal64L( iLastAccessed ); - // ref - aWriteStream.WriteUint32L( iRef ); - // size - aWriteStream.WriteUint32L( iBodySize ); - // size - aWriteStream.WriteUint32L( iHeaderSize ); - // protected - aWriteStream.WriteInt32L( iProtected ); - ); // end of TRAPD + // check directory matches filename + ASSERT(aDirectory.CompareF(iFileName->Left(aDirectory.Length())) == 0); - return err; + // url length + aWriteStream.WriteInt32L( iUrl->Length() ); + // url + aWriteStream.WriteL( iUrl->Des() ); + // filename + // know that filenames are 8 chars and no extension. Can reconstruct on + // import from directory and last char. See HttpCacheUtil::GenerateNameLC. + aWriteStream.WriteL( iFileName->Des().Right( KFilenameLength ) ); + // la + aWriteStream.WriteReal64L( iLastAccessed ); + // ref + aWriteStream.WriteUint32L( iRef ); + // size + aWriteStream.WriteUint32L( iBodySize ); + // size + aWriteStream.WriteUint32L( iHeaderSize ); + // protected + aWriteStream.WriteInt32L( iProtected ); + // header data length + aWriteStream.WriteInt32L( iHeaderBuffer->Length() ); + // header data + aWriteStream.WriteL( iHeaderBuffer->Des() ); } // ----------------------------------------------------------------------------- @@ -320,18 +357,7 @@ } // ----------------------------------------------------------------------------- -// CHttpCacheEntry::SetCacheFilesOpened -// -// ----------------------------------------------------------------------------- -// -void CHttpCacheEntry::SetCacheFilesOpened( TBool aCacheFilesOpened ) - { - // Set our files open flag - iCacheFilesOpened = aCacheFilesOpened; - } - -// ----------------------------------------------------------------------------- -// CHttpCacheEntry::CacheBuffer +// CHttpCacheEntry::SetCacheBufferL // NOTE: Cache buffer is created on: // 1. Normal content entrypoint into CacheManager // CacheManager::ReceivedResponseHeadersL -> CacheHandler::ReceivedResponseHeadersL -> @@ -339,42 +365,134 @@ // accumulate body content on multiple CacheHandler::ReceivedBodyDataL calls) // 2. Multipart content entrypoint into CacheManager // CacheManager::SaveL -> CacheHandler::SaveL -> CacheHandler::SaveBuffer -> -// CacheStreamHandler::SaveBodyData (calls this method - CacheBuffer, needed -// because cacheBuffer=null and single call made, no accumulation of body data) -// ----------------------------------------------------------------------------- -// -TPtr8 CHttpCacheEntry::CacheBuffer() - { - if ( iCacheBuffer == NULL ) - { - // Create the cache buffer, if needed - iCacheBuffer = HBufC8::New( KBufferSize32k ); - if ( iCacheBuffer == NULL ) - { - // OOM, return empty cache buffer - TPtr8 emptyCacheBuffer( NULL, 0, 0 ); - return emptyCacheBuffer; - } - } - - return iCacheBuffer->Des(); - } - -// ----------------------------------------------------------------------------- -// CHttpCacheEntry::SetCacheBufferL -// +// CacheStreamHandler::SaveBodyData (calls this method - SetCacheBufferL, needed +// because cacheBuffer=null and single call made, no accumulation of body data) // ----------------------------------------------------------------------------- // void CHttpCacheEntry::SetCacheBufferL( TInt aCacheBufferSize ) { - if ( aCacheBufferSize > 0 && iCacheBuffer == NULL ) + // Delete cacheBuffer and null, a way to zero buffer and handle if NewL leave + delete iCacheBuffer; + iCacheBuffer = NULL; + + if ( aCacheBufferSize > 0 ) { - iCacheBuffer = HBufC8::NewL( aCacheBufferSize ); - } - else if ( aCacheBufferSize <= 0 ) - { - delete iCacheBuffer; - iCacheBuffer = NULL; + iCacheBuffer = CSegmentedHeapBuffer::NewL( aCacheBufferSize, KBufferGranularity4k ); } } + +// ----------------------------------------------------------------------------- +// CHttpCacheEntry::CreateHeaderBufferL +// +// ----------------------------------------------------------------------------- +// +void CHttpCacheEntry::CreateHeaderBufferL( TInt aHeaderBufferSize ) + { + // Delete cacheBuffer and null, a way to zero buffer and handle if NewL leave + delete iHeaderBuffer; + iHeaderBuffer = NULL; + + if ( aHeaderBufferSize > 0 ) + { + iHeaderBuffer = HBufC8::NewL( aHeaderBufferSize ); + } + SetHeaderSize( aHeaderBufferSize ); + } + +// ----------------------------------------------------------------------------- +// CHttpCacheEntry::CreateHeaderBufferL +// +// ----------------------------------------------------------------------------- +// +void CHttpCacheEntry::CreateHeaderBufferL( const TDesC8& aHeaderData ) + { + // Delete cacheBuffer and null, a way to zero buffer and handle if NewL leave + delete iHeaderBuffer; + iHeaderBuffer = NULL; + + TInt aHeaderBufferSize = aHeaderData.Length(); + if ( aHeaderBufferSize > 0 ) + { + iHeaderBuffer = aHeaderData.AllocL(); + } + SetHeaderSize( aHeaderBufferSize ); + } + +// ----------------------------------------------------------------------------- +// CHttpCacheEntry::BodyData +// +// ----------------------------------------------------------------------------- +// +CSegmentedHeapBuffer& CHttpCacheEntry::BodyData() + { + return *iCacheBuffer; + } + +// ----------------------------------------------------------------------------- +// CHttpCacheEntry::BodyFile +// +// ----------------------------------------------------------------------------- +// +RFile& CHttpCacheEntry::BodyFile() + { + return iBodyFile; + } + +// ----------------------------------------------------------------------------- +// CHttpCacheEntry::HeaderData +// +// ----------------------------------------------------------------------------- +// +TDesC8& CHttpCacheEntry::HeaderData() + { + return *iHeaderBuffer; + } + +// ----------------------------------------------------------------------------- +// CHttpCacheEntry::BodyWriteInProgress +// +// ----------------------------------------------------------------------------- +// +void CHttpCacheEntry::BodyWriteInProgress() + { + SetBodyDataPartiallyWritten( ETrue ); + } + +// ----------------------------------------------------------------------------- +// CHttpCacheEntry::BodyWriteComplete +// +// ----------------------------------------------------------------------------- +// +void CHttpCacheEntry::BodyWriteComplete() + { + iCacheBuffer->Reset(); + SetBodyDataPartiallyWritten( EFalse ); + SetBodyDataCached( EFalse ); + } + +// ----------------------------------------------------------------------------- +// CHttpCacheEntry::WriteBodyDataAsync +// +// ----------------------------------------------------------------------------- +// +void CHttpCacheEntry::WriteBodyDataAsync(TRequestStatus& aStatus) + { + delete iWriteHelper; + iWriteHelper = NULL; + TRAP_IGNORE( iWriteHelper = CHttpCacheEntryAsyncWriteHelper::NewL( this, aStatus ) ); + } + +// ----------------------------------------------------------------------------- +// CHttpCacheEntry::CancelBodyWrite +// +// ----------------------------------------------------------------------------- +// +void CHttpCacheEntry::CancelBodyWrite() + { + if ( BodyDataPartiallyWritten() && iWriteHelper ) + { + iWriteHelper->Cancel(); + } + } + // End of File diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/src/HttpCacheEvictionHandler.cpp --- a/webengine/osswebengine/cache/src/HttpCacheEvictionHandler.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/cache/src/HttpCacheEvictionHandler.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -11,7 +11,7 @@ * * Contributors: * -* Description: Implementation of CHttpCacheEvictionHandler +* Description: Implementation of CHttpCacheEvictionHandler * */ @@ -111,11 +111,11 @@ CHttpCacheEvictionHandler::~CHttpCacheEvictionHandler() { if (iBuckets) - { - // delete the entries - for( TInt i=0; iCount(); ++i ) - delete iBuckets->At( i ); - } + { + // delete the entries + for( TInt i=0; iCount(); ++i ) + delete iBuckets->At( i ); + } delete iBuckets; } @@ -337,25 +337,25 @@ } } - // remove from the bucket, add it to the evicted list, + // remove from the bucket, add it to the evicted list, // reduce space needed size if ( candidate ) { #ifdef __CACHELOG__ // no protected entries should be evacuated if( candidate->Protected() ) - { - HttpCacheUtil::WriteUrlToLog( 0, _L( "CHttpCacheEvictionHandler::EvictL - PROTECTED entry is about to be removed" ), candidate->Url() ); - } + { + HttpCacheUtil::WriteUrlToLog( 0, _L( "CHttpCacheEvictionHandler::EvictL - PROTECTED entry is about to be removed" ), candidate->Url() ); + } HttpCacheUtil::WriteLogFilenameAndUrl( 0, _L("CHttpCacheEvictionHandler::EvictL - removing entry "), candidate->Filename(), candidate->Url(), - candidate->BodySize(), + candidate->BodySize(), ELogEntrySize ); #endif //__CACHELOG__ - + iBuckets->At( bucketInd )->Remove( *candidate ); // Reduce size needed aSpaceNeeded -= candidate->BodySize(); @@ -366,7 +366,7 @@ #ifdef __CACHELOG__ if ( aSpaceNeeded > 0 ) { HttpCacheUtil::WriteLog( 0, _L( "CHttpCacheEvictionHandler::EvictL - more space needed aSpaceNeeded = " ), aSpaceNeeded ); - } + } #endif } else @@ -474,7 +474,7 @@ _L("CHttpCacheEvictionHandler::ItemIsInBucket - entry NOT found"), aCacheEntry.Filename(), aCacheEntry.Url(), - aCacheEntry.BodySize(), + aCacheEntry.BodySize(), ELogEntrySize ); } #endif // __CACHELOG__ @@ -511,12 +511,13 @@ TBucketIter bucketIter( *(iBuckets->At( i )) ); // bucketIter.SetToFirst(); - while( ( entry = bucketIter++ ) != NULL ) + while ( ( entry = bucketIter++ ) != NULL ) { _LIT( KDateString,"%D%M%Y%/0%1%/1%2%/2%3%/3 %-B%:0%J%:1%T%:2%S%.%*C4%:3%+B"); _LIT( KRefSizeString,"CHttpCacheEvictionHandler::LogBuckets - size: %d refcount:%d"); - TBuf<50> refStr; + // note ref string is 60 chars before we format it + TBuf<80> refStr; TBuf<50> lastAccessedStr; TTime lastAccessed( entry->LastAccessed() ); @@ -529,7 +530,7 @@ _L("CHttpCacheEvictionHandler::LogBuckets - "), entry->Filename(), entry->Url(), - i, + i, ELogBucketIndex ); } } diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/src/HttpCacheFileWriteHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/osswebengine/cache/src/HttpCacheFileWriteHandler.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -0,0 +1,545 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CHttpCacheFileWriteHandler +* +*/ + +// INCLUDE FILES +#include "HttpCacheFileWriteHandler.h" +#include "HttpCacheEntry.h" +#include "HttpCacheHandler.h" +#include "HttpCacheStreamHandler.h" +#include "HttpCachePostponeWriteUtilities.h" +#include "HttpCacheUtil.h" +#include +#include +#include +#include + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS +const TInt KMaxCollectCount = 5; // collect a max of 5 items. + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +void CHttpCacheFileWriteHandler::OutputQueueContentToDebug() + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: %d objects on queue. Contents:"), iObjectQueue.Count()); + TBuf<80> txt; + TInt totalSize=0; + for(TInt tmploop = 0; tmploop BodySize(), entry ); + totalSize+=entry->BodySize(); + HttpCacheUtil::WriteUrlToLog( 0, txt, entry->Url() ); + } + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: %d bytes cached"), totalSize); +#endif + } + +// FORWARD DECLARATIONS + +// ============================ MEMBER FUNCTIONS =============================== +// ----------------------------------------------------------------------------- +// CHttpCacheFileWriteHandler::CHttpCacheFileWriteHandler +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CHttpCacheFileWriteHandler::CHttpCacheFileWriteHandler(CHttpCacheHandler* aHandler, CHttpCacheStreamHandler* aStreamHandler, RFs& aRfs) + : CActive(EPriorityHigh), + iCacheHandler( aHandler ), + iCacheStreamHandler(aStreamHandler), + iFs(aRfs) + { + } + +// ----------------------------------------------------------------------------- +// CHttpCacheFileWriteHandler::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CHttpCacheFileWriteHandler::ConstructL(const TInt aWriteTimeout) + { + iObjectQueue.Reset(); + iObjectQueue.ReserveL(32); + + iWaitTimer = CHttpCacheWriteTimeout::NewL( aWriteTimeout ); + CActiveScheduler::Add(this); + + MemoryManager::AddCollector(this); + } + +// ----------------------------------------------------------------------------- +// CHttpCacheFileWriteHandler::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CHttpCacheFileWriteHandler* CHttpCacheFileWriteHandler::NewL(CHttpCacheHandler* aHandler, CHttpCacheStreamHandler* aStreamHandler, RFs& aRfs, const TInt aWriteTimeout) + { + CHttpCacheFileWriteHandler* self = new( ELeave ) CHttpCacheFileWriteHandler(aHandler, aStreamHandler, aRfs); + + CleanupStack::PushL( self ); + self->ConstructL(aWriteTimeout); + CleanupStack::Pop(); + + return self; + } + +// ----------------------------------------------------------------------------- +// Destructor +// ----------------------------------------------------------------------------- +// +CHttpCacheFileWriteHandler::~CHttpCacheFileWriteHandler() + { + Cancel(); + + DumpAllObjects(); + + if ( iWaitTimer ) + { + iWaitTimer->Cancel(); + delete iWaitTimer; + } + + MemoryManager::RemoveCollector( this ); + } + +// ----------------------------------------------------------------------------- +// CHttpCacheFileWriteHandler::DumpAllObjectsL +// Emergency method - write everything to disk synchronously. +// ----------------------------------------------------------------------------- +// +void CHttpCacheFileWriteHandler::DumpAllObjects() + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: >>FileWriteHandler::DumpAllObjects")); + OutputQueueContentToDebug(); +#endif + for ( TInt i=0; i < iObjectQueue.Count(); i++ ) + { + iCacheStreamHandler->Flush(*iObjectQueue[i]); + } + iObjectQueue.Reset(); +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: < second ) + { + return -1; + } + + if ( second > first ) + { + return 1; + } + + return 0; + } + +// ----------------------------------------------------------------------------- +// CHttpCacheFileWriteHandler::CollectMemory +// ----------------------------------------------------------------------------- +// +void CHttpCacheFileWriteHandler::CollectMemory(TUint aRequired) + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: >>FileWriteHandler::CollectMemory looking for %d bytes"), aRequired); + OutputQueueContentToDebug(); +#endif + if ( !iObjectQueue.Count() ) + { + return; + } + + TInt count = KMaxCollectCount; + while ( aRequired && count && iObjectQueue.Count() ) + { + count--; + CHttpCacheEntry* entry = iObjectQueue[0]; + iObjectQueue.Remove(0); + TInt size = entry->BodySize(); + iCacheStreamHandler->Flush(*entry); + aRequired -= size; + } + } + +// ----------------------------------------------------------------------------- +// CHttpCacheFileWriteHandler::AddEntry +// ----------------------------------------------------------------------------- +// +TInt CHttpCacheFileWriteHandler::AddEntry(TAddStatus &aAddStatus, CHttpCacheEntry* aEntry) + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: >>FileWriteHandler::AddEntry")); +#endif + + if ( iImmediateWriteThreshold && ( aEntry->BodySize() <= iImmediateWriteThreshold ) ) + { + aAddStatus = EBodySmallerThanThreshold; +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: File smaller than minimum")); + HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: <IsActive() ) + { + // we have some items queued for write, begin to flush them since we're going to run out of memory soon anyway. + iWaitTimer->Cancel(); + BeginWriting(); + } + + return KErrNone; + } + + // if we get here, we're not in low memory state any more. + iLowMemoryState = EFalse; + + // add entry to queue + TInt err = iObjectQueue.InsertInOrderAllowRepeats(aEntry, TLinearOrder(CompareHttpCacheEntrySize)); + + #ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: CHttpCacheFileWriteHandler: Added object %08x to postpone queue."), aEntry); + OutputQueueContentToDebug(); +#endif + + // reset timer + if ( err == KErrNone ) + { + aAddStatus = EAddedOk; + iWaitTimer->Start( CHttpCacheFileWriteHandler::WriteTimeout, this ); + } + else + { + aAddStatus = ECheckReturn; + } + +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: <>FileWriteHandler::RemoveEntry called for entry %08x"), aEntry); +#endif + + // take object off list. + if ( aEntry == iObjectFlushing && IsActive() ) + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: CHttpCacheFileWriteHandler::RemoveEntry - entry %08x is currently being written. Returning 'not found'."), aEntry); +#endif + // the object will be removed from the list when it's done writing out, so we don't need to worry about it + entry = 0; + // back off from flushing anything else for a bit in case we want that as well.. + iWaitTimer->Start(CHttpCacheFileWriteHandler::WriteTimeout, this); + } + else + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: CHttpCacheFileWriteHandler::RemoveEntry - entry %08x not active."), aEntry); +#endif + TInt index = iObjectQueue.Find( aEntry ); + if ( index >= 0 ) + { + iObjectQueue.Remove( index ); + if ( !iObjectQueue.Count() ) + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: CHttpCacheFileWriteHandler::RemoveEntry - nothing left on list, stopping timer.")); +#endif + // nothing on the list, so stop the timer. + iWaitTimer->Cancel(); + } + } + } + +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: <BeginWriting(); + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CHttpCacheFileWriteHandler::BeginWriting +// ----------------------------------------------------------------------------- +// +void CHttpCacheFileWriteHandler::BeginWriting() + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: >>FileWriteHandler::BeginWriting")); +#endif + + if ( !IsActive() ) + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: Setting FileWriteHandler %08x to active."), this); +#endif + iStatus = KRequestPending; + SetActive(); + TRequestStatus *stat = &iStatus; + User::RequestComplete(stat, KErrNone); + } +#ifdef __CACHELOG__ + else + { + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: FileWriteHandler %08x already active!"), this); + } + + HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: <>FileWriteHandler::RunL")); + OutputQueueContentToDebug(); +#endif + + TInt result = iStatus.Int(); + + // first, see if we have been writing anything + if ( iObjectFlushing ) + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: iObjectFlushing set, been writing something.")); +#endif + + // should always be first item, find just in case... + TInt index = iObjectQueue.Find(iObjectFlushing); + +#ifdef __CACHELOG__ + if ( index < 0 ) + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: iObjectFlushing (%08x) not found in object queue!"), iObjectFlushing); +#endif + + if ( index >= 0 ) + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: iObjectFlushing (%08x) is at position %d in list"), iObjectFlushing, index); +#endif + // the object might not exist in the queue.. how can this happen? + iObjectQueue.Remove(index); + // + if ( result != KErrNone ) + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: FileWriteHandler::RunL Failure while writing object %08x"), iObjectFlushing); +#endif + // write failed. Clean up this entry. + // first, remove it from the cache handler so that we won't try to reuse a dead entry + iCacheHandler->RemoveL( iObjectFlushing->Url() ); + } + } + iObjectFlushing = 0; + } + + // next, check to see if we've added anything to the cache while we've been writing out. + TInt count = iObjectQueue.Count(); + if ( iWaitTimer->IsActive() ) + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: FileWriteHandler::RunL New entry detected on postpone queue, wait for timeout again.")); +#endif + // something has been added to the queue, back off until it completes. + // this case intentionally left blank... + } + else + { + // remove any items from the top of the queue which have no body data. + while ( iObjectQueue.Count() && iObjectQueue[0]->BodySize() == 0 ) + { + iObjectQueue.Remove(0); + }; + + // check to see if there is anything ready to write out + if ( iObjectQueue.Count() ) + { + SetActive(); + iStatus = KRequestPending; + iCacheStreamHandler->FlushAsync( *iObjectQueue[0], iStatus ); + iObjectFlushing = iObjectQueue[0]; +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: FileWriteHandler::RunL continue cache flush, Starting object %08x."), iObjectFlushing); +#endif + } + else + { // nothing left to write, go idle. + #ifdef __CACHELOG__ + HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: FileWriteHandler::RunL complete with nothing else to write.")); + #endif + iCacheHandler->SaveLookupTableL(); + iLowMemoryState = EFalse; + } + } + } + +// ----------------------------------------------------------------------------- +// CHttpCacheFileWriteHandler::Collect +// ----------------------------------------------------------------------------- +// +TUint CHttpCacheFileWriteHandler::Collect(TUint aRequired) + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: >>FileWriteHandler::Collect on FileWriteHandler %08x (low memory collector)"), this); +#endif + if ( iWaitTimer->IsActive() ) + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: Wait timer is active, cancel it and call DumpAllObjects")); +#endif + + iWaitTimer->Cancel(); + CollectMemory( aRequired ); + iLowMemoryState = ETrue; + BeginWriting(); + } +#ifdef __CACHELOG__ + else + { + HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: Wait timer not active.")); + } + HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: <= 0 ) + { + return ETrue; + } + + return EFalse; + } + +// End of File diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/src/HttpCacheHandler.cpp --- a/webengine/osswebengine/cache/src/HttpCacheHandler.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/cache/src/HttpCacheHandler.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -24,12 +24,14 @@ #include "HttpCacheUtil.h" #include "HttpCacheEvictionHandler.h" #include "HttpCacheObserver.h" +#include "HttpCacheFileWriteHandler.h" #include #include #include #include #include #include +#include #include // EXTERNAL DATA STRUCTURES @@ -39,6 +41,7 @@ // CONSTANTS // MACROS +//#define __USE_VALIDATION_FILES__ // LOCAL CONSTANTS AND MACROS @@ -58,6 +61,13 @@ } // ============================ MEMBER FUNCTIONS =============================== +THttpCachePostponeParameters::THttpCachePostponeParameters() + { + iEnabled = EFalse; + iFreeRamThreshold = 0; + iImmediateWriteThreshold = 0; + iWriteTimeout = 0; + } // ----------------------------------------------------------------------------- // CHttpCacheHandler::CHttpCacheHandler @@ -65,8 +75,8 @@ // might leave. // ----------------------------------------------------------------------------- // -CHttpCacheHandler::CHttpCacheHandler( - TInt aSize ) : iSize( aSize ) +CHttpCacheHandler::CHttpCacheHandler( TInt aSize ) + : iSize( aSize ) { } @@ -78,41 +88,36 @@ void CHttpCacheHandler::ConstructL( const TDesC& aDirectory, const TDesC& aIndexFile, - TInt aCriticalLevel) + TInt aCriticalLevel, + const THttpCachePostponeParameters& aPostpone) { - User::LeaveIfError(iRfs.Connect()); + User::LeaveIfError(iRfs.Connect()); // iIndexFile = aIndexFile.AllocL(); // iDirectory = aDirectory.AllocL(); - // - iEvictionHandler = CHttpCacheEvictionHandler::NewL(); - // - iStreamHandler = CHttpCacheStreamHandler::NewL( iDirectory->Des(), aCriticalLevel ); - // - iLookupTable = CHttpCacheLookupTable::NewL( *iEvictionHandler, *iStreamHandler ); - //1. Set up top-level cache directory if it doesn't exist. + //1. Set up top-level cache directory if it doesn't exist. TEntry entry; TInt err( KErrNone ); - if (iRfs.Entry(iDirectory->Des(), entry) != KErrNone) + if ( iRfs.Entry(iDirectory->Des(), entry) != KErrNone ) { - err = iRfs.MkDirAll(iDirectory->Des()); + err = iRfs.MkDirAll( iDirectory->Des() ); } //2. Create subdirectories to store header/body files if ( err == KErrNone || err == KErrAlreadyExists ) { //harmless errors - + __ASSERT_DEBUG ( (iDirectory->Des().LocateReverse( KPathDelimiter ) == (iDirectory->Des().Length() - 1)), PanicCacheHandler( KErrCorrupt ) ); // We assume that iDirectory is terminated by a forward slash - + HBufC* subDir = HBufC::NewL(KMaxPath); // Base cache dir + subdir name + another delimiter _LIT(KFormat,"%S%x%c"); - for (TUint i = 0; i < KCacheSubdirCount; i++) + for ( TUint i = 0; i < KCacheSubdirCount; i++ ) { - TPtrC ptr (iDirectory->Des()); - subDir->Des().Format(KFormat, &ptr, i, KPathDelimiter); - TInt err2 = iRfs.MkDir(subDir->Des()); - __ASSERT_DEBUG ( (err2 == KErrNone || err2 == KErrAlreadyExists), PanicCacheHandler( err2 ) ); + TPtrC ptr ( iDirectory->Des() ); + subDir->Des().Format( KFormat, &ptr, i, KPathDelimiter ); + TInt err2 = iRfs.MkDir( subDir->Des() ); + __ASSERT_DEBUG ( (err2 == KErrNone || err2 == KErrAlreadyExists), PanicCacheHandler( err2 ) ); } delete subDir; //end cache dir + subdir creation @@ -120,7 +125,57 @@ User::Leave(err); } - OpenLookupTableL(); + // set path for the entries + iRfs.SetSessionPath( aDirectory ); +#ifdef __USE_VALIDATION_FILES__ + // create validation file + TFileName validateFile; + GenerateValidationFilename(validateFile, aIndexFile); + + TBool validateCacheEntries( EFalse ); + RFile validate; + TInt validateErr = validate.Create(iRfs, validateFile, EFileShareExclusive | EFileWrite); + if ( validateErr != KErrNone ) + { + if ( validateErr == KErrAlreadyExists ) + { + validateCacheEntries = ETrue; + } +#ifdef _DEBUG + else + { + // oh dear, we failed to create the file for some other reason, something must have gone properly wrong... + User::Panic(_L("CacheHandler"), -9999); + } +#endif + } + validate.Close(); +#endif + // + iEvictionHandler = CHttpCacheEvictionHandler::NewL(); + // + iStreamHandler = CHttpCacheStreamHandler::NewL( iDirectory->Des(), aCriticalLevel, iRfs ); + // + if ( aPostpone.iEnabled ) + { + iPostponeHandler = CHttpCacheFileWriteHandler::NewL(this, iStreamHandler, iRfs, aPostpone.iWriteTimeout); + } + // + iLookupTable = CHttpCacheLookupTable::NewL( *iEvictionHandler, *iStreamHandler ); + TRAP( err, OpenLookupTableL() ); + if ( err != KErrNone ) + { + // failed to open the lookup table, delete the old one and start again. + delete iLookupTable; + iLookupTable = NULL; + iLookupTable = CHttpCacheLookupTable::NewL( *iEvictionHandler, *iStreamHandler ); + } +#ifdef __USE_VALIDATION_FILES__ + if ( validateCacheEntries ) +#endif + // ensure that the disk content matches the cache content + ValidateCacheEntriesL(); + // iHttpCacheObserver = CHttpCacheObserver::NewL(iDirectory, iIndexFile, this); iHttpCacheObserver->StartObserver(); @@ -135,12 +190,13 @@ TInt aSize, const TDesC& aDirectory, const TDesC& aIndexFile, - TInt aCriticalLevel) + TInt aCriticalLevel, + const THttpCachePostponeParameters& aPostpone) { CHttpCacheHandler* self = new( ELeave ) CHttpCacheHandler( aSize ); CleanupStack::PushL( self ); - self->ConstructL( aDirectory, aIndexFile, aCriticalLevel ); + self->ConstructL( aDirectory, aIndexFile, aCriticalLevel, aPostpone ); CleanupStack::Pop(); return self; @@ -152,9 +208,23 @@ // CHttpCacheHandler::~CHttpCacheHandler() { +#ifndef __USE_VALIDATION_FILES__ TRAP_IGNORE( SaveLookupTableL() ); +#else + + TRAPD( err, SaveLookupTableL() ); + if ( err == KErrNone && iIndexFile ) + { + TFileName validateFile; + GenerateValidationFilename(validateFile, iIndexFile->Des()); + // we saved the index successfully, remove the validate file marker + iRfs.Delete(validateFile); + } +#endif // delete iHttpCacheObserver; + // must delete before eviction handler + delete iPostponeHandler; // if ( iEvictionHandler ) { @@ -187,7 +257,6 @@ #ifdef __CACHELOG__ HttpCacheUtil::WriteUrlToLog( 0, _L( "request item" ), aTrans.Request().URI().UriDes() ); #endif - TInt status( KErrNotFound ); CHttpCacheEntry* entry = NULL; // 0. check if we need to check cache at all (protected vs no cache mode) @@ -197,17 +266,18 @@ // use protected item on reload // currently not and do not use cache for post - if( aCacheMode != TBrCtlDefs::ECacheModeNoCache && - HttpCacheUtil::MethodFromStr( aTrans.Request().Method(), aTrans.Session().StringPool() ) != EMethodPost ) + if ( aCacheMode != TBrCtlDefs::ECacheModeNoCache && + HttpCacheUtil::MethodFromStr( aTrans.Request().Method(), aTrans.Session().StringPool() ) != EMethodPost ) { // If the cacheMode is noCache then it must ignore the cached entry. entry = iLookupTable->Find( aTrans.Request().URI().UriDes() ); + // check if the trailing slash is missing - if( !entry ) + if ( !entry ) { TUriC8 uri = aTrans.Request().URI(); - if( uri.Extract( EUriPath ).Length() == 0 ) + if ( uri.Extract( EUriPath ).Length() == 0 ) { CUri8* fixeduri = CUri8::NewLC( uri ); fixeduri->SetComponentL( _L8("/"), EUriPath ); @@ -218,39 +288,29 @@ } } // - if( entry && entry->State() == CHttpCacheEntry::ECacheComplete ) + if ( entry && entry->State() == CHttpCacheEntry::ECacheComplete ) { #ifdef __CACHELOG__ HttpCacheUtil::WriteLog( 0, _L( "item is in the cache" ) ); -#endif +#endif // status = CacheNeedsValidationL( *entry, aTrans, aCacheMode ) ? KErrNotReady : KErrNone; // entry could be invalidated at this point. check for status to make sure // the entry is still valid + } // prepare stream for request - if( status == KErrNone ) + if ( status == KErrNone ) { #ifdef __CACHELOG__ HttpCacheUtil::WriteLog( 0, _L( "prepare item for sending" ) ); #endif - // attach entry to the stream - if( iStreamHandler->AttachL( *entry ) ) - { - entry->SetState( CHttpCacheEntry::ECacheRequesting ); - entry->Accessed(); - } - else - { - // cleanup on the corrupt entry - DeleteCacheEntry( *entry ); - entry = NULL; - // item is not in cache - status = KErrNotFound; - } + // access the entry + entry->SetState( CHttpCacheEntry::ECacheRequesting ); + entry->Accessed(); } // cleanup - if( status == KErrNone && entry ) + if ( status == KErrNone && entry ) { // save handler and entry so that // on next call we don't have to start a lookup again @@ -270,14 +330,15 @@ #ifdef __CACHELOG__ else { - HttpCacheUtil::WriteLog( 0, _L( "reload: do not use cache" ) ); + HttpCacheUtil::WriteLog( 0, _L( "reload or post: do not use cache" ) ); } - if( status != KErrNone && entry ) + + if ( status != KErrNone && entry ) { - // HttpCacheUtil::WriteLog( 0, _L( "item needs validation" ) ); } - else + + if ( !entry ) { // HttpCacheUtil::WriteLog( 0, _L( "item is not in the cache" ) ); @@ -301,7 +362,7 @@ TInt status( KErrNotFound ); CHttpCacheEntry* entry = aCacheEntry.iCacheEntry; // - if( entry && entry->State() == CHttpCacheEntry::ECacheRequesting ) + if ( entry && entry->State() == CHttpCacheEntry::ECacheRequesting ) { // response headers should already have all the headers // as RequestL call adds them all. @@ -310,7 +371,7 @@ status = KErrNone; #ifdef __CACHELOG__ HttpCacheUtil::WriteLog( 0, _L( "sending http headers" ) ); -#endif +#endif } return status; } @@ -330,7 +391,7 @@ HBufC8* bodyStr = NULL; CHttpCacheEntry* entry = aCacheEntry.iCacheEntry; // - if( entry && entry->State() == CHttpCacheEntry::ECacheRequesting ) + if ( entry && entry->State() == CHttpCacheEntry::ECacheRequesting ) { // get next chunk bodyStr = iStreamHandler->NextChunkL( *entry, aLastChunk ); @@ -361,14 +422,12 @@ if ( entry->State() == CHttpCacheEntry::ECacheRequesting ) { entry->SetState( CHttpCacheEntry::ECacheComplete ); - iStreamHandler->Detach( *entry ); } // transaction is closed without being completed else if ( entry->State() == CHttpCacheEntry::ECacheResponding || entry->State() == CHttpCacheEntry::ECacheDestroyed ) { // remove uncompleted/destroyed entry - iStreamHandler->Detach( *entry ); DeleteCacheEntry( *entry ); entry = NULL; aCacheEntry.iCacheEntry = NULL; @@ -462,30 +521,30 @@ TBool protectedEntry( EFalse ); // check if the item is cacheable // no item should be bigger than the 1/3 of the cache size - if( HttpCacheUtil::IsCacheable( aTrans, ( iSize / 3 ), protectedEntry ) ) + if ( HttpCacheUtil::IsCacheable( aTrans, ( iSize / 3 ), protectedEntry ) ) { // check if the entry is already in the cache CHttpCacheEntry* entry = iLookupTable->Find( aTrans.Request().URI().UriDes() ); - if( entry ) + if ( entry ) { #ifdef __CACHELOG__ - HttpCacheUtil::WriteLogFilenameAndUrl( 0, + HttpCacheUtil::WriteLogFilenameAndUrl( 0, _L("CHttpCacheHandler::ReceivedResponseHeadersL"), entry->Filename(), entry->Url(), - entry->BodySize(), + entry->BodySize(), ELogEntrySize ); #endif - if( entry->State() != CHttpCacheEntry::ECacheComplete ) + if ( entry->State() != CHttpCacheEntry::ECacheComplete ) { // multiple incoming entries doh. #ifdef __CACHELOG__ - HttpCacheUtil::WriteLogFilenameAndUrl( 0, + HttpCacheUtil::WriteLogFilenameAndUrl( 0, _L("CHttpCacheHandler::ReceivedResponseHeadersL - ERROR MULTIPLE requests"), entry->Filename(), entry->Url(), - entry->BodySize(), + entry->BodySize(), ELogEntrySize ); #endif // ignore this one and the first will proceed. @@ -501,17 +560,17 @@ AdjustResponseTime( aTrans ); // hash it entry = iLookupTable->InsertL( aTrans.Request().URI().UriDes() ); - if( entry ) + if ( entry ) { // protect this entry - if( protectedEntry ) + if ( protectedEntry ) { #ifdef __CACHELOG__ - HttpCacheUtil::WriteLogFilenameAndUrl( 0, + HttpCacheUtil::WriteLogFilenameAndUrl( 0, _L("CHttpCacheHandler::ReceivedResponseHeadersL - this is protected item"), entry->Filename(), entry->Url(), - entry->BodySize(), + entry->BodySize(), ELogEntrySize ); #endif entry->SetProtected(); @@ -528,46 +587,37 @@ __ASSERT_DEBUG( EFalse, PanicCacheHandler( KErrCorrupt ) ); } } + // save headers - if( entry ) + if ( entry ) { - // attach it to the stream handler - if( iStreamHandler->AttachL( *entry ) ) - { - entry->SetState( CHttpCacheEntry::ECacheResponding ); - // 1. handle only 304 and 200 - // 2. check if either the header or the body ( or both ) need to be updated - // 3. update the headers anyway in case of notmodified (304) - // 4. remove the old body in case of bodyupdate - TInt httpStatus( aTrans.Response().StatusCode() ); + entry->SetState( CHttpCacheEntry::ECacheResponding ); + // 1. handle only 304 and 200 + // 2. check if either the header or the body ( or both ) need to be updated + // 3. update the headers anyway in case of notmodified (304) + // 4. remove the old body in case of bodyupdate + TInt httpStatus( aTrans.Response().StatusCode() ); #ifdef __CACHELOG__ - HttpCacheUtil::WriteLog( 0, _L("CHttpCacheHandler::ReceivedResponseHeadersL - status code ="), httpStatus ); + HttpCacheUtil::WriteLog( 0, _L("CHttpCacheHandler::ReceivedResponseHeadersL - status code ="), httpStatus ); #endif - TBool ok( EFalse ); - if( httpStatus == HTTPStatus::EOk ) - { - ok = HandleResponseOkL( *entry, aTrans ); - } - else if( httpStatus == HTTPStatus::ENotModified ) - { - ok = HandleResponseNotModifiedL( *entry, aTrans ); - } + TBool ok( EFalse ); + if ( httpStatus == HTTPStatus::EOk ) + { + ok = HandleResponseOkL( *entry, aTrans ); + } + else if ( httpStatus == HTTPStatus::ENotModified ) + { + ok = HandleResponseNotModifiedL( *entry, aTrans ); + } - // entry could be corrupted at this point - if( ok ) - { - // save handler and entry so that - // on next call we don't have to start a lookup again - aCacheEntry.iCacheHandler = this; - aCacheEntry.iCacheEntry = entry; - } - else - { - iStreamHandler->Detach( *entry ); - DeleteCacheEntry( *entry ); - entry = NULL; - } + // entry could be corrupted at this point + if ( ok ) + { + // save handler and entry so that + // on next call we don't have to start a lookup again + aCacheEntry.iCacheHandler = this; + aCacheEntry.iCacheEntry = entry; } else { @@ -602,23 +652,22 @@ HttpCacheUtil::WriteLog( 0, _L("---> CHttpCacheHandler::ReceivedResponseBodyDataL"), entry->BodySize() ); #endif HBufC8* bodyStr = HttpCacheUtil::BodyToBufferL( aBodyDataSupplier ); - if ( bodyStr ) + if( bodyStr ) { // Do we have old body data to remove first if ( entry->BodyFileDeleteNeeded() ) { iStreamHandler->RemoveBodyData( *entry ); entry->SetBodyFileDeleteNeeded( EFalse ); - } - + } + // erase entry if we are unable to save it (low disk space) - if( !SaveBuffer( *entry, bodyStr->Des(), ETrue ) ) + if ( !SaveBuffer( *entry, bodyStr->Des(), ETrue ) ) { - // detach it from the stream and erase it - iStreamHandler->Detach( *entry ); + // erase it DeleteCacheEntry( *entry ); -#ifdef __CACHELOG__ +#ifdef __CACHELOG__ HttpCacheUtil::WriteLog( 0, _L( "CHttpCacheHandler::ReceivedResponseBodyDataL - body cannot be saved" ) ); -#endif +#endif entry = NULL; // remove entry aCacheEntry.iCacheEntry = NULL; @@ -663,32 +712,59 @@ if ( entry->State() == CHttpCacheEntry::ECacheResponding ) { - // Flush the entry - if ( !iStreamHandler->Flush( *entry ) ) + TBool postponed( EFalse ); + // flush the entry if necessary + if ( iPostponeHandler ) { - // We failed saving (flush), cleanup - iStreamHandler->Detach( *entry ); + CHttpCacheFileWriteHandler::TAddStatus addStatus; + TInt err = iPostponeHandler->AddEntry( addStatus, entry ); - // Deleting the entry frees cache buffer - DeleteCacheEntry( *entry ); - entry = NULL; - aCacheEntry.iCacheEntry = NULL; + switch ( addStatus ) + { + case CHttpCacheFileWriteHandler::EAddedOk: + entry->SetState( CHttpCacheEntry::ECacheComplete ); + postponed = ETrue; +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog( 0, _L(" Added object to postpone list.")); +#endif + break; + case CHttpCacheFileWriteHandler::EBodySmallerThanThreshold: +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog( 0, _L(" Not postponed. EBodySmallerThanThreshold")); +#endif + break; + case CHttpCacheFileWriteHandler::ENotEnoughFreeMemory: +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog( 0, _L(" Not postponed. ENotEnoughFreeMemory")); +#endif + break; + case CHttpCacheFileWriteHandler::ECheckReturn: +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog( 0, _L(" Not postponed. ECheckReturn - %d"), err ); +#endif + default: + break; + } } - else + + if ( !postponed ) { - // We successfully saved (flush) body - entry->SetState( CHttpCacheEntry::ECacheComplete ); - iStreamHandler->Detach( *entry ); - - // Clear the flushed cache buffer, we were using for incoming body - TRAP_IGNORE( entry->SetCacheBufferL( KBufferSizeZero ) ); + if ( !iStreamHandler->Flush( *entry ) ) + { + // remove entry + DeleteCacheEntry( *entry ); + entry = NULL; + aCacheEntry.iCacheEntry = NULL; + } + else + { + // We successfully saved (flushed) body + entry->SetState( CHttpCacheEntry::ECacheComplete ); + } } } - else if( entry->State() == CHttpCacheEntry::ECacheDestroyed ) + else if ( entry->State() == CHttpCacheEntry::ECacheDestroyed ) { - iStreamHandler->Detach( *entry ); - - // Deleting the entry frees cache buffer DeleteCacheEntry( *entry, EFalse ); entry = NULL; aCacheEntry.iCacheEntry = NULL; @@ -697,7 +773,7 @@ } // ----------------------------------------------------------------------------- -// Removes all entries in the Cache lookup table, commits table to disk. +// Removes all entries in the Cache lookup table, commits table to disk. // // ----------------------------------------------------------------------------- // @@ -707,8 +783,16 @@ HttpCacheUtil::WriteLog( 0, _L( "remove all items" ) ); #endif TInt numberOfBytes; + + // by definition, all entries in the postpone handler aren't active. + if ( iPostponeHandler ) + { + iPostponeHandler->RemoveAll(); + } + // clear all the inactive entries numberOfBytes = iLookupTable->RemoveAll(); + // and save it. user initiated. no need to do idle save SaveLookupTableL(); return numberOfBytes; @@ -778,27 +862,26 @@ TBool saved( EFalse ); // check if entry exist. do not overwrite. CHttpCacheEntry* entry = iLookupTable->Find( aUrl ); - if( !entry ) + if ( !entry ) { entry = iLookupTable->InsertL( aUrl ); // prepare for saving - if( entry && iStreamHandler->AttachL( *entry ) ) + if ( entry ) { // save header and body saved = SaveBuffer( *entry, aHeader, EFalse ) && SaveBuffer( *entry, aContent, ETrue ); - if( saved ) + if ( saved ) { // flush saved = iStreamHandler->Flush( *entry ); - if( saved ) + if ( saved ) { entry->SetState( CHttpCacheEntry::ECacheComplete ); } } - iStreamHandler->Detach( *entry ); } // cleanup - if( !saved && entry ) + if ( !saved && entry ) { DeleteCacheEntry( *entry ); } @@ -819,24 +902,21 @@ TInt status( KErrNotFound ); // CHttpCacheEntry* entry = iLookupTable->Find( aUrl ); - if( entry ) + if ( entry ) { - TBool attached; - // - attached = iStreamHandler->AttachL( *entry ); // get headers HBufC8* headersStr = iStreamHandler->HeadersL( *entry ); - if( headersStr ) + if ( headersStr ) { CleanupStack::PushL( headersStr ); // alter headers and save them HBufC8* newHeaderStr = HttpCacheUtil::AddHeaderLC( aName, aValue, headersStr->Des() ); - if( newHeaderStr ) + if ( newHeaderStr ) { // remove old headers first iStreamHandler->RemoveHeaders( *entry ); // save new headers - if( !SaveBuffer( *entry, newHeaderStr->Des(), EFalse ) ) + if ( !SaveBuffer( *entry, newHeaderStr->Des(), EFalse ) ) { status = KErrDirFull; // failed. should we save the original headers? @@ -844,10 +924,9 @@ // original save should never fail __ASSERT_DEBUG( saveOk, PanicCacheHandler( KErrCorrupt ) ); - if( !saveOk ) + if ( !saveOk ) { // sorry, we made this entry corrupt. remove it - iStreamHandler->Detach( *entry ); DeleteCacheEntry( *entry ); entry = NULL; } @@ -860,11 +939,6 @@ } CleanupStack::PopAndDestroy(); // headersStr } - // detach - if( attached ) - { - iStreamHandler->Detach( *entry ); - } } return status; } @@ -891,75 +965,65 @@ // been validated -- that is when it tries to refetch an entry from // cache after receiving a 304 response. // get cached headers - if( iStreamHandler->AttachL( aCacheEntry ) ) + HBufC8* headersStr = iStreamHandler->HeadersL( aCacheEntry ); + CleanupStack::PushL( headersStr ); + // headersStr == NULL happens if you erase the cache directory + // using a file manager + if ( headersStr ) { - HBufC8* headersStr = iStreamHandler->HeadersL( aCacheEntry ); - CleanupStack::PushL( headersStr ); - iStreamHandler->Detach( aCacheEntry ); - // headersStr == NULL happens if you erase the cache directory - // using a file manager - if( headersStr ) + // use response headers for retreiving cached headers + RHTTPHeaders responseHeaders = aTrans.Response().GetHeaderCollection(); + RHTTPHeaders requestHeaders = aTrans.Request().GetHeaderCollection(); + RStringPool strP = aTrans.Session().StringPool(); + // convert the buffer to httpHeader + HttpCacheUtil::BufferToHeadersL( headersStr->Des(), responseHeaders, strP ); + + // check if we need to validate the cahce + if ( aCacheMode == TBrCtlDefs::ECacheModeOnlyCache || aCacheMode == TBrCtlDefs::ECacheModeHistory ) { - // use response headers for retreiving cached headers - RHTTPHeaders responseHeaders = aTrans.Response().GetHeaderCollection(); - RHTTPHeaders requestHeaders = aTrans.Request().GetHeaderCollection(); - RStringPool strP = aTrans.Session().StringPool(); - // convert the buffer to httpHeader - HttpCacheUtil::BufferToHeadersL( headersStr->Des(), responseHeaders, strP ); - - // check if we need to validate the cahce - if( aCacheMode == TBrCtlDefs::ECacheModeOnlyCache || aCacheMode == TBrCtlDefs::ECacheModeHistory ) + // no validation required +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog( 0, _L( "prefer cache mode. no need to revalidate" ), aCacheMode ); +#endif + mustRevalidate = EFalse; + } + else + { + // Get the pragma no-cache header from the headers + // no-cache on request header means "do not use cache" + if ( !HttpCacheUtil::PragmaNoCache( aTrans ) ) { - // no validation required + if ( !HttpCacheUtil::CacheTimeIsFresh( requestHeaders, responseHeaders, strP ) ) + { #ifdef __CACHELOG__ - HttpCacheUtil::WriteLog( 0, _L( "prefer cache mode. no need to revalidate" ), aCacheMode ); -#endif - mustRevalidate = EFalse; + HttpCacheUtil::WriteLog( 0, _L( "cache item is not fresh. needs revalidation" ) ); +#endif + // Avoid removing cache entry here + mustRevalidate = ETrue; + // add headers like EIfModifiedSince, EETag, EIfNoneMatch + HttpCacheUtil::AddValidationHeaders( responseHeaders, requestHeaders, strP ); + } + else + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog( 0, _L( "cache item is fresh. needs no revalidation" ) ); +#endif + // + mustRevalidate = EFalse; + } } else { - // Get the pragma no-cache header from the headers - // no-cache on request header means "do not use cache" - if( !HttpCacheUtil::PragmaNoCache( aTrans ) ) - { - if( !HttpCacheUtil::CacheTimeIsFresh( requestHeaders, responseHeaders, strP ) ) - { + // needs validation #ifdef __CACHELOG__ - HttpCacheUtil::WriteLog( 0, _L( "cache item is not fresh. needs revalidation" ) ); + HttpCacheUtil::WriteLog( 0, _L( "no cache/no store header present. need revalidation" ) ); #endif - // MKLE-7PRD27: Avoid removing cache entry here - mustRevalidate = ETrue; - // add headers like EIfModifiedSince, EETag, EIfNoneMatch - HttpCacheUtil::AddValidationHeaders( responseHeaders, requestHeaders, strP ); - } - else - { -#ifdef __CACHELOG__ - HttpCacheUtil::WriteLog( 0, _L( "cache item is fresh. needs no revalidation" ) ); -#endif - // - mustRevalidate = EFalse; - } - } - else - { - // needs validation -#ifdef __CACHELOG__ - HttpCacheUtil::WriteLog( 0, _L( "no cache/no store header present. need revalidation" ) ); -#endif - mustRevalidate = ETrue; - } - + mustRevalidate = ETrue; } } - CleanupStack::PopAndDestroy(); // headersStr } - else - { - DeleteCacheEntry( aCacheEntry ); - // needs validation - mustRevalidate = ETrue; - } + CleanupStack::PopAndDestroy(); // headersStr + return mustRevalidate; } @@ -987,10 +1051,10 @@ HttpCacheUtil::WriteLog( 0, _L( "cached items" ) ); const CArrayPtrFlat& entries = iLookupTable->Entries(); - for( TInt i = 0; i < entries.Count(); i++ ) + for ( TInt i = 0; i < entries.Count(); i++ ) { CHttpCacheEntry* entry = entries.At( i ); - if( entry && entry != (CHttpCacheEntry*)0xffffffff ) + if ( entry && entry != (CHttpCacheEntry*)0xffffffff ) { HttpCacheUtil::WriteUrlToLog( 0, entry->Url(), entry->BodySize() ); size += entry->BodySize(); @@ -1003,40 +1067,28 @@ CArrayPtrFlat* evictedList = iEvictionHandler->EvictL( aSize ); if ( evictedList && evictedList->Count() ) { - // Delete entry items marked for eviction + // destroy items CHttpCacheEntry* entry; for ( TInt i = 0; i < evictedList->Count(); i++ ) { + // entry = evictedList->At( i ); - if ( entry ) { - // Handle removing valid and invalid entries. Check entry - // for validity, and if in lookup table. It has been - // found that the evictList can have invalid entries in it. - // These invalid entries are not in the lookup table. - TInt lookupTableIndex( -1 ); - iLookupTable->FindCacheEntryIndex( *entry, &lookupTableIndex ); - - TInt sizeBody = entry->BodySize(); - if ( sizeBody == 0 && lookupTableIndex >= 0 ) + if ( iPostponeHandler ) { - // This is an empty body cache entry that exists - // in the lookup table, remove it from file system and - // lookup table. - // Use CreateNewFilesL() to open file handles, so we can delete - // the files associated with the cache entry. We don't check - // return value of RemoveByPosition(), because we already - // checked for index in FindCacheEntryIndex(). - iStreamHandler->CreateNewFilesL( *entry ); - iStreamHandler->EraseCacheFile( *entry ); - iLookupTable->RemoveByPosition( lookupTableIndex ); + iPostponeHandler->RemoveEntry( entry ); } - else if ( lookupTableIndex >= 0 ) - { - // Remove valid entries that are found in lookup table - iLookupTable->Remove( entry->Url() ); - } + + // when an item is destroyed, it will attempt to remove itself from the lookup table which will fail and panic + // because EvictL already removed it. + // In this scenario, we need to tell the item that it's no longer a candidate to prevent that. + // we don't want to make lookuptable::remove do that though, because this only applies when we are removing + // an item because of eviction and NOT for any other reason. + entry->UnsetEvictionCandidate(); + + // destroy + iLookupTable->Remove( entry->Url() ); } } @@ -1050,11 +1102,9 @@ // or the incoming -not yet complete- items take the entire cache? #ifdef __CACHELOG__ HttpCacheUtil::WriteLog( 0, _L( "NO SPACE can be released!!!" ) ); -#endif +#endif ok = EFalse; } - - // Cleanup the evicted list, including any invalid entries delete evictedList; } return ok; @@ -1077,7 +1127,7 @@ TBool update( ETrue ); // get cached headers to compare HBufC8* cachedHeaderStr = iStreamHandler->HeadersL( aEntry ); - + // we've got some headers to update, check if we really need to update them if ( cachedHeaderStr ) { @@ -1095,7 +1145,7 @@ _L("CHttpCacheHandler::HandleResponseOkL - cache UPDATE needed"), aEntry.Filename(), aEntry.Url(), - aEntry.BodySize(), + aEntry.BodySize(), ELogEntrySize ); #endif if ( aEntry.HeaderSize() ) @@ -1106,27 +1156,22 @@ // save new headerFile saveOk = SaveBuffer( aEntry, responseHeaderStr->Des() ); - + if ( aEntry.BodySize() ) { // We will remove this body data, after we confirm that we get new // body data aEntry.SetBodyFileDeleteNeeded( ETrue ); } - - // Setup a cache buffer to hold the incoming body - aEntry.SetCacheBufferL( KBufferSize32k ); } else { - // if neither the header nor the body need to be updated, then - // detach entry to protect from being updated + // neither the header nor the body need to be updated #ifdef __CACHELOG__ HttpCacheUtil::WriteLog( 0, _L( "CHttpCacheHandler::HandleResponseOkL - no update needed, ignore response" ) ); -#endif +#endif // aEntry.SetState( CHttpCacheEntry::ECacheComplete ); - iStreamHandler->Detach( aEntry ); // pretend that save was ok. saveOk = ETrue; } @@ -1146,7 +1191,7 @@ CHttpCacheEntry& aEntry, RHTTPTransaction& aTrans ) { - // oos? -out of space + // Are we out of space ? TBool saveOk( ETrue ); RHTTPHeaders responseHeader = aTrans.Response().GetHeaderCollection(); RStringPool strP = aTrans.Session().StringPool(); @@ -1156,30 +1201,31 @@ HBufC8* mergedHeadersStr = NULL; HBufC8* cachedHeaderStr = iStreamHandler->HeadersL( aEntry ); CleanupStack::PushL( cachedHeaderStr ); + // don't merge with empty headers - if( cachedHeaderStr ) + if ( cachedHeaderStr ) { mergedHeadersStr = HttpCacheUtil::MergeHeadersLC( cachedHeaderStr->Des(), responseHeader, strP ); CleanupStack::Pop(); // mergedHeadersStr } // don't update empty headers - if( mergedHeadersStr || responseHeaderStr ) + if ( mergedHeadersStr || responseHeaderStr ) { // remove cached headers first iStreamHandler->RemoveHeaders( aEntry ); // save merged headers (reponse + cached) - if( mergedHeadersStr ) + if ( mergedHeadersStr ) { saveOk = SaveBuffer( aEntry, mergedHeadersStr->Des() ); } - else if( responseHeaderStr ) + else if ( responseHeaderStr ) { // save responseheader instead saveOk = SaveBuffer( aEntry, responseHeaderStr->Des() ); } // if save failed, let's see if we can save old // headers - if( !saveOk && cachedHeaderStr ) + if ( !saveOk && cachedHeaderStr ) { saveOk = SaveBuffer( aEntry, cachedHeaderStr->Des() ); } @@ -1189,12 +1235,13 @@ CleanupStack::PopAndDestroy( 2 ); // cachedHeaderStr, responseHeaderStr // check if save was ok. // or nothing was not saved at all - if( saveOk ) + if ( saveOk ) { // this item does not need update aEntry.SetState( CHttpCacheEntry::ECacheComplete ); - iStreamHandler->Detach( aEntry ); + //iStreamHandler->Detach( aEntry ); } + return saveOk; } @@ -1205,48 +1252,87 @@ // void CHttpCacheHandler::OpenLookupTableL() { - OpenLookupTableL(iLookupTable); + OpenLookupTableL( iLookupTable ); } // ----------------------------------------------------------------------------- // CHttpCacheHandler::OpenLookupTableL -// Opens the index*.dat lookup table from file system. +// Opens the index*.dat lookup table from file system. // ----------------------------------------------------------------------------- // void CHttpCacheHandler::OpenLookupTableL(CHttpCacheLookupTable* aLookupTable) { +#if 0 // read entries from index.dat RFileReadStream readStream; - iRfs.SetSessionPath( iDirectory->Des() ); + iRfs.SetSessionPath( iDirectory->Des() ); - TInt ret = KErrNone; - TInt tryCount = 0; - for (tryCount = 0; tryCount < 5; tryCount++) + TInt ret = KErrNone; + TInt tryCount = 0; + for (tryCount = 0; tryCount < 5; tryCount++) + { + ret = readStream.Open( iRfs, iIndexFile->Des(), EFileRead | EFileShareAny ); + if (ret == KErrInUse) + { + // When the cache is full, it takes 65 - 85 miliseconds to write the index. + // So wait 50 miliseconds and try again + User::After(50000); + } + else { - ret = readStream.Open( iRfs, iIndexFile->Des(), EFileRead | EFileShareAny ); - if (ret == KErrInUse) - { - // When the cache is full, it takes 65 - 85 miliseconds to write the index. - // So wait 50 miliseconds and try again - User::After(50000); - } - else - { - break; - } + break; + } + } + if( ret == KErrNone ) + { + CleanupClosePushL( readStream ); + aLookupTable->InternalizeL( readStream, iDirectory->Des() ); + CleanupStack::PopAndDestroy(1); // readStream + } +#else + RFile readFile; + iRfs.SetSessionPath( iDirectory->Des() ); + + TInt ret = KErrNone; + TInt tryCount = 0; + for (tryCount = 0; tryCount < 5; tryCount++) + { + ret = readFile.Open( iRfs, iIndexFile->Des(), EFileRead | EFileShareAny ); + if (ret == KErrInUse) + { + // When the cache is full, it takes 65 - 85 miliseconds to write the index. + // So wait 50 miliseconds and try again + User::After(50000); } - if( ret == KErrNone ) + else + { + break; + } + } + + if ( ret == KErrNone ) + { + CleanupClosePushL(readFile); + TInt size; + readFile.Size(size); + + if ( size ) { - TRAPD ( err, aLookupTable->InternalizeL( readStream, iDirectory->Des() ) ); - readStream.Close(); - if ( err != KErrNone ) - { - // In case Bad Things Happen (TM), do RemoveAllL() which clears this cache's - // in-memory data structures + saves an updated lookup table to disk replacing the old one. - TRAP_IGNORE( RemoveAllL() ); - } + HBufC8* buffer = HBufC8::NewLC(size); + TPtr8 buf( buffer->Des() ); + User::LeaveIfError( readFile.Read(buf, size) ); + RDesReadStream readStream( buf ); + CleanupClosePushL(readStream); + aLookupTable->InternalizeL( readStream, iDirectory->Des() ); + CleanupStack::PopAndDestroy(3); // read stream, buffer then file } + else + { + CleanupStack::PopAndDestroy(1); // close the file. + } + } +#endif } // ----------------------------------------------------------------------------- @@ -1263,12 +1349,10 @@ RFileWriteStream writeStream; // Don't get notified about own changes - if ( iHttpCacheObserver ) - iHttpCacheObserver->Cancel(); - + iHttpCacheObserver->Cancel(); TInt ret = KErrNone; TInt tryCount = 0; - for (tryCount = 0; tryCount < 5; tryCount++) + for (tryCount = 0; tryCount < 5; tryCount++) { ret = writeStream.Replace( iRfs, iIndexFile->Des(), EFileWrite ); if (ret == KErrInUse) @@ -1282,16 +1366,14 @@ break; } } - if( ret == KErrNone ) + if ( ret == KErrNone ) { CleanupClosePushL( writeStream ); - iLookupTable->ExternalizeL( writeStream ); + iLookupTable->ExternalizeL( writeStream , iDirectory->Des() ); writeStream.CommitL(); CleanupStack::PopAndDestroy(); // writeStream } - - if ( iHttpCacheObserver ) - iHttpCacheObserver->StartObserver(); + iHttpCacheObserver->StartObserver(); } // ----------------------------------------------------------------------------- @@ -1300,27 +1382,26 @@ // ----------------------------------------------------------------------------- // void CHttpCacheHandler::DeleteCacheEntry( - CHttpCacheEntry& aEntry, + CHttpCacheEntry& aStrayEntry, TBool aUpdate ) { - // suppress compiler and PC-lint warnings - (void)aUpdate; - + (void)aUpdate;//suppress compiler and PC-lint warnings #ifdef __CACHELOG__ - HttpCacheUtil::WriteLogFilenameAndUrl( 0, - _L("CHttpCacheHandler::DeleteCacheEntry"), - aEntry.Filename(), - aEntry.Url(), - aEntry.BodySize(), - ELogEntrySize ); + HttpCacheUtil::WriteLog( 0, _L( "delete this stray entry" ) ); #endif - // Remove from the lookuptable - iLookupTable->EraseCacheEntry( aEntry.Url() ); + // need to make sure this entry is removed from postpone handler, if it might be there. + if ( iPostponeHandler ) + { + iPostponeHandler->RemoveEntry( &aStrayEntry ); + } + + // remove from the lookuptable + iLookupTable->EraseCacheEntry( aStrayEntry.Url() ); } // ----------------------------------------------------------------------------- -// There used to be a CHttpCacheHandler::FixLookupTableL here. +// There used to be a CHttpCacheHandler::FixLookupTableL here. // Go back in SVN to re-discover it :) // // ----------------------------------------------------------------------------- @@ -1336,7 +1417,7 @@ TBool aBody ) { TBool ok( EFalse ); - + TRAPD( err, ok = CacheNeedsSpaceL( aBuffer.Length() ) ); if ( err == KErrNone && ok ) { @@ -1350,10 +1431,10 @@ HttpCacheUtil::WriteUrlToLog( 0, _L( "item cannot be saved. remove it please" ), aEntry.Url() ); } #endif // __CACHELOG__ + return ok; } - // ----------------------------------------------------------------------------- // CHttpCacheHandler::UpdateLookupTable // @@ -1362,14 +1443,12 @@ void CHttpCacheHandler::UpdateLookupTable() { TRAP_IGNORE(UpdateLookupTableL()); - - if ( iHttpCacheObserver ) - iHttpCacheObserver->StartObserver(); + iHttpCacheObserver->StartObserver(); } // ----------------------------------------------------------------------------- // CHttpCacheHandler::UpdateLookupTableL -// Slow method due to much file-system interaction. Don't call it from performance critical code. +// Slow method due to much file-system interaction. Don't call it from performance critical code. // ----------------------------------------------------------------------------- // void CHttpCacheHandler::UpdateLookupTableL() @@ -1380,6 +1459,410 @@ CleanupStack::PushL(lookupTable); OpenLookupTableL(lookupTable); iLookupTable->MergeL(lookupTable, iRfs); - CleanupStack::PopAndDestroy(2); // lookupTable, evictionHandler + CleanupStack::PopAndDestroy(2); // lookupTable, evictionHandler + } + +// ----------------------------------------------------------------------------- +// CHttpCacheHandler::GenerateValidationFilename +// ----------------------------------------------------------------------------- +// +#ifdef __USE_VALIDATION_FILES__ + void CHttpCacheHandler::GenerateValidationFilename(TDes& aFilename, const TDesC& aIndexFilename) const +#else + void CHttpCacheHandler::GenerateValidationFilename(TDes& /*aFilename*/, const TDesC& /*aIndexFilename*/) const +#endif + { +#ifdef __USE_VALIDATION_FILES__ + _LIT(KValidationExtension, ".val"); + TParse filenameParser; + filenameParser.Set(aIndexFilename, NULL, NULL); + aFilename.Copy(filenameParser.DriveAndPath()); + aFilename.Append(filenameParser.Name()); + aFilename.Append(KValidationExtension); +#else + PanicCacheHandler(KErrNotSupported); +#endif + } + +// ----------------------------------------------------------------------------- +// DestroyBadUrlArray +// ----------------------------------------------------------------------------- +// +static void DestroyBadUrlArray(TAny* aPtr) + { + RPointerArray *tmp = (RPointerArray*)aPtr; + tmp->ResetAndDestroy(); + } + +// ----------------------------------------------------------------------------- +// CHttpCacheHandler::ValidateCacheEntriesL +// ----------------------------------------------------------------------------- +// +void CHttpCacheHandler::ValidateCacheEntriesL() + { + // iterate through entries and check if file is present. + // if not, add URL to a list of bad ones otherwise remove directory entry from list + // at the end, go through list of bad entries and remove them from cache, + // go through list of unreferenced files and delete them too. + THttpCacheLookupTableEntryIterator iter; + iLookupTable->BeginEntryIteration(iter); +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog(0, _L("CHttpCacheHandler::ValidateCacheEntriesL")); +#endif + // if the cache contains no items, we should still do this so we detect other files. + + // get list of files on disk + CCacheDirectoryFiles *dirFiles = CCacheDirectoryFiles::NewLC(iRfs, *iDirectory); + + // look for bad entries + RPointerArray badEntries; + CleanupStack::PushL(TCleanupItem(DestroyBadUrlArray, &badEntries)); + const CHttpCacheEntry *tmpEntry; + while(tmpEntry = iLookupTable->NextEntry(iter), tmpEntry) + { + if(!dirFiles->ValidateEntryL(*tmpEntry)) + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteUrlToLog(0, _L("Bad Entry: "), tmpEntry->Url() ); +#endif + badEntries.AppendL(tmpEntry->Url().AllocL()); + } + } + + // remove bad entries + for(TInt i=0; i < badEntries.Count(); i++) + { + iLookupTable->Remove(badEntries[i]->Des()); + } + CleanupStack::PopAndDestroy(1); // bad entry list + + // remove orphan files + dirFiles->RemoveLeftoverFilesL(); + CleanupStack::PopAndDestroy(dirFiles); + } + +// ----------------------------------------------------------------------------- +// CCacheDirectoryFiles::NewL +// ----------------------------------------------------------------------------- +// +CCacheDirectoryFiles* CCacheDirectoryFiles::NewL(RFs aRfs, const TDesC& aDir) + { + CCacheDirectoryFiles* me = CCacheDirectoryFiles::NewLC(aRfs, aDir); + CleanupStack::Pop(me); + return me; + } + +// ----------------------------------------------------------------------------- +// CCacheDirectoryFiles::NewLC +// ----------------------------------------------------------------------------- +// +CCacheDirectoryFiles* CCacheDirectoryFiles::NewLC(RFs aRfs, const TDesC& aDir) + { + CCacheDirectoryFiles *me = new (ELeave) CCacheDirectoryFiles(aRfs, aDir); + CleanupStack::PushL(me); + me->ConstructL(); + return me; + } + +// ----------------------------------------------------------------------------- +// CCacheDirectoryFiles::ValidateEntryL +// ----------------------------------------------------------------------------- +// +TBool CCacheDirectoryFiles::ValidateEntryL(const CHttpCacheEntry& aEntry) + { + // check the files associated with the cache entry are present where they should be + // if the file is present, then remove it from the dir list + // if the file is present AND the size matches the entry, then return ETrue in aPresentAndValid + // otherwise, return EFalse there. + TBool presentAndValid = EFalse; + + TParse tmpParse; + tmpParse.Set(aEntry.Filename(), NULL, NULL); + // for this file to be part of the cache it must meet the following rules.. + // length of name is 8 chars + if(tmpParse.Name().Length() != 8) + return presentAndValid; + + // this filename has a chance of existing and we can assume correct format from now on + TUint32 cacheUintName; + if(TCompressedEntry::ConvertANameToUint32(tmpParse.Name(), cacheUintName)) + { + TInt arrayIndex = cacheUintName & 0x0000000F; + presentAndValid = iDirContent[arrayIndex]->ValidateCacheEntryL( aEntry ); + } + // after all cache entries have been checked against the list, it should only contain orphaned files + // files which match but are corrupt will have been removed from this list + // however they should be cleaned up when the 'corrupt' entries are removed at a later date. + return presentAndValid; + } + +// ----------------------------------------------------------------------------- +// CCacheDirectoryFiles::RemoveLeftoverFilesL +// ----------------------------------------------------------------------------- +// +void CCacheDirectoryFiles::RemoveLeftoverFilesL() + { + // delete all the files which are still listed. + TFileName tempFilename; + for (TInt subDir=0; subDir < 16; subDir++) + { + for (TInt fileIdx = 0; fileIdx < iDirContent[subDir]->Count(); fileIdx++ ) + { + // each file needs to have the full path prepended in order to delete + HBufC *name = iDirContent[subDir]->NameAtL(fileIdx); + tempFilename.Format(_L("%S%x\\%S"), &iDir, subDir, name); +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("Deleting file %S"), &tempFilename); +#endif + iRfs.Delete(tempFilename); + delete name; + } + } + } + +// ----------------------------------------------------------------------------- +// CCacheDirectoryFiles::~CCacheDirectoryFiles +// ----------------------------------------------------------------------------- +// +CCacheDirectoryFiles::~CCacheDirectoryFiles() + { + iDirContent.ResetAndDestroy(); + } + +// ----------------------------------------------------------------------------- +// CCacheDirectoryFiles::ConstructL +// ----------------------------------------------------------------------------- +// +void CCacheDirectoryFiles::ConstructL() + { + CDir* baseDirs; + User::LeaveIfError(iRfs.GetDir(iDir,KEntryAttDir,ESortByName,baseDirs)); + CleanupStack::PushL(baseDirs); + + // we know that the cache format is a single letter directory from 0-f + // so we ignore any other directories - they might belong to other caches + // and our cache will not have written any files out into anywhere except the + // 0-f dirs, even if we lost track of something. + // See HttpCacheUtil::GenerateNameLC + iDirContent.ReserveL(16); + + TInt numdirs = baseDirs->Count(); + // storage for + '0/' + HBufC* currentDir = HBufC::NewLC( iDir.Length() + KSubdirNameLength ); + for(TInt i=0; i < numdirs; i++) + { + TInt arrayIndex = -1; + const TEntry& entry = (*baseDirs)[i]; + if(entry.IsDir() && entry.iName.Length()==1) + { + TUint16 chr = *(entry.iName.Right(1).Ptr()); + arrayIndex = TCompressedEntry::ConvertAsciiToIntSingleHexDigit(chr); + } + + if(arrayIndex >=0 && arrayIndex <= 15) + { + // initialise subdir name to base directory + currentDir->Des().Copy(iDir); + currentDir->Des().AppendFormat(_L("%x\\"), arrayIndex); // if base path wasn't terminated with trailing / we would have blown up at creation time. + + // get subdirectory content + CDir *dir; + iRfs.GetDir(currentDir->Des(), KEntryAttMatchExclude | KEntryAttDir, ESortByName, dir); // only files this time... + if(dir) + { + iDirContent.Insert( CCustomCacheDirList::NewL( dir ), arrayIndex ); + } + delete dir; + } + } + CleanupStack::PopAndDestroy(2); // baseDirs & currentDir + } + +// ----------------------------------------------------------------------------- +// CCustomCacheDirList::NewL +// ----------------------------------------------------------------------------- +// +CCustomCacheDirList* CCustomCacheDirList::NewL(CDir *aSrc) + { + CCustomCacheDirList *me = new (ELeave) CCustomCacheDirList; + CleanupStack::PushL( me ); + me->ConstructL( aSrc ); + CleanupStack::Pop( me ); + return me; + } + +// ----------------------------------------------------------------------------- +// CCustomCacheDirList::ValidateCacheEntryL +// ----------------------------------------------------------------------------- +// +TBool CCustomCacheDirList::ValidateCacheEntryL( const CHttpCacheEntry& aEntry ) + { + TBool presentAndValid = EFalse; + TUint32 shortName; + if( TCompressedEntry::ConvertANameToUint32( aEntry.Filename().Right(8), shortName) ) + { + for(TInt i=0; iIsCompressed() && + (iDirList[i]->GetCompressedName() == shortName) && + (iDirList[i]->GetSize() == aEntry.BodySize())) + { + presentAndValid = ETrue; + iDirList.Remove(i); + break; + } + } + } + return presentAndValid; + } + +// ----------------------------------------------------------------------------- +// CCustomCacheDirList::Count +// ----------------------------------------------------------------------------- +// +TInt CCustomCacheDirList::Count() + { + return iDirList.Count(); + } + +// ----------------------------------------------------------------------------- +// CCustomCacheDirList::NameAtL +// ----------------------------------------------------------------------------- +// +HBufC* CCustomCacheDirList::NameAtL( TInt aIndex ) + { + return iDirList[aIndex]->GetNameL(); + } + +// ----------------------------------------------------------------------------- +// CCustomCacheDirList::CCustomCacheDirList +// ----------------------------------------------------------------------------- +// +CCustomCacheDirList::CCustomCacheDirList() + { + } + +// ----------------------------------------------------------------------------- +// CCustomCacheDirList::ConstructL +// ----------------------------------------------------------------------------- +// +void CCustomCacheDirList::ConstructL(CDir *aSrc) + { + TInt items = aSrc->Count(); + if(items) + { + iDirList.ReserveL(items); + for(TInt i=0; i < items; i++) + { + TCompressedEntry *newDirEntry = TCompressedEntry::NewL( (*aSrc)[i] ); + iDirList.AppendL( newDirEntry ); + } + } + } + +// ----------------------------------------------------------------------------- +// TCompressedEntry::NewL +// ----------------------------------------------------------------------------- +// +TCompressedEntry *TCompressedEntry::NewL( const TEntry& aEntry ) + { + TCompressedEntry *newEntry = new (ELeave) TCompressedEntry; + CleanupStack::PushL( newEntry ); + newEntry->ConstructL( aEntry ); + CleanupStack::Pop( newEntry ); + + return newEntry; + } + +// ----------------------------------------------------------------------------- +// TCompressedEntry::ConstructL +// ----------------------------------------------------------------------------- +// +void TCompressedEntry::ConstructL( const TEntry& aEntry ) + { + TUint32 compressedName; + if ( ConvertANameToUint32(aEntry.iName, compressedName) ) + { + iFlags |= EFilenameStoredAsUint32; + iName.iNameAsUint32 = compressedName; + } + else + { + iName.iNameAsHBuf = aEntry.iName.AllocL(); + } + iSize = aEntry.iSize; + } + +// ----------------------------------------------------------------------------- +// TCompressedEntry::ConvertANameToUint32 +// ----------------------------------------------------------------------------- +// +TBool TCompressedEntry::ConvertANameToUint32( const TDesC& aName, TUint32& aConverted) + { + TBool success = EFalse; + aConverted = 0; + + if ( aName.Length() == 8 ) + { + TUint32 scratch = 0; + for ( TInt i=0; i < 8; i++ ) + { + scratch <<= 4; + TInt val = TCompressedEntry::ConvertAsciiToIntSingleHexDigit(aName[i]); + if ( val >= 0 ) + { + scratch += val & 0x0F; + } + else + break; + + if ( i==7 ) + { + aConverted = scratch; + success = ETrue; + } + } + } + + return success; + } + +// ----------------------------------------------------------------------------- +// TCompressedEntry::ConvertAsciiToIntSingleHexDigit +// ----------------------------------------------------------------------------- +// +TInt TCompressedEntry::ConvertAsciiToIntSingleHexDigit(const TUint16& aDigitChar) + { + if ( aDigitChar >=48 && aDigitChar <=57 ) + { + return (aDigitChar - 48); //numerals + } + else if ( aDigitChar >= 65 && aDigitChar <= 70 ) + { + return (aDigitChar - 55); // uppercase hex letters + } + else if ( aDigitChar >= 97 && aDigitChar <= 102 ) + { + return (aDigitChar - 87); // lowercase hex letters + } + + return -1; + } + +// ----------------------------------------------------------------------------- +// TCompressedEntry::GetNameL +// ----------------------------------------------------------------------------- +// +HBufC* TCompressedEntry::GetNameL() + { + if ( !IsCompressed() ) + { + return iName.iNameAsHBuf->AllocL(); + } + + HBufC* name = HBufC::NewL(8); + name->Des().Format(_L("%08x"), iName.iNameAsUint32); + + return name; } // End of File diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/src/HttpCacheLookupTable.cpp --- a/webengine/osswebengine/cache/src/HttpCacheLookupTable.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/cache/src/HttpCacheLookupTable.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -72,8 +72,8 @@ // void CHttpCacheLookupTable::ConstructL() { - iEntries = new( ELeave )CArrayPtrFlat( KHttpCacheLookupTableSize ); - for( TInt i = 0; i < KHttpCacheLookupTableSize; i++ ) + iEntries = new( ELeave )CArrayPtrFlat( KHttpCacheLookupTableSize ); + for ( TInt i = 0; i < KHttpCacheLookupTableSize; i++ ) { iEntries->AppendL( NULL ); } @@ -118,7 +118,6 @@ } delete iEntries; - } // ----------------------------------------------------------------------------- @@ -140,7 +139,12 @@ } else { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L(" Added entry %08x to list."), entry); +#endif entry->Accessed(); + iStreamHandler->InitialiseCacheEntryL(*entry); + // lookuptable takes ownership CleanupStack::Pop(); // entry } @@ -156,20 +160,29 @@ { CHttpCacheEntry* entry = NULL; TInt pos( Probe( aUrl, EFalse ) ); - +#ifdef __CACHELOG__ + HttpCacheUtil::WriteUrlToLog(0, _L("CHttpCacheLookupTable::Find"), aUrl); + HttpCacheUtil::WriteFormatLog(0, _L(" Probe returned position %d"), pos); +#endif if ( Valid( pos ) ) { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L(" Entry %d valid."), pos); +#endif entry = iEntries->At( pos ); - + if ( entry ) { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L(" BodySize is %d\n State is %d"), entry->BodySize(), entry->State()); +#endif if ( entry->BodySize() == 0 && entry->State() == CHttpCacheEntry::ECacheComplete ) { #ifdef __CACHELOG__ HttpCacheUtil::WriteLogFilenameAndUrl( 0, - _L("CHttpCacheLookupTable::Find - Found ZERO size"), + _L("CHttpCacheLookupTable::Find - Found ZERO size (can't reuse)"), entry->Filename(), entry->Url(), pos, @@ -179,6 +192,9 @@ } } } +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L(" returning entry pointer 0x%08x"), entry); +#endif return entry; } @@ -192,7 +208,10 @@ { TInt status( KErrNotFound ); TInt pos( Probe( aUrl, EFalse ) ); - +#ifdef __CACHELOG__ + HttpCacheUtil::WriteUrlToLog(0, _L("CHttpCacheLookupTable::Remove"), aUrl); + HttpCacheUtil::WriteFormatLog(0, _L(" Probe returned position %d"), pos); +#endif if( Valid( pos ) ) { // remove only nonactive entry @@ -225,7 +244,7 @@ } else { - HttpCacheUtil::WriteLog( 0, _L( "CHttpCacheLookupTable::Remove - item is not valid. cannot be removed" ), pos ); + HttpCacheUtil::WriteFormatLog( 0, _L( "CHttpCacheLookupTable::Remove - item %d is not valid. cannot be removed" ), pos ); } #endif // __CACHELOG__ @@ -233,27 +252,6 @@ } // ----------------------------------------------------------------------------- -// CHttpCacheLookupTable::RemoveByPosition -// -// ----------------------------------------------------------------------------- -// -TInt CHttpCacheLookupTable::RemoveByPosition( TInt aPos ) - { - TInt status( KErrNotFound ); - - if ( Valid( aPos ) ) - { - CHttpCacheEntry* entry = iEntries->At( aPos ); - SetDeleted( aPos ); - delete entry; - iCount--; - status = KErrNone; - } - - return status; - } - -// ----------------------------------------------------------------------------- // CHttpCacheLookupTable::EraseCacheEntry // // ----------------------------------------------------------------------------- @@ -261,7 +259,7 @@ void CHttpCacheLookupTable::EraseCacheEntry( const TDesC8& aUrl ) { TInt pos( Probe( aUrl, EFalse ) ); - + if ( Valid( pos ) ) { Erase( pos ); @@ -320,13 +318,13 @@ TInt count( 0 ); TInt error( KErrNone ); - //1. Tally up + //1. Tally up for (TInt i = 0; i < iEntries->Count(); i++) { if (Valid(i)) count++; } - //2. Preallocation. + //2. Preallocation. TInt existing( aFilenameList.Count() ); error = aFilenameList.Reserve( existing + count ); @@ -337,13 +335,13 @@ { if (Valid(i)) { - //add filename pointer to the array. + //add filename pointer to the array. const TDesC* ptr = &(iEntries->At(i)->Filename()); aFilenameList.Append( ptr ); // no ownership transfer happens here } } } - + return error; } @@ -354,14 +352,22 @@ // ----------------------------------------------------------------------------- // void CHttpCacheLookupTable::InternalizeL( - RFileReadStream& aReadStream, - const TDesC& /*aDirectory*/ ) + RReadStream& aReadStream, + const TDesC& aDirectory ) { // get number of entries TInt version = 0; version = aReadStream.ReadInt32L(); - if( version == KCacheVersionNumber ) + if ( version == KCacheVersionNumber ) { + // read directory stub and validate it + TInt len = aReadStream.ReadInt32L(); + HBufC* dirstub = HBufC::NewLC(len); + TPtr dirstubptr = dirstub->Des(); + aReadStream.ReadL( dirstubptr, len ); + ASSERT( aDirectory.CompareF( dirstubptr ) == 0 ); + CleanupStack::PopAndDestroy( dirstub ); + TInt count( aReadStream.ReadInt32L() ); TInt contentSize( 0 ); TInt err; @@ -370,27 +376,22 @@ // create empty object CHttpCacheEntry* entry = CHttpCacheEntry::NewLC( KNullDesC8, *iEvictionHandler ); // read it - err = entry->Internalize( aReadStream ); - - if ( err == KErrNone && entry->BodySize() > 0 ) + err = entry->Internalize( aReadStream, aDirectory ); + // leave only on no memory + if( err == KErrNone ) { - // cacheEntry is valid, insert into the table + // insert to the table InsertL( entry ); contentSize += entry->HeaderSize(); contentSize += entry->BodySize(); } else if ( err == KErrNoMemory ) { - // Only leave if no memory User::Leave( KErrNoMemory ); } - else if ( entry->BodySize() == 0 ) + else { - // This is an empty cache entry, remove it from file system. - // Use CreateNewFilesL() to open file handles, so we can delete - // the files associated with the cache entry. - iStreamHandler->CreateNewFilesL( *entry ); - iStreamHandler->EraseCacheFile( *entry ); + // suggestions } // takes ownership @@ -415,22 +416,40 @@ // ----------------------------------------------------------------------------- // void CHttpCacheLookupTable::ExternalizeL( - RFileWriteStream& aWriteStream ) + RWriteStream& aWriteStream, const TDesC& aDirectory ) { // write version number and the number of entries - TRAP_IGNORE( aWriteStream.WriteInt32L( KCacheVersionNumber ); - aWriteStream.WriteInt32L( iCount ) ); + TRAP_IGNORE( aWriteStream.WriteInt32L( KCacheVersionNumber ) ); + + // directory stub length + aWriteStream.WriteInt32L( aDirectory.Length() ) ; + // directory stub + aWriteStream.WriteL( aDirectory ); + + // entry count - don't write entries with zero body length, so precalculate this. + TInt goingToWrite = 0; for( TInt i = 0; i < iEntries->Count(); i++ ) { CHttpCacheEntry* entry = iEntries->At( i ); // save complete entries only - if( Valid( i ) ) + if( Valid( i ) && entry->BodySize() > 0 ) + { + goingToWrite++; + } + } + aWriteStream.WriteInt32L( goingToWrite ); + + for( TInt i = 0; i < iEntries->Count(); i++ ) + { + CHttpCacheEntry* entry = iEntries->At( i ); + // save complete entries only + if( Valid( i ) && entry->BodySize() > 0 ) { // save entry TInt err; - err = entry->Externalize( aWriteStream ); + err = entry->Externalize( aWriteStream, aDirectory ); // leave only on no memory - if( err == KErrNoMemory ) + if ( err == KErrNoMemory ) { User::Leave( KErrNoMemory ); } @@ -454,15 +473,27 @@ if ( aCacheEntry ) { pos = Probe( aCacheEntry->Url(), ETrue ); +#ifdef __CACHELOG__ + HttpCacheUtil::WriteUrlToLog(0, _L("CHttpCacheLookupTable::InsertL"), aCacheEntry->Url()); + HttpCacheUtil::WriteFormatLog(0, _L(" Probe returned position %d"), pos); +#endif // double check if( Valid( pos ) ) { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog(0, _L(" Valid entry already exists according to Valid(). Rehash table.")); +#endif // try to rehash the table if probe failed ReHashL(); pos = Probe( aCacheEntry->Url(), ETrue ); - +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L(" ReProbe after rehash returned new position %d"), pos); +#endif if( pos == -1 || Valid( pos ) ) { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog(0, _L(" Pos already filled (or == -1) - Couldn't find an empty slot to store it.")); +#endif // completly failed pos = -1; } @@ -473,13 +504,15 @@ { iEntries->At( pos ) = aCacheEntry; iCount++; - #ifdef __CACHELOG__ - HttpCacheUtil::WriteLog( 0, _L( "insert new item to the lookuptable" ), pos ); + HttpCacheUtil::WriteFormatLog( 0, _L( "insert new item at %d in the lookuptable" ), pos ); #endif // check if the hashtable is full if ( iCount > ( iEntries->Count() >> 1 ) ) { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog(0, _L(" But! hashtable is full - rehash.")); +#endif ReHashL(); } } @@ -687,9 +720,6 @@ if( entry ) { - // delete file associated with this entry - TBool attached( EFalse ); - #ifdef __CACHELOG__ HttpCacheUtil::WriteLogFilenameAndUrl( 0, _L("CHttpCacheLookupTable::Erase"), @@ -697,14 +727,8 @@ entry->Url(), aPos, ELogLookupTablePos ); -#endif - TRAPD( err, attached = iStreamHandler->AttachL( *entry ) ); - if ( err == KErrNone && attached ) - { - iStreamHandler->EraseCacheFile( *entry ); - iStreamHandler->Detach( *entry ); - } - +#endif + iStreamHandler->Erase( *entry ); SetDeleted( aPos ); delete entry; iCount--; @@ -826,7 +850,7 @@ CHttpCacheEntry* myEntry = InsertL(newEntry->Url()); myEntry->SetState( CHttpCacheEntry::ECacheComplete ); myEntry->Accessed(newEntry->LastAccessed(), newEntry->Ref()); - } + } aHttpCacheLookupTable->SetDeleted(pos); delete newEntry; aHttpCacheLookupTable->iCount--; @@ -835,28 +859,32 @@ } // ----------------------------------------------------------------------------- -// CHttpCacheLookupTable::FindCacheEntryIndex +// CHttpCacheLookupTable::BeginEntryIteration +// +// ----------------------------------------------------------------------------- +// +void CHttpCacheLookupTable::BeginEntryIteration(THttpCacheLookupTableEntryIterator& aIter) + { + aIter.iPos = 0; + aIter.iCount = iCount; + } + +// ----------------------------------------------------------------------------- +// CHttpCacheLookupTable::NextEntry // // ----------------------------------------------------------------------------- // -void CHttpCacheLookupTable::FindCacheEntryIndex( - const CHttpCacheEntry& aCacheEntry, - TInt* aIndex ) +const CHttpCacheEntry* CHttpCacheLookupTable::NextEntry(THttpCacheLookupTableEntryIterator& aIter) { - *aIndex = -1; - for ( TInt i = 0; i < iEntries->Count(); i++ ) - { - CHttpCacheEntry* entry = iEntries->At( i ); + const CHttpCacheEntry *entry = NULL; - if ( entry == &aCacheEntry ) - { - if ( aIndex ) - { - *aIndex = i; - } - break; - } + while ( !entry && aIter.iPos < iEntries->Count() ) + { + entry = Valid(aIter.iPos) ? iEntries->At(aIter.iPos) : NULL; + aIter.iPos++; } + + return entry; } // End of File diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/src/HttpCacheManager.cpp --- a/webengine/osswebengine/cache/src/HttpCacheManager.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/cache/src/HttpCacheManager.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -19,6 +19,7 @@ #include "HttpCacheManager.h" #include "HttpCacheHandler.h" #include "HttpCacheUtil.h" +#include "HttpCacheFileWriteHandler.h" #include #include #include @@ -40,10 +41,13 @@ // kbyte const TUint KDefaultCacheSize = 1048576; // 1MB = 1024*1024 _LIT( KDefaultCacheDir, "c:\\cache\\"); +_LIT( KDefaultOperatorCacheDir, "c:\\cache\\op\\"); +_LIT( KDefaultVssCacheDir, "c:\\cache\\vss\\"); _LIT( KDefaultIndexFile, "index.dat" ); _LIT( KDefaultOpIndexFile, "index_op.dat" ); _LIT( KDefaultVSSIndexFile, "index_vss.dat" ); _LIT( KIndexFileExtension, ".dat" ); +_LIT( KValidationFileExtension, ".val" ); _LIT8( KVSSHeaderFileldName, "X-Vodafone-Content" ); _LIT8( KVSSHeaderFileldValue, "Portal" ); @@ -115,7 +119,9 @@ return self; } +// ----------------------------------------------------------------------------- // Destructor +// ----------------------------------------------------------------------------- CHttpCacheManager::~CHttpCacheManager() { delete iOfflineNotifyHandler; @@ -125,6 +131,7 @@ delete iOpDomain; delete iphoneSpecificCache; delete iVSSWhiteList; + delete iFileWriteHandler; } // ----------------------------------------------------------------------------- @@ -132,9 +139,9 @@ // // ----------------------------------------------------------------------------- // -TBool CHttpCacheManager::VSSRequestCheck( const RHTTPTransaction& aTrans, - const RHTTPHeaders& aHttpHeader, - const TDesC8& aUrl ) +TBool CHttpCacheManager::VSSRequestCheckL( const RHTTPTransaction& aTrans, + const RHTTPHeaders& aHttpHeader, + const TDesC8& aUrl ) { TBool VSSTransaction ( EFalse ); if ( iVSSCacheEnabled && HttpCacheUtil::VSSCacheContent( aUrl, iVSSWhiteList ) ) @@ -178,9 +185,9 @@ } CleanupStack::PopAndDestroy(); // VSSnameStr } //end if( iVSSCacheEnabled && HttpCacheUtil::VSSCacheContent( aUrl, iVSSWhiteList ) ) - return VSSTransaction; } + // ----------------------------------------------------------------------------- // CHttpCacheManager::RequestL // @@ -214,18 +221,18 @@ status = iphoneSpecificCache->RequestL( aTrans, aCacheMode, aCacheEntry ); if( (status == KErrNotReady) || (status == KErrNone ) ) { - aCacheEntry.iCacheHandler = iphoneSpecificCache; + aCacheEntry.iCacheHandler = iphoneSpecificCache; } else { // No entry found in any cache. Default to normal cache - aCacheEntry.iCacheHandler = cache; + aCacheEntry.iCacheHandler = cache; } - } + } else { - aCacheEntry.iCacheHandler = cache; - } + aCacheEntry.iCacheHandler = cache; + } } //end if( cache ) }//end if( iCacheEnabled || iVSSCacheEnabled ) @@ -260,11 +267,11 @@ THttpCacheEntry& aCacheEntry ) { HBufC8* bodyStr = NULL; - if( ( iCacheEnabled || iVSSCacheEnabled ) && aCacheEntry.iCacheHandler ) { bodyStr = aCacheEntry.iCacheHandler->RequestNextChunkL( aTrans, aLastChunk, aCacheEntry ); } + return bodyStr; } @@ -292,15 +299,16 @@ RHTTPTransaction& aTrans, THttpCacheEntry& aCacheEntry ) { - if( iCacheEnabled || iVSSCacheEnabled ) + if ( iCacheEnabled || iVSSCacheEnabled ) { - if( iVSSCacheEnabled && VSSRequestCheck( aTrans, aTrans.Response().GetHeaderCollection(), - aTrans.Request().URI().UriDes() ) ) + if ( iVSSCacheEnabled && + VSSRequestCheckL( aTrans, aTrans.Response().GetHeaderCollection(), + aTrans.Request().URI().UriDes() ) ) { //Modify the cache handler if VSS specific aCacheEntry.iCacheHandler = iphoneSpecificCache; } - if( aCacheEntry.iCacheHandler ) + if ( aCacheEntry.iCacheHandler ) { aCacheEntry.iCacheHandler->ReceivedResponseHeadersL( aTrans, aCacheEntry ); } @@ -340,7 +348,7 @@ // ----------------------------------------------------------------------------- // CHttpCacheManager::RemoveAllL -// Removes all files from HTTP cache. Also tries to remove orphaned files, +// Removes all files from HTTP cache. Also tries to remove orphaned files, // i.e files found on disk, but not registered in the cache's lookup table // ----------------------------------------------------------------------------- // @@ -352,43 +360,46 @@ { numOfBytes = iCache->RemoveAllL(); } - + //failure here is not mission critical - TRAP_IGNORE( RemoveOrphanedFilesL() ); - + TRAP_IGNORE( RemoveOrphanedFilesL() ); + return numOfBytes; } - +// ----------------------------------------------------------------------------- +// FilePathHash // Hash function for Symbian file paths: discards case first +// ----------------------------------------------------------------------------- static TUint32 FilepathHash(const TDesC& aDes) { - //since this function is intensively used by the HashMap, - //keeping (slow) heap allocation out of it. - TBuf normalized ( aDes ); - + //since this function is intensively used by the HashMap, + //keeping (slow) heap allocation out of it. + TBuf normalized ( aDes ); + normalized.LowerCase(); return DefaultHash::Des16( normalized ); } -// Comparator for Symbian file paths: Use case-insensitive compare +// ----------------------------------------------------------------------------- +// FilepathIdent +// Comparator for Symbian file paths: Use case-insensitive compare +// ----------------------------------------------------------------------------- static TBool FilepathIdent(const TDesC& aL, const TDesC& aR) { - return ( aL.CompareF(aR) == 0 ); + return ( aL.CompareF(aR) == 0 ); } - // ----------------------------------------------------------------------------- -// CHttpCacheManager::RemoveOrphanedFilesL +// CHttpCacheManager::RemoveOrphanedFilesL // Removes header/body files that exist on the file-system, but are not known to the in-memory Cache lookup table(s) -// We do this because cache performance degrades substantially if there are too many files in a Symbian FAT32 directory. -// Browser crash or out-of-battery situations may cause SaveLookuptable() to be not called, leading to such "orphaned files". -// Due to high file-server interaction, don't call this method from performance critical code. +// We do this because cache performance degrades substantially if there are too many files in a Symbian FAT32 directory. +// Browser crash or out-of-battery situations may cause SaveLookuptable() to be not called, leading to such "orphaned files". +// Due to high file-server interaction, don't call this method from performance critical code. // ----------------------------------------------------------------------------- void CHttpCacheManager::RemoveOrphanedFilesL() { - - //Map that contains pointers to fully-qualified file paths as Keys, and "to be deleted flag" as Value. + //Map that contains pointers to fully-qualified file paths as Keys, and "to be deleted flag" as Value. RPtrHashMap onDiskFilesMap(&FilepathHash, &FilepathIdent); CleanupClosePushL( onDiskFilesMap ); @@ -397,7 +408,7 @@ const TInt needsDelete( 1 ); const TInt noDelete( 0 ); - //collects objects that need to be deleted later on + //collects objects that need to be deleted later on RPointerArray cleanupList; CleanupResetAndDestroyPushL( cleanupList ); @@ -411,20 +422,22 @@ //Step 1. Find out all files on disk: by walking the directory hierarchy, one directory at a time for (;;) { - //1a. Get list of files in current directory, NULL if no directory left in tree + //1a. Get list of files in current directory, NULL if no directory left in tree scanner->NextL( matchingFiles ); if ( !matchingFiles ) break; - TPtrC dir( scanner->FullPath() ); - + TPtrC dir( scanner->FullPath() ); + //1b. Add any files found to the HashTable const TInt nMatches = matchingFiles->Count(); for ( TInt i = 0; i < nMatches; i++ ) { - TEntry entry ( (*matchingFiles)[i] ) ; - if (entry.iName.Right( KIndexFileExtension().Length() ). - CompareF( KIndexFileExtension ) != 0) // ignore any .dat index files + TEntry entry ( (*matchingFiles)[i] ) ; + TPtrC ext( entry.iName.Right( KIndexFileExtension().Length() )); + + if ( ext.CompareF( KIndexFileExtension ) != 0 && // ignore any .dat index files + ext.CompareF( KValidationFileExtension ) != 0 ) // ignore any .val index files { HBufC* fullPath = HBufC::NewL( dir.Length() + entry.iName.Length() ); cleanupList.Append( fullPath ); //keep object safe for later destruction @@ -433,7 +446,6 @@ onDiskFilesMap.Insert( fullPath, &needsDelete ); //add to the hash } } - delete matchingFiles; } // End of step 1: adding all known files on disk to Map @@ -442,29 +454,29 @@ #ifdef __CACHELOG__ { - RDebug::Print(_L("-----------START PRINTING MAP OF SIZE %d---------"), onDiskFilesMap.Count()); + HttpCacheUtil::WriteFormatLog(0, _L("-----------START PRINTING MAP OF SIZE %d---------"), onDiskFilesMap.Count()); TPtrHashMapIter iter(onDiskFilesMap); const TDesC* key; while ((key = iter.NextKey()) != 0) { const TInt val = *(iter.CurrentValue()); - RDebug::Print(_L("MAP WALK: %S, with value = %d "), key, val); + HttpCacheUtil::WriteFormatLog(0, _L("MAP WALK: %S, with value = %d "), key, val); } - RDebug::Print(_L("-----------DONE PRINTING MAP-------------")); + HttpCacheUtil::WriteFormatLog(0, _L("-----------DONE PRINTING MAP-------------")); } #endif - + //Step 2. Get list of known (non-orphaned) files in each Cache's in-memory lookup table. Flag them as DO NOT DELETE - RPointerArray knownFiles; + RPointerArray knownFiles; CleanupClosePushL( knownFiles ); - //Ask CacheHandlers to add their KNOWN files to this array. No ownership transfer occurs. + //Ask CacheHandlers to add their KNOWN files to this array. No ownership transfer occurs. //Don't go ahead if any of the cache handlers choke to insure correct deletion of files. if (iCache) - User::LeaveIfError( iCache->ListFiles( knownFiles ) ); + User::LeaveIfError( iCache->ListFiles( knownFiles ) ); if (iOperatorCache) User::LeaveIfError( iOperatorCache->ListFiles( knownFiles ) ); if (iphoneSpecificCache) - User::LeaveIfError( iphoneSpecificCache->ListFiles( knownFiles ) ); + User::LeaveIfError( iphoneSpecificCache->ListFiles( knownFiles ) ); //2a. HashTable lookup, and modification of flag for (TInt i = 0; i < knownFiles.Count(); i++) @@ -474,18 +486,19 @@ if (ptr) { // Reinsert into Map, this time with NO DELETE - onDiskFilesMap.Insert( knownFiles[i], &noDelete ); - + onDiskFilesMap.Insert( knownFiles[i], &noDelete ); +#if 0 // no header files any more. // Add the header file to HashMap - HBufC* headerFile = HBufC::NewL( KHttpCacheHeaderExt().Length() + (*(knownFiles[i])).Length() ); + HBufC* headerFile = HBufC::NewL( KHttpCacheHeaderExt().Length() + (*(knownFiles[i])).Length() ); cleanupList.Append( headerFile ); //keep for later destruction - TPtr ptr( headerFile->Des() ); + TPtr ptr( headerFile->Des() ); HttpCacheUtil::GetHeaderFileName( *(knownFiles[i]), ptr ); onDiskFilesMap.Insert( headerFile, &noDelete ); // register Header files as NO DELETE +#endif } } - knownFiles.Close(); + knownFiles.Close(); CleanupStack::Pop( 1, &knownFiles ); //Step 3. Delete all files on disk that don't belong to any of the Cache Handlers. @@ -501,12 +514,12 @@ } delete fileMan; - CleanupStack::Pop(1, &cleanupList); + CleanupStack::Pop(1, &cleanupList); cleanupList.ResetAndDestroy(); //should delete all HBufC objects - + CleanupStack::Pop(1, &onDiskFilesMap); onDiskFilesMap.Close(); // doesn't own any K,V object - + } // ----------------------------------------------------------------------------- @@ -667,6 +680,17 @@ CRepository* repositoryDiskLevel = CRepository::NewLC( KCRUidDiskLevel ); TInt err; + // Get Cache Postpone Parameters. + // + THttpCachePostponeParameters postpone; + + if (KErrNone == repository->Get(KCacheWritePostponeEnabled, postpone.iEnabled) ) + { + User::LeaveIfError( repository->Get( KCacheWritePostponeFreeRAMThreshold, postpone.iFreeRamThreshold ) ); + User::LeaveIfError( repository->Get( KCacheWritePostponeImmediateWriteThreshold, postpone.iImmediateWriteThreshold ) ); + User::LeaveIfError( repository->Get( KCacheWritePostponeWriteTimeout, postpone.iWriteTimeout ) ); + } + // cache on/off TInt cacheEnabled( 0 ); err = repository->Get( KCacheManagerHttpCacheEnabled, cacheEnabled ); @@ -684,61 +708,62 @@ { iCacheFolder.Append( _L("\\") ); } - - // get drive letter for sysutil - TParsePtrC pathParser( iCacheFolder ); - TDriveUnit drive = pathParser.Drive(); - // get critical level - // RAM drive can have different critical level - TVolumeInfo vinfo; - User::LeaveIfError( CCoeEnv::Static()->FsSession().Volume( vinfo, drive ) ); - // - TInt criticalLevel; - User::LeaveIfError( repositoryDiskLevel->Get( ( vinfo.iDrive.iType == EMediaRam ? KRamDiskCriticalLevel : KDiskCriticalThreshold ), - criticalLevel ) ); - if( (err == KErrNone) && iCacheEnabled ) + // get drive letter for sysutil + TParsePtrC pathParser( iCacheFolder ); + TDriveUnit drive = pathParser.Drive(); + // get critical level + // RAM drive can have different critical level + TVolumeInfo vinfo; + User::LeaveIfError( CCoeEnv::Static()->FsSession().Volume( vinfo, drive ) ); + // + TInt criticalLevel; + User::LeaveIfError( repositoryDiskLevel->Get( ( vinfo.iDrive.iType == EMediaRam ? KRamDiskCriticalLevel : KDiskCriticalThreshold ), + criticalLevel ) ); + + if ( (err == KErrNone) && iCacheEnabled ) { // create cache handler - iCache = CHttpCacheHandler::NewL( cacheSize, iCacheFolder, KDefaultIndexFile(), criticalLevel ); + iCache = CHttpCacheHandler::NewL( cacheSize, iCacheFolder, KDefaultIndexFile(), criticalLevel, postpone); // create operator cache. same settings - if( FeatureManager::FeatureSupported( KFeatureIdOperatorCache ) ) + if ( FeatureManager::FeatureSupported( KFeatureIdOperatorCache ) ) { TBuf<512> url; // if domain is missing, then no need to read further - if( repository->Get( KOperatorDomainUrl, url ) == KErrNone ) + if ( repository->Get( KOperatorDomainUrl, url ) == KErrNone ) { HBufC8* opDomain8 = HBufC8::NewL( url.Length() ); - CleanupStack::PushL(opDomain8); - opDomain8->Des().Append( url ); + CleanupStack::PushL(opDomain8); + opDomain8->Des().Append( url ); - TInt slashPos = opDomain8->LocateReverse('/'); - if(slashPos == -1) - { - slashPos = 0; - } - TPtrC8 temp = opDomain8->Left(slashPos); - iOpDomain = temp.AllocL(); - CleanupStack::PopAndDestroy(opDomain8); + TInt slashPos = opDomain8->LocateReverse('/'); + if (slashPos == -1) + { + slashPos = 0; + } + + TPtrC8 temp = opDomain8->Left(slashPos); + iOpDomain = temp.AllocL(); + CleanupStack::PopAndDestroy(opDomain8); // op cache size TInt opCacheSize( KDefaultCacheSize ); repository->Get( KOperatorCacheSize, opCacheSize ); // op cache folder - TFileName opCacheFolder( KDefaultCacheDir ); + TFileName opCacheFolder( KDefaultOperatorCacheDir ); repository->Get( KOperatorCacheFolder, opCacheFolder ); - if( opCacheFolder.LocateReverse( '\\' ) != opCacheFolder.Length() - 1 ) + if ( opCacheFolder.LocateReverse( '\\' ) != opCacheFolder.Length() - 1 ) { opCacheFolder.Append( _L("\\") ); } // create op cache - iOperatorCache = CHttpCacheHandler::NewL( opCacheSize, opCacheFolder, KDefaultOpIndexFile(), criticalLevel ); - } + iOperatorCache = CHttpCacheHandler::NewL( opCacheSize, opCacheFolder, KDefaultOpIndexFile(), criticalLevel, postpone); + } } //end if( FeatureManager::FeatureSupported( KFeatureIdOperatorCache ) ) } //end if( iCacheEnabled ) @@ -746,15 +771,15 @@ err = repository->Get( KPhoneSpecificCacheEnabled, VSScacheEnabled ); iVSSCacheEnabled = VSScacheEnabled; - - if( (err == KErrNone) && iVSSCacheEnabled ) + + if ( (err == KErrNone) && iVSSCacheEnabled ) { // cache size TInt VSScacheSize( KDefaultCacheSize ); repository->Get( KPhoneSpecificCacheSize, VSScacheSize ); // cache folder - TFileName VSScacheFolder( KDefaultCacheDir ); + TFileName VSScacheFolder( KDefaultVssCacheDir ); // ignore cache folder. use c:\ to save memory. (same for operator cache. see below) repository->Get( KPhoneSpecificCacheFolder, VSScacheFolder ); // fix folder by appending trailing \\ to the end -symbian thing @@ -767,7 +792,7 @@ //Get the white list TBuf<2048> whiteList; - if( repository->Get( KPhoneSpecificCacheDomainUrl, whiteList ) == KErrNone ) + if ( repository->Get( KPhoneSpecificCacheDomainUrl, whiteList ) == KErrNone ) { iVSSWhiteList = HBufC8::NewL( whiteList.Length() ); iVSSWhiteList->Des().Append( whiteList ); @@ -778,8 +803,9 @@ } // create cache handler - iphoneSpecificCache = CHttpCacheHandler::NewL( VSScacheSize, VSScacheFolder, KDefaultVSSIndexFile(), criticalLevel ); + iphoneSpecificCache = CHttpCacheHandler::NewL( VSScacheSize, VSScacheFolder, KDefaultVSSIndexFile(), criticalLevel, postpone); } + CleanupStack::PopAndDestroy(2); // repository, , repositoryDiskLevel } @@ -804,4 +830,3 @@ return cache; } // End of File - diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/src/HttpCacheObserver.cpp --- a/webengine/osswebengine/cache/src/HttpCacheObserver.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/cache/src/HttpCacheObserver.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -45,8 +45,9 @@ // might leave. // ----------------------------------------------------------------------------- // -CHttpCacheObserver::CHttpCacheObserver(CHttpCacheHandler* aHttpCacheHandler) : CActive( CActive::EPriorityIdle ), -iHttpCacheHandler(aHttpCacheHandler) +CHttpCacheObserver::CHttpCacheObserver(CHttpCacheHandler* aHttpCacheHandler) + : CActive( CActive::EPriorityIdle ), + iHttpCacheHandler(aHttpCacheHandler) { CActiveScheduler::Add(this); } diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/src/HttpCachePostponeWriteUtilities.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/osswebengine/cache/src/HttpCachePostponeWriteUtilities.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -0,0 +1,444 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CHttpCachePostponeWriteUtilities +* +*/ + +// INCLUDE FILES +#include "HttpCachePostponeWriteUtilities.h" +#include "HttpCacheUtil.h" + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + +// ============================= LOCAL FUNCTIONS =============================== + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CHttpCacheEntryAsyncWriteHelper::CHttpCacheEntryAsyncWriteHelper +// ----------------------------------------------------------------------------- +// +CHttpCacheEntryAsyncWriteHelper::CHttpCacheEntryAsyncWriteHelper(TRequestStatus& aStatus, MHttpCacheWriteSource* aSource, TInt aPriority) + : CActive(aPriority), + iSignalStatus(aStatus), + iSource(aSource) + { + } + +// ----------------------------------------------------------------------------- +// CHttpCacheEntryAsyncWriteHelper::NewL +// ----------------------------------------------------------------------------- +// +CHttpCacheEntryAsyncWriteHelper* CHttpCacheEntryAsyncWriteHelper::NewL(MHttpCacheWriteSource* aSource, TRequestStatus& aStatus) + { + CHttpCacheEntryAsyncWriteHelper *obj = new (ELeave) CHttpCacheEntryAsyncWriteHelper(aStatus, aSource, EPriorityHigh); + CleanupStack::PushL(obj); + obj->ConstructL(); + CleanupStack::Pop(obj); + return obj; + } + +// ----------------------------------------------------------------------------- +// CHttpCacheEntryAsyncWriteHelper::~CHttpCacheEntryAsyncWriteHelper +// ----------------------------------------------------------------------------- +// +CHttpCacheEntryAsyncWriteHelper::~CHttpCacheEntryAsyncWriteHelper() + { + Cancel(); + } + +// ----------------------------------------------------------------------------- +// CHttpCacheEntryAsyncWriteHelper::DoCancel +// ----------------------------------------------------------------------------- +// +void CHttpCacheEntryAsyncWriteHelper::DoCancel() + { + TRequestStatus *stat = &(TRequestStatus&)iSignalStatus; + User::RequestComplete(stat, KErrCancel); // Signal cancellation to the observer. + // cannot meaningfully do anything with the unwritten data assuming there is some. + // we will clean it up when we are deleted. + iSource->BodyFile().Close(); + iSource->BodyWriteComplete(); +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: CHttpCacheEntryAsyncWriteHelper::DoCancel called on object %08x"), this); +#endif + } + +// ----------------------------------------------------------------------------- +// CHttpCacheEntryAsyncWriteHelper::WriteNextBodyBlock +// ----------------------------------------------------------------------------- +// +void CHttpCacheEntryAsyncWriteHelper::WriteNextBodyBlock() + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: CHttpCacheEntryAsyncWriteHelper::WriteNextBodyBlock called on object %08x for block %d"), this, iBodyPart ); +#endif + + TPtrC8 bufferPtr( iSource->BodyData().GetSegmentData(iBodyPart) ); + iSource->BodyFile().Write(bufferPtr, iStatus); + } + +// ----------------------------------------------------------------------------- +// CHttpCacheEntryAsyncWriteHelper::RunL +// ----------------------------------------------------------------------------- +// +void CHttpCacheEntryAsyncWriteHelper::RunL() + { + /* General algorithm. + * Write out next section of body data unless done. Then write out header data. + */ +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: CHttpCacheEntryAsyncWriteHelper::RunL called on object %08x"), this); +#endif + if ( iSource->BodyData().Count() > iBodyPart ) + { + WriteNextBodyBlock(); + SetActive(); + } + else + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: - body write completed with status code %d"), iStatus.Int()); +#endif + // Body file writing is complete + iSource->BodyFile().Close(); + iSource->BodyWriteComplete(); + TRequestStatus *stat = &(TRequestStatus&)iSignalStatus; + User::RequestComplete(stat, iStatus.Int()); // signal completion to observer + } + } + +// ----------------------------------------------------------------------------- +// CHttpCacheEntryAsyncWriteHelper::GetResult +// ----------------------------------------------------------------------------- +// +TInt CHttpCacheEntryAsyncWriteHelper::GetResult() + { + return iStatus.Int(); + } + +// ----------------------------------------------------------------------------- +// CHttpCacheEntryAsyncWriteHelper::ConstructL +// ----------------------------------------------------------------------------- +// +void CHttpCacheEntryAsyncWriteHelper::ConstructL() + { + CActiveScheduler::Add(this); + iSource->BodyWriteInProgress(); + // setup to arrive in RunL when next possible. + SetActive(); + TRequestStatus *stat = &(TRequestStatus&)iStatus; + User::RequestComplete(stat, KErrNone); + } + +// ----------------------------------------------------------------------------- +// CSegmentedHeapBuffer::~CSegmentedHeapBuffer +// ----------------------------------------------------------------------------- +// +CSegmentedHeapBuffer::~CSegmentedHeapBuffer() + { + Reset(); + } + +// ----------------------------------------------------------------------------- +// CSegmentedHeapBuffer::ConstructL +// ----------------------------------------------------------------------------- +// +void CSegmentedHeapBuffer::ConstructL() + { + } + +// ----------------------------------------------------------------------------- +// CSegmentedHeapBuffer::NewL +// ----------------------------------------------------------------------------- +// +CSegmentedHeapBuffer *CSegmentedHeapBuffer::NewL(TInt aBufferSize, TInt aCompressGranularity) + { + CSegmentedHeapBuffer *obj= new (ELeave) CSegmentedHeapBuffer(aBufferSize, aCompressGranularity); + CleanupStack::PushL(obj); + obj->ConstructL(); + CleanupStack::Pop(obj); + + return obj; + } + +// ----------------------------------------------------------------------------- +// CSegmentedHeapBuffer::AppendL +// ----------------------------------------------------------------------------- +// +void CSegmentedHeapBuffer::AppendL(TInt& aRemainder, const TDesC8& aDes) + { + aRemainder = aDes.Length(); // consumed nothing yet. + TInt workingLen; + TInt workingOffset=0; // read position in source descriptor + HBufC8* currentBuffer; + + TInt lastBuffer = iBufferList.Count()-1; + if ( lastBuffer < 0 ) + { + // TODO: Make the first block only equal to the size of data we need? + // Take some traces to see what happens. + + // no blocks allocated. May leave here if we can't get space. + currentBuffer = HBufC8::NewLC(iBufferSize); + iBufferList.AppendL(currentBuffer); + CleanupStack::Pop(currentBuffer); + lastBuffer = 0; + } + else + { + currentBuffer = iBufferList[lastBuffer]; + } + + // here, currentBuffer always points to a buffer we can use. + while ( aRemainder ) + { + workingLen = iBufferSize - currentBuffer->Length(); // workingLen = amount of space left in this segment + workingLen = (aRemainder > workingLen) ? workingLen : aRemainder; // workingLen = smaller of (amount of data left in source) or (amount of space left in current segment) + if ( workingLen ) + { + // we have some space in this block to store data. + TPtr8 ptr(currentBuffer->Des()); + ptr.Append(aDes.Mid(workingOffset ,workingLen)); + } + aRemainder -= workingLen; // track how much is consumed + workingOffset += workingLen; // remember where we get the next bit from in the source + if ( aRemainder ) + { + // we have more data to store, append another block. Might result in a leave. + currentBuffer = HBufC8::NewLC(iBufferSize); + iBufferList.AppendL(currentBuffer); + CleanupStack::Pop(currentBuffer); + } + } + // will only exit here if we consumed all data + } + +// ----------------------------------------------------------------------------- +// CSegmentedHeapBuffer::Length +// ----------------------------------------------------------------------------- +// +TInt CSegmentedHeapBuffer::Length() + { + // all segments are same size except last one + TInt len = 0; + TInt count = iBufferList.Count(); + if ( count ) + { + len = iBufferSize * (count - 1); // all segments are same size except last one + len += iBufferList[count-1]->Length(); + } + return len; + } + +// ----------------------------------------------------------------------------- +// CSegmentedHeapBuffer::SpareCapacity +// ----------------------------------------------------------------------------- +// +TInt CSegmentedHeapBuffer::SpareCapacity() + { + TInt len = 0; + TInt count = iBufferList.Count(); + if ( count ) + { + len = iBufferSize - (iBufferList[count-1]->Length()); + } + + // return how much is left in last segment. + return len; + } + +// ----------------------------------------------------------------------------- +// CSegmentedHeapBuffer::Count +// ----------------------------------------------------------------------------- +// +TInt CSegmentedHeapBuffer::Count() + { + return iBufferList.Count(); // number of segments + } + +// ----------------------------------------------------------------------------- +// CSegmentedHeapBuffer::GetSegmentData +// ----------------------------------------------------------------------------- +// +TPtrC8 CSegmentedHeapBuffer::GetSegmentData(TInt& aSegment) + { + return iBufferList[aSegment++]->Des(); + } + +// ----------------------------------------------------------------------------- +// CSegmentedHeapBuffer::ReleaseSegmentData +// ----------------------------------------------------------------------------- +// +void CSegmentedHeapBuffer::ReleaseSegmentData(const TInt aSegment) + { + HBufC8* buf = iBufferList[aSegment]; + iBufferList[aSegment] = 0; // don't want to reshuffle contents + delete buf; + } + +// ----------------------------------------------------------------------------- +// CSegmentedHeapBuffer::Compress +// ----------------------------------------------------------------------------- +// +void CSegmentedHeapBuffer::Compress() + { + TInt count = iBufferList.Count(); + if ( count ) + { + HBufC8* buf = iBufferList[count-1]; + // first, see if we can shrink by at least one iCompressGranularity + if ( iBufferSize - buf->Length() >= iCompressGranularity ) + { + // calculate new size + TInt newsize = (iCompressGranularity * (1 + (buf->Length() / iCompressGranularity))); + HBufC8 *newbuf = buf->ReAlloc(newsize); + // we should be realloc'ing in place since we're shrinking this piece, but you never know. + // don't care if realloc operation fails since it will leave original data alone. + if ( newbuf ) + { + iBufferList[count-1] = newbuf; + } + } + } + } + +// ----------------------------------------------------------------------------- +// CSegmentedHeapBuffer::Reset +// ----------------------------------------------------------------------------- +// +void CSegmentedHeapBuffer::Reset() + { + iBufferList.ResetAndDestroy(); // call delete on all buffers + } + +// ----------------------------------------------------------------------------- +// CSegmentedHeapBuffer::CSegmentedHeapBuffer +// ----------------------------------------------------------------------------- +// +CSegmentedHeapBuffer::CSegmentedHeapBuffer(TInt aBufferSize, TInt aCompressGranularity) : iBufferSize(aBufferSize), iCompressGranularity(aCompressGranularity) + { + } + +// ----------------------------------------------------------------------------- +// CHttpCacheWriteTimeout::CHttpCacheWriteTimeout +// ----------------------------------------------------------------------------- +// +CHttpCacheWriteTimeout::CHttpCacheWriteTimeout( const TInt aTimeout ) + : CActive(EPriorityStandard), + iTimeout(aTimeout) // Standard priority + { + } + +// ----------------------------------------------------------------------------- +// CHttpCacheWriteTimeout::NewLC +// ----------------------------------------------------------------------------- +// +CHttpCacheWriteTimeout* CHttpCacheWriteTimeout::NewLC(const TInt aTimeout) + { + CHttpCacheWriteTimeout* self = new ( ELeave ) CHttpCacheWriteTimeout(aTimeout); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +// ----------------------------------------------------------------------------- +// CHttpCacheWriteTimeout::NewL +// ----------------------------------------------------------------------------- +// +CHttpCacheWriteTimeout* CHttpCacheWriteTimeout::NewL(const TInt aTimeout) + { + CHttpCacheWriteTimeout* self = CHttpCacheWriteTimeout::NewLC(aTimeout); + CleanupStack::Pop(); // self; + return self; + } + +// ----------------------------------------------------------------------------- +// CHttpCacheWriteTimeout::ConstructL +// ----------------------------------------------------------------------------- +// +void CHttpCacheWriteTimeout::ConstructL() + { + User::LeaveIfError(iTimer.CreateLocal()); // Initialize timer + CActiveScheduler::Add(this); // Add to scheduler + } + +// ----------------------------------------------------------------------------- +// CHttpCacheWriteTimeout::~CHttpCacheWriteTimeout +// ----------------------------------------------------------------------------- +// +CHttpCacheWriteTimeout::~CHttpCacheWriteTimeout() + { + Cancel(); // Cancel any request, if outstanding + iTimer.Close(); // Destroy the RTimer object + // Delete instance variables if any + } + +// ----------------------------------------------------------------------------- +// CHttpCacheWriteTimeout::DoCancel +// ----------------------------------------------------------------------------- +// +void CHttpCacheWriteTimeout::DoCancel() + { + iTimer.Cancel(); + } + +// ----------------------------------------------------------------------------- +// CHttpCacheWriteTimeout::Start +// ----------------------------------------------------------------------------- +// +void CHttpCacheWriteTimeout::Start(TCallBack aCallbackFn, TAny *aToken) + { + Cancel(); // Cancel any request, just to be sure + + iToken = aToken; + iCallbackFn = aCallbackFn; + + iTimer.After(iStatus, iTimeout); // Set for later + SetActive(); // Tell scheduler a request is active + } + +// ----------------------------------------------------------------------------- +// CHttpCacheWriteTimeout::RunL +// ----------------------------------------------------------------------------- +// +void CHttpCacheWriteTimeout::RunL() + { + iCallbackFn.iFunction(iToken); + } + +// ----------------------------------------------------------------------------- +// CHttpCacheWriteTimeout::RunError +// ----------------------------------------------------------------------------- +// +TInt CHttpCacheWriteTimeout::RunError(TInt aError) + { + return aError; + } + +// End of File diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/src/HttpCacheStreamHandler.cpp --- a/webengine/osswebengine/cache/src/HttpCacheStreamHandler.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/cache/src/HttpCacheStreamHandler.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -53,7 +53,8 @@ // might leave. // ----------------------------------------------------------------------------- // -CHttpCacheStreamHandler::CHttpCacheStreamHandler() +CHttpCacheStreamHandler::CHttpCacheStreamHandler(RFs& aRFs) + : iRfs( aRFs ) { } @@ -64,11 +65,8 @@ // void CHttpCacheStreamHandler::ConstructL( const TDesC& aDirectory, - TInt aCriticalLevel ) + TInt aCriticalLevel) { - User::LeaveIfError( iRfs.Connect() ); - // set path for the entries - iRfs.SetSessionPath( aDirectory ); iActiveEntries = new( ELeave )CArrayPtrFlat( KHttpCacheActiveCount ); // get drive letter for sysutil TParsePtrC pathParser( aDirectory ); @@ -83,9 +81,10 @@ // CHttpCacheStreamHandler* CHttpCacheStreamHandler::NewL( const TDesC& aDirectory , - TInt aCriticalLevel) + TInt aCriticalLevel, + RFs& aRFs) { - CHttpCacheStreamHandler* self = new( ELeave ) CHttpCacheStreamHandler(); + CHttpCacheStreamHandler* self = new( ELeave ) CHttpCacheStreamHandler(aRFs); CleanupStack::PushL( self ); self->ConstructL( aDirectory , aCriticalLevel); @@ -105,150 +104,90 @@ iActiveEntries->ResetAndDestroy(); } delete iActiveEntries; - - iRfs.Close(); } // ----------------------------------------------------------------------------- -// CHttpCacheStreamHandler::AttachL +// CHttpCacheStreamHandler::InitialiseCacheEntryL +// ----------------------------------------------------------------------------- +// +void CHttpCacheStreamHandler::InitialiseCacheEntryL(CHttpCacheEntry& aCacheEntry) + { + // create a filename for the cache entry. + TPath sessionPath; + User::LeaveIfError( iRfs.SessionPath( sessionPath ) ); + + // Given the full URL, generates a fully qualified path for saving the HTTP response + HBufC* bodyFileName = HttpCacheUtil::GenerateNameLC( aCacheEntry.Url(), sessionPath ); + TPtrC bodyFileNamePtr( *bodyFileName ); + aCacheEntry.SetFileNameL(bodyFileNamePtr); + + CleanupStack::PopAndDestroy(bodyFileName); + + // any more one-time initialisation to go here. + aCacheEntry.SetState( CHttpCacheEntry::ECacheInitialized ); + + // since this only happens one time, we can check if we have files left over with no index entry + // we're too late to reuse any information stored in there, so lets just delete them. This might prevent any + // problems later down the line.. + iRfs.Delete(aCacheEntry.Filename()); + // header filename + TFileName headerFileName; + HttpCacheUtil::GetHeaderFileName( aCacheEntry.Filename(), headerFileName ); + iRfs.Delete(headerFileName); + } + +// ----------------------------------------------------------------------------- +// CHttpCacheStreamHandler::Erase // // ----------------------------------------------------------------------------- // -TBool CHttpCacheStreamHandler::AttachL( CHttpCacheEntry& aCacheEntry ) - { -#ifdef __CACHELOG__ - // check for duplicates - for ( TInt i = 0; i < iActiveEntries->Count(); i++ ) - { - __ASSERT_DEBUG( iActiveEntries->At( i ) != &aCacheEntry, - User::Panic( _L("cacheStreamHandler Panic"), KErrCorrupt ) ); - } -#endif // __CACHELOG__ - - TBool cacheFilesOpened( EFalse ); - - if ( aCacheEntry.CacheFilesOpened() ) - { - // Cache files already opened, no need to reopen - cacheFilesOpened = ETrue; - } - else if ( aCacheEntry.State() == CHttpCacheEntry::ECacheUninitialized ) - { - // Create new cache files, they don't already exist - cacheFilesOpened = CreateNewFilesL( aCacheEntry ); - } - else - { - // Open existing cache files - cacheFilesOpened = OpenCacheFiles( aCacheEntry ); - } - - if ( cacheFilesOpened ) - { - // Add to our active array, if not already there - TInt index( -1 ); - FindCacheEntryIndex( aCacheEntry, &index ); - if ( index == -1 ) - { - iActiveEntries->AppendL( &aCacheEntry ); - } - } - - aCacheEntry.SetCacheFilesOpened( cacheFilesOpened ); - - // Return ETrue, if files opened and attached - return cacheFilesOpened; - } - -// ----------------------------------------------------------------------------- -// CHttpCacheStreamHandler::Detach -// -// ----------------------------------------------------------------------------- -// -void CHttpCacheStreamHandler::Detach( CHttpCacheEntry& aCacheEntry ) - { - // Close the files, this will commit changes - if ( aCacheEntry.CacheFilesOpened() ) - { - aCacheEntry.BodyFile().Close(); - aCacheEntry.HeaderFile().Close(); - aCacheEntry.SetCacheFilesOpened( EFalse ); - } - - // Delete from our active array - TInt index( -1 ); - FindCacheEntryIndex( (const CHttpCacheEntry&)aCacheEntry, &index ); - if ( index >= 0 ) - { - iActiveEntries->Delete( index ); - } - } - -// ----------------------------------------------------------------------------- -// CHttpCacheStreamHandler::EraseCacheFile -// -// ----------------------------------------------------------------------------- -// -void CHttpCacheStreamHandler::EraseCacheFile( CHttpCacheEntry& aCacheEntry ) +void CHttpCacheStreamHandler::Erase( CHttpCacheEntry& aCacheEntry ) { HttpCacheUtil::WriteUrlToLog( 0, _L( "CHttpCacheStreamHandler::Erase - erase files associated with" ), aCacheEntry.Url() ); - aCacheEntry.HeaderFile().Close(); - aCacheEntry.BodyFile().Close(); - aCacheEntry.SetCacheFilesOpened( EFalse ); - - // Get body filename - TFileName bodyFileName = aCacheEntry.Filename(); + // just in case it's busy being written out... + aCacheEntry.CancelBodyWrite(); - // Get header filename - TFileName headerFileName; - HttpCacheUtil::GetHeaderFileName( bodyFileName, headerFileName ); - + // Delete body file +#ifndef __CACHELOG__ + iRfs.Delete( aCacheEntry.Filename() ); +#else TInt statusBody( KErrNotFound ); - statusBody = iRfs.Delete( bodyFileName ); - - TInt statusHeader( KErrNotFound ); - statusHeader = iRfs.Delete( headerFileName ); - + statusBody = iRfs.Delete( aCacheEntry.Filename() ); +#endif // Adjust the size iContentSize -= aCacheEntry.BodySize(); iContentSize -= aCacheEntry.HeaderSize(); #ifdef __CACHELOG__ - if ( statusBody != KErrNone ) { + if ( statusBody == KErrNone ) + { HttpCacheUtil::WriteLogFilenameAndUrl( 0, - _L("CCHttpCacheStreamEntry::Erase - ERROR bodyFile delete"), - aCacheEntry.Filename(), - aCacheEntry.Url(), - statusBody, - ELogFileErrorCode ); - } - else { - HttpCacheUtil::WriteLogFilenameAndUrl( 0, - _L("CCHttpCacheStreamEntry::Erase - SUCCESS bodyFile delete"), + _L("CHttpCacheStreamHandler::Erase - SUCCESS bodyFile delete"), aCacheEntry.Filename(), aCacheEntry.Url(), aCacheEntry.BodySize(), ELogEntrySize ); } - if ( statusHeader != KErrNone ) { + else if ( statusBody == KErrNotFound ) + { HttpCacheUtil::WriteLogFilenameAndUrl( 0, - _L("CCHttpCacheStreamEntry::Erase - ERROR headerFile delete"), + _L("CHttpCacheStreamHandler::Erase - CHECK bodyFile not found."), aCacheEntry.Filename(), aCacheEntry.Url(), - statusHeader, + statusBody, ELogFileErrorCode ); } - else { - HttpCacheUtil::WriteLogFilenameAndUrl( 0, - _L("CCHttpCacheStreamEntry::Erase - SUCCESS headerFile delete"), - aCacheEntry.Filename(), - aCacheEntry.Url(), - aCacheEntry.BodySize(), - ELogEntrySize ); + else + { + HttpCacheUtil::WriteLogFilenameAndUrl( 0, + _L("CHttpCacheStreamHandler::Erase - ERROR bodyFile delete"), + aCacheEntry.Filename(), + aCacheEntry.Url(), + statusBody, + ELogFileErrorCode ); } #endif //__CACHELOG__ - } // ----------------------------------------------------------------------------- @@ -258,25 +197,7 @@ // HBufC8* CHttpCacheStreamHandler::HeadersL( CHttpCacheEntry& aCacheEntry ) { - HBufC8* headerStr = NULL; - TInt headerLen( 0 ); - TInt err( KErrNone ); - - if ( !aCacheEntry.CacheFilesOpened() ) - { - OpenCacheFiles( aCacheEntry ); - } - - err = aCacheEntry.HeaderFile().Size( headerLen ); - if ( err == KErrNone && headerLen > 0 ) - { - headerStr = HBufC8::NewL( headerLen ); - TPtr8 ptr( headerStr->Des() ); - // read headers - aCacheEntry.HeaderFile().Read( 0, ptr, headerLen ); - } - - return headerStr; + return aCacheEntry.HeaderData().AllocL(); } // ----------------------------------------------------------------------------- @@ -288,47 +209,60 @@ CHttpCacheEntry& aCacheEntry, TBool& aLastChunk ) { - HBufC8* bodyStr = NULL; - // Read whole body - TInt size( 0 ); - TInt sizeErr( KErrNone ); + HBufC8 *bodyStr = NULL; - if ( !aCacheEntry.CacheFilesOpened() ) + if ( !aCacheEntry.BodyDataCached() && OpenBodyFile(aCacheEntry) ) { - OpenCacheFiles( aCacheEntry ); - } - - sizeErr = aCacheEntry.BodyFile().Size( size ); - if ( sizeErr == KErrNone && size > 0 ) - { - bodyStr = HBufC8::NewL( size ); - TPtr8 ptr( bodyStr->Des() ); - - TInt readErr( KErrNone ); - readErr = aCacheEntry.BodyFile().Read( ptr, size ); + CleanupClosePushL( aCacheEntry.BodyFile() ); + // read body + TInt size; + TInt err( aCacheEntry.BodyFile().Size( size ) ); + if ( err == KErrNone && size > 0 ) + { + bodyStr = HBufC8::NewL( size ); + TPtr8 ptr( bodyStr->Des() ); + // + err = aCacheEntry.BodyFile().Read( ptr, size ); #ifdef __CACHELOG__ - if ( readErr != KErrNone ) { - HttpCacheUtil::WriteLogFilenameAndUrl( 0, - _L("CCHttpCacheStreamEntry::NextChunkL - bodyFile.read"), - aCacheEntry.Filename(), - aCacheEntry.Url(), - readErr, - ELogFileErrorCode ); + if ( err != KErrNone ) { + HttpCacheUtil::WriteLogFilenameAndUrl( 0, + _L("CCHttpCacheStreamEntry::NextChunkL - bodyFile.read"), + aCacheEntry.Filename(), + aCacheEntry.Url(), + err, + ELogFileErrorCode ); + } + else { + HttpCacheUtil::WriteLogFilenameAndUrl( 0, + _L("CCHttpCacheStreamEntry::NextChunkL - bodyFile.read"), + aCacheEntry.Filename(), + aCacheEntry.Url(), + ptr.Length(), + ELogEntrySize ); + } +#endif // __CACHELOG__ } - else { - HttpCacheUtil::WriteLogFilenameAndUrl( 0, - _L("CCHttpCacheStreamEntry::NextChunkL - bodyFile.read"), - aCacheEntry.Filename(), - aCacheEntry.Url(), - ptr.Length(), - ELogEntrySize ); + // Close body file + CleanupStack::PopAndDestroy(1); + } + else + { + // reuse stored data if we have any. + CSegmentedHeapBuffer& buffer = aCacheEntry.BodyData(); + TInt size = buffer.Length(); + bodyStr = HBufC8::NewL( size ); + TPtr8 ptr(bodyStr->Des()); + + TInt readSegment = 0; + TInt count = buffer.Count(); + while(readSegment < count) + { + TPtrC8 source = buffer.GetSegmentData(readSegment); + ptr.Append(source); } -#endif // __CACHELOG__ - } aLastChunk = ETrue; - return bodyStr; } @@ -342,26 +276,17 @@ const TDesC8& aHeaderStr ) { TBool headerSaved( EFalse ); + TInt headerLen = aHeaderStr.Length(); - if ( !aCacheEntry.CacheFilesOpened() ) - { - OpenCacheFiles( aCacheEntry ); - } - - if ( aHeaderStr.Length() && IsDiskSpaceAvailable( aHeaderStr.Length() ) ) + if ( headerLen && IsDiskSpaceAvailable( headerLen ) ) { - // We have space on disk, save headers. Don't force a flush, as the - // File Server takes care of write and read consistency. - TInt writeErr = aCacheEntry.HeaderFile().Write( aHeaderStr ); - - if ( writeErr == KErrNone ) + TRAPD(err, aCacheEntry.CreateHeaderBufferL(aHeaderStr)); + if ( err == KErrNone ) { - aCacheEntry.SetHeaderSize( aHeaderStr.Length() ); - iContentSize += aHeaderStr.Length(); + iContentSize += aCacheEntry.HeaderSize(); headerSaved = ETrue; } } - return headerSaved; } @@ -374,9 +299,7 @@ { iContentSize -= aCacheEntry.HeaderSize(); - // Destroy data - aCacheEntry.HeaderFile().SetSize( 0 ); - aCacheEntry.SetHeaderSize( 0 ); + TRAP_IGNORE( aCacheEntry.CreateHeaderBufferL( 0 ) ); } // ----------------------------------------------------------------------------- @@ -388,101 +311,67 @@ CHttpCacheEntry& aCacheEntry, const TDesC8& aBodyStr ) { - TInt bodySaved( EFalse ); + TInt bodySaved( KErrNone ); TInt newBodyLength( aBodyStr.Length() ); - TPtr8 buffer( aCacheEntry.CacheBuffer() ); + + if ( newBodyLength ) + { + TInt remainder = 0; + CSegmentedHeapBuffer& cacheBuffer = aCacheEntry.BodyData(); - if ( newBodyLength && buffer.MaxLength() ) - { - // Calculate if we have enough space in the buffer for incoming body - if ( buffer.Length() + newBodyLength > buffer.MaxLength() ) + // Add data to the buffer + TRAPD( err, cacheBuffer.AppendL(remainder, aBodyStr) ); + if ( err == KErrNone ) + { + aCacheEntry.SetBodyDataCached(ETrue); + } + else { - // Incoming data is too big for the buffer - HBufC8* overflowBuffer = NULL; - TInt bufferSpaceLeft( -1 ); - TPtrC8 writePtr; + // We failed to allocate memory to store the new data in the current buffer. + // Check to see if it's possible to write it to disk instead. + TBool bodyFileCreated = CreateNewBodyFile( aCacheEntry ); + if ( !bodyFileCreated ) + { + return EFalse; + } - if ( buffer.Length() == 0 ) + TBool enoughSpace; + enoughSpace = IsDiskSpaceAvailable( cacheBuffer.Length() + remainder ); + if ( enoughSpace ) { - // Buffer is empty and the body is bigger than the buffer, - // just take all of the incoming data - writePtr.Set( aBodyStr ); + // In this case, we have not been able to store all the data. + // if there is enough space on disk to write everything we know + // about now, we will flush the current buffer out synchronously. + TInt block=0; + TInt count = cacheBuffer.Count(); + while ( bodySaved == KErrNone && count > block ) + { + TPtrC8 buf = cacheBuffer.GetSegmentData(block); + bodySaved = aCacheEntry.BodyFile().Write(buf); + } } else { - // We have some data in buffer, how much space do we have left - bufferSpaceLeft = buffer.MaxLength() - buffer.Length(); - - if ( newBodyLength - bufferSpaceLeft > buffer.MaxLength() ) - { - // Not enough space, so lets put the buffer and the new - // body together and write it in one go. - overflowBuffer = HBufC8::New( buffer.Length() + newBodyLength ); - if ( !overflowBuffer ) - { - return EFalse; - } - - TPtr8 overflowPtr( overflowBuffer->Des() ); - overflowPtr.Copy( buffer ); - overflowPtr.Append( aBodyStr ); - writePtr.Set( overflowBuffer->Des() ); - - // empty buffer - buffer.Zero(); - // no leftover left - bufferSpaceLeft = -1; - } - else - { - // Copy what we have enough space for - buffer.Append( aBodyStr.Left( bufferSpaceLeft ) ); - writePtr.Set( buffer ); - } + // disk too full, drop the cache data + bodySaved = KErrDiskFull; + // reset buffers + cacheBuffer.Reset(); } - // Write to the disk, if we have disk space - TInt writeErr( KErrNone ); - if ( IsDiskSpaceAvailable( writePtr.Length() ) ) - { - - if ( !aCacheEntry.CacheFilesOpened() ) - { - OpenCacheFiles( aCacheEntry ); - } - - // We have enough disk space, save body - TInt writeErr = aCacheEntry.BodyFile().Write( writePtr ); - bodySaved = ETrue; - } - else + if ( bodySaved == KErrNone ) { - // We don't have enough disk space, clean up - bodySaved = EFalse; - buffer.Zero(); - } - - if ( writeErr == KErrNone && bufferSpaceLeft >= 0 ) - { - // Copy what we can of the leftover in to the buffer - buffer.Copy( aBodyStr.Mid( bufferSpaceLeft ) ); + // We have completed writing out the cached data, now + // try to save the new data if we haven't run out of disk space. + bodySaved = aCacheEntry.BodyFile().Write(aBodyStr.Right(remainder)); } - delete overflowBuffer; + aCacheEntry.SetBodyDataCached(EFalse); + aCacheEntry.BodyFile().Close(); } - else - { - // We have enough space in buffer, add and wait for next body - // before writing to file - buffer.Append( aBodyStr ); - bodySaved = ETrue; - } - - // Body saved, update state + // update size information aCacheEntry.SetBodySize( aCacheEntry.BodySize() + newBodyLength ); iContentSize += aBodyStr.Length(); } - - return bodySaved; + return ( bodySaved == KErrNone ); } // ----------------------------------------------------------------------------- @@ -501,11 +390,15 @@ ELogEntrySize ); #endif - // Remove data + // Remove data iContentSize -= aCacheEntry.BodySize(); aCacheEntry.SetBodySize( 0 ); - aCacheEntry.CacheBuffer().Zero(); - aCacheEntry.BodyFile().SetSize( 0 ); + aCacheEntry.BodyData().Reset(); + if ( OpenBodyFile(aCacheEntry) ) + { + aCacheEntry.BodyFile().SetSize( 0 ); + aCacheEntry.BodyFile().Close(); + } } // ----------------------------------------------------------------------------- @@ -515,64 +408,141 @@ // TBool CHttpCacheStreamHandler::Flush( CHttpCacheEntry& aCacheEntry ) { - TBool saved( EFalse ); - TInt writeErr( KErrGeneral ); - TInt cacheBufferLen( aCacheEntry.CacheBuffer().Length() ); + TInt err( KErrNone ); + TBool bFlushed( EFalse ); - if ( cacheBufferLen && IsDiskSpaceAvailable( cacheBufferLen ) ) + TRAP( err, bFlushed = FlushL( aCacheEntry ) ); + if ( err || !bFlushed ) { - // We have enough space, save cache buffer - TPtr8 bufferPtr( aCacheEntry.CacheBuffer() ); - if ( bufferPtr.Length() ) - { - if ( !aCacheEntry.CacheFilesOpened() ) - { - OpenCacheFiles( aCacheEntry ); - } - - writeErr = aCacheEntry.BodyFile().Write( bufferPtr ); - if ( writeErr == KErrNone ) - { - saved = ETrue; - } - } - - // Clear the buffer - bufferPtr.Zero(); + return EFalse; } - return saved; + return ETrue; } // ----------------------------------------------------------------------------- -// CHttpCacheStreamHandler::OpenCacheFiles +// CHttpCacheStreamHandler::FlushL // // ----------------------------------------------------------------------------- // -TBool CHttpCacheStreamHandler::OpenCacheFiles( CHttpCacheEntry& aCacheEntry ) +TBool CHttpCacheStreamHandler::FlushL( CHttpCacheEntry& aCacheEntry ) { - TInt statusHeader( KErrNotFound ); + TInt saveOk( KErrNone ); + +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: >>StreamHander::Flush object %08x"), &aCacheEntry ); +#endif + CSegmentedHeapBuffer& cacheBuffer = aCacheEntry.BodyData(); + + TInt dataLength = cacheBuffer.Length() + aCacheEntry.HeaderData().Length(); + + if ( !IsDiskSpaceAvailable( dataLength ) || !CreateNewBodyFile( aCacheEntry ) ) + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: Flush failed: not enough space or cannot create file.")); +#endif + // can't flush if not enough space, or cannot create new files + return EFalse; + } + + // files are open, push them onto cleanup stack. + CleanupClosePushL( aCacheEntry.BodyFile() ); + + if ( aCacheEntry.BodyDataCached() ) + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: Body Data is Cached")); +#endif + // append body + TInt segment=0; + TInt count=cacheBuffer.Count(); +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: %d segments stored"), count); +#endif + while ( saveOk == KErrNone && count > segment ) + { + TPtrC8 segBuf = cacheBuffer.GetSegmentData(segment); + saveOk = aCacheEntry.BodyFile().Write( segBuf ); +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: segment %d write returned %d"), (segment-1), saveOk ); +#endif + } + + cacheBuffer.Reset(); + aCacheEntry.SetBodyDataCached(EFalse); + } + // close files + CleanupStack::PopAndDestroy(1); + + return ( saveOk == KErrNone ); + } + +// ----------------------------------------------------------------------------- +// CHttpCacheStreamHandler::FlushAsync +// +// ----------------------------------------------------------------------------- +// +TInt CHttpCacheStreamHandler::FlushAsync(CHttpCacheEntry& aEntry, TRequestStatus& aStatus) + { + TInt saveOk( KErrNone ); + + TInt datalen = aEntry.BodyData().Length() + aEntry.HeaderData().Length(); + +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: CHttpCacheStreamEntry::FlushAsync called on object %08x. Cached data %d bytes"), &aEntry, datalen ); +#endif + + if ( datalen && aEntry.BodyData().Length() ) // don't bother writing files which have no body data + { + if ( IsDiskSpaceAvailable( datalen ) && CreateNewBodyFile( aEntry ) ) + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: Triggering Async write for object 0x%08x."), &aEntry); +#endif + // trim any spare space available. + aEntry.BodyData().Compress(); + aEntry.WriteBodyDataAsync(aStatus); + aEntry.SetDelayedWriteInProgress(ETrue); + } + else + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: FAILED FlushAsync.")); +#endif + // !enoughSpace + saveOk = KErrDiskFull; + aEntry.BodyData().Reset(); + } + } + else + { +#ifdef __CACHELOG__ + HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: Not writing file %S for entry %08x since it has no data."), &(aEntry.Filename()), &aEntry ); +#endif + TRequestStatus* stat = &aStatus; + User::RequestComplete(stat, KErrNone); + } + + return ( saveOk == KErrNone ); + } + +// ----------------------------------------------------------------------------- +// CHttpCacheStreamHandler::OpenBodyFile +// ----------------------------------------------------------------------------- +// +TBool CHttpCacheStreamHandler::OpenBodyFile( CHttpCacheEntry& aCacheEntry ) + { TInt statusBody( KErrNotFound ); // get body filename TFileName bodyFileName = aCacheEntry.Filename(); - // header filename - TFileName headerFileName; - HttpCacheUtil::GetHeaderFileName( bodyFileName, headerFileName ); - - statusHeader = aCacheEntry.HeaderFile().Open( iRfs, headerFileName, EFileShareExclusive | EFileWrite ); statusBody = aCacheEntry.BodyFile().Open( iRfs, bodyFileName, EFileShareExclusive | EFileWrite ); - TBool fileOk( statusHeader == KErrNone && statusBody == KErrNone ); - if ( fileOk ) - { - aCacheEntry.SetCacheFilesOpened( ETrue ); - } - - return fileOk; + return ( statusBody == KErrNone ); } +#if 0 // ----------------------------------------------------------------------------- // CHttpCacheStreamHandler::CreateNewFilesL // @@ -582,40 +552,28 @@ { TInt statusHeader( KErrNotFound ); TInt statusBody( KErrNotFound ); - TPath sessionPath; - User::LeaveIfError( iRfs.SessionPath( sessionPath ) ); - - // Given the full URL, generates a fully qualified path for saving the HTTP response - HBufC* bodyFileName = HttpCacheUtil::GenerateNameLC( aCacheEntry.Url(), sessionPath ); - TPtrC bodyFileNamePtr( *bodyFileName ); - + // Create header file name from body file name TFileName headerFileName; - HttpCacheUtil::GetHeaderFileName( bodyFileNamePtr, headerFileName ); + HttpCacheUtil::GetHeaderFileName( aCacheEntry.Filename(), headerFileName ); - // Create the body file or replace it, if it exists. - statusBody = aCacheEntry.BodyFile().Replace( iRfs, bodyFileNamePtr, EFileShareExclusive | EFileWrite ); + // Create the body file or replace it, if it exists. + statusBody = aCacheEntry.BodyFile().Replace( iRfs, aCacheEntry.Filename(), EFileShareExclusive | EFileWrite ); if ( statusBody == KErrNone ) { // Header file should not fail statusHeader = aCacheEntry.HeaderFile().Replace( iRfs, headerFileName, EFileShareExclusive | EFileWrite ); } -#ifdef __CACHELOG__ +#ifdef __CACHELOG__ HttpCacheUtil::WriteUrlToLog( 0, bodyFileNamePtr, aCacheEntry.Url() ); -#endif +#endif TBool fileOk( statusHeader == KErrNone && statusBody == KErrNone ); - if ( fileOk ) + if ( !fileOk ) { - // Both body and header files created correctly - aCacheEntry.SetFileNameL( bodyFileNamePtr ); - aCacheEntry.SetState( CHttpCacheEntry::ECacheInitialized ); - } - else - { - // Only the body file created, no header file, delete body file - iRfs.Delete( bodyFileNamePtr ); + // Only the body file created, no header file, delete body file + iRfs.Delete( aCacheEntry.Filename() ); iRfs.Delete( headerFileName ); aCacheEntry.SetBodySize( 0 ); @@ -627,9 +585,35 @@ // __ASSERT_DEBUG( EFalse, User::Panic( _L("CHttpCacheHandler::CreateNewFilesL Panic"), KErrCorrupt ) ); } - CleanupStack::PopAndDestroy( bodyFileName ); + return fileOk; + } +#endif + +// ----------------------------------------------------------------------------- +// CHttpCacheStreamHandler::CreateNewBodyFile +// +// ----------------------------------------------------------------------------- +// +TBool CHttpCacheStreamHandler::CreateNewBodyFile( CHttpCacheEntry& aCacheEntry ) + { + TInt statusBody( KErrNotFound ); - return fileOk; + // Create the body file or replace it, if it exists. + statusBody = aCacheEntry.BodyFile().Replace( iRfs, aCacheEntry.Filename(), EFileShareExclusive | EFileWrite ); + +#ifdef __CACHELOG__ + HttpCacheUtil::WriteUrlToLog( 0, aCacheEntry.Filename(), aCacheEntry.Url() ); +#endif + + if ( statusBody != KErrNone ) + { + aCacheEntry.SetBodySize( 0 ); + aCacheEntry.BodyData().Reset(); +#ifdef __CACHELOG__ + HttpCacheUtil::WriteLog( 0, _L( "CHttpCacheEntry::CreateNewBodyFileL - create body file failed!" ) ); +#endif + } + return ( statusBody == KErrNone ); } // ----------------------------------------------------------------------------- @@ -641,7 +625,6 @@ const CHttpCacheEntry& aCacheEntry, TInt* aIndex ) { - *aIndex = -1; for ( TInt i = 0; i < iActiveEntries->Count(); i++ ) { CHttpCacheEntry* entry = iActiveEntries->At( i ); diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/src/HttpCacheUtil.cpp --- a/webengine/osswebengine/cache/src/HttpCacheUtil.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/cache/src/HttpCacheUtil.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -653,35 +653,43 @@ // ----------------------------------------------------------------------------- // TBool HttpCacheUtil::VSSCacheContent( const TDesC8& aUrl, const HBufC8* aWhiteList ) - { + { TBool found( EFalse ); - if( aWhiteList ) - { - TUint8* bufPtr = (TUint8* ) aWhiteList->Ptr(); - TUint8* startBufPtr = bufPtr; - TUint len = aWhiteList->Length(); - TInt i, startUri, uriLen; - TPtrC8 uri ( aUrl ); - for(i=0; i < len; i++) - { - startUri = i; - for( ;( ( *bufPtr != ';' ) && ( iPtr(); + TUint8* startBufPtr = bufPtr; + TUint len = aWhiteList->Length(); + TInt i, startUri, uriLen; + TPtrC8 uri ( aUrl ); + for ( i=0; i < len; i++ ) + { + startUri = i; + + for ( ;( ( *bufPtr != ';' ) && ( i expires) { return EFalse; } - + if( err == KErrNone || maxAge > 0 ) { hasExplicitCache = ETrue; @@ -1150,6 +1155,45 @@ } // ----------------------------------------------------------------------------- +// HttpCacheUtil::WriteFormatLog +// +// ----------------------------------------------------------------------------- +// +void HttpCacheUtil::WriteFormatLog( + TInt aLogLevel, + TRefByValue aBuf, ... ) + { +#ifdef __CACHELOG__ + TBool log( aLogLevel <= KCurrentLogLevel ); + TPtrC fileName( KHttpCacheGeneralFileName ); + + if ( aLogLevel == 1 ) + { + // write logging to hash.txt + fileName.Set( KHttpCacheHashFileName ); + log = ETrue; + } + + if ( log ) + { + VA_LIST args; + VA_START(args, aBuf); + // Be careful of string length when debugging + TBuf16<1024> string; + // TDes16OverflowIgnore, not supported in 3.2.3 + // TDes16OverflowIgnore overflow; + // string.AppendFormatList(aBuf, args, &overflow); + string.AppendFormatList(aBuf, args); + RFileLogger::WriteFormat(_L("Browser"), fileName, EFileLoggingModeAppend, string); + VA_END(args); + } +#else // __CACHELOG__ + (void)aLogLevel; + (void)aBuf; +#endif // __CACHELOG__ + } + +// ----------------------------------------------------------------------------- // HttpCacheUtil::WriteLogFilenameAndUrl // // ----------------------------------------------------------------------------- @@ -1170,7 +1214,7 @@ TInt tmpLen( aMethodName.Length() + aFilename.Length() + 3*KColonSpace().Length() + aUrl.Length() + itemTypeStringLen ); HBufC* tmp = HBufC::New( tmpLen ); - + if ( tmp ) { TPtr tmpPtr( tmp->Des() ); tmpPtr.Copy( aMethodName ); @@ -1198,17 +1242,17 @@ tmpPtr.Append( KColonSpace ); } } - + // Append the bucketIndex, lookup table pos, etc... switch ( aItemType ) { case ELogItemTypeNone: break; - + case ELogBucketIndex: tmpPtr.Append( _L("bucketIndex =") ); break; - + case ELogEntrySize: tmpPtr.Append( _L("entrySize =") ); break; @@ -1321,28 +1365,33 @@ // ----------------------------------------------------------------------------- // HttpCacheUtil::GenerateNameLC -// Given a URL, generates fully qualified Symbian path for storing HTTP response. -// The format is + + . -// Caller must free the returned HBufC* when done. +// Given a URL, generates fully qualified Symbian path for storing HTTP response. +// The format is + + . +// Caller must free the returned HBufC* when done. // ----------------------------------------------------------------------------- -HBufC* HttpCacheUtil::GenerateNameLC( - const TDesC8& aUrl, const TDesC& aBaseDir) +HBufC* HttpCacheUtil::GenerateNameLC( const TDesC8& aUrl, const TDesC& aBaseDir ) { - TUint32 crc (0); - - //use the entire URL for CRC calculation: maximizes source entropy/avoids collisions - Mem::Crc32(crc, aUrl.Ptr(), aUrl.Size()); - TUint32 nibble (crc & (KCacheSubdirCount-1)); // extract least significant 4 bits (nibble) for subdirectory - - HBufC* fileName = HBufC::NewLC( KMaxPath ); // e.g E\078AFEFE - _LIT(KFormat,"%S%x%c%08x"); // Note the %08x : a 32-bit value can represented as 0xFFFFFFFF + + // Use the entire URL for CRC calculation: maximizes source + // entropy/avoids collisions. Returns 8 char hex filename, use + // KMaxFilenameLength to internalize/externalize. + Mem::Crc32(crc, aUrl.Ptr(), aUrl.Size()); + + // extract least significant 4 bits (nibble) for subdirectory + TUint32 nibble( crc & (KCacheSubdirCount-1) ); + + // filename has full path, drive:\directory\sub-directory\8-char filename + // e.g. c:\system\cache\E\078AFEFE, where E is calculated by nibble() + // and 078AFEFE is calculated by crc32() + HBufC* fileName = HBufC::NewLC( KMaxPath ); + // Note in KFormat, the %08x : a 32-bit value can represented as 0xFFFFFFFF + _LIT(KFormat,"%S%x%c%08x"); fileName->Des().Format(KFormat, &aBaseDir, nibble, KPathDelimiter, crc); + return fileName; - } - // ----------------------------------------------------------------------------- // HttpCacheUtil::Freshness // @@ -1368,7 +1417,7 @@ // Get the date from the headers fieldName = aStrP.StringF( HTTP::EDate, RHTTPSession::GetTable() ); err = aHeaders.GetField( fieldName, 0, hdrValue ); - if( err == KErrNotFound || hdrValue.Type() != THTTPHdrVal::KDateVal ) + if ( err == KErrNotFound || hdrValue.Type() != THTTPHdrVal::KDateVal ) { date = aResponseTime; } @@ -1379,12 +1428,12 @@ // Get useful cache-control directives status = GetCacheControls( aHeaders, &maxAge, NULL, NULL, NULL, NULL, NULL, aStrP ); - if( status == KErrNone ) + if ( status == KErrNone ) { // max-age is in delta-seconds. Convert it to micro seconds. // All our calculations are in micro-seconds // If maxAge is present, use it - if( maxAge != -1 ) + if ( maxAge != -1 ) { freshness = maxAge * 1000 * 1000; @@ -1394,7 +1443,7 @@ // Get the expires from the headers fieldName = aStrP.StringF( HTTP::EExpires, RHTTPSession::GetTable() ); err = aHeaders.GetField( fieldName, 0, hdrValue ); - if( err == KErrNotFound || hdrValue.Type() != THTTPHdrVal::KDateVal ) + if ( err == KErrNotFound || hdrValue.Type() != THTTPHdrVal::KDateVal ) { expires = 0; } @@ -1404,7 +1453,7 @@ } // Otherwise, if the expires is present use it - if( err != KErrNotFound ) + if ( err != KErrNotFound ) { freshness = expires.Int64() - date.Int64(); return freshness; @@ -1423,7 +1472,7 @@ } // Otherwise, if last-modified is present use it - if( err != KErrNotFound ) + if ( err != KErrNotFound ) { if( aResponseTime > lastModified ) { diff -r 10e98eab6f85 -r a359256acfc6 webengine/webkitutils/HistoryProvider/HistoryController.cpp --- a/webengine/webkitutils/HistoryProvider/HistoryController.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/webkitutils/HistoryProvider/HistoryController.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -399,11 +399,11 @@ HistoryEntry* deadEntry = m_historyStack[index]; m_historyStack.Remove(index); delete deadEntry; - // Shift current page if removing previous pages - if (index <= m_currentIndex && m_currentIndex > 0) - { - m_currentIndex--; - } + // Shift current page if removing previous pages + if (index <= m_currentIndex && m_currentIndex >= 0) + { + m_currentIndex--; + } } } @@ -418,20 +418,23 @@ */ void HistoryController::updateGlobalHistoryForReload() { - HistoryEntry* entry = m_historyStack[m_currentIndex]; - entry->touch(); - updateCurrentEntryPositionIfNeeded(); + HistoryEntry* entry = entryByIndex(m_currentIndex); + if ( entry ) + { + entry->touch(); + updateCurrentEntryPositionIfNeeded(); + } } /** */ void HistoryController::goBackOrForward(int distance) -{ - m_tempCurrentIndex = m_currentIndex; - m_currentIndex += distance; - m_historyLoadOffset = distance; - const HistoryEntry* currentEntry = entryByIndex(m_currentIndex); +{ + const HistoryEntry* currentEntry = entryByIndex(m_currentIndex+distance); if (currentEntry) { + m_tempCurrentIndex = m_currentIndex; + m_currentIndex += distance; + m_historyLoadOffset = distance; TPtrC8 url = currentEntry->requestUrl(); m_historyCallback->doHistoryGet( url, TBrCtlDefs::ECacheModeHistory ); } diff -r 10e98eab6f85 -r a359256acfc6 webengine/webkitutils/ToolBar/ToolBar.cpp --- a/webengine/webkitutils/ToolBar/ToolBar.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/webkitutils/ToolBar/ToolBar.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -390,7 +390,7 @@ // ---------------------------------------------------------------------------- void CToolBar::UpdateCursorPosition() { - if (iButtonArray->Length() > 0 && iButtonArray->Length() >= iFocusedButtonIndex) { + if (iButtonArray->Count() > iFocusedButtonIndex) { CToolBarButton* b = iButtonArray->At(iFocusedButtonIndex); if (b) { TPoint pt = iPosition + b->Position() + TPoint(b->Size().iWidth/2,b->Size().iHeight/2); @@ -731,6 +731,7 @@ case EToolBarViewImages: { TRAP_IGNORE(iToolBarCallback->ViewImagesL()); + TRAP_IGNORE(iToolBarCallback->CloseToolBarL()); break; } diff -r 10e98eab6f85 -r a359256acfc6 webengine/webkitutils/loc/toolbar.loc --- a/webengine/webkitutils/loc/toolbar.loc Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/webkitutils/loc/toolbar.loc Thu Aug 27 07:44:59 2009 +0300 @@ -25,6 +25,11 @@ //w: //r: 5.0 #define qtn_browser_tooltip_recent_urls "Recent URLs" +//d: Tooltip text for display when hovering over a toolbar button. +//l: popup_preview_text_window_t1 +//w: +//r: 3.2 +#define qtn_browser_tooltip_frequently_used_urls "Frequently used URLs" //d: Tooltip text for display when hovering over a toolbar button. //l: popup_preview_text_window_t1 @@ -49,6 +54,17 @@ //w: //r: 5.0 #define qtn_browser_tooltip_subscribe_to_feeds "Subscribe to Feeds" +//d: Tooltip text for display when hovering over a toolbar button +//l: popup_preview_text_window_t1 +//w: +//r: 3.2 +#define qtn_browser_tooltip_find "Find In Page" + +//d: Tooltip text for display when hovering over a toolbar button +//l: popup_preview_text_window_t1 +//w: +//r: 3.2 +#define qtn_browser_tootip_list_subscribe_to "Subscribe To" //d: Tooltip text for display when hovering over a toolbar button. //l: popup_preview_text_window_t1 diff -r 10e98eab6f85 -r a359256acfc6 webengine/widgetbackuprestore/Src/WidgetActiveCallback.cpp --- a/webengine/widgetbackuprestore/Src/WidgetActiveCallback.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/widgetbackuprestore/Src/WidgetActiveCallback.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -27,7 +27,7 @@ _LIT(KWidgetUiPath, "\\private\\10282822\\"); _LIT(KWidgetBURTempPath, "WidgetBURTemp\\"); _LIT(KWidgetBURDummy, "dummy data for backup"); - +_LIT( KWidgetEntryStoreXmlFile, "\\private\\10282f06\\WidgetEntryStore.xml" ); // ======== MEMBER FUNCTIONS ======== // --------------------------------------------------------------------------- @@ -277,6 +277,8 @@ // Move widget data to BUR path CFileMan* fileManager = CFileMan::NewL( iFs ); CleanupStack::PushL( fileManager ); + // Prepare to backup the registration files + User::LeaveIfError( fileManager->Copy( KWidgetEntryStoreXmlFile, KWidgetUiPath, CFileMan::EOverWrite ) ); User::LeaveIfError( fileManager->Move( KWidgetUiPath, *iPathBUR, CFileMan::ERecurse ) ); CleanupStack::PopAndDestroy(); // fileMananger } diff -r 10e98eab6f85 -r a359256acfc6 webengine/widgetengine/inc/WidgetJSObjectProtector.h --- a/webengine/widgetengine/inc/WidgetJSObjectProtector.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/widgetengine/inc/WidgetJSObjectProtector.h Thu Aug 27 07:44:59 2009 +0300 @@ -1,5 +1,5 @@ /* -* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies). +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). * All rights reserved. * This component and the accompanying materials are made available * under the terms of the License "Eclipse Public License v1.0" @@ -11,7 +11,7 @@ * * Contributors: * -* Description: +* Description: Interface MJSObjectProtector * */ diff -r 10e98eab6f85 -r a359256acfc6 webengine/widgetinstaller/Inc/WidgetBackupRegistryXml.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/widgetinstaller/Inc/WidgetBackupRegistryXml.h Thu Aug 27 07:44:59 2009 +0300 @@ -0,0 +1,163 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: This file contains the header file of the CWidgetBackupRegistryXml class. +* +* This class processes persistent registry data in XML. +* +*/ + + +#ifndef WIDGETBACKUPREGISTRYXML_H +#define WIDGETBACKUPREGISTRYXML_H + +// INCLUDES +#include +#include "WidgetRegistryConstants.h" +#include "WidgetPropertyValue.h" + +class RFs; +/** +* CWidgetBackupRegistryXml +* @since 5.0 +*/ +class CWidgetBackupRegistryXml: public CBase + { +public: + + /** + * Two-phased constructor. + */ +// static CWidgetBackupRegistryXml* NewL(); + static CWidgetBackupRegistryXml* NewL(); + + /** + * Destructor. + */ + virtual ~CWidgetBackupRegistryXml(); + +protected: + + /** + * C++ default constructor. + */ + CWidgetBackupRegistryXml(); + + /** + * Symbian 2nd phase constructor + */ + void ConstructL(); + +public: + + /** + * Traverse to the next Node + * + * @param aNode: current node + * @since 5.0 + * @return next node + */ + xmlNode* TraverseNextNode( xmlNode* aNode ); + + /** + * Convert a string in some encoding to UCS2. + * + * @param aEncoding encoding number + * @param aUnicodeSizeMultiplier how many input bytes per unicode char + * @param aInBuf input data + * @param aOutBuf output data, allocated and returned to caller + * @param aFileSession + * @since 5.0 + * @return void + */ + void ToUnicodeL( TInt aEncoding, + TInt aUnicodeSizeMultiplier, + TPtrC8 aInBuf, HBufC16** aOutBuf, + RFs& aFileSession ); + + /** + * Convert a string to some encoding from UCS2. + * + * @param aEncoding encoding number + * @param aUnicodeSizeMultiplier how many input bytes per unicode char + * @param aInBuf input data + * @param aOutBuf output data, allocated and returned to caller + * @param aFileSession + * @since 5.0 + * @return void + */ + void FromUnicodeL( TInt aEncoding, + TInt aUnicodeSizeMultiplier, + TPtrC16 aInBuf, HBufC8** aOutBuf, + RFs& aFileSession ); + + + /** + * Utility to bundle extraction of XML text content + * + * @param aEncoding input buffer encoding + * @param aUnicodeSizeMultiplier how many bytes of input make one unicode char + * @param aInBuf input data in encoding + * @param aOutBuf malloc'ed output buf, caller takes ownership + * @param aFileSession CCnvCharacterSetConverter requires it + * @since 5.0 + * @return void + */ + void GetContentL( RFs& aFileSession, + xmlDocPtr aDoc, + xmlNode* aNode, + HBufC** aContent ); + + /** + * Utility to extract XML content as a string + * + * @param aFileSession CCnvCharacterSetConverter requires it + * @param aDoc + * @param aNode + * @param aContent + * @since 5.0 + * @return void + */ + void GetTextContentAsStringL( RFs& aFileSession, + xmlDocPtr aDoc, + xmlNode* aNode, + HBufC** aContent ); + + void GetSubtreeAsStringL (RFs& aFileSession, xmlDocPtr aDoc, xmlNode* aNode, HBufC** aBuf, TInt& aLen); + + xmlChar* EncodeStringL(xmlDocPtr aDoc, xmlChar* aStringToConvert); + HBufC* EncodeStringL(xmlDocPtr aDoc, TPtrC aStringToConvert, RFs& aFileSession); + + TInt EncodedStringLength(TPtrC8 aStringToConvert); + + TInt GetPropertyId( + const TDesC& aKeyName ); + + const TPtrC& XmlPropertyName( TInt aPropertyId ); + + class TWidgetProperty + { + public: + TInt id; // the TWidgetPropertyId for this name + TPtrC name; + TWidgetPropertyType type; // the type if valid + TInt flags; + }; + + // Table describing registry entries for XML processing. Used by + // parser and generator. + + RArray iProperties; + }; + +#endif // WIDGETREGISTRYXML_H diff -r 10e98eab6f85 -r a359256acfc6 webengine/widgetinstaller/Inc/WidgetInstaller.h --- a/webengine/widgetinstaller/Inc/WidgetInstaller.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/widgetinstaller/Inc/WidgetInstaller.h Thu Aug 27 07:44:59 2009 +0300 @@ -148,6 +148,13 @@ */ TInt PreprocessWidgetBundleL( TDesC& aRestoreDir ); + /** + * Fix the widget properties need to restore from the backup + * @return void + * @since 5.0 + */ + void FixWidgetPropsL(); + void ProcessRestoreDirL( TDesC& aRestoreDir ); /** diff -r 10e98eab6f85 -r a359256acfc6 webengine/widgetinstaller/Src/WidgetBackupRegistryXml.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/widgetinstaller/Src/WidgetBackupRegistryXml.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -0,0 +1,550 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Processes registry persistent data in XML. +* +*/ + + +#include +#include +#include +#include +#include +#include "WidgetBackupRegistryXml.h" + +_LIT( KPropertyListVersion, "PropertyListVersion" ); +_LIT( KBundleIdentifier, "BundleIdentifier" ); +_LIT( KBundleName, "BundleName" ); +_LIT( KBundleDisplayName, "BundleDisplayName" ); +_LIT( KMainHTML, "MainHTML" ); +_LIT( KBundleShortVersion, "BundleShortVersion" ); +_LIT( KBundleVersion, "BundleVersion" ); +_LIT( KHeight, "Height" ); +_LIT( KWidth, "Width" ); +_LIT( KAllowFullAccess, "AllowFullAccess" ); +_LIT( KAllowNetworkAccess, "AllowNetworkAccess" ); +_LIT( KDriveName, "DriveName" ); +_LIT( KBasePath, "BasePath" ); +_LIT( KIconPath, "IconPath" ); +_LIT( KUrl, "Url" ); +_LIT( KFileSize, "FileSize" ); +_LIT( KUid, "Uid" ); +_LIT( KNokiaWidget, "NokiaWidget" ); +_LIT( KMiniViewEnabled, "MiniViewEnabled" ); +_LIT( KBlanketPermGranted, "BlanketPermissionGranted" ); // optional + +// ============================================================================ +// CWidgetBackupRegistryXml::NewL() +// two-phase constructor +// +// @since 5.0 +// ============================================================================ +// +CWidgetBackupRegistryXml* CWidgetBackupRegistryXml::NewL() + { + CWidgetBackupRegistryXml *self = new (ELeave) CWidgetBackupRegistryXml(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +// ============================================================================ +// CWidgetBackupRegistryXml::CWidgetBackupRegistryXml() +// C++ constructor +// +// @since 5.0 +// ============================================================================ +// +CWidgetBackupRegistryXml::CWidgetBackupRegistryXml() : iProperties(EWidgetPropertyIdCount) + { + } + +// ============================================================================ +// CWidgetUIConfigHandler::ConstructL() +// C++ constructor +// +// @since 5.0 +// ============================================================================ +// +void CWidgetBackupRegistryXml::ConstructL() + { + TWidgetProperty property; + + property.id = EWidgetPropertyListVersion; + property.name.Set( KPropertyListVersion ); + property.type = EWidgetPropTypeInt; + iProperties.AppendL(property); + // + property.id = EBundleIdentifier; + property.name.Set( KBundleIdentifier ); + property.type = EWidgetPropTypeString; + iProperties.AppendL(property); + // + property.id = EBundleName; + property.name.Set( KBundleName ); + property.type = EWidgetPropTypeString; + iProperties.AppendL(property); + // + property.id = EBundleDisplayName; + property.name.Set( KBundleDisplayName ); + property.type = EWidgetPropTypeString; + iProperties.AppendL(property); + // + property.id = EMainHTML; + property.name.Set( KMainHTML ); + property.type = EWidgetPropTypeString; + iProperties.AppendL(property); + // + property.id = EBundleShortVersion; + property.name.Set( KBundleShortVersion ); + property.type = EWidgetPropTypeString; + iProperties.AppendL(property); + // + property.id = EBundleVersion; + property.name.Set( KBundleVersion ); + property.type = EWidgetPropTypeString; + iProperties.AppendL(property); + // + property.id = EHeight; + property.name.Set( KHeight ); + property.type = EWidgetPropTypeInt; + iProperties.AppendL(property); + // + property.id = EWidth; + property.name.Set( KWidth ); + property.type = EWidgetPropTypeInt; + iProperties.AppendL(property); + // + property.id = EAllowFullAccess; + property.name.Set( KAllowFullAccess ); + property.type = EWidgetPropTypeInt; + iProperties.AppendL(property); + // + property.id = EAllowNetworkAccess; + property.name.Set( KAllowNetworkAccess ); + property.type = EWidgetPropTypeInt; + iProperties.AppendL(property); + // + property.id = EDriveName; + property.name.Set( KDriveName ); + property.type = EWidgetPropTypeString; + iProperties.AppendL(property); + // + property.id = EBasePath; + property.name.Set( KBasePath ); + property.type = EWidgetPropTypeString; + iProperties.AppendL(property); + // + property.id = EIconPath; + property.name.Set( KIconPath ); + property.type = EWidgetPropTypeString; + iProperties.AppendL(property); + // + property.id = EUrl; + property.name.Set( KUrl ); + property.type = EWidgetPropTypeString; + iProperties.AppendL(property); + // + property.id = EFileSize; + property.name.Set( KFileSize ); + property.type = EWidgetPropTypeInt; + iProperties.AppendL(property); + // + property.id = EUid; + property.name.Set( KUid ); + property.type = EWidgetPropTypeInt; // not TUid + iProperties.AppendL(property); + // + property.id = ENokiaWidget; + property.name.Set( KNokiaWidget ); + property.type = EWidgetPropTypeInt; + iProperties.AppendL(property); + // + property.id = EMiniViewEnable; + property.name.Set( KMiniViewEnabled ); + property.type = EWidgetPropTypeInt; + iProperties.AppendL(property); + // + property.id = EBlanketPermGranted; + property.name.Set( KBlanketPermGranted ); + property.type = EWidgetPropTypeInt; + iProperties.AppendL(property); + } + +// ============================================================================ +// CWidgetBackupRegistryXml::~CWidgetBackupRegistryXml() +// destructor +// +// @since 5.0 +// ============================================================================ +// +CWidgetBackupRegistryXml::~CWidgetBackupRegistryXml() + { + for (TInt i = iProperties.Count() - 1; i >= EWidgetPropertyIdCount; i--) + { + TUint16* name = const_cast(iProperties[i].name.Ptr()); + iProperties[i].name.Set(KNullDesC); + delete [] name; + } + iProperties.Reset(); + iProperties.Close(); + } + +// ============================================================================ +// Get the property descriptiont by finding entry for name. +// +// @param aPropName The name of the prop: propName +// @since 5.0 +// @return prop type. +// ============================================================================ +// +TInt CWidgetBackupRegistryXml::GetPropertyId( + const TDesC& aPropName ) + { + TInt i = 0; + for (; i < iProperties.Count(); ++i ) + { + // use case insensitive match for property names + if ( 0 == aPropName.CompareF( iProperties[i].name ) ) + { + return iProperties[i].id; + } + } + TUint16* name = NULL; + name = new TUint16 [aPropName.Length()]; + if (name) + { + TPtr namePtr(name, aPropName.Length()); + namePtr.Copy(aPropName); + TWidgetProperty property; + property.id = iProperties.Count(); + property.name.Set( namePtr ); + property.type = EWidgetPropTypeUnknown; + TInt err = iProperties.Append(property); + if (err == KErrNone) + { + return iProperties.Count() - 1; + } + delete name; + } + return EWidgetPropertyIdInvalid; + } + +// ============================================================================ +// Get the property name from the property id. Used in entry Externalize +// +// @param aPropertyId property id +// @since 5.0 +// @return property name. +// ============================================================================ +// + +const TPtrC& CWidgetBackupRegistryXml::XmlPropertyName( + TInt aPropertyId ) + { + for ( TInt i = 0; i < iProperties.Count(); i++ ) + { + if ( iProperties[i].id == aPropertyId ) + { + return iProperties[i].name; + } + } + return iProperties[0].name; // should never get here + } + + +// ============================================================================ +// CWidgetBackupRegistryXml::ToUnicodeL +// Utility to bundle transcoding to unicode steps. +// +// @since 5.0 +// @param aEncoding input buffer encoding +// @param aUnicodeSizeMultiplier how many bytes of input make one unicode char +// @param aInBuf input data in encoding +// @param aOutBuf malloc'ed output buf, caller takes ownership +// @param aFileSession CCnvCharacterSetConverter requires it +// ============================================================================ +// +void CWidgetBackupRegistryXml::ToUnicodeL( TInt aEncoding, + TInt aUnicodeSizeMultiplier, + TPtrC8 aInBuf, HBufC16** aOutBuf, + RFs& aFileSession ) + { + *aOutBuf = NULL; + + // outbuf sizing and alloction + HBufC16* outBuf = HBufC16::NewLC(aUnicodeSizeMultiplier * aInBuf.Length()); + TPtr16 outPtr = outBuf->Des(); + + // convert to unicode + CCnvCharacterSetConverter* charConv = CCnvCharacterSetConverter::NewLC(); + charConv->PrepareToConvertToOrFromL( aEncoding, aFileSession ); + TInt state = CCnvCharacterSetConverter::KStateDefault; + TInt rep = 0; // number of unconvertible characters + TInt rIndx = 0; // index of first unconvertible character + User::LeaveIfError( + charConv->ConvertToUnicode( outPtr, aInBuf, state, rep, rIndx ) ); + CleanupStack::PopAndDestroy( charConv ); + + CleanupStack::Pop( outBuf ); + *aOutBuf = outBuf; + } + +// ============================================================================ +// CWidgetBackupRegistryXml::FromUnicodeL +// Utility to bundle transcoding to unicode steps. +// +// @since 5.0 +// @param aEncoding input buffer encoding +// @param aUnicodeSizeMultiplier how many bytes of input make one unicode char +// @param aInBuf input data in encoding +// @param aOutBuf malloc'ed output buf, caller takes ownership +// @param aFileSession CCnvCharacterSetConverter requires it +// ============================================================================ +// +void CWidgetBackupRegistryXml::FromUnicodeL( TInt aEncoding, + TInt aUnicodeSizeMultiplier, + TPtrC16 aInBuf, HBufC8** aOutBuf, + RFs& aFileSession ) + { + *aOutBuf = NULL; + + // outbuf sizing and alloction + HBufC8* outBuf = HBufC8::NewLC(aUnicodeSizeMultiplier * (aInBuf.Length() + 1)); + TPtr8 outPtr = outBuf->Des(); + + // convert from unicode + CCnvCharacterSetConverter* charConv = CCnvCharacterSetConverter::NewLC(); + charConv->PrepareToConvertToOrFromL( aEncoding, aFileSession ); + User::LeaveIfError( + charConv->ConvertFromUnicode( outPtr, aInBuf)); + outPtr.ZeroTerminate(); + CleanupStack::PopAndDestroy( charConv ); + + CleanupStack::Pop( outBuf ); + *aOutBuf = outBuf; + } + +// ============================================================================ +// CWidgetBackupRegistryXml::GetContentL +// Utility to bundle extraction of XML text content +// +// @since 5.0 +// @param aEncoding input buffer encoding +// @param aUnicodeSizeMultiplier how many bytes of input make one unicode char +// @param aInBuf input data in encoding +// @param aOutBuf malloc'ed output buf, caller takes ownership +// @param aFileSession CCnvCharacterSetConverter requires it +// ============================================================================ +// +void CWidgetBackupRegistryXml::GetContentL( RFs& aFileSession, + xmlDocPtr aDoc, + xmlNode* aNode, + HBufC** aContent ) + { + // xml uses UTF-8 for the internal representation + xmlChar* xmlContent = + xmlNodeListGetString( aDoc, aNode, 1 /* expand entities inline */); + if ( NULL == xmlContent ) + { + User::Leave( OOM_FLAG ? KErrNoMemory : KErrCorrupt ); + } + // we must transcode UTF-8 to UCS-2 (historical + // and now inaccurate name "unicode") + CleanupStack::PushL( xmlContent ); + TPtrC8 content( xmlContent ); + ToUnicodeL( KCharacterSetIdentifierUtf8, 2, + content, aContent, aFileSession ); + CleanupStack::PopAndDestroy(); // xmlContent equivalent to xmlFree() + if ( NULL == *aContent ) + { + User::Leave( KErrCorrupt ); + } + } + +// ============================================================================ +// CWidgetBackupRegistryXml::GetTextContentAsStringL +// +// ============================================================================ +// +void CWidgetBackupRegistryXml::GetTextContentAsStringL( RFs& aFileSession, xmlDocPtr aDoc, + xmlNode* aNode, HBufC** aContent ) + { + HBufC* tmpBuf = NULL; + TInt len = 0; + GetSubtreeAsStringL (aFileSession, aDoc, aNode, NULL, len); + tmpBuf = HBufC::NewLC(len); + GetSubtreeAsStringL (aFileSession, aDoc, aNode, &tmpBuf, len); + *aContent = tmpBuf; + CleanupStack::Pop(); // tmpBuf + } + +void CWidgetBackupRegistryXml::GetSubtreeAsStringL (RFs& aFileSession, xmlDocPtr aDoc, xmlNode* aNode, HBufC** aBuf, TInt& aLen) + { + xmlNode* node = aNode; + switch (node->type) + { + case XML_ELEMENT_NODE: + { + const xmlChar* name = node->name; + TPtrC8 tmpName(name); + if (aBuf) + { + HBufC* tmpBuf = NULL; + ToUnicodeL( KCharacterSetIdentifierUtf8, 2, + tmpName, &tmpBuf, aFileSession ); + CleanupStack::PushL(tmpBuf); + (*aBuf)->Des().Append(_L("<")); + (*aBuf)->Des().Append(*tmpBuf); + (*aBuf)->Des().Append(_L(">")); + if (node->children) + { + GetSubtreeAsStringL (aFileSession, aDoc, node->children, aBuf, aLen); + } + (*aBuf)->Des().Append(_L("Des().Append(*tmpBuf); + (*aBuf)->Des().Append(_L(">")); + CleanupStack::PopAndDestroy(tmpBuf); + } + else + { + aLen += (5 + 2 * tmpName.Length()); + if (node->children) + { + GetSubtreeAsStringL (aFileSession, aDoc, node->children, aBuf, aLen); + } + } + break; + } + //case XML_ATTRIBUTE_NODE: + case XML_TEXT_NODE: + { + xmlChar* content = node->content; + TPtrC8 tmpContent(content); + if (aBuf) + { + HBufC* tmpBuf = NULL; + xmlChar* encodedContent = EncodeStringL(aDoc, content); + CleanupStack::PushL( encodedContent ); + TPtrC8 encodedContentPtr(encodedContent); + ToUnicodeL( KCharacterSetIdentifierUtf8, 2, + encodedContentPtr, &tmpBuf, aFileSession ); + CleanupStack::PushL(tmpBuf); + (*aBuf)->Des().Append(*tmpBuf); + CleanupStack::PopAndDestroy(2); // encodedContent, tmpBuf + } + else + { + aLen += EncodedStringLength(tmpContent); + } + break; + } + case XML_CDATA_SECTION_NODE: + { + xmlChar* content = node->content; + TPtrC8 tmpContent(content); + if (aBuf) + { + HBufC* tmpBuf = NULL; + ToUnicodeL( KCharacterSetIdentifierUtf8, 2, + content, &tmpBuf, aFileSession); + CleanupStack::PushL(tmpBuf); + (*aBuf)->Des().Append(_L("Des().Append(*tmpBuf); + (*aBuf)->Des().Append(_L("]]>")); + CleanupStack::PopAndDestroy(); // tmpBuf + } + else + { + aLen += (12 + tmpContent.Length()); + } + break; + } + //case XML_ENTITY_REF_NODE: + //case XML_ENTITY_NODE: + //case XML_PI_NODE: + //case XML_COMMENT_NODE: + //case XML_DOCUMENT_NODE: + //case XML_DOCUMENT_TYPE_NODE: + //case XML_DOCUMENT_FRAG_NODE: + //case XML_NOTATION_NODE: + //case XML_HTML_DOCUMENT_NODE: + //case XML_DTD_NODE: + //case XML_ELEMENT_DECL: + //case XML_ATTRIBUTE_DECL: + //case XML_ENTITY_DECL: + //case XML_NAMESPACE_DECL: + //case XML_XINCLUDE_START: + //case XML_XINCLUDE_END: + } + if (node->next) + { + node = node->next; + GetSubtreeAsStringL(aFileSession, aDoc, node, aBuf, aLen); + } + } + +xmlChar* CWidgetBackupRegistryXml::EncodeStringL(xmlDocPtr aDoc, xmlChar* aStringToConvert) + { + xmlChar* noEntitiesContent = xmlEncodeSpecialChars(aDoc, aStringToConvert); + if ( NULL == noEntitiesContent ) + { + User::Leave( OOM_FLAG ? KErrNoMemory : KErrCorrupt ); + } + return noEntitiesContent; + } + +HBufC* CWidgetBackupRegistryXml::EncodeStringL(xmlDocPtr aDoc, TPtrC aStringToConvert, RFs& aFileSession) + { + HBufC8* out = NULL; + FromUnicodeL( KCharacterSetIdentifierUtf8, 2, aStringToConvert, &out, aFileSession ); + CleanupStack::PushL(out); + xmlChar* noEntitiesContent = xmlEncodeSpecialChars(aDoc, out->Des().Ptr()); + if ( NULL == noEntitiesContent ) + { + User::Leave( OOM_FLAG ? KErrNoMemory : KErrCorrupt ); + } + CleanupStack::PushL( noEntitiesContent ); + TPtrC8 noEntitiesPtr(noEntitiesContent); + HBufC* noEntitiesBuf = NULL; + noEntitiesBuf = HBufC::NewL(noEntitiesPtr.Length()); + noEntitiesBuf->Des().Copy(noEntitiesPtr); + CleanupStack::PopAndDestroy(2, out); // out, noEntitiesContent + + return noEntitiesBuf; + } + + +TInt CWidgetBackupRegistryXml::EncodedStringLength(TPtrC8 aStringToConvert) + { + _LIT(KEntity, "\"&\r<>"); + if (aStringToConvert.Length() == 0 ) return 0; + TInt entityLength[] = {6,5,5,4,4}; + TInt i; + TInt count = 0; + for (i = 0; i < aStringToConvert.Length(); i++) + { + TInt entityIndex = KEntity().Locate(aStringToConvert[i]); + if (entityIndex != KErrNotFound) + { + count+= entityLength[entityIndex]; + } + else + { + count++; + } + } + return count; + } diff -r 10e98eab6f85 -r a359256acfc6 webengine/widgetinstaller/Src/WidgetInstaller.cpp --- a/webengine/widgetinstaller/Src/WidgetInstaller.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/widgetinstaller/Src/WidgetInstaller.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -23,10 +23,22 @@ #include #include +#include +#include +#include +#include + +#include "Browser_platform_variant.hrh" + +#ifdef BRDO_SYMBIAN_LIBXML_FF +#include +#endif + #include "WidgetInstaller.h" #include "WidgetConfigHandler.h" // info.plist parser #include "WidgetRegistrationManager.h" // interface to "shell" #include "IconConverter.h" +#include "WidgetBackupRegistryXml.h" // CONSTANTS _LIT( KInfoPList,"Info.plist" ); @@ -34,6 +46,18 @@ _LIT( KMBMExt, ".mbm"); _LIT( KLprojExt, ".lproj" ); _LIT( KInfoPlistStrings, "InfoPlist.strings" ); +_LIT( KWidgetPropFile, "\\private\\10282822\\WidgetEntryStore.xml" ); + +// For parsing backedup registration file +_LIT8( KWidgetRegistry, "widgetregistry" ); +_LIT8( KEntry, "entry" ); +_LIT8( KXmlPropTag, "prop" ); +_LIT8( KXmlValTag, "val" ); +_LIT8( KXmlTypeTag, "type" ); +_LIT( KXmlDataTypeBool, "bool" ); +_LIT( KXmlDataTypeInt, "int" ); +_LIT( KXmlDataTypeString, "string" ); +_LIT( KXmlDataTypeUid, "uid" ); // TODO MW has a hard dependency to APP domain. Not very good... // TODO Hard-coded UID. @@ -250,6 +274,273 @@ return found; } + +// ============================================================================ +// CWidgetInstaller::FixWidgetPropsL() +// Handles preprocessing of widget properties +// +// @since 5.0 +// ============================================================================ +// +void CWidgetInstaller::FixWidgetPropsL() + { + TInt backupBlanketPerm = -1; + + CWidgetBackupRegistryXml* aXmlProcessor = CWidgetBackupRegistryXml::NewL(); + RPointerArray backupPropertyValues; + + TInt i = 0; + // empty values + for ( ; i < EWidgetPropertyIdCount; ++i ) + { + CWidgetPropertyValue* value = CWidgetPropertyValue::NewL(); + CleanupStack::PushL( value ); + User::LeaveIfError( backupPropertyValues.Insert( value, i ) ); + CleanupStack::Pop( value ); + } + +// Algorithm +// 1. Look for the entry +// 2. Check if the EBundleIdentifier is what we are looking for +// 3. If so, looking for the value of EBlanketPermGranted +// 4. If exist, then we fix it + // hardcode the filename first + RFile file; + TFileName propFile( KWidgetPropFile ); + User::LeaveIfError( file.Open( iRfs, propFile, EFileRead )); + CleanupClosePushL( file ); + + TInt size; + User::LeaveIfError ( file.Size ( size )); + HBufC8* buf = HBufC8::NewLC ( size ); + TPtr8 bufPtr ( buf->Des() ); + User::LeaveIfError( file.Read( bufPtr ) ); + + // initialize the parser and check compiled code matches lib version + LIBXML_TEST_VERSION + + xmlDocPtr doc; + doc = xmlReadMemory( (const char *)bufPtr.Ptr(), bufPtr.Length(), + NULL, + NULL, + 0); + if ( !doc ) + { + User::Leave( KErrCorrupt ); + } + + xmlNode* rootElement = xmlDocGetRootElement( doc ); + TPtrC8 rootTag( rootElement->name ); + if ( 0 != rootTag.Compare( KWidgetRegistry() ) ) + { + User::Leave( KErrCorrupt ); + } + + for ( xmlNode* m = rootElement->children; + m; + m = m->next ) + { + if ( m->type == XML_ELEMENT_NODE ) + { + TPtrC8 element( m->name ); + + if ( 0 == element.Compare( KEntry() ) ) + { + backupBlanketPerm = -1; // reset this value for every entry + if ( NULL == m->children ) + { + // malformed? should we require entry to have + // some minimal info? + continue; + } + + // extract one entry + xmlNode* n; + n = m->children; + for ( ; + n; + ) + { + while ( n && ( n->type != XML_ELEMENT_NODE )) + { + n = n->next; + } + if ( NULL == n ) + { + break; + } + + TPtrC8 propTag( n->name ); + if ( 0 != propTag.Compare( KXmlPropTag() ) ) + { + // unrecognized subtree? + break; + } + // validate n->children != NULL and type XML_TEXT_NODE + HBufC* name; + aXmlProcessor->GetContentL( iRfs, doc, n->children, &name ); + + // get value array index (TWidgetPropertyId) for name + TPtr namePtr( name->Des() ); + TInt propId = + aXmlProcessor->GetPropertyId( namePtr ); + delete name; + name = NULL; + if ( EWidgetPropertyIdInvalid == propId ) + { + User::Leave( KErrNoMemory ); + } + + n = n->children->next; // down to val + if ( NULL == n ) + { + User::Leave( KErrCorrupt ); + } + TPtrC8 valTag( n->name ); + if ( 0 != valTag.Compare( KXmlValTag() ) ) + { + User::Leave( KErrCorrupt ); + } + if (propId >= EWidgetPropertyIdCount) // unsupported property + { + HBufC* value = NULL; + if (n->children) + { + aXmlProcessor->GetTextContentAsStringL( iRfs, doc, n->children, &value ); + } + else + { + value = KNullDesC().AllocL(); + } + + n = (n->parent)->next; // up two and next sibling + continue; + } + HBufC* value; + aXmlProcessor->GetContentL( iRfs, doc, n->children, &value ); + CleanupStack::PushL( value ); + + n = n->children->next; // down to type + if ( NULL == n ) + { + User::Leave( KErrCorrupt ); + } + TPtrC8 typeTag( n->name ); + if ( 0 != typeTag.Compare( KXmlTypeTag() ) ) + { + User::Leave( KErrCorrupt ); + } + // validate n->children != NULL and type XML_TEXT_NODE + HBufC* type; + aXmlProcessor->GetContentL( iRfs, doc, n->children, &type ); + CleanupStack::PushL( type ); + // + // assume void/unknown is not put in XML format so anything + // not recognized should be handled like other unrecognized + // subtree + TWidgetPropertyType typeEnum = EWidgetPropTypeUnknown; + if ( 0 == type->Des().Compare( KXmlDataTypeBool() ) ) + { + typeEnum = EWidgetPropTypeBool; + } + else if ( 0 == type->Des().Compare( KXmlDataTypeInt() ) ) + { + typeEnum = EWidgetPropTypeInt; + } + else if ( 0 == type->Des().Compare( KXmlDataTypeString() ) ) + { + typeEnum = EWidgetPropTypeString; + } + else if ( 0 == type->Des().Compare( KXmlDataTypeUid() ) ) + { + typeEnum = EWidgetPropTypeUid; + } + CleanupStack::PopAndDestroy( type ); + + // set prop according to type + switch ( typeEnum ) + { + case EWidgetPropTypeBool: + if ( 0 == value->Des().Compare( _L("0") ) ) + { + *backupPropertyValues[propId] = 0; + } + else + { + *(backupPropertyValues[propId]) = 1; + } + break; + + case EWidgetPropTypeInt: + TLex toInt( value->Des() ); + TInt k; + if ( KErrNone != toInt.Val( k ) ) + { + User::Leave( KErrCorrupt ); + } + if ( propId == EBlanketPermGranted ) + backupBlanketPerm = k; + break; + + case EWidgetPropTypeString: + *(backupPropertyValues[propId]) = *value; + break; + + case EWidgetPropTypeUid: + { + TLex toUid( value->Des() ); + TInt u; + if ( KErrNone != toUid.Val( u ) ) + { + User::Leave( KErrCorrupt ); + } + *(backupPropertyValues[propId]) = TUid::Uid( u ); + } + break; + }; + + CleanupStack::Pop( value ); + if ( EWidgetPropTypeString != typeEnum ) + { + delete value; + } + + n = ((n->parent)->parent)->next; // up two and next sibling + } + // Compare to see if it's this widget + if ( 0 == (iPropertyValues[EBundleIdentifier]->iValue.s)->Compare(*backupPropertyValues[EBundleIdentifier]->iValue.s) ) + { + if ( backupBlanketPerm != -1 ) + { + (*iPropertyValues[EBlanketPermGranted]) = backupBlanketPerm; + } + break; + } + } // if + } // if n is element + } // for + + + TInt j = 0; + for ( ; j < EWidgetPropertyIdCount; ++j ) + { + delete backupPropertyValues[j]; + } + backupPropertyValues.Close(); + + // cleanup + xmlFreeDoc(doc); + xmlCleanupParser(); + +#ifdef BRDO_SYMBIAN_LIBXML_FF + XmlEngineCleanup(); +#else + xmlCleanupGlobalData(); +#endif + CleanupStack::PopAndDestroy( 2, &file ); // buf, file + + delete aXmlProcessor; + } // ============================================================================ // CWidgetInstaller::PreprocessWidgetBundleL() @@ -326,6 +617,9 @@ CleanupStack::PopAndDestroy( 2, &rFile ); // rFile, buffer + // Fix the widget properties from restored file + TRAP_IGNORE (FixWidgetPropsL()); // Even the fixing leaves, it should not stop the process going + ////////////////////////////////////////////////////////////////////////////////////////////////// // EXISTING WIDGET? if( iRegistry.WidgetExistsL( *(iPropertyValues[EBundleIdentifier]) ) ) diff -r 10e98eab6f85 -r a359256acfc6 webengine/widgetinstaller/eabi/WidgetInstalleru.def --- a/webengine/widgetinstaller/eabi/WidgetInstalleru.def Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/widgetinstaller/eabi/WidgetInstalleru.def Thu Aug 27 07:44:59 2009 +0300 @@ -9,4 +9,6 @@ _ZN16CWidgetInstaller8RunErrorEi @ 8 NONAME _ZTI14CIconConverter @ 9 NONAME ; ## _ZTV14CIconConverter @ 10 NONAME ; ## + _ZTI24CWidgetBackupRegistryXml @ 11 NONAME ; ## + _ZTV24CWidgetBackupRegistryXml @ 12 NONAME ; ## diff -r 10e98eab6f85 -r a359256acfc6 webengine/widgetinstaller/group/WidgetInstaller.mmp --- a/webengine/widgetinstaller/group/WidgetInstaller.mmp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/widgetinstaller/group/WidgetInstaller.mmp Thu Aug 27 07:44:59 2009 +0300 @@ -41,6 +41,7 @@ SOURCE WidgetConfigHandler.cpp SOURCE WidgetRegistrationManager.cpp SOURCE IconConverter.cpp +SOURCE WidgetBackupRegistryXml.cpp // Includes USERINCLUDE . ../Inc/ diff -r 10e98eab6f85 -r a359256acfc6 webengine/widgetregistry/Server/src/WidgetRegistry.cpp --- a/webengine/widgetregistry/Server/src/WidgetRegistry.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/widgetregistry/Server/src/WidgetRegistry.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -26,7 +26,7 @@ #include "WidgetRegistry.h" #include "WidgetInstaller.h" #include -#include +#include #include #include #include diff -r 10e98eab6f85 -r a359256acfc6 webengine/wmlengine/src/MVC/src/MVCView.cpp --- a/webengine/wmlengine/src/MVC/src/MVCView.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/wmlengine/src/MVC/src/MVCView.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -137,7 +137,6 @@ #endif /* DEBUG */ #endif /* WINS */ -_LIT( KMessageTextFormat, "At least %U\ncharacters\nmust be entered" ); // ============================= PRIVATE FUNCTIONS =============================== NW_Bool @@ -770,9 +769,10 @@ } else { + TBuf<8> aMinStr; + aMinStr.Format(_L("%U"),aMin); // We require a minimum number of chars - message = HBufC::NewLC(KMessageTextFormat().Length()); - message->Des().Format( KMessageTextFormat(), aMin ); + message = StringLoader::LoadLC(R_TEXT_MORE_INPUT_REQ,aMinStr); } TRAPD (err, ((CView*)aCEpoc32View)->iBrCtl->brCtlDialogsProvider()->DialogNoteL(message->Des())); diff -r 10e98eab6f85 -r a359256acfc6 webengine/wmlengine/src/image/include/Epoc32ImageDecoder.h --- a/webengine/wmlengine/src/image/include/Epoc32ImageDecoder.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/wmlengine/src/image/include/Epoc32ImageDecoder.h Thu Aug 27 07:44:59 2009 +0300 @@ -99,6 +99,21 @@ inline void SetImageHasNotBeenOpened (NW_Bool aImageHasNotBeenOpened) { iImageHasNotBeenOpened = aImageHasNotBeenOpened; } + + enum TDecoderState + { + ID_IDLE = 0, + ID_INITIALIZING, + ID_DECODING, + // state added to check if the decoding is already complete + ID_DECODE_COMPLETE + }; + /* + @function getDecoderState + @discussion Return the current state of the decoder + */ + + inline TDecoderState getDecoderState() { return iState; } private: @@ -145,12 +160,7 @@ TInt CheckForDRMImage(); private: - enum - { - ID_IDLE = 0, - ID_INITIALIZING, - ID_DECODING - } iState; // Current decoder operation + enum TDecoderState iState; // Current decoder operation CBufferedImageDecoder* iImageConverter; // Connection to media server diff -r 10e98eab6f85 -r a359256acfc6 webengine/wmlengine/src/image/src/Epoc32ImageDecoder.cpp --- a/webengine/wmlengine/src/image/src/Epoc32ImageDecoder.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/wmlengine/src/image/src/Epoc32ImageDecoder.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -1030,7 +1030,8 @@ // if( iIsAnimated == NW_FALSE ) { - // + // Set the decode state after decoding complete + iState = ID_DECODE_COMPLETE; DeleteImageConverterBitmapMask(); } } diff -r 10e98eab6f85 -r a359256acfc6 webengine/wmlengine/src/image/src/Epoc32SimpleImage.cpp --- a/webengine/wmlengine/src/image/src/Epoc32SimpleImage.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/wmlengine/src/image/src/Epoc32SimpleImage.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -367,9 +367,11 @@ /* If there is a decoder, then the image needs to be decoded before displaying * if not done already, or if "needsDecode" (animated image has moved on to - * next frame). + * next frame). Also, image is to be decoded based on the state of the decoder */ - if (decoder != NULL && (thisObj->bitmap == NULL || thisObj->needsDecode)) + if (decoder != NULL && (thisObj->bitmap == NULL || thisObj->needsDecode || + (decoder->getDecoderState() != CEpoc32ImageDecoder::ID_DECODE_COMPLETE)&& + (decoder->getDecoderState() != CEpoc32ImageDecoder::ID_DECODING))) { decoder->Decode(); } diff -r 10e98eab6f85 -r a359256acfc6 webengine/wmlengine/src/urlloader/include/nwx_http_defs.h --- a/webengine/wmlengine/src/urlloader/include/nwx_http_defs.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/wmlengine/src/urlloader/include/nwx_http_defs.h Thu Aug 27 07:44:59 2009 +0300 @@ -159,6 +159,8 @@ extern const char NW_Koi8r_CharsetStr[]; extern const char NW_Koi8u_CharsetStr[]; +extern const char NW_EucKr_CharsetStr[]; +extern const char NW_ksc5601_1987_CharsetStr[]; /* Character set */ #define HTTP_gb2312 0x07E9 @@ -196,6 +198,8 @@ #define HTTP_Koi8_r 0x0824 #define HTTP_Koi8_u 0x0828 + #define HTTP_euc_kr 0x0026 + #define HTTP_ksc_5601 0x0024 #define HTTP_undefined 0xFD /* Nokia specific thingie */ #define HTTP_unknown 0xFE /* Nokia specific thingie */ @@ -482,6 +486,8 @@ EWindows874, EKoi8_r, EKoi8_u, + EEucKr, + EKsc_5601, EDummyLast }; diff -r 10e98eab6f85 -r a359256acfc6 webengine/wmlengine/src/urlloader/src/nwx_http_content_type_strings.c --- a/webengine/wmlengine/src/urlloader/src/nwx_http_content_type_strings.c Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/wmlengine/src/urlloader/src/nwx_http_content_type_strings.c Thu Aug 27 07:44:59 2009 +0300 @@ -167,6 +167,8 @@ const char NW_Koi8r_CharsetStr[] = {"koi8-r"}; const char NW_Koi8u_CharsetStr[] = {"koi8-u"}; + const char NW_EucKr_CharsetStr[] = {"euc-kr"}; + const char NW_ksc5601_1987_CharsetStr[] = {"ks_c_5601-1987"}; /* End Content Type */ diff -r 10e98eab6f85 -r a359256acfc6 webengine/wmlengine/src/utils/src/TEncodingMapping.cpp --- a/webengine/wmlengine/src/utils/src/TEncodingMapping.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/wmlengine/src/utils/src/TEncodingMapping.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -58,6 +58,8 @@ {0x101F8761, HTTP_Koi8_u, EKoi8_u, (NW_Uint8*)NW_Koi8u_CharsetStr, NW_TRUE}, // no header file is provided with the converter Ukrainian {KCharacterSetIdentifierUcs2, HTTP_iso_10646_ucs_2, EISO10646_UCS_2, (NW_Uint8*)NW_Iso10646Ucs2_CharsetStr, NW_FALSE}, {KCharacterSetIdentifierUcs2, HTTP_iso_10646_ucs_2, EISO10646_UCS_2, (NW_Uint8*)NW_Unicode_CharsetStr, NW_FALSE}, + {0x2000E526, HTTP_euc_kr, EEucKr, (NW_Uint8*)NW_EucKr_CharsetStr, NW_TRUE}, // no header file is provided with the converter Ukrainian + {0x200113CD, HTTP_ksc_5601, EKsc_5601, (NW_Uint8*)NW_ksc5601_1987_CharsetStr, NW_TRUE}, // no header file is provided with the converter Ukrainian {0, 0, EAutomatic, (NW_Uint8*)NULL, NW_TRUE}, {0, 0, EDummyLast, (NW_Uint8*)NULL, NW_TRUE} }; diff -r 10e98eab6f85 -r a359256acfc6 webengine/wmlengine/src/utils/src/nw_loadreq.cpp --- a/webengine/wmlengine/src/utils/src/nw_loadreq.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/wmlengine/src/utils/src/nw_loadreq.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -584,6 +584,8 @@ NW_Uint32 convertedValueLen = 0; NW_Uint32 parameterLen = 0; + const char* ie = "ie"; + const char* euc = "EUC-KR"; NW_TRY( status ) { @@ -600,13 +602,20 @@ return KBrsrSuccess; } - status = KBrsrFailure; + // set status to KBrsrSuccess because if the were only ie=EUC-KR as + // postdata we need to return KBrsrSuccess + status = KBrsrSuccess; CBufFlat* buffer = CBufFlat::NewL(20); // arbitrary granularity. NW_Bool needSep = NW_FALSE; (void) NW_NVPair_ResetIter( postfields ); while ( KBrsrSuccess == (status = NW_NVPair_GetNext( postfields, &name, &value ))) { + if ( 0 == NW_Str_StrnicmpConst( name, ie, NW_Str_Strlen( name ) ) && + 0 == NW_Str_StrnicmpConst( value, euc, NW_Str_Strlen( value ) ) ) + { + continue; + } if ( needSep ) { diff -r 10e98eab6f85 -r a359256acfc6 webengine/wrtharvester/data/2001FE2C.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/wrtharvester/data/2001FE2C.rss Thu Aug 27 07:44:59 2009 +0300 @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: ECOM registration for CP harvesting +* +*/ + + +// INCLUDES +#include +#include + +// RESOURCE DEFINITIONS +// ----------------------------------------------------------------------------- +// +// REGISTRY_INFO theInfo +// Declares info for the "all" implementation +// +// ----------------------------------------------------------------------------- +// +RESOURCE REGISTRY_INFO theInfo + { + // UID for the DLL + dll_uid = 0x2001FE2C; + // Declare array of interface info + interfaces = + { + INTERFACE_INFO + { + // UID of interface that is implemented + interface_uid = KContentHarvesterPluginUid; + implementations = + { + IMPLEMENTATION_INFO + { + implementation_uid = 0xA12345FE; + version_no = 1; + display_name = "wrt"; + default_data = "wrt"; + opaque_data = "wrt"; + } + }; + } + }; + } + +// End of File diff -r 10e98eab6f85 -r a359256acfc6 webengine/wrtharvester/data/A12345FD.rss --- a/webengine/wrtharvester/data/A12345FD.rss Fri Jul 03 15:54:40 2009 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* -* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: ECOM registration for CP harvesting -* -*/ - - -// INCLUDES -#include -#include - -// RESOURCE DEFINITIONS -// ----------------------------------------------------------------------------- -// -// REGISTRY_INFO theInfo -// Declares info for the "all" implementation -// -// ----------------------------------------------------------------------------- -// -RESOURCE REGISTRY_INFO theInfo - { - // UID for the DLL - dll_uid = 0xA12345FD; - // Declare array of interface info - interfaces = - { - INTERFACE_INFO - { - // UID of interface that is implemented - interface_uid = KContentHarvesterPluginUid; - implementations = - { - IMPLEMENTATION_INFO - { - implementation_uid = 0xA12345FE; - version_no = 1; - display_name = "wrt"; - default_data = "wrt"; - opaque_data = "wrt"; - } - }; - } - }; - } - -// End of File diff -r 10e98eab6f85 -r a359256acfc6 webengine/wrtharvester/data/wrtharvester.rss --- a/webengine/wrtharvester/data/wrtharvester.rss Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/wrtharvester/data/wrtharvester.rss Thu Aug 27 07:44:59 2009 +0300 @@ -15,43 +15,26 @@ * */ +// RESOURCE IDENTIFIER +NAME WHAR // 4 letter resource identifier // INCLUDES -#include -#include +#include +#include +#include +#include +#include +#include // RESOURCE DEFINITIONS -// ----------------------------------------------------------------------------- -// -// REGISTRY_INFO theInfo -// Declares info for the "all" implementation -// -// ----------------------------------------------------------------------------- -// -RESOURCE REGISTRY_INFO theInfo - { - // UID for the DLL - dll_uid = 0x2001FE2C; - // Declare array of interface info - interfaces = - { - INTERFACE_INFO - { - // UID of interface that is implemented - interface_uid = KContentHarvesterPluginUid; - implementations = - { - IMPLEMENTATION_INFO - { - implementation_uid = 0xA12345FE; - version_no = 1; - display_name = "wrt"; - default_data = "wrt"; - opaque_data = "wrt"; - } - }; - } - }; - } + +RESOURCE RSS_SIGNATURE { } + +RESOURCE TBUF { buf = ""; } + +// ================== STRING RESOURCES ======================================= + +// query to grant permission for phone information +RESOURCE TBUF r_wrthrv_platform_access { buf = qtn_wrthrv_blanketpermission_prompt; } // End of File diff -r 10e98eab6f85 -r a359256acfc6 webengine/wrtharvester/group/bld.inf --- a/webengine/wrtharvester/group/bld.inf Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/wrtharvester/group/bld.inf Thu Aug 27 07:44:59 2009 +0300 @@ -24,7 +24,10 @@ DEFAULT PRJ_EXPORTS -../rom/wrtharvester.iby CORE_MW_LAYER_IBY_EXPORT_PATH(wrtharvester.iby) +// export localization files +../loc/wrtharvester.loc MW_LAYER_LOC_EXPORT_PATH(wrtharvester.loc) +../rom/wrtharvester.iby CORE_MW_LAYER_IBY_EXPORT_PATH(wrtharvester.iby) +../rom/wrtharvesterResources.iby LANGUAGE_MW_LAYER_IBY_EXPORT_PATH(wrtharvesterResources.iby) PRJ_MMPFILES wrtharvester.mmp diff -r 10e98eab6f85 -r a359256acfc6 webengine/wrtharvester/group/wrtharvester.mmp --- a/webengine/wrtharvester/group/wrtharvester.mmp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/wrtharvester/group/wrtharvester.mmp Thu Aug 27 07:44:59 2009 +0300 @@ -30,26 +30,39 @@ SOURCE wrtharvesterpublisherobserver.cpp SOURCE wrtharvesterregistryaccess.cpp - MW_LAYER_SYSTEMINCLUDE MW_LAYER_ECOM_SYSTEMINCLUDE USERINCLUDE ../inc -USERINCLUDE ../../../inc -SOURCEPATH ../data -START RESOURCE wrtharvester.rss +START RESOURCE ../data/2001FE2C.rss +TARGET wrtharvester.rsc +END + +START RESOURCE ../data/wrtharvester.rss HEADER TARGET wrtharvester.rsc -TARGETPATH resource/plugins +TARGETPATH resource END -LIBRARY ecom.lib -LIBRARY euser.lib -LIBRARY bafl.lib -LIBRARY apgrfx.lib -LIBRARY apparc.lib -LIBRARY estor.lib -LIBRARY liwservicehandler.lib -LIBRARY widgetregistryclient.lib +#ifdef __S60_32__ +LANG sc +#else +LANGUAGE_IDS +#endif + +LIBRARY ecom.lib +LIBRARY euser.lib +LIBRARY bafl.lib +LIBRARY apgrfx.lib +LIBRARY apparc.lib +LIBRARY estor.lib +LIBRARY liwservicehandler.lib +LIBRARY widgetregistryclient.lib +LIBRARY efsrv.lib +LIBRARY aknnotify.lib +LIBRARY eiksrv.lib +LIBRARY cone.lib // CoeControl +LIBRARY CommonEngine.lib +LIBRARY ws32.lib //end of file diff -r 10e98eab6f85 -r a359256acfc6 webengine/wrtharvester/inc/wrtharvester.h --- a/webengine/wrtharvester/inc/wrtharvester.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/wrtharvester/inc/wrtharvester.h Thu Aug 27 07:44:59 2009 +0300 @@ -22,7 +22,7 @@ // INCLUDES #include // RApaLsSession #include -#include "widgetappdefs.rh" +#include #include "wrtharvesterregistryaccess.h" @@ -31,19 +31,44 @@ class CWrtHarvesterPublisherObserver; class MLiwInterface; class CLiwGenericParamList; +class CWrtInfo; // CONSTANTS +enum TWidgetState + { + EActivatedState = 0, + EResumeState + }; + +class TWrtState + { + public: + /** + * Constructor + */ + inline TWrtState(TUid aUid, TWidgetState aState) + { + iUid = aUid; + iState = aState; + } + + public: + TUid iUid; + TWidgetState iState; + }; + // CLASS DECLARATION /** - * - * - * @lib ??????.dll - * @since S60 S60 v3.1 */ - class CWrtHarvester: public CContentHarvesterPlugin { + struct SWidgetOperation + { + TWidgetOperations iOperation; + TUid iUid; + }; + public: // Constructors and destructor /** * Two-phased constructor. @@ -65,13 +90,28 @@ /** * */ - void TryLaunchNextWidgetL(); + void TryLaunchNextOperationL(); /** * @param aContentId * @param aTrigger */ void HandlePublisherNotificationL( const TDesC& aContentId, const TDesC8& aTrigger ); + + /** + *Clears the Event Queue + */ + + void ClearAllOperations(); + + /** + * Queues widget operation + * @param aOperation Operation to be queued + * @param aUid Uid of the widget + */ + void QueueOperationL( TWidgetOperations aOperation, TUid aUid ); + + void DialogShown(){ iDialogShown = EFalse; } private: @@ -92,39 +132,44 @@ void UpdatePublishersL(); /** + * + */ + void RemoveObsoletePublishersL(); + + /** + * + */ + void RegisteredPublishersL( RPointerArray& publishers ); + + /** * - * @param aPublisherId - * @param aContentId - * @param aContentType - * @param aResultType + * @param aWrtInfo * @return TInt */ - TInt RegisterPublisherL( const TDesC& aPublisherId, const TDesC& aContentId, - const TDesC& aContentType, const TDesC8& aResultType ); + TInt RegisterPublisherL( CWrtInfo& aWrtInfo ); /** * - * @param aPublisherId - * @param aContentId - * @param aContentType + * @param aBundleId */ - void RemovePublisherL( const TDesC& aPublisherId, const TDesC& aContentId, - const TDesC& aContentType ); + void RemovePublisherAndObserverL( const TDesC& aBundleId ); /** - * Starts WRT widget - * @param aUid Uid of the widget - */ - void StartWidgetL( TUid aUid ); + * + * @param aBundleId + */ + void RemoveObserver(const TDesC& aBundleId); /** * - * @param aPublisherId - * @param aContentId - * @param aContentType + * @param aWrtInfo */ - void RequestForNotificationL( const TDesC& aPublisherId, const TDesC& aContentId, - const TDesC& aContentType ); + void RequestForNotificationL( CWrtInfo& aWrtInfo ); + + /** + * + */ + TUid WidgetUid( TPtrC aBundleId ); /** * @@ -137,8 +182,59 @@ /** * */ - void LaunchWidgetL( TWidgetOperations aOperation, TUid aUid ); - + void LaunchWidgetOperationL( SWidgetOperation aOperation ); + + /** + * Check If widget Ui Process Exists + */ + TBool CheckTaskExistsL(); + + /** + * Queues widget resume operation + * @param aUid Uid of the widget + * @return void + */ + void QueueResumeL( TUid& aUid ); + + /** + * Processes online/offline event + * @param aUid Uid of the widget + * @param aOperation Online/Offline operation to be queued + * @return void + */ + void ProcessNetworkModeL( TUid& aUid, TWidgetOperations aOperation ); + + /** + * Finds widget in the widget state array which has + * the same uid and state as specified in the params + * @param aUid Uid of the widget to be found + * @param aState Widget state + * @returns the array index of the widget found + */ + TInt FindWidget( TUid& aUid, TWidgetState aState ); + + /** + * Finds widget in the widget state array which has + * the same uid as specified in the params + * @param aUid Uid of the widget to be found + * @returns the array index of the widget found + */ + TInt FindWidget( TUid& aUid ); + + /** + * Checks if the widget has network access + * @param aUid Uid of the widget to be checked + * @returns ETrue if widget has network access, + * else returns EFalse + */ + TBool CheckNetworkAccessL( TUid& aUid ); + + /** + * Prompt for Allow Platform Access + * @param aUid Uid of the widget + * @return void + */ + void AllowPlatformAccessL( TUid& aUid ); private: // data @@ -165,10 +261,26 @@ */ CWrtHarvesterPSNotifier* iWidgetMMCListener; + /** + * Publish & Subscribe listener + * own + */ + CWrtHarvesterPSNotifier* iWidgetUsbListener; + /** * */ - RWrtArray< CWrtHarvesterPublisherObserver > iObservers; + RWrtArray iObservers; + + /** + * + */ + RWrtArray iWidgetInfo; + + /** + * + */ + RWrtArray iWidgetStateArray; /** * @@ -178,12 +290,27 @@ /** * */ - RArray iWidgetUids; + RArray iWidgetOperations; /** * */ RApaLsSession iApaSession; + + /** + * Resource offset + */ + TInt iResourceFileOffset; + + /** + * + */ + TInt iHSCount; + /** + * + * + */ + TBool iDialogShown; }; #endif // C_WRTCONTENTHARVESTER_H diff -r 10e98eab6f85 -r a359256acfc6 webengine/wrtharvester/inc/wrtharvesterconst.h --- a/webengine/wrtharvester/inc/wrtharvesterconst.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/wrtharvester/inc/wrtharvesterconst.h Thu Aug 27 07:44:59 2009 +0300 @@ -35,7 +35,9 @@ _LIT8( KFilter, "filter" ); _LIT8( KDataMap, "data_map"); _LIT8( KActionTrigger, "action_trigger" ); -_LIT( KExecute, "execute" ); +_LIT( KExecute, "execute" ); +_LIT8( KGetList, "GetList" ); +_LIT8( KResults, "results" ); _LIT8( KRequestNotification, "RequestNotification" ); _LIT8( KChangeInfo, "change_info" ); _LIT8( KPublisherId, "publisher" ); @@ -46,7 +48,22 @@ _LIT8( KActive, "active"); _LIT8( KSuspend , "suspend"); _LIT8( KResume, "resume"); - - +_LIT8( KSelected, "selected"); +_LIT8( KHSOnline, "online"); +_LIT8( KHSOffline, "offline"); +_LIT8( KTemplateType, "template_type"); +_LIT8( KWidgetName, "widget_name"); +_LIT8( KWidgetInfo, "widget_info"); +_LIT( KTemplatedWidget, "ai3templatedwidget"); +_LIT8( KMyActionMap, "action_map" ); +_LIT8( KMyItem, "item" ); +_LIT8( KMyAdd, "Add" ); +_LIT8( KMyDelete, "Delete" ); +_LIT8( KMyItemId, "item_id" ); +_LIT8( KItemOnlineOffline, "online_offline"); +_LIT8( KMenuItems, "menuitems"); +_LIT( KTemplateName, "wideimage" ); +_LIT( KMyActionName, "data" ); +_LIT( KWRTPublisher, "wrt_publisher"); #endif /* WRTHARHESTERCONST_H */ diff -r 10e98eab6f85 -r a359256acfc6 webengine/wrtharvester/inc/wrtharvesterpsnotifier.h --- a/webengine/wrtharvester/inc/wrtharvesterpsnotifier.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/wrtharvester/inc/wrtharvesterpsnotifier.h Thu Aug 27 07:44:59 2009 +0300 @@ -26,7 +26,7 @@ // Content Harvester server secure id const TUid KPropertyCat = { 0x10282E5A }; // Can not conflict with other Content Harvester plugin keys -enum TPropertyKeys { EWidgetUIState = 109, EWidgetRegAltered, EWidgetMMCAltered }; +enum TPropertyKeys { EWidgetUIState = 109, EWidgetRegAltered, EWidgetMMCAltered, EWidgetMassStorageMode }; /** * Publish&Subscribe event listener diff -r 10e98eab6f85 -r a359256acfc6 webengine/wrtharvester/inc/wrtharvesterpublisherobserver.h --- a/webengine/wrtharvester/inc/wrtharvesterpublisherobserver.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/wrtharvester/inc/wrtharvesterpublisherobserver.h Thu Aug 27 07:44:59 2009 +0300 @@ -41,7 +41,7 @@ /** * Two-phased constructor. */ - static CWrtHarvesterPublisherObserver* NewLC( const TDesC& aName, CWrtHarvester* aHarvester ); + static CWrtHarvesterPublisherObserver* NewLC( const TDesC& aBundleId, CWrtHarvester* aHarvester ); /** * Destructor. @@ -80,14 +80,19 @@ /** * */ - const TDesC& Name(); + const TDesC& BundleId(); - + /** + * Cancel all the registered notifications. + * @return void. + */ + void ReleaseL(); + private: /** * Perform the second phase construction */ - void ConstructL( const TDesC& aName ); + void ConstructL( const TDesC& aBundleId ); /** * Default constructor. @@ -96,12 +101,6 @@ // Prhohibited CWrtHarvesterPublisherObserver(); - - /** - * Cancel all the registered notifications. - * @return void. - */ - void ReleaseL(); /** * Initialise Liw connection to Content publishing service. @@ -129,7 +128,7 @@ // Name of the observed publisher // Owned - HBufC* iName; + HBufC* iBundleId; // Call back error code TInt iError; diff -r 10e98eab6f85 -r a359256acfc6 webengine/wrtharvester/inc/wrtharvesterregistryaccess.h --- a/webengine/wrtharvester/inc/wrtharvesterregistryaccess.h Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/wrtharvester/inc/wrtharvesterregistryaccess.h Thu Aug 27 07:44:59 2009 +0300 @@ -60,11 +60,39 @@ ptr->Close(); } }; - + +class CWrtInfo : public CBase + { + public: + /** + * Constructor + */ + inline CWrtInfo() + { + iUid = TUid::Uid(0); + iDisplayName = NULL; + iBundleId = NULL; + } + + /** + * Destructor. + */ + inline virtual ~CWrtInfo() + { + delete iDisplayName; + delete iBundleId; + } + + public: + TUid iUid; + HBufC* iDisplayName;// widget display name + HBufC* iBundleId; // widget bundle identifier + }; + // CLASS DECLARATION /** - * Widget Register accessor. + * Widget Registry interface. * * Handles communication & widget bookkeeping of miniview-capable widgets. * @@ -85,22 +113,14 @@ ~WrtHarvesterRegistryAccess(); /** - * Get widget bundle names for widgets supporting miniviews. + * Get widget bundle ids for widgets supporting miniviews. * * NOTE: Ownership of pointers in the array is not transferred! * Caller must not delete them. * * @param aArray Array where the descriptor pointers are to be stored. */ - void WidgetBundleNamesL( RPointerArray< HBufC >& aArray ); - - /** - * Get widget uid. - * - * @param aBundleName Name of the widget - * @return TUid of the widget. - */ - TUid WidgetUid( TPtrC aBundleName ); + void WidgetInfosL( RWrtArray< CWrtInfo >& aWidgetInfoArray ); private: /** @@ -113,19 +133,17 @@ TBool SupportsMiniviewL( RWidgetRegistryClientSession& aSession, const TUid& aUid ); /** - * Returns the Bundle identifier for the given widget. Ownership transfered. + * Returns the property value for the widget as a string. Ownership transferred. * * @param aSession Widget registry session * @param aUid UID of widget. + * aPropertyId Id of the property. * @return Identifier in a descriptor. */ - HBufC* ConstructWidgetNameL( RWidgetRegistryClientSession& aSession, CWidgetInfo& aInfo ); + HBufC* WidgetPropertyL( RWidgetRegistryClientSession& aSession, const TUid& aUid, TWidgetPropertyId aPropertyId ); - private: // data - /** - * - */ - RWrtArray< CWidgetInfo > iWidgetInfoArray; + + }; #endif // WRHARVESTERREGISTRYACCESS_H diff -r 10e98eab6f85 -r a359256acfc6 webengine/wrtharvester/loc/wrtharvester.loc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/wrtharvester/loc/wrtharvester.loc Thu Aug 27 07:44:59 2009 +0300 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: loc file for wrtharvester +* +*/ + +// LOCALISATION STRINGS + +// d: Pop up to grant access to phone information +// l: popup_note_window +// r: 5.0 +#define qtn_wrthrv_blanketpermission_prompt "Allow application to access information on your phone?" + +// End of File diff -r 10e98eab6f85 -r a359256acfc6 webengine/wrtharvester/rom/wrtharvesterResources.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/wrtharvester/rom/wrtharvesterResources.iby Thu Aug 27 07:44:59 2009 +0300 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: The resource iby file contains resource that needs to be +* localized for wrtharvester +* +*/ + + +#ifndef WRTHARVESTERRESOURCES_IBY +#define WRTHARVESTERRESOURCES_IBY + +#include + +#ifdef BRDO_WRT_HS_FF +data=ZRESOURCE\wrtharvester.rsc RESOURCE_FILES_DIR\wrtharvester.rsc +#endif + +#endif // WRTHARVESTERRESOURCES_IBY \ No newline at end of file diff -r 10e98eab6f85 -r a359256acfc6 webengine/wrtharvester/src/wrtharvester.cpp --- a/webengine/wrtharvester/src/wrtharvester.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/wrtharvester/src/wrtharvester.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -24,6 +24,7 @@ #include "wrtharvesterconst.h" #include +#include #include @@ -35,24 +36,99 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// CONSTANTS +_LIT( KResourceFileName, "\\resource\\wrtharvester.rsc" ); +_LIT( KResourceDir, "Z:wrtharvester.rsc" ); -// TODO Check these types, should they be definedin sapidatapluginconst.h? -_LIT( KTemplatedWidget, "ai3templatedwidget"); -_LIT8( KMySelected, "selected"); -_LIT8( KMyActionMap, "action_map" ); -_LIT8( KMyItem, "item" ); -_LIT8( KMyAdd, "Add" ); -_LIT8( KMyDelete, "Delete" ); -_LIT8( KMyItemId, "item_id" ); -_LIT8( KMyImage, "image" ); -_LIT( KMyContType, "wideimage" ); -_LIT8( KMyResultName,"mydata" ); -_LIT( KMyActionName, "data" ); +/** +* Utility class to show the prompt for platform security access. +* +* The class exists only to provide platform security access prompt +* for the widgets which are launched in minview +*/ +class CGlobalQueryHandlerAO : public CActive + { +public: + /** + * Startup. + * + * @param aManager Window Manager. + * @param aWindow Window. + * @param aMessage Message to be prompted. + * @param aSoftkeys for prompt. + * @param aWrtHarvester for callback + */ + static CGlobalQueryHandlerAO* StartLD ( + TUid& aUid, + const TDesC& aMessage, + TInt aSoftkeys, + CWrtHarvester* aWrtHarvester); + /** + * ShowGlobalQueryDialogL. + * + * @param aMessage Message to be prompted. + * @param aSoftkeys for prompt. + */ + void ShowGlobalQueryDialogL ( + const TDesC& aMessage, + TInt aSoftkeys ); +protected: // From CActive + /** + * Execute asynchronous operation. + */ + void RunL(); + + /** + * Provide cancellation methods. + */ + void DoCancel(); + +private: + + /** + * Constructor. + * + * @param aManager Manager. + * @param aWindow Window. + * @param aMessage Message for prompt. + * @param aSoftkeys for prompt. + * @param aWrtHarvester for callback + */ + CGlobalQueryHandlerAO ( + TUid& aUid, + const TDesC& aMessage, + TInt aSoftkeys, + CWrtHarvester* aWrtHarvester); + + /** + * Destructor. + * + * Private on purpose. + */ + ~CGlobalQueryHandlerAO(); + +private: + + TUid iWidgetUid; + CAknGlobalConfirmationQuery* iGlobalConfirmationQuery ; + HBufC* iConfirmationText; + CWrtHarvester* iWrtHarvester; + }; + // ============================= LOCAL FUNCTIONS =============================== // ---------------------------------------------------------------------------- -// ta +// Returns the app full name // ---------------------------------------------------------------------------- // static HBufC* GetAppNameLC( RApaLsSession& aSession, const TUid& aUid ) @@ -65,7 +141,7 @@ // ---------------------------------------------------------------------------- -// +// Sends the command to Widget launcher // ---------------------------------------------------------------------------- // static void HandleWidgetCommandL( @@ -132,7 +208,8 @@ // ---------------------------------------------------------------------------- // CWrtHarvester::CWrtHarvester( MLiwInterface* aCPSInterface ): - iCPSInterface( aCPSInterface ) + iCPSInterface( aCPSInterface ), + iHSCount(0) { } @@ -146,6 +223,25 @@ iWidgetUIListener = CWrtHarvesterPSNotifier::NewL( this, EWidgetUIState ); iWidgetRegListener = CWrtHarvesterPSNotifier::NewL( this, EWidgetRegAltered ); iWidgetMMCListener = CWrtHarvesterPSNotifier::NewL( this, EWidgetMMCAltered ); + iWidgetUsbListener = CWrtHarvesterPSNotifier::NewL( this, EWidgetMassStorageMode ); + + TFileName resourceFileName; + TParse parse; + Dll::FileName (resourceFileName); + parse.Set(KResourceFileName, &resourceFileName, NULL); + resourceFileName = parse.FullName(); + + CCoeEnv* coeEnv = CCoeEnv::Static(); + BaflUtils::NearestLanguageFile(coeEnv->FsSession(), resourceFileName); + + if ( !BaflUtils::FileExists( coeEnv->FsSession(), resourceFileName ) ) + { + // Use resource file on the Z drive instead + parse.Set( KResourceDir, &KDC_RESOURCE_FILES_DIR, NULL ); + resourceFileName = parse.FullName(); + BaflUtils::NearestLanguageFile( coeEnv->FsSession(),resourceFileName ); + } + iResourceFileOffset = coeEnv->AddResourceFileL(resourceFileName); } // ---------------------------------------------------------------------------- @@ -167,16 +263,23 @@ // CWrtHarvester::~CWrtHarvester() { + if ( iResourceFileOffset ) + { + CCoeEnv::Static()->DeleteResourceFile( iResourceFileOffset ); + } iObservers.ResetAll(); + iWidgetInfo.ResetAll(); + iWidgetStateArray.ResetAll(); delete iWidgetUIListener; delete iWidgetRegListener; delete iWidgetMMCListener; - iWidgetUids.Close(); + delete iWidgetUsbListener; + iWidgetOperations.Close(); iApaSession.Close(); } // ---------------------------------------------------------------------------- -// +// Is called by Content Harvester server // ---------------------------------------------------------------------------- // void CWrtHarvester::UpdateL() @@ -185,37 +288,68 @@ } // ---------------------------------------------------------------------------- -// +// Is called when Homescreen sends events to publisher // ---------------------------------------------------------------------------- // void CWrtHarvester::HandlePublisherNotificationL( const TDesC& aContentId, const TDesC8& aTrigger ) { - TUid uid( iRegistryAccess.WidgetUid( aContentId ) ); - if( aTrigger == KActive() ) + TUid uid( WidgetUid( aContentId ) ); + TWidgetOperations operation( Uninitialized ); + if( aTrigger == KActive ) { - StartWidgetL( uid ); - } - else - { - TWidgetOperations operation( Uninitialized ); - if ( aTrigger == KDeActive ) + iHSCount++; + // queue the activated state event only for network accessing widgets + if ( CheckNetworkAccessL( uid) ) { - operation = Deactivate; + TWrtState* widgetState = NULL; + widgetState = new TWrtState( uid, EActivatedState ); + if ( widgetState ) + { + iWidgetStateArray.AppendL( widgetState ); + } } - else if( aTrigger == KSuspend ) - { - operation = WidgetSuspend; - } - else if( aTrigger == KResume ) + + operation = LaunchMiniview; + } + else if ( aTrigger == KDeActive ) + { + iHSCount--; + operation = Deactivate; + } + else if( aTrigger == KSuspend ) + { + operation = WidgetSuspend; + } + else if( aTrigger == KResume ) + { + TInt idx = FindWidget( uid ); + + // if unable to find the widget, queue the resume as usual + if ( idx == -1 ) { - operation = WidgetResume; + QueueResumeL( uid ); } - else if( aTrigger == KMySelected ) + else { - operation = WidgetSelect; + iWidgetStateArray[idx]->iState = EResumeState; } - LaunchWidgetL( operation, uid ); + return; + } + else if( aTrigger == KSelected ) + { + operation = WidgetSelect; } + else if( aTrigger == KHSOnline ) + { + ProcessNetworkModeL( uid, WidgetOnline ); + return; + } + else if( aTrigger == KHSOffline ) + { + ProcessNetworkModeL( uid, WidgetOffline ); + return; + } + QueueOperationL( operation, uid ); } // ---------------------------------------------------------------------------- @@ -224,20 +358,41 @@ // void CWrtHarvester::UpdatePublishersL() { - RPointerArray< HBufC > bundleNames; + iRegistryAccess.WidgetInfosL( iWidgetInfo ); + RemoveObsoletePublishersL(); - // The array contain references. - CleanupClosePushL( bundleNames ); - - iRegistryAccess.WidgetBundleNamesL( bundleNames ); + for( TInt i = iWidgetInfo.Count() - 1; i >= 0; --i ) + { + // Register the observer first as notification may be + // received immediately after registration + RequestForNotificationL( *iWidgetInfo[i] ); + TInt id = RegisterPublisherL( *iWidgetInfo[i] ); + if( id == KErrNotFound ) + { + // remove the observer as the publisher registration failed + RemoveObserver( *iWidgetInfo[i]->iBundleId); + } + } + } + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +// +void CWrtHarvester::RemoveObsoletePublishersL() + { + RWrtArray publishers; + publishers.PushL(); + RegisteredPublishersL( publishers ); // Remove observer and CPS registry entry of uninstalled widget - for( TInt i = 0; i < iObservers.Count(); i++ ) + TInt count = publishers.Count(); + for( TInt i = count - 1; i >= 0; --i ) { TBool found( EFalse ); - for( TInt j = 0; j < bundleNames.Count(); j++ ) + for( TInt j = 0; j < iWidgetInfo.Count(); j++ ) { - if( iObservers[i]->Name() == bundleNames[j] ) + if( *publishers[i] == iWidgetInfo[j]->iBundleId ) { found = ETrue; break; @@ -245,39 +400,80 @@ } if( found == EFalse ) { - RemovePublisherL( KTemplatedWidget, iObservers[i]->Name(), KMyContType ); - delete iObservers[i]; - iObservers.Remove( i ); + RemovePublisherAndObserverL( *publishers[i] ); } } - - for( TInt i = bundleNames.Count() - 1; i >= 0; --i ) - { - TInt id = RegisterPublisherL( - KTemplatedWidget, - *( bundleNames[ i ] ), - KMyContType, - KMyImage ); - - if( id != KErrNotFound ) - { - RequestForNotificationL( KTemplatedWidget, *( bundleNames[ i ] ), KMyContType ); - } - } - - CleanupStack::PopAndDestroy( &bundleNames ); + CleanupStack::PopAndDestroy( &publishers ); } // ---------------------------------------------------------------------------- // // ---------------------------------------------------------------------------- // -TInt CWrtHarvester::RegisterPublisherL( - const TDesC& aPublisherId, - const TDesC& aContentId, - const TDesC& aContentType, - const TDesC8& aResultType ) +void CWrtHarvester::RegisteredPublishersL( RPointerArray& publishers ) { + publishers.ResetAndDestroy(); + + CLiwGenericParamList* publisherList( CLiwGenericParamList::NewLC() ); + CLiwGenericParamList* inParamList( CLiwGenericParamList::NewLC() ); + + TLiwGenericParam type( KType, TLiwVariant( KPubData )); + inParamList->AppendL( type ); + + CLiwDefaultMap* filter = CLiwDefaultMap::NewLC(); + + filter->InsertL( KPublisherId, TLiwVariant( KWRTPublisher ) ); + filter->InsertL( KContentType, TLiwVariant( KTemplatedWidget ) ); + + //append filter to input param + TLiwGenericParam item( KFilter, TLiwVariant( filter )); + inParamList->AppendL( item ); + + // Get all publishers from CPS + iCPSInterface->ExecuteCmdL( KGetList, *inParamList, *publisherList ); + CleanupStack::PopAndDestroy( filter ); + CleanupStack::PopAndDestroy( inParamList ); + + TInt pos = 0; + publisherList->FindFirst( pos, KResults ); + if( pos != KErrNotFound ) + { + //extract iterator on results list + TLiwVariant variant = (*publisherList)[pos].Value(); + CLiwIterable* iterable = variant.AsIterable(); + iterable->Reset(); + + //get all the templated widget publishers + while( iterable->NextL( variant ) ) + { + //extract content map + CLiwDefaultMap* publisherMap = CLiwDefaultMap::NewLC(); + variant.Get( *publisherMap ); + variant.Reset(); + + if( publisherMap && publisherMap->FindL( KContentId , variant )) + { + HBufC* bundleId = variant.AsDes().AllocLC(); + publishers.AppendL( bundleId ); + CleanupStack::Pop( bundleId ); + } + CleanupStack::PopAndDestroy( publisherMap ); + } + + variant.Reset(); + } + CleanupStack::PopAndDestroy( publisherList ); + } + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +// +TInt CWrtHarvester::RegisterPublisherL( CWrtInfo& wrtInfo ) + { + TBool networkAccess = CheckNetworkAccessL( wrtInfo.iUid ); + + __UHEAP_MARK; TInt id( KErrNotFound ); if( iCPSInterface ) { @@ -291,20 +487,39 @@ CLiwDefaultMap* actionmap( NULL ); // Create the data map for publisher registry - cpdatamap->InsertL( KContentType, TLiwVariant( aContentType )); - cpdatamap->InsertL( KContentId, TLiwVariant( aContentId )); - cpdatamap->InsertL( KPublisherId, TLiwVariant( aPublisherId )); - datamap->InsertL( KMyResultName, TLiwVariant( aResultType )); + cpdatamap->InsertL( KPublisherId, TLiwVariant( KWRTPublisher )); + cpdatamap->InsertL( KContentType, TLiwVariant( KTemplatedWidget )); + cpdatamap->InsertL( KContentId, TLiwVariant( wrtInfo.iBundleId )); + // Widget info map + CLiwDefaultMap* widgetInfo = CLiwDefaultMap::NewLC(); + widgetInfo->InsertL( KTemplateType, TLiwVariant( KTemplateName )); + widgetInfo->InsertL( KWidgetName, TLiwVariant( wrtInfo.iDisplayName )); + datamap->InsertL( KWidgetInfo , TLiwVariant( widgetInfo )); + CleanupStack::PopAndDestroy( widgetInfo ); + + // Take dynamic menu items into use + if (networkAccess) + { + CLiwDefaultMap* mapMenu = CLiwDefaultMap::NewLC(); + mapMenu->InsertL( KItemOnlineOffline, TLiwVariant( KMyActionName )); + datamap->InsertL( KMenuItems, TLiwVariant( mapMenu )); + CleanupStack::PopAndDestroy(mapMenu); + } cpdatamap->InsertL( KDataMap, TLiwVariant(datamap) ); // Create the action map for publisher registry actionmap = CLiwDefaultMap::NewLC(); - actionmap->InsertL(KActive, TLiwVariant( KMyActionName )); - actionmap->InsertL(KDeActive, TLiwVariant( KMyActionName )); - actionmap->InsertL(KSuspend, TLiwVariant( KMyActionName )); - actionmap->InsertL(KResume, TLiwVariant( KMyActionName )); - actionmap->InsertL(KMySelected, TLiwVariant( KMyActionName )); + actionmap->InsertL( KActive, TLiwVariant( KMyActionName )); + actionmap->InsertL( KDeActive, TLiwVariant( KMyActionName )); + actionmap->InsertL( KSuspend, TLiwVariant( KMyActionName )); + actionmap->InsertL( KResume, TLiwVariant( KMyActionName )); + actionmap->InsertL( KSelected, TLiwVariant( KMyActionName )); + if (networkAccess) + { + actionmap->InsertL( KHSOnline, TLiwVariant( KMyActionName )); + actionmap->InsertL( KHSOffline, TLiwVariant( KMyActionName )); + } cpdatamap->InsertL( KMyActionMap, TLiwVariant(actionmap)); CleanupStack::PopAndDestroy( actionmap ); @@ -321,7 +536,8 @@ type.Reset(); CleanupStack::PopAndDestroy(outparam); CleanupStack::PopAndDestroy(inparam); - } + } + __UHEAP_MARKEND; return id; } @@ -329,9 +545,28 @@ // // ---------------------------------------------------------------------------- // -void CWrtHarvester::RemovePublisherL( const TDesC& aPublisherId, const TDesC& aContentId, - const TDesC& aContentType ) +void CWrtHarvester::RemoveObserver(const TDesC& aBundleId) + { + TInt count = iObservers.Count(); + for( TInt i = 0; i < count; i++ ) + { + if( iObservers[i]->BundleId() == aBundleId ) + { + delete iObservers[i]; + iObservers.Remove( i ); + break; + } + } + } +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +// +void CWrtHarvester::RemovePublisherAndObserverL( const TDesC& aBundleId ) { + RemoveObserver( aBundleId ); + + __UHEAP_MARK; if( iCPSInterface ) { CLiwGenericParamList* inparam = CLiwGenericParamList::NewLC(); @@ -342,9 +577,9 @@ CLiwDefaultMap* datamap = CLiwDefaultMap::NewLC(); // Create data map - cpdatamap->InsertL( KContentType, TLiwVariant( aContentType )); - cpdatamap->InsertL( KContentId, TLiwVariant( aContentId )); - cpdatamap->InsertL( KPublisherId, TLiwVariant( aPublisherId )); + cpdatamap->InsertL( KPublisherId, TLiwVariant( KWRTPublisher )); + cpdatamap->InsertL( KContentType, TLiwVariant( KTemplatedWidget )); + cpdatamap->InsertL( KContentId, TLiwVariant( aBundleId )); cpdatamap->InsertL( KDataMap, TLiwVariant(datamap) ); @@ -359,19 +594,19 @@ CleanupStack::PopAndDestroy(outparam); CleanupStack::PopAndDestroy(inparam); } + __UHEAP_MARKEND; } // ---------------------------------------------------------------------------- // // ---------------------------------------------------------------------------- // -void CWrtHarvester::RequestForNotificationL( const TDesC& aPublisherId, const TDesC& aContentId, - const TDesC& aContentType ) +void CWrtHarvester::RequestForNotificationL( CWrtInfo& wrtInfo ) { // Preventing duplicate entries. for( TInt i = 0; i < iObservers.Count(); i++ ) { - if( iObservers[i]->Name() == aContentId ) + if( iObservers[i]->BundleId() == wrtInfo.iBundleId ) { return; } @@ -380,12 +615,12 @@ CWrtHarvesterPublisherObserver* observer( NULL ); CLiwDefaultMap* filter = CLiwDefaultMap::NewLC(); - filter->InsertL( KPublisherId, TLiwVariant( aPublisherId ) ); - filter->InsertL( KContentId, TLiwVariant( aContentId ) ); - filter->InsertL( KContentType, TLiwVariant( aContentType ) ); + filter->InsertL( KPublisherId, TLiwVariant( KWRTPublisher ) ); + filter->InsertL( KContentType, TLiwVariant( KTemplatedWidget ) ); + filter->InsertL( KContentId, TLiwVariant( wrtInfo.iBundleId ) ); filter->InsertL( KOperation, TLiwVariant( KExecute )); - observer = CWrtHarvesterPublisherObserver::NewLC( aContentId, this ); + observer = CWrtHarvesterPublisherObserver::NewLC( *wrtInfo.iBundleId, this ); observer->RegisterL(filter); iObservers.AppendL( observer ); @@ -399,29 +634,82 @@ // // ---------------------------------------------------------------------------- // -void CWrtHarvester::StartWidgetL( TUid aUid ) +void CWrtHarvester::QueueOperationL( TWidgetOperations aOperation, TUid aUid ) { - iWidgetUids.Append( aUid ); - TryLaunchNextWidgetL(); + //Hack to find out if WidgetUi exist as Queue keeps filling up + if((iHSCount*3 <= iWidgetOperations.Count() && !CheckTaskExistsL()) || (aOperation == WidgetSelect)) + { + ClearAllOperations(); + iWidgetUIListener->SetValue(1); + } + SWidgetOperation op = { aOperation, aUid }; + iWidgetOperations.Append( op ); + TryLaunchNextOperationL(); } // ---------------------------------------------------------------------------- // // ---------------------------------------------------------------------------- // -void CWrtHarvester::TryLaunchNextWidgetL() +TBool CWrtHarvester::CheckTaskExistsL() + { + TUid widgetAppUid( TUid::Uid( KWidgetAppUid ) ); + RWsSession wsSession; + + // Create Window server session + User::LeaveIfError( wsSession.Connect() ); + + TApaTaskList taskList( wsSession ); + TApaTask task = taskList.FindApp( widgetAppUid ); + return task.Exists()?ETrue:EFalse; + } + + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +// +void CWrtHarvester::TryLaunchNextOperationL() { TInt value = KErrNone; TInt error = iWidgetUIListener->GetValue(value); - if( error == KErrNone && value == 1 && iWidgetUids.Count() != 0 ) + if( error == KErrNone && value == 1 && iWidgetOperations.Count() != 0 ) { // Set value to 0 so that next widget is not launched before Widget App sets value to 1. iWidgetUIListener->SetValue( 0 ); - //Always launch the first widget - LaunchWidgetL( LaunchMiniview, iWidgetUids[0] ); - iWidgetUids.Remove( 0 ); + //Always launch the first in operation + LaunchWidgetOperationL( iWidgetOperations[0] ); + iWidgetOperations.Remove( 0 ); + } + } + +void CWrtHarvester::ClearAllOperations() + { + TInt value = KErrNone; + TInt error = iWidgetUIListener->GetValue(value); + if( error == KErrNone ) + { + iWidgetOperations.Reset(); } } +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +// +TUid CWrtHarvester::WidgetUid( TPtrC aBundleId ) + { + TInt count( iWidgetInfo.Count()); + TUid uid = {0}; + for( TInt i = 0; i < count; i++ ) + { + if( iWidgetInfo[i]->iBundleId == aBundleId ) + { + uid = iWidgetInfo[i]->iUid; + break; + } + } + return uid; + } // ---------------------------------------------------------------------------- // @@ -448,11 +736,219 @@ // // ---------------------------------------------------------------------------- // -void CWrtHarvester::LaunchWidgetL( TWidgetOperations aOperation, TUid aUid ) +void CWrtHarvester::LaunchWidgetOperationL( SWidgetOperation aOperation ) + { + HBufC* widgetName( GetAppNameLC( iApaSession, aOperation.iUid) ); + HandleWidgetCommandL( iApaSession, *widgetName, aOperation.iUid, aOperation.iOperation ); + CleanupStack::PopAndDestroy( widgetName ); + } + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +// +void CWrtHarvester::QueueResumeL( TUid& aUid ) + { + RWidgetRegistryClientSession session; + CleanupClosePushL( session ); + User::LeaveIfError( session.Connect() ); + if ( session.IsBlanketPermGranted ( aUid ) == EBlanketUnknown && !iDialogShown ) + { + iDialogShown = ETrue; + AllowPlatformAccessL( aUid ); + } + else if(!iDialogShown) + { + QueueOperationL( WidgetResume, aUid ); + } + CleanupStack::PopAndDestroy( &session ); + } + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +// +void CWrtHarvester::ProcessNetworkModeL( TUid& aUid, TWidgetOperations aOperation ) + { + // first queue the online/offline event and then the resume event + QueueOperationL( aOperation, aUid ); + + // check if there is a resume event to queue + TInt idx = FindWidget(aUid, EResumeState); + if ( idx != -1 ) + { + QueueResumeL( aUid ); + } + idx = (idx == -1) ? FindWidget(aUid): idx; + if(idx != -1 ) + { + // remove it from the array, no longer needed + delete iWidgetStateArray[idx]; + iWidgetStateArray.Remove(idx); + } + } + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +// +TInt CWrtHarvester::FindWidget( TUid& aUid, TWidgetState aState ) + { + TInt idx = -1; + for( TInt i( iWidgetStateArray.Count() - 1 ); i >= 0; --i ) + { + if ( ( iWidgetStateArray[i]->iUid == aUid ) && ( iWidgetStateArray[i]->iState == aState ) ) + { + idx = i; + } + } + return idx; + } + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +// +TInt CWrtHarvester::FindWidget( TUid& aUid ) + { + TInt idx = -1; + for( TInt i( iWidgetStateArray.Count() - 1 ); i >= 0; --i ) + { + if ( iWidgetStateArray[i]->iUid == aUid ) + { + idx = i; + } + } + return idx; + } + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +// +TBool CWrtHarvester::CheckNetworkAccessL( TUid& aUid ) + { + RWidgetRegistryClientSession session; + CleanupClosePushL( session ); + User::LeaveIfError( session.Connect() ); + TBool networkAccess = *(session.GetWidgetPropertyValueL( aUid, EAllowNetworkAccess ) ); + CleanupStack::PopAndDestroy( &session ); + + return networkAccess; + } + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +// +void CWrtHarvester::AllowPlatformAccessL( TUid& aUid ) { - HBufC* widgetName( GetAppNameLC( iApaSession, aUid) ); - HandleWidgetCommandL( iApaSession, *widgetName, aUid, aOperation ); - CleanupStack::PopAndDestroy( widgetName ); + HBufC* confirmationText = StringLoader::LoadLC(R_WRTHRV_PLATFORM_ACCESS); + TInt softKey = R_AVKON_SOFTKEYS_OK_CANCEL; + CGlobalQueryHandlerAO* tmp = CGlobalQueryHandlerAO::StartLD( aUid, confirmationText->Des(), softKey, this ); + CleanupStack::PopAndDestroy(confirmationText); + } + +// ------------------------------------------------------------------------ +// CGlobalQueryHandlerAO::StartLD +// +// Initialize AO. +// ------------------------------------------------------------------------ +CGlobalQueryHandlerAO* CGlobalQueryHandlerAO::StartLD( + TUid& aUid, + const TDesC& aMessage, + TInt aSoftkeys, + CWrtHarvester* aWrtHarvester) + { + CGlobalQueryHandlerAO* self( new( ELeave ) CGlobalQueryHandlerAO( aUid, aMessage, aSoftkeys, aWrtHarvester) ); + TRAPD(error, self->ShowGlobalQueryDialogL ( aMessage, aSoftkeys )); + if ( error ) + { + delete self; + User::Leave(error); + } + self->SetActive(); + return self; + } + +// ------------------------------------------------------------------------ +// CGlobalQueryHandlerAO::CGlobalQueryHandlerAO +// +// Constructor. +// ------------------------------------------------------------------------ +CGlobalQueryHandlerAO::CGlobalQueryHandlerAO( + TUid& aUid, + const TDesC& aMessage, + TInt /*aSoftkeys*/, + CWrtHarvester* aWrtHarvester):CActive( EPriorityHigh ), + iWidgetUid(aUid), + iConfirmationText(aMessage.AllocL()), + iWrtHarvester(aWrtHarvester) + { + CActiveScheduler::Add( this ); + } + +// ------------------------------------------------------------------------ +// CGlobalQueryHandlerAO::CGlobalQueryHandlerAO +// +// ISet network and platform access permission based on user response. +// ------------------------------------------------------------------------ +void CGlobalQueryHandlerAO::RunL() + { + RWidgetRegistryClientSession session; + CleanupClosePushL( session ); + User::LeaveIfError( session.Connect() ); + if (iStatus == EAknSoftkeyOk) + { + session.SetBlanketPermissionL( iWidgetUid, EBlanketTrue ); + } + else if ( iStatus == EAknSoftkeyCancel) + { + session.SetBlanketPermissionL( iWidgetUid, EBlanketFalse ); + } + iWrtHarvester->QueueOperationL( WidgetResume, iWidgetUid ); + iWrtHarvester->DialogShown(); + CleanupStack::PopAndDestroy( &session ); + + delete this; + } + +// ------------------------------------------------------------------------ +// CGlobalQueryHandlerAO::DoCancel +// +// Do nothing. +// ------------------------------------------------------------------------ +void CGlobalQueryHandlerAO::DoCancel() + { + if ( iGlobalConfirmationQuery ) + { + iGlobalConfirmationQuery->CancelConfirmationQuery(); + } + } + +// ------------------------------------------------------------------------ +// CGlobalQueryHandlerAO::~CGlobalQueryHandlerAO +// +// Destructor. +// ------------------------------------------------------------------------ +CGlobalQueryHandlerAO::~CGlobalQueryHandlerAO() + { + Cancel(); + delete iGlobalConfirmationQuery; + delete iConfirmationText; + } + +// --------------------------------------------------------- +// CGlobalQueryHandlerAO::ShowGlobalQueryDialogL() +// --------------------------------------------------------- +// +void CGlobalQueryHandlerAO::ShowGlobalQueryDialogL(const TDesC& aMessage, TInt aSoftkeys) + { + iGlobalConfirmationQuery = CAknGlobalConfirmationQuery::NewL(); + iGlobalConfirmationQuery->ShowConfirmationQueryL + (iStatus, + aMessage, + aSoftkeys); } // End of File diff -r 10e98eab6f85 -r a359256acfc6 webengine/wrtharvester/src/wrtharvesterpsnotifier.cpp --- a/webengine/wrtharvester/src/wrtharvesterpsnotifier.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/wrtharvester/src/wrtharvesterpsnotifier.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -19,7 +19,8 @@ #include "wrtharvesterpsnotifier.h" #include "wrtharvester.h" #include //For MMC Observing - +#include //For USB monitor + // ============================ MEMBER FUNCTIONS ============================= // --------------------------------------------------------------------------- @@ -85,6 +86,10 @@ { User::LeaveIfError( iProperty.Attach( KPSUidUikon,KUikMMCInserted )); } + else if( iKey == EWidgetMassStorageMode ) + { + User::LeaveIfError( iProperty.Attach( KUsbMsDriveState_Category,EUsbMsDriveState_DriveStatus )); + } else { User::LeaveIfError( iProperty.Attach( KPropertyCat, iKey)); @@ -123,28 +128,57 @@ TInt value( 0 ); TInt r (KErrNone); - if( iKey != EWidgetMMCAltered ) + TUsbMsDrivesStatus allDrivesStatus; + if( iKey != EWidgetMMCAltered && iKey != EWidgetMassStorageMode ) { iProperty.Get( KPropertyCat, iKey, value ); } + else if( iKey == EWidgetMMCAltered ) + { + r = iProperty.Get( KPSUidUikon, KUikMMCInserted , value ); + } else - { - iProperty.Get( KPSUidUikon, KUikMMCInserted , value ); + { + r = iProperty.Get( allDrivesStatus ); } - if( r == KErrNone ) { if( iKey == EWidgetUIState && value == 1 ) { - iHarvester->TryLaunchNextWidgetL(); + iHarvester->TryLaunchNextOperationL(); + } + else if(iKey == EWidgetUIState && value == 2) + { + iHarvester->ClearAllOperations(); + SetValue(1); } else if( iKey == EWidgetRegAltered && value == 1 ) { iHarvester->UpdateL(); } - else if( iKey ==EWidgetMMCAltered ) - { + else if( iKey == EWidgetMMCAltered ) + { iHarvester->UpdateL(); + } + else if( iKey == EWidgetMassStorageMode ) + { + TInt count = allDrivesStatus.Length()/2; + for ( TInt i = 0; i < count; i++ ) + { + TInt driveNumber = allDrivesStatus[2*i]; + TInt driveStatus = allDrivesStatus[2*i+1]; + switch( driveStatus ) + { + case EUsbMsDriveState_Connected: + case EUsbMsDriveState_Disconnected: + { + iHarvester->UpdateL(); + } + break; + default: + break; + } + } } } } diff -r 10e98eab6f85 -r a359256acfc6 webengine/wrtharvester/src/wrtharvesterpublisherobserver.cpp --- a/webengine/wrtharvester/src/wrtharvesterpublisherobserver.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/wrtharvester/src/wrtharvesterpublisherobserver.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -57,13 +57,13 @@ // ---------------------------------------------------------------------------- // CWrtHarvesterPublisherObserver* CWrtHarvesterPublisherObserver::NewLC( - const TDesC& aName, CWrtHarvester* aHarvester ) + const TDesC& aBundleId, CWrtHarvester* aHarvester ) { CWrtHarvesterPublisherObserver* self( new( ELeave ) CWrtHarvesterPublisherObserver( aHarvester ) ); CleanupStack::PushL( self ); - self->ConstructL( aName ); + self->ConstructL( aBundleId ); return self; } @@ -74,16 +74,16 @@ CWrtHarvesterPublisherObserver::~CWrtHarvesterPublisherObserver() { ReleaseLiw(); - delete iName; + delete iBundleId; } // ---------------------------------------------------------------------------- // Symbian 2nd phase constructor can leave. // ---------------------------------------------------------------------------- // -void CWrtHarvesterPublisherObserver::ConstructL( const TDesC& aName ) +void CWrtHarvesterPublisherObserver::ConstructL( const TDesC& aBundleId ) { - iName = aName.AllocL(); + iBundleId = aBundleId.AllocL(); InitLiwL(); } @@ -178,9 +178,9 @@ // CWrtHarvesterPublisherObserver::Name // --------------------------------------------------------------------------- // -const TDesC& CWrtHarvesterPublisherObserver::Name() +const TDesC& CWrtHarvesterPublisherObserver::BundleId() { - return *iName; + return *iBundleId; } // --------------------------------------------------------------------------- diff -r 10e98eab6f85 -r a359256acfc6 webengine/wrtharvester/src/wrtharvesterregistryaccess.cpp --- a/webengine/wrtharvester/src/wrtharvesterregistryaccess.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/wrtharvester/src/wrtharvesterregistryaccess.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -20,9 +20,6 @@ #include "wrtharvesterregistryaccess.h" -_LIT( KSeparator, ":" ); - - // ============================ MEMBER FUNCTIONS ============================== // ---------------------------------------------------------------------------- @@ -39,28 +36,25 @@ // WrtHarvesterRegistryAccess::~WrtHarvesterRegistryAccess() { - iWidgetInfoArray.ResetAll(); } // --------------------------------------------------------------------------- // Collect bundle names of widgets supporting miniviews. // --------------------------------------------------------------------------- // -void WrtHarvesterRegistryAccess::WidgetBundleNamesL( - RPointerArray< HBufC >& aArray ) +void WrtHarvesterRegistryAccess::WidgetInfosL( + RWrtArray< CWrtInfo >& aWidgetInfoArray ) { RWrtArray< CWidgetInfo > widgetInfoArr; - RWidgetRegistryClientSession session; - - CleanupClosePushL( session ); widgetInfoArr.PushL(); + RWidgetRegistryClientSession session; + CleanupClosePushL( session ); User::LeaveIfError( session.Connect() ); - - aArray.Reset(); + // Reset previously appended widget infos - iWidgetInfoArray.ResetAll(); - + aWidgetInfoArray.ResetAll(); + TInt err = session.InstalledWidgetsL( widgetInfoArr ); for( TInt i( widgetInfoArr.Count() - 1 ); i >= 0; --i ) @@ -69,42 +63,15 @@ if ( SupportsMiniviewL( session, widgetInfo->iUid ) ) { - aArray.AppendL( ConstructWidgetNameL( session, *widgetInfo ) ); - iWidgetInfoArray.AppendL( widgetInfo ); - } - else - { - delete widgetInfo; - } - - widgetInfoArr.Remove( i ); - } - - CleanupStack::PopAndDestroy( 2, &session ); - } - -// --------------------------------------------------------------------------- -// Find widget by UID. -// --------------------------------------------------------------------------- -// -TUid WrtHarvesterRegistryAccess::WidgetUid( TPtrC aBundleName ) - { - TUid uid={0}; - TInt pos = aBundleName.Find( KSeparator ); - if( pos != KErrNotFound ) - { - aBundleName.Set( aBundleName.Right( aBundleName.Length()-pos-1 )); - } - - for( TInt i = 0; i < iWidgetInfoArray.Count(); i++ ) - { - if( aBundleName == *iWidgetInfoArray[i]->iBundleName ) - { - uid = iWidgetInfoArray[i]->iUid; - break; + CWrtInfo* info = new CWrtInfo(); + info->iUid = widgetInfo->iUid; + info->iBundleId = WidgetPropertyL( session, widgetInfo->iUid, EBundleIdentifier ); + info->iDisplayName = WidgetPropertyL( session, widgetInfo->iUid, EBundleDisplayName ); + aWidgetInfoArray.AppendL( info ); } } - return uid; + CleanupStack::PopAndDestroy( &session ); + CleanupStack::PopAndDestroy( &widgetInfoArr ); } // --------------------------------------------------------------------------- @@ -127,27 +94,21 @@ } // --------------------------------------------------------------------------- -// Get the Bundle identifier. +// Get the widget property as string. // --------------------------------------------------------------------------- // -HBufC* WrtHarvesterRegistryAccess::ConstructWidgetNameL( +HBufC* WrtHarvesterRegistryAccess::WidgetPropertyL( RWidgetRegistryClientSession& aSession, - CWidgetInfo& aInfo ) + const TUid& aUid, TWidgetPropertyId aPropertyId ) { CWidgetPropertyValue* value( NULL ); - value = aSession.GetWidgetPropertyValueL( aInfo.iUid, EBundleIdentifier ); + value = aSession.GetWidgetPropertyValueL( aUid, aPropertyId ); CleanupStack::PushL( value ); - const TDesC& identifier = *value; - HBufC* bundle = aInfo.iBundleName; - - HBufC* name = HBufC::NewL( identifier.Length() + KSeparator().Length() + bundle->Length()); - TPtr ptr = name->Des(); - ptr.Append( identifier ); - ptr.Append( KSeparator ); - ptr.Append( *bundle); + const TDesC& str = *value; + HBufC* strBuf = str.AllocL(); CleanupStack::PopAndDestroy( value ); - return name; + return strBuf; } // End of File diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetapp/data/WidgetUi.loc --- a/widgets/widgetapp/data/WidgetUi.loc Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetapp/data/WidgetUi.loc Thu Aug 27 07:44:59 2009 +0300 @@ -37,8 +37,3 @@ // r: 3.2 #define qtn_widgetui_oom_event "Out of Memory! Closing all widgets." -// d: Pop up to grant access to phone information and network -// l: popup_note_window -// r: 5.0 -#define qtn_widgetui_blanketpermission_prompt "Do you want to allow the widget to access information on your phone and connect to the network? " -// End of File diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetapp/data/WidgetUi.rss --- a/widgets/widgetapp/data/WidgetUi.rss Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetapp/data/WidgetUi.rss Thu Aug 27 07:44:59 2009 +0300 @@ -173,8 +173,4 @@ RESOURCE TBUF r_widgetui_softkey_option { buf = text_softkey_option; } -// query to grant permission for phone inofrmation and network access -RESOURCE TBUF r_widgetui_platform_access { buf = qtn_widgetui_blanketpermission_prompt; } -RESOURCE TBUF r_widgetui_please_work { buf = qtn_widgetui_blanketpermission_prompt; } - // End of File diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetapp/group/WidgetUi.mmp --- a/widgets/widgetapp/group/WidgetUi.mmp Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetapp/group/WidgetUi.mmp Thu Aug 27 07:44:59 2009 +0300 @@ -60,6 +60,7 @@ SOURCE WidgetUiWindow.cpp SOURCE WidgetUiAsyncExit.cpp SOURCE WidgetUiDialogsProviderProxy.cpp +SOURCE WidgetUiNetworkListener.cpp #ifdef BRDO_WRT_HS_FF SOURCE cpspublisher.cpp #endif @@ -69,6 +70,7 @@ TARGETPATH /private/10003a3f/apps END +MACRO OOM_WIDGET_CLOSEALL // INCLUDE PATHS USERINCLUDE . @@ -114,10 +116,12 @@ #ifdef RD_SCALABLE_UI_V2 LIBRARY cdlengine.lib #endif +LIBRARY esock.lib DEBUGLIBRARY flogger.lib LIBRARY browserengine.lib +LIBRARY oommonitor.lib #if defined( RD_PF_SEC_APPARC ) LIBRARY ServiceHandler.lib diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetapp/group/bld.inf --- a/widgets/widgetapp/group/bld.inf Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetapp/group/bld.inf Thu Aug 27 07:44:59 2009 +0300 @@ -26,7 +26,7 @@ // export localization files ../loc/WidgetUi.loc MW_LAYER_LOC_EXPORT_PATH(WidgetUi.loc) -../inc/widgetappdefs.rh |../../../inc/widgetappdefs.rh +../inc/widgetappdefs.rh MW_LAYER_PLATFORM_EXPORT_PATH(widgetappdefs.rh) PRJ_MMPFILES diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetapp/inc/WidgetUiAppUi.h --- a/widgets/widgetapp/inc/WidgetUiAppUi.h Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetapp/inc/WidgetUiAppUi.h Thu Aug 27 07:44:59 2009 +0300 @@ -172,6 +172,14 @@ * @since 5.0 */ void ProcessCommandL(TInt aCommand); + + /** + * Closes widget Window and exits WidgetUI if no windowleft + * @return void + * @since 5.0 + */ + + void CloseAndExitIfNoneLeft(); private: // From CEikAppUi @@ -273,6 +281,13 @@ */ void LaunchWindowL( const TDesC8& aParams ); +#ifdef OOM_WIDGET_CLOSEALL + /** + * CloseAllWidgetsAndExit + * @param none + */ + void CloseAllWidgetsAndExit(); +#endif private: // WindowManager to manage the list of running widget windows CWidgetUiWindowManager* iWindowManager; diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetapp/inc/WidgetUiNetworkListener.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/widgets/widgetapp/inc/WidgetUiNetworkListener.h Thu Aug 27 07:44:59 2009 +0300 @@ -0,0 +1,102 @@ +/* +* Copyright (c) 2008, 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifndef WIDGETUINETWORKLISTENER_H_ +#define WIDGETUINETWORKLISTENER_H_ + +// INCLUDES +#include +#include +#include "WidgetUiWindowManager.h" + +// CLASS DECLARATION + +/** +* Listens real interfaces and reports changes to Widget UI. +*/ +class CWidgetUiNetworkListener : public CActive + { + public: //Methods + + // Constructors and destructor + + /** + * Static constructor + */ + static CWidgetUiNetworkListener* NewL(CWidgetUiWindowManager& aWindowManager); + + /** + * Destructor + */ + ~CWidgetUiNetworkListener(); + + /** + * Starts listening of all intefaces. + * @return: error code, KErrNone if successfull. + */ + TInt StartListening(); + + private: // Methods + /** + * Constructor. + */ + CWidgetUiNetworkListener(CWidgetUiWindowManager& aWindowManager); + + /** + * Implement RunL of class CActive. + */ + void RunL(); + + /** + * Implement DoCancel of class CActive. + */ + void DoCancel(); + + /** + * Connects to the socket server + */ + TInt Connect(); + + /** + * Closes connection + */ + void Close(); + + /** + * Check for existing active connections + * @return: ETrue if there is an active network connection, else EFalse + */ + TBool CheckActiveNetworkConnection(); + + private: // Data + + // reference to WidgetUiWindowManager object + CWidgetUiWindowManager& iWindowManager; + + // buffer to receive interface notification + TInterfaceNotificationBuf iNote; + + // connection to interfaces + RConnection iConn; + + // socket server + RSocketServ iSocketServer; + + }; + +#endif /* WIDGETUINETWORKLISTENER_H_ */ diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetapp/inc/WidgetUiWindow.h --- a/widgets/widgetapp/inc/WidgetUiWindow.h Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetapp/inc/WidgetUiWindow.h Thu Aug 27 07:44:59 2009 +0300 @@ -42,6 +42,14 @@ EPublishStart, EPublishSuspend }; + +enum TNetworkState + { + ENetworkNotAllowed = 0, + ENetworkAccessAllowed, + ENetworkAccessible + }; + struct TWidgetState { TBool iFullViewState; // full view or not @@ -64,7 +72,7 @@ class CFbsBitmap; class CSchemeHandler; class CBrCtlInterface; - +class CJpgSaver; // CLASS DECLARATION /** @@ -231,6 +239,7 @@ * @param none * @return CBrCtlInterface* */ + void Done(); CBrCtlInterface* Engine() const { return iEngine; } /** @@ -348,6 +357,14 @@ void SetWidgetLoaded( TBool aWidgetLoaded ); /** + * IsWidgetLoaded + * Return ETrue if widget has finished loading, else EFalse + * @since 5.0 + * @return none + */ + TBool IsWidgetLoaded( ) { return iWidgetLoaded; } + + /** * GetBundleName * Gets the Bundle name for Uid * @since 5.0 @@ -410,24 +427,60 @@ * @since 5.0 * @return none */ - void SetIsCurrentWindow(TBool aIsCurrent){ iIsCurrent = aIsCurrent;} + void SetIsCurrentWindow(TBool aIsCurrent){ iIsCurrent = aIsCurrent;} + /** + * GetClickCount + * Get the count for widget being selected from homescreen + * @since 5.0 + * @return TInt + */ + TInt GetClickCount(){ return iClickCount;} + + /** + * IncrementClickCount + * Increase the click count for widgets being selected from homescreen + * @since 5.0 + * @return none + */ + void IncrementClickCount(){ ++iClickCount;} + + /** + * SetTime + * Set the time when widget is ReStarted after OOM + * @since 5.0 + * @return none + */ + void SetTime(){iOOMWidgetStartTime.HomeTime();} - /** - * GetBlanketPromptDisplayed - * Get whether blanketprompt is displayed - * @since 5.0 - * @return TBool - */ - TBool GetBlanketPromptDisplayed(){ return iBlanketPromptDisplayed;} - - /** - * SetBlanketPermissionDisplayed - * Sets Blanket Permission Prompt when displayed - * @since 5.0 - * @return none - */ - void SetBlanketPromptDisplayed(TBool aBlanketPromptDisplayed){ iBlanketPromptDisplayed = aBlanketPromptDisplayed;} - + /** + * GetTime when widget was started after OOM + * @since 5.0 + * @return TTime + */ + TTime GetTime(){return iOOMWidgetStartTime;} + + /** + * IsWidgetLoadStarted + * @since 5.0 + * @return TBool + */ + TBool IsWidgetLoadStarted(){return iWidgetLoadStarted;} + + /** + * CheckUserPermissionChanged + * Checks if the user permission to access network has changed + * @since 5.0 + * @return none + */ + void CheckUserPermissionChanged(TBool iCurrUserPerm); + + /** + * DetermineNetworkState + * Determine the current network state + * @since 5.0 + * @return none + */ + void DetermineNetworkState(); protected: @@ -493,7 +546,8 @@ private: CWidgetUiObserver* iWidgetUiObserver; // owned, responsible for deleting CWidgetUiWindowManager& iWindowManager; - + + CCpsPublisher* iCpsPublisher; // Interface to publish bitmap CWidgetUiDialogsProviderProxy* iWidgetUiDialogsProviderProxy; // owned, responsible for deleting HBufC* iUrl; // owned, responsible for deleting CBrCtlInterface* iEngine; // owned, responsible for deleting @@ -513,13 +567,18 @@ TBool iPenEnabled; // For touch TInt iCount; TWidgetState iWidgetWindowState; - TBool iSchemeProcessing; - // Interface to publish bitmap - CCpsPublisher* iCpsPublisher; + TBool iSchemeProcessing; + TNetworkState iNetworkState; + TBool iUserPermission; // ETrue if user chooses to allow network access when prompted, else EFalse //Download transaction ID - long iDlId; - TBool iBlanketPromptDisplayed; + long iDlId; + TInt iClickCount; + CFbsBitmap* iMiniviewBitmap ; + TTime iOOMWidgetStartTime; + TBool iWidgetLoadStarted; // Set to true when widget load starts + CJpgSaver* iJpgSaver; + }; #endif // diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetapp/inc/WidgetUiWindowManager.h --- a/widgets/widgetapp/inc/WidgetUiWindowManager.h Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetapp/inc/WidgetUiWindowManager.h Thu Aug 27 07:44:59 2009 +0300 @@ -28,6 +28,13 @@ #include "Browser_platform_variant.hrh" // CONSTANTS +enum TNetworkMode + { + EUnknownMode = 0, + EOnlineMode, + EOfflineMode + }; + // MACROS // DATA TYPES @@ -47,6 +54,7 @@ class MLiwInterface; class CInternetConnectionManager; class CSchemeHandler; +class CWidgetUiNetworkListener; #ifdef BRDO_WRT_HS_FF class CCpsPublisher; @@ -93,14 +101,6 @@ void HandleWidgetCommandL( const TUid& aUid, TUint32 aOperation ); - -// Suspend/resume miniview stuff. - /** - * Suspend a widget. - * @since 5.0 - * @param aUid UID of widget. - */ - void SuspendWidget( const TUid& aUid ); /** * Resume a suspended widget. @@ -110,59 +110,6 @@ void ResumeWidgetL( const TUid& aUid ); /** - * Suspend all the publishing widget. - * @since 5.0 - * @return none. - */ - void SuspendAllWidget(); - - /** - * Stop mini view and exit - * @since 5.0 - * @param aUrl - * @return none - */ - void DeactivateMiniViewL( const TUid& aUid ); - - /** - * Suspend publishing on home screen - * @since 5.0 - * @param aUid UID of widget. - * @param aSize Size of miniview. - * @return Successful or not. - */ - TBool ActivateMiniViewL( const TUid& aUid, const TRect& aRect ); - -// Close / terminate widgets. - - /** - * CloseWindow - * Closes the window of the widget identified by a Uid - * @since 3.1 - * @param aUid - Uid to identify the widget - * @return none - */ - void CloseWindow( const TUid& aUid ); - - /** - * CloseWindow - * Closes the window of the widget - * @since 3.1 - * @param aWidgetWindow - window of the widget - * @return none - */ - void CloseWindow( CWidgetUiWindow* aWidgetWindow ); - - /** - * RemoveFromWindowList - * Remove the widget window from window list - * @since 5.0 - * @param aWidgetWindow - window of the widget - * @return none - */ - void RemoveFromWindowList( CWidgetUiWindow* aWidgetWindow ); - - /** * CloseWindowsAsync * Close window async * @param aAllWindows ETrue closes all windows; EFalse closes active window @@ -288,13 +235,6 @@ */ void HandleOOMEventL( TBool aForeground ); - /** - * AllowPlatformAccessL - * Prompt for Allow Platform Access - * @since 5.0 - */ - void AllowPlatformAccessL( const TUid& aUid ); - // Utility stuff. /** @@ -350,7 +290,122 @@ * @return CActiveApDb */ CActiveApDb* GetDb() {return iDb;} - + + /** + * GetNetworkMode + * @since 5.0 + * @returns online/offline mode + */ + TNetworkMode GetNetworkMode() {return iNetworkMode;} + + /** + * GetNetworkConn + * @since 5.0 + * @returns ETrue if there is an active network connection + */ + TBool GetNetworkConn() {return iNetworkConnected;} + + /** + * GetCenrepHSModeL + * @since 5.0 + * @returns online/offline mode read from the cenrep + */ + TInt GetCenrepHSModeL(); + + /** + * FullViewWidgetsOpen + * @since 5.0 + * @returns ETrue if atleast one full view widget is open + */ + TBool FullViewWidgetsOpen(); + + /** + * CloseWindowWithLeastClick + * Removes widget window with least click count + * @since 5.0 + * @return TBool + */ + TBool CloseWindowWithLeastClick(); + + /** + * DeleteOOMNotifyTimer + * @since 5.0 + * @return void + */ + void DeleteOOMNotifyTimer(); + + /** + * OpenOrCreateWindowL + * @since 5.0 + * @param aUid UID of widget. + * @param aOperation Whether to open widget to miniview or full screen. + */ + void OpenOrCreateWindowL( + const TUid& aUid, + TUint32 aOperation ); + + /** + * CanWindowBeCreated + * Checks for available RAM before creating window + * @since 5.0 + * @return none + */ + void CanWindowBeCreated(const TUid& aUid, TUint32 aOperation); + + /** + * StartHarvesterNotifyTimer + * @since 5.0 + * @return void + */ + void StartHarvesterNotifyTimer(); + + /** + * DeleteHarvesterNotifyTimer + * @since 5.0 + * @return void + */ + void DeleteHarvesterNotifyTimer(); + + /** + * SendAppToBackground + * Send widget ui to background + * @since 5.0 + * @return void + */ + void SendAppToBackground(); + + /** + * NotifyConnecionChange + * Notify widgets of a network connection change + * @since 5.0 + * @return void + */ + void NotifyConnecionChange(TBool aConn); + +#ifdef OOM_WIDGET_CLOSEALL + /** + * CloseAllWidgetsUnderOOM + * @param none + * @return ETrue if all widgets were closed else EFalse + */ + TBool CloseAllWidgetsUnderOOM(); + + /** + * GetLastWidgetRestartTime + * @param none + * @return Time when last widget was created after OOM + */ + TTime GetLastWidgetRestartTime(){return iTimeLastWidgetOpen; } + + /** + * SetLastWidgetRestartTime + * The time when last widget was restarted in case of OOM + * @param aStartTime + * @return none + */ + void SetLastWidgetRestartTime(TTime aStartTime){iTimeLastWidgetOpen = aStartTime;} +#endif // OOM_WIDGET_CLOSEALL + protected: /** @@ -372,8 +427,59 @@ void ConstructL(); private: + + /** + * Suspend a widget. + * @since 5.0 + * @param aUid UID of widget. + */ + void SuspendWidget( const TUid& aUid ); + + /** + * Suspend all the publishing widget. + * @since 5.0 + * @return none. + */ + void SuspendAllWidget(); /** + * Stop mini view and exit + * @since 5.0 + * @param aUrl + * @return ETrue if last window was closed + */ + TBool DeactivateMiniViewL( const TUid& aUid ); + + /** + * Suspend publishing on home screen + * @since 5.0 + * @param aUid UID of widget. + * @param aSize Size of miniview. + * @return Successful or not. + */ + TBool ActivateMiniViewL( const TUid& aUid, const TRect& aRect ); + +// Close / terminate widgets. + + /** + * CloseWindow + * Closes the window of the widget + * @since 3.1 + * @param aWidgetWindow - window of the widget + * @return ETrue if last window was closed + */ + TBool CloseWindow( CWidgetUiWindow* aWidgetWindow ); + + /** + * RemoveFromWindowList + * Remove the widget window from window list + * @since 5.0 + * @param aWidgetWindow - window of the widget + * @return ETrue if last window was closed + */ + TBool RemoveFromWindowList( CWidgetUiWindow* aWidgetWindow ); + + /** * Hide the window. * @param aWindow Window. Ownership is retained. */ @@ -408,16 +514,7 @@ * @return Whether widgets are supported or not. */ TBool DoesWidgetSupportMiniviewL( const TUid& aUid ); - - /** - * OpenOrCreateWindowL - * @since 5.0 - * @param aUid UID of widget. - * @param aOperation Whether to open widget to miniview or full screen. - */ - void OpenOrCreateWindowL( - const TUid& aUid, - TUint32 aOperation ); + /** * Set the given window as "active full-screen window". @@ -425,16 +522,15 @@ * @since 5.0 * @param aWindow Window. Onwership is retained. */ - void ShowWindow( - CWidgetUiWindow* aWindow ); + void ShowWindow( CWidgetUiWindow* aWindow ); /** - * Exit Publishing Widget + * SendWidgetToBackground * @since 5.0 * @param aUid * @return none */ - void ExitPublishingWidget( const TUid& aUid ); + void SendWidgetToBackground( const TUid& aUid ); private: @@ -442,18 +538,25 @@ CWidgetUiWindowView* iContentView; // not owned, not responsible for deleting RPointerArray iWindowList; // owned, responsible for deleting CWidgetUiAppUi& iAppUi; // not owned, not responsible for deleting. + CWidgetUiNetworkListener* iNetworkListener; // owned, responsible for deleting CDocumentHandler* iHandler; // own RWidgetRegistryClientSession iClientSession; // owned TBool iServerConnected; // connected to Widget Registry server ? TBool iStrictMode; CBrowserDialogsProvider* iDialogsProvider;// owned, responsible for deleting - CInternetConnectionManager* iConnection; // owned, responsible for deleting + CInternetConnectionManager* iConnection; // owned, responsible for deleting + TNetworkMode iNetworkMode; // unknown mode = 0, online mode = 1, offline mode = 2 + TBool iNetworkConnected; // ETrue if there is an active network connection, else EFalse #ifdef BRDO_WRT_HS_FF CCpsPublisher* iCpsPublisher; // Owned, interface to publish bitmap to CPS #endif // TODO should this be created only when needed? - CActiveApDb* iDb; // owned, responsible for deleting - + CActiveApDb* iDb; // owned, responsible for deleting + CPeriodic* iNotifyOOMFlagTimer;//Timer for one min timeout before next oom note is shown + CPeriodic* iNotifyHarvester;//Notify harvester to send next event +#ifdef OOM_WIDGET_CLOSEALL + TTime iTimeLastWidgetOpen; +#endif }; #endif // WIDGETUIWINDOWMANAGER_H_ diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetapp/inc/WidgetUiWindowView.h --- a/widgets/widgetapp/inc/WidgetUiWindowView.h Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetapp/inc/WidgetUiWindowView.h Thu Aug 27 07:44:59 2009 +0300 @@ -80,25 +80,15 @@ */ CWidgetUiWindowContainer* Container(); - /** - * ShowActivatedObject - * show/hide the status pane and CBAs - * @since 3.1 - * @param aVisible - ETrue to show; EFalse to hide - * @param aShowStatusPane - - * ETrue shows StatusPane and CBA - * EFalse to show CBA only - * @return void - */ - void ShowActivatedObject(TBool aVisible, TBool aShowStatusPane = EFalse); /** * UpdateStatusPane * show/hide the status pane * @since 3.1 + * @param aVisible - ETrue to show; EFalse to hide * @return void */ - void UpdateStatusPane(); + void UpdateStatusPane( TBool aVisible ); /** * CbaGroup @@ -162,7 +152,14 @@ * @return void */ void StateChanged( TBrCtlDefs::TBrCtlState aState, TInt aValue ); - + + /** + * UpdateToolbar in case Orientation is changed + * @param aShow to define visibility of toolbar + * @return void + */ + void UpdateToolbar(TBool aShow); + private: /** diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetapp/inc/cpspublisher.h --- a/widgets/widgetapp/inc/cpspublisher.h Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetapp/inc/cpspublisher.h Thu Aug 27 07:44:59 2009 +0300 @@ -69,14 +69,15 @@ public: TSize BitmapSize(); void PublishBitmapL( CFbsBitmap& aBitmap, const TDesC& aBundleName ); + void NetworkConnectionCancelledL(); + void NetworkConnectionAllowedL(); private: void GetBitmapSizeL(); void InitCpsInterfaceL(); - void AddImageHandleL( const TDesC& aPublisherId, const TDesC& aContentType, - const TDesC& aContentId, const TInt& aHandle, const TInt& aMaskHandle, - const TDesC8& aImageKey ); + void AddImageHandleL( const TDesC& aBundleId, const TInt& aHandle, + const TInt& aMaskHandle, const TDesC8& aImageKey ); void ExecuteCommandL(CLiwDefaultMap* aInFilter, CLiwDefaultMap* aOutDataMap, const TDesC16& aRegistry ); void ExecuteRegistrationCommandL( TUint aOption ); diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetapp/inc/widgetappdefs.rh --- a/widgets/widgetapp/inc/widgetappdefs.rh Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetapp/inc/widgetappdefs.rh Thu Aug 27 07:44:59 2009 +0300 @@ -58,6 +58,9 @@ WidgetResume, WidgetSuspend, WidgetSelect, + WidgetOnline, + WidgetOffline, + WidgetRestart, Uninitialized }; diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetapp/src/WidgetUiAppUi.cpp --- a/widgets/widgetapp/src/WidgetUiAppUi.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetapp/src/WidgetUiAppUi.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -32,6 +32,10 @@ #include #include +#ifdef BRDO_WRT_HS_FF +#include +#endif + // EXTERNAL DATA STRUCTURES // EXTERNAL FUNCTION PROTOTYPES @@ -50,13 +54,12 @@ // FORWARD DECLARATIONS -// ============================= LOCAL FUNCTIONS ================================ - -static void NotifyWidgetRunning() +//LOCAL FUNCTION +void NotifyCommandHandled() { const TUid KMyPropertyCat = { 0x10282E5A }; enum TMyPropertyKeys { EMyPropertyState = 109 }; - TInt state( 1 ); + TInt state( 2 ); RProperty::Set( KMyPropertyCat, EMyPropertyState , state ); } @@ -239,13 +242,7 @@ ProcessMessageArgumentsL( aMessage, uid, operation ); iWindowManager->HandleWidgetCommandL( uid, operation ); - - // Widget is up and running, notify that next one can be launched - // TODO magic numbers from Launcher. - if( operation == LaunchMiniview ) - { - NotifyWidgetRunning(); - } + } // ------------------------------------------------------------------------------ @@ -377,13 +374,13 @@ if ( iWindowManager ) { if(aEventType == KAppOomMonitor_FreeRam ) - { + { +#ifdef OOM_WIDGET_CLOSEALL + CloseAllWidgetsAndExit(); +#else if // OOM_WIDGET_CLOSEALL iWindowManager->HandleOOMEventL(iIsForeground); - } - else if(aEventType == KAppOomMonitor_MemoryGood && iWindowManager->ActiveWindow()) - { - iWindowManager->ActiveWindow()->Engine()->HandleCommandL( - (TInt)TBrCtlDefs::ECommandMemoryGood + (TInt)TBrCtlDefs::ECommandIdBase); + CloseAndExitIfNoneLeft(); +#endif } } } @@ -486,16 +483,29 @@ // // ----------------------------------------------------------------------------- // -void CWidgetUiAppUi::AsyncExit( TBool aAllWidgets ) +void CWidgetUiAppUi::AsyncExit( TBool /*aAllWidgets*/ ) { - if (aAllWidgets && iWindowManager) - { - iWindowManager->CloseAllWindowsExceptCurrent(); - } iWidgetUiAsyncExit->Start(); // close current and exits app if no widgets left running } // ----------------------------------------------------------------------------- +// CWidgetUiAppUi::CloseAndExitIfNoneLeft() +// +// ----------------------------------------------------------------------------- +// +void CWidgetUiAppUi::CloseAndExitIfNoneLeft() + { + if(iWindowManager) + { + if(iWindowManager->CloseWindowWithLeastClick()) + { + //Exit Application + NotifyCommandHandled(); + Exit(); + } + } + } +// ----------------------------------------------------------------------------- // CWidgetUiAppUi::HandleDelayedForegroundEventCallback() // CIdle callback function to handle delayed foreground events for WidgetUI // @@ -532,10 +542,8 @@ TUint32& aOperation ) { __UHEAP_MARK; - CWidgetPropertyValue* value( NULL ); TUint32 version( -1 ); TPtrC ptr( NULL, 0 ); - HBufC* tmp( NULL ); RDesReadStream stream( aLine ); CleanupClosePushL( stream ); @@ -587,4 +595,23 @@ } } +#ifdef OOM_WIDGET_CLOSEALL +// ----------------------------------------------------------------------------- +// CWidgetUiAppUi::CloseAllWidgetsAndExit() +// Close all widgets and exit in case of OOM +// +// ----------------------------------------------------------------------------- +// +void CWidgetUiAppUi::CloseAllWidgetsAndExit() +{ + if(iWindowManager->CloseAllWidgetsUnderOOM()) + { + //Exit Application + NotifyCommandHandled(); + Exit(); + } +} + +#endif + // End of File diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetapp/src/WidgetUiNetworkListener.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/widgets/widgetapp/src/WidgetUiNetworkListener.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -0,0 +1,133 @@ +/* +* Copyright (c) 2008, 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include "WidgetUiNetworkListener.h" + +CWidgetUiNetworkListener* CWidgetUiNetworkListener::NewL(CWidgetUiWindowManager& aWindowManager) + { + CWidgetUiNetworkListener* self = new (ELeave) CWidgetUiNetworkListener(aWindowManager); + return self; + } + +CWidgetUiNetworkListener::CWidgetUiNetworkListener(CWidgetUiWindowManager& aWindowManager) + : CActive(0), iWindowManager(aWindowManager) + { + CActiveScheduler::Add(this); + StartListening(); + } + +CWidgetUiNetworkListener::~CWidgetUiNetworkListener() + { + Cancel(); + Close(); + } + +TInt CWidgetUiNetworkListener::StartListening() + { + TInt err = KErrNone; + // If already listening do nothing + if(!IsActive()) + { + if((err = Connect()) == KErrNone) + { + // check if there is a current active connection + if ( CheckActiveNetworkConnection() ) + { + // notify widgets of an existing active network connection + iWindowManager.NotifyConnecionChange( ETrue ); + } + iConn.AllInterfaceNotification( iNote, iStatus ); + SetActive(); + } + } + return err; + } + +TBool CWidgetUiNetworkListener::CheckActiveNetworkConnection() + { + TUint iNumConnections, netConnections; + TPckgBuf connectionInfo; + + iConn.EnumerateConnections(iNumConnections); + netConnections = iNumConnections; + for(TUint i = 1; i <= iNumConnections; i++) + { + iConn.GetConnectionInfo(i, connectionInfo); + // dont count bluetooth connection + if(connectionInfo().ConnectionType() >= EConnectionBTPAN) + { + netConnections--; + } + } + + if (netConnections > 0) + { + return ETrue; + } + + return EFalse; + } + +void CWidgetUiNetworkListener::RunL() + { + if ( iNote().iState == EInterfaceUp ) + { + // notify widgets of an active network connection + iWindowManager.NotifyConnecionChange( ETrue ); + } + else if ( iNote().iState == EInterfaceDown ) + { + // check if there are no other active connections + if ( !CheckActiveNetworkConnection() ) + { + // notify widgets of a network connection going down + iWindowManager.NotifyConnecionChange( EFalse ); + } + } + + iConn.AllInterfaceNotification( iNote, iStatus ); + SetActive(); + } + +void CWidgetUiNetworkListener::DoCancel() + { + iConn.CancelAllInterfaceNotification(); + Close(); + } + +TInt CWidgetUiNetworkListener::Connect() + { + TInt err; + + if( ( err = iSocketServer.Connect() ) == KErrNone ) + { + if( ( err = iConn.Open(iSocketServer, KAfInet) ) != KErrNone ) + { + //failed, close server too + iSocketServer.Close(); + } + } + + return err; + } + +void CWidgetUiNetworkListener::Close() + { + iConn.Close(); // destructor does these + iSocketServer.Close(); + } diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetapp/src/WidgetUiObserver.cpp --- a/widgets/widgetapp/src/WidgetUiObserver.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetapp/src/WidgetUiObserver.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -193,11 +193,11 @@ if ((elementtype == TBrCtlDefs::EElementActivatedInputBox) || (elementtype == TBrCtlDefs::EElementActivatedObjectBox)) { - iWindow->WindowManager().View()->ShowActivatedObject( ETrue ); + iWindow->WindowManager().View()->UpdateStatusPane( ETrue ); } else { - iWindow->WindowManager().View()->ShowActivatedObject( EFalse ); + iWindow->WindowManager().View()->UpdateStatusPane( EFalse ); } } } diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetapp/src/WidgetUiWindow.cpp --- a/widgets/widgetapp/src/WidgetUiWindow.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetapp/src/WidgetUiWindow.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -51,7 +51,7 @@ const TUint KWmlNoDefaultAccessPoint = KMaxTUint; // see cenrep setting default -1 as int, here as uint const TUint KWmlNoDefaultSnapId = KMaxTUint; // see cenrep setting default -1 as int, here as uint -_LIT( KSeparator, ":" ); + // MACROS // LOCAL CONSTANTS AND MACROS @@ -92,8 +92,8 @@ : iWindowManager( aWindowManager ), iCpsPublisher( aCpsPublisher ), iNetworkAccessGrant(EInvalid), iPreferredOrientation(TBrCtlDefs::EOrientationUndefined), iIsCurrent(EFalse), iShowSoftkeys(EFalse), iWidgetLoaded(EFalse), - iSchemeProcessing (EFalse), - iBlanketPromptDisplayed (EFalse) + iSchemeProcessing (EFalse),iClickCount(0), iWidgetLoadStarted(EFalse), + iNetworkState(ENetworkNotAllowed), iUserPermission(ETrue) { } @@ -171,6 +171,9 @@ } iDlId = 0; + + // determine initial widget online/offline network state + DetermineNetworkState(); } // ----------------------------------------------------------------------------- @@ -195,6 +198,7 @@ delete iLeftSoftKeyLabel; delete iWidgetUiDialogsProviderProxy; delete iSchemeHandler; + delete iMiniviewBitmap; } // ----------------------------------------------------------------------------- @@ -318,7 +322,10 @@ if (CbaGroup()) { CbaGroup()->MakeVisible( iShowSoftkeys ); - iWindowManager.View()->UpdateStatusPane(); + iWindowManager.View()->UpdateStatusPane( aVisible ); + //in case CBA keys are disbaled by javascript ,SetToolbarVisibility EFalse, + //Since it would take entire screen.Else SetToolbarVisibility to ETrue in Landscape mode + iShowSoftkeys?iWindowManager.View()->UpdateToolbar(ETrue):iWindowManager.View()->UpdateToolbar(EFalse); CbaGroup()->DrawNow(); TRect clientRect = iWindowManager.View()->ClientRect(); // resize the container to take into account the size of the softkey labels @@ -404,7 +411,7 @@ // make sure softkeys are visible before setting the text // CEikButtonGroupContainer::Current() returns NULL if softkeys are not visible - SetSoftkeysVisible(ETrue); + SetSoftkeysVisible(iShowSoftkeys); TInt err(KErrNotFound); // check to see if aText is a filename @@ -495,11 +502,11 @@ // void CWidgetUiWindow::SetCurrentWindow( TBool aCurrent ) { - if (iIsCurrent != aCurrent && iWindowManager.View()) + if (iIsCurrent != aCurrent && iWindowManager.View() && Engine()) { iIsCurrent = aCurrent; - iWindowManager.View()->ShowActivatedObject(EFalse); // deactivates any open edit boxes + iWindowManager.View()->UpdateStatusPane(EFalse); // deactivates any open edit boxes if (aCurrent) { @@ -516,9 +523,11 @@ iWindowManager.View()->DeActivateOptionsMenu(); Engine()->MakeVisible(EFalse);// hide the active widget } - if ( !aCurrent ) + if ( !aCurrent && (EPublishStart != WidgetMiniViewState())) + { iWidgetExtension->HandleCommandL ( (TInt)TBrCtlDefs::ECommandAppBackground + (TInt)TBrCtlDefs::ECommandIdBase ); - + Engine()->HandleCommandL( (TInt)TBrCtlDefs::ECommandAppBackground + (TInt)TBrCtlDefs::ECommandIdBase); + } if ( aCurrent ) { Engine()->HandleCommandL( (TInt)TBrCtlDefs::ECommandAppForeground + (TInt)TBrCtlDefs::ECommandIdBase); @@ -568,10 +577,12 @@ void CWidgetUiWindow::ReloadWidget( ) { SetWidgetLoaded(EFalse); + iWidgetLoadStarted = ETrue; TRAPD(err,iEngine->LoadFileL( iUrl->Des() )); if (err != KErrNone) { SetWidgetLoaded(ETrue); + iWidgetLoadStarted = EFalse; } } @@ -601,64 +612,27 @@ // void CWidgetUiWindow::PublishSnapShot() { - if( iWidgetLoaded ) + if( iWidgetLoaded && (WidgetMiniViewState() == EPublishStart ) ) { #ifdef BRDO_WRT_HS_FF - CFbsBitmap* bitmap( new CFbsBitmap() ); - if ( bitmap && iCpsPublisher) + if ( !iMiniviewBitmap ) { - + iMiniviewBitmap = new CFbsBitmap(); + } + + if ( iMiniviewBitmap && iCpsPublisher) + { TRAP_IGNORE( - (iEngine->TakeSnapshotL( *bitmap )); - HBufC* publisherName = WidgetIdAndNameLC(); - RDebug::Printf( "CWidgetUiWindow::PublishSnapShot" ); - iCpsPublisher->PublishBitmapL( *bitmap, *publisherName ); - CleanupStack::PopAndDestroy( publisherName ); + (iEngine->TakeSnapshotL( *iMiniviewBitmap )); + iCpsPublisher->PublishBitmapL( *iMiniviewBitmap, *iWidgetBundleId ); ); - - - delete bitmap; } #endif } } -// ----------------------------------------------------------------------------- -// CWidgetUiWindow::WidgetIdAndNameLC() -// Constructs the publisher identifier -// -// ----------------------------------------------------------------------------- -// -HBufC* CWidgetUiWindow::WidgetIdAndNameLC() - { - HBufC* widgetBundleName = HBufC::NewLC( KWidgetRegistryVal ); - TPtr bundleName( widgetBundleName->Des() ); - GetBundleName( bundleName ); - - HBufC* name = HBufC::NewL( bundleName.Length() + KSeparator().Length() + iWidgetBundleId->Length() ); - TPtr namePtr( name->Des()); - namePtr.Append( *iWidgetBundleId ); - namePtr.Append( KSeparator ); - namePtr.Append( bundleName ); - CleanupStack::PopAndDestroy( widgetBundleName ); - CleanupStack::PushL( name ); - return name; - } - -// ----------------------------------------------------------------------------- -// CWidgetUiWindow::GetBundleName() -// Get Bundle name for the current widget Uid -// -// ----------------------------------------------------------------------------- -// -void CWidgetUiWindow::GetBundleName( TPtr& aBundleName ) - { - RWidgetRegistryClientSession clientSession = iWindowManager.WidgetUIClientSession(); - - clientSession.GetWidgetBundleName( iUid, aBundleName ); - } // ----------------------------------------------------------------------------- // CWidgetUiWindow::HasMiniviewL() @@ -683,22 +657,32 @@ // TBool CWidgetUiWindow::CheckNetworkAccessL() { + // if widgets in offline mode, deny network access + if (iWindowManager.GetNetworkMode() == EOfflineMode) + { + // if widget is in full view, offer user the option to go to online mode +#ifdef BRDO_WRT_HS_FF + if ( WidgetFullViewState() && WidgetMiniViewState() != EPublishStart ) + { + iCpsPublisher->NetworkConnectionAllowedL(); + } +#endif + SetNetworkAccessGrant( EDeny ); + User::Leave( KErrAccessDenied ); + } + // begin info.plist (declare EAllowNetworkAccess or EAllowFullAccess ?) RWidgetRegistryClientSession& widgetRegistry = iWindowManager.WidgetUIClientSession(); - CWidgetPropertyValue* propValue = widgetRegistry.GetWidgetPropertyValueL( iUid, EAllowNetworkAccess ); + CWidgetPropertyValue* propValue = widgetRegistry.GetWidgetPropertyValueL(iUid, EAllowNetworkAccess ); TInt networkAccess = *propValue; delete propValue; - propValue = widgetRegistry.GetWidgetPropertyValueL( iUid, EAllowFullAccess ); + propValue = widgetRegistry.GetWidgetPropertyValueL(iUid, EAllowFullAccess ); TInt fullAccess = *propValue; delete propValue; - propValue = widgetRegistry.GetWidgetPropertyValueL( iUid, EBlanketPermGranted ); - TInt blanketPermission = *propValue; - delete propValue; - TInt inMiniView = widgetRegistry.IsWidgetInMiniView( iUid); - if ( !( networkAccess || fullAccess ) || - ( inMiniView && !blanketPermission )) + + if ( !( networkAccess || fullAccess ) ) { SetNetworkAccessGrant( EDeny ); User::Leave( KErrAccessDenied ); @@ -734,8 +718,8 @@ prompt = 1; // got error, force prompt } delete rep; - } - + } + if ( prompt ) { CBrowserDialogsProvider* dialogProvider @@ -748,6 +732,8 @@ CleanupStack::PopAndDestroy( 3 ); // save prompt result for session SetNetworkAccessGrant( grant? EAllow : EDeny ); + + CheckUserPermissionChanged( grant ); } else { @@ -826,9 +812,9 @@ TInt connFailure = iWindowManager.GetConnection()->StartConnectionL( ETrue ); if (KErrCancel == connFailure) { - // Only if user cancelled, do we treat this as - // session deny permission to prevent repeated attempts - SetNetworkAccessGrant( EDeny ); +#ifdef BRDO_WRT_HS_FF + iCpsPublisher->NetworkConnectionCancelledL(); +#endif User::Leave( connFailure ); } else if ( KErrNone != connFailure ) @@ -1098,4 +1084,54 @@ return genericParamList; } +// --------------------------------------------------------- +// CWidgetUiWindow::CheckUserPermissionChanged() +// --------------------------------------------------------- +// +void CWidgetUiWindow::CheckUserPermissionChanged(TBool iCurrUserPerm) + { + if ( iUserPermission != iCurrUserPerm ) + { + iUserPermission = iCurrUserPerm; + DetermineNetworkState(); + } + } + +// --------------------------------------------------------- +// CWidgetUiWindow::DetermineNetworkState() +// --------------------------------------------------------- +// +void CWidgetUiWindow::DetermineNetworkState() + { + TNetworkState currNetState; + RWidgetRegistryClientSession& widgetRegistry = iWindowManager.WidgetUIClientSession(); + TInt inMiniView = widgetRegistry.IsWidgetInMiniView( iUid); + CWidgetPropertyValue* propValue = widgetRegistry.GetWidgetPropertyValueL( iUid, EAllowNetworkAccess ); + TInt netAccessWdgtProp = *propValue; // AllowNetworkAccess in the info.plist file + + if ( netAccessWdgtProp && ((inMiniView && (iWindowManager.GetNetworkMode() == (TInt)EOnlineMode)) + || (!inMiniView && iUserPermission)) ) + { + if ( iWindowManager.GetNetworkConn() ) + { + currNetState = ENetworkAccessible; + } + else + { + currNetState = ENetworkAccessAllowed; + } + } + else + { + currNetState = ENetworkNotAllowed; + } + + if ( iNetworkState != currNetState ) + { + iNetworkState = currNetState; + // send the new widget network state to widget engine + iWidgetExtension->SetParamL( TBrCtlDefs::EWidgetNetworkState, (TInt)iNetworkState ); + } + } + // End of file diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetapp/src/WidgetUiWindowContainer.cpp --- a/widgets/widgetapp/src/WidgetUiWindowContainer.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetapp/src/WidgetUiWindowContainer.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -316,7 +316,7 @@ if ( iWindowManager.ActiveWindow() && iWindowManager.View()->CbaGroup()->IsVisible() ) { - iWindowManager.View()->ShowActivatedObject(ETrue, showStausPane); + iWindowManager.View()->UpdateStatusPane(ETrue); editing = ETrue; } } @@ -333,7 +333,7 @@ (Engine()->FocusedElementType() != TBrCtlDefs::EElementActivatedInputBox && Engine()->FocusedElementType() != TBrCtlDefs::EElementActivatedObjectBox )) { - iWindowManager.View()->ShowActivatedObject(EFalse); + iWindowManager.View()->UpdateStatusPane(EFalse); } } diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetapp/src/WidgetUiWindowManager.cpp --- a/widgets/widgetapp/src/WidgetUiWindowManager.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetapp/src/WidgetUiWindowManager.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -21,6 +21,7 @@ #include "WidgetUiWindowContainer.h" #include "WidgetUiWindow.h" #include "WidgetUiAppUi.h" +#include "WidgetUiNetworkListener.h" #include "WidgetInstallerInternalCRKeys.h" #include "SWInstWidgetUid.h" #include "widgetappdefs.rh" @@ -42,39 +43,28 @@ #include #include +#include +#include +// LOCAL FUNCTION PROTOTYPES +TInt doDestructOOMNotifyTimer( TAny* ptr ); +TInt doNotifyHarvester( TAny* ptr ); -/** -* Utility class to show the prompt for platform security access. -* -* The class exists only to provide platform security access prompt -* for the widgets which are launched in minview -*/ -class CGlobalQueryHandlerAO : public CActive +// CONSTANTS +#define KUidWidgetOOMPlugin 0x10282855 +const TUint32 KCRUidActiveIdleLV = 0x10275102; +const TUint32 KAIWebStatus = 0x0000300F; +const TInt KMemoryToCreateWidgetWindow = 10*1024*1024; +const TInt KOOMNotificationDialogIntervalTimeOut = 60000000; +const TInt KOOMNotificationDialogTimeOut = 2000000; +const TInt KOOMHarvesterNotificationTimeOut = 5000000; +const TInt KOOMWidgetCloseTimeOut = 15;//Do not close the widget that was started after OOM within 15 sec + +class CRequestRAM : public CActive { -public: - /** - * Startup. - * - * @param aManager Window Manager. - * @param aWindow Window. - * @param aMessage Message to be prompted. - * @param aSoftkeys for prompt. - */ - static CGlobalQueryHandlerAO* StartLD ( - CWidgetUiWindowManager& aManager, - CWidgetUiWindow& aWindow, - const TDesC& aMessage, - TInt aSoftkeys); - /** - * ShowGlobalQueryDialogL. - * - * @param aMessage Message to be prompted. - * @param aSoftkeys for prompt. - */ - void ShowGlobalQueryDialogL ( - const TDesC& aMessage, - TInt aSoftkeys ); +public: + + static CRequestRAM* StartLD(CWidgetUiWindowManager* aWidgetUiWindowManager, const TUid& aUid, TUint32 aOperation); protected: // From CActive /** * Execute asynchronous operation. @@ -85,39 +75,38 @@ * Provide cancellation methods. */ void DoCancel(); + void ConstructL(); private: /** * Constructor. - * - * @param aManager Manager. - * @param aWindow Window. - * @param aMessage Message for prompt. - * @param aSoftkeys for prompt. */ - CGlobalQueryHandlerAO ( - CWidgetUiWindowManager& aManager, - CWidgetUiWindow& aWindow, - const TDesC& aMessage, - TInt aSoftkeys); + CRequestRAM (CWidgetUiWindowManager* aWidgetUiWindowManager, const TUid& aUid, TUint32 aOperation); /** * Destructor. * * Private on purpose. */ - ~CGlobalQueryHandlerAO(); + ~CRequestRAM(); private: + ROomMonitorSession iOomSession; + CWidgetUiWindowManager* iWidgetUiWindowManager; + TUid iUid; + TUint32 iOperation; + }; - CWidgetUiWindowManager& iManager; - CWidgetUiWindow& iWindow; - CAknGlobalConfirmationQuery* iGlobalConfirmationQuery ; - CActiveSchedulerWait iScheduler; - HBufC* iConfirmationText; +// ============================= LOCAL FUNCTIONS ================================ - }; +static void NotifyCommandHandled() + { + const TUid KMyPropertyCat = { 0x10282E5A }; + enum TMyPropertyKeys { EMyPropertyState = 109 }; + TInt state( 1 ); + RProperty::Set( KMyPropertyCat, EMyPropertyState , state ); + } // ============================================================================= @@ -129,7 +118,9 @@ // CWidgetUiWindowManager::CWidgetUiWindowManager(CWidgetUiAppUi& aAppUi): iAppUi(aAppUi), - iStrictMode(ETrue) + iStrictMode(ETrue), + iNetworkMode(EUnknownMode), + iNetworkConnected(EFalse) { } @@ -168,6 +159,8 @@ #ifdef BRDO_WRT_HS_FF iCpsPublisher = CCpsPublisher::NewL(); #endif + + iNetworkListener = CWidgetUiNetworkListener::NewL( *this ); } // ----------------------------------------------------------------------------- @@ -196,6 +189,8 @@ CWidgetUiWindowManager::~CWidgetUiWindowManager() { iWindowList.ResetAndDestroy(); + + delete iNetworkListener; // TODO Why there is a "Disconnect" method in the first place... // RHandleBase::Close() should be enough? @@ -227,23 +222,22 @@ // // ----------------------------------------------------------------------------- // -void CWidgetUiWindowManager::DeactivateMiniViewL( const TUid& aUid ) +TBool CWidgetUiWindowManager::DeactivateMiniViewL( const TUid& aUid ) { CWidgetUiWindow* wdgt_window = GetWindow(aUid); if(!wdgt_window) - return ; + return EFalse; wdgt_window->SetWindowStateMiniViewL( EMiniViewEnabled ); - SuspendWidget( aUid ); // TODO also other states are possible when we should react? // Removing . Miniview, shall remove full view as well. For blanket permissions // will be revoked for miniview - iClientSession.SetBlanketPermissionL( aUid, EFalse ); + iClientSession.SetBlanketPermissionL( aUid, EBlanketUnknown ); iClientSession.SetMiniViewL( aUid, EFalse ); - CloseWindow( wdgt_window ); + return CloseWindow( wdgt_window ); } // ----------------------------------------------------------------------------- @@ -271,17 +265,7 @@ HideWindow( iActiveFsWindow ); //This is done to prevent offscreen bit map overlap //when widget selected from FSW - wdgt_window->Engine()->MakeVisible( EFalse ); - - if ( !iClientSession.IsBlanketPermGranted ( aUid) ) - { - AllowPlatformAccessL(aUid); - } - else - { - wdgt_window->SetBlanketPromptDisplayed(ETrue); - ResumeWidgetL(aUid); - } + wdgt_window->Engine()->MakeVisible( EFalse ); } res = ETrue; @@ -300,6 +284,8 @@ const TUid& aUid, TUint32 aOperation ) { + TBool exit( EFalse ); + TBool needToNotify (ETrue) ; switch ( aOperation ) { case LaunchFullscreen: @@ -310,11 +296,12 @@ break; case Deactivate: { - DeactivateMiniViewL( aUid ); + exit = DeactivateMiniViewL( aUid ); } break; case WidgetResume: { + needToNotify = GetWindow(aUid) ? ETrue: EFalse; ResumeWidgetL( aUid ); } break; @@ -324,20 +311,75 @@ } break; case WidgetSelect: - { + { // If we don't have window we know that WidgetUI has died // We must enable miniview state - if( !GetWindow( aUid )) - { - OpenOrCreateWindowL( aUid, LaunchMiniview ); + if( !GetWindow(aUid)) + { + needToNotify = EFalse; + CanWindowBeCreated( aUid, aOperation ); + break; } //WidgetLauncher modified to bring app to foreground - OpenOrCreateWindowL( aUid, LaunchFullscreen ); + GetWindow( aUid)->IncrementClickCount(); + OpenOrCreateWindowL( aUid, LaunchFullscreen ); + } + break; + case WidgetOnline: + { + iNetworkMode = EOnlineMode; + GetWindow( aUid )->DetermineNetworkState(); + } + break; + case WidgetOffline: + { + iNetworkMode = EOfflineMode; + // if no full view widgets open, then close the network connection + if ( ( !FullViewWidgetsOpen() ) && ( iConnection->Connected() ) ) + { + CWidgetUiWindow* wdgt_window( GetWindow( aUid ) ); + wdgt_window->Engine()->HandleCommandL( + (TInt)TBrCtlDefs::ECommandIdBase + + (TInt)TBrCtlDefs::ECommandDisconnect ); + iConnection->StopConnectionL(); + } + GetWindow( aUid )->DetermineNetworkState(); } break; + case WidgetRestart: + { + OpenOrCreateWindowL( aUid, LaunchMiniview ); + ResumeWidgetL( aUid ); + } + break; + } + if(needToNotify) + // Widget is up and running, notify that next one can be launched + NotifyCommandHandled(); + + if( exit ) + { + iAppUi.Exit(); } } - + +// ------------------------------------------------------------------------ +// CWidgetUiWindowManager::CanWindowBeCreated() +// Check for availaibilty for window creation +// +// ------------------------------------------------------------------------ +// +void CWidgetUiWindowManager::CanWindowBeCreated(const TUid& aUid, TUint32 aOperation) + { + CRequestRAM* requestRam = CRequestRAM::StartLD(this, aUid, aOperation); + } + +// ------------------------------------------------------------------------ +// CWidgetUiWindowManager::OpenOrCreateWindowL() +// Open or create widget window +// +// ------------------------------------------------------------------------ +// void CWidgetUiWindowManager::OpenOrCreateWindowL( const TUid& aUid, TUint32 aOperation ) @@ -436,11 +478,13 @@ { iActiveFsWindow = wdgt_window; iActiveFsWindow->SetWindowStateFullView(ETrue); - iActiveFsWindow->SetCurrentWindow( ETrue ); + if ( iActiveFsWindow->Engine()->Rect() != View()->ClientRect()) { iActiveFsWindow->Engine()->SetRect( View()->ClientRect() ); } + iActiveFsWindow->SetCurrentWindow( ETrue ); + iActiveFsWindow->Engine()->SetFocus(ETrue); //iActiveFsWindow->Engine()->MakeVisible( ETrue ); } @@ -449,25 +493,6 @@ } // ============================================================================= -// CWidgetUiWindowManager::AllowPlatformAccessL() -// Prompt for network access allow -// -// ============================================================================= -// -void CWidgetUiWindowManager::AllowPlatformAccessL( const TUid& aUid ) - { - CWidgetUiWindow* wdgt_window( GetWindow( aUid ) ); - if( !wdgt_window) - return ; - - HBufC* confirmationText = StringLoader::LoadLC(R_WIDGETUI_PLEASE_WORK); - TInt softKey = R_AVKON_SOFTKEYS_OK_CANCEL; - CGlobalQueryHandlerAO* tmp = NULL; - TRAP_IGNORE( tmp = CGlobalQueryHandlerAO::StartLD( *this, *wdgt_window , confirmationText->Des(), softKey ) ); - CleanupStack::PopAndDestroy(confirmationText); - } - -// ============================================================================= // CWidgetUiWindowManager::GetWindow() // return the window of a widget with a particular url // @@ -511,12 +536,12 @@ // // ============================================================================= // -void CWidgetUiWindowManager::CloseWindow( CWidgetUiWindow* aWidgetWindow ) +TBool CWidgetUiWindowManager::CloseWindow( CWidgetUiWindow* aWidgetWindow ) { TBool lastOne( iWindowList.Count() == 1 ); - - RemoveFromWindowList( aWidgetWindow ); + TBool ret( EFalse ); + ret = RemoveFromWindowList( aWidgetWindow ); if ( !lastOne ) { @@ -532,15 +557,16 @@ CWidgetUiWindow* window( iWindowList[i] ); if ( window->WidgetMiniViewState() == EPublishStart ) { - TRAP_IGNORE (window->WidgetExtension()->HandleCommandL( - (TInt)TBrCtlDefs::ECommandAppForeground + - (TInt)TBrCtlDefs::ECommandIdBase)); + TRAP_IGNORE (window->WidgetExtension()->HandleCommandL( + (TInt)TBrCtlDefs::ECommandAppForeground + + (TInt)TBrCtlDefs::ECommandIdBase)); break; } } } + return ret; } // ============================================================================= @@ -549,12 +575,12 @@ // // ============================================================================= // -void CWidgetUiWindowManager::RemoveFromWindowList( CWidgetUiWindow* aWidgetWindow ) +TBool CWidgetUiWindowManager::RemoveFromWindowList( CWidgetUiWindow* aWidgetWindow ) { __ASSERT_DEBUG( aWidgetWindow, User::Invariant() ); if ( iDialogsProvider->IsDialogLaunched() ) { - return; + return EFalse; } if ( iClientSession.IsWidgetInFullView ( aWidgetWindow->Uid())) @@ -574,6 +600,9 @@ iWindowList.Remove( iWindowList.Find( aWidgetWindow ) ); TBool lastOne( iWindowList.Count() == 0 ); + TRAP_IGNORE( aWidgetWindow->Engine()->HandleCommandL( + (TInt)TBrCtlDefs::ECommandIdBase + + (TInt)TBrCtlDefs::ECommandCancelFetch ) ); if ( lastOne ) { TRAP_IGNORE( aWidgetWindow->Engine()->HandleCommandL( @@ -581,75 +610,58 @@ (TInt)TBrCtlDefs::ECommandDisconnect ) ); delete aWidgetWindow; - iAppUi.Exit(); + return ETrue; } else { delete aWidgetWindow; } + return EFalse; } // ============================================================================= -// CWidgetUiWindowManager::CloseWindow() -// close window of widget with a particular Uid -// -// ============================================================================= -// -void CWidgetUiWindowManager::CloseWindow( const TUid& aUid ) - { - CWidgetUiWindow* widgetWindow = GetWindow( aUid ); - CloseWindow( widgetWindow ); - } - -// ============================================================================= -// CWidgetUiWindowManager::CloseAllWindowsExceptCurrent() -// close all window except the current widget +// CWidgetUiWindowManager::CloseWindowWithLeastClick() +// return true for the last widgets to be closed // // ============================================================================= // -void CWidgetUiWindowManager::CloseAllWindowsExceptCurrent() +TBool CWidgetUiWindowManager::CloseWindowWithLeastClick() { - TInt idx(0); - SuspendAllWidget(); - while (iWindowList.Count() > 1) + + TInt temp(iWindowList[0]->GetClickCount()); + TInt err(KErrNone); + CWidgetUiWindow* windowToBeClosed(NULL); + TTime currentTime; + currentTime.HomeTime(); + TTimeIntervalSeconds seconds; + for ( TInt i = 0; i < iWindowList.Count(); i++ ) { - CWidgetUiWindow* window = iWindowList[idx]; - TRAP_IGNORE(iClientSession.SetMiniViewL( window->Uid(), EFalse )); - if(CheckIfWindowNeedsToBeClosed(window)) + CWidgetUiWindow* window = iWindowList[i]; + err = currentTime.SecondsFrom(window->GetTime(),seconds); + if ( window->GetClickCount() <= temp && window != iActiveFsWindow && + (err == KErrOverflow || seconds.Int() > KOOMWidgetCloseTimeOut)) { - RemoveFromWindowList( window ); + temp = window->GetClickCount(); + windowToBeClosed = window; } - else + else if( window == iActiveFsWindow ) { - idx++;// skip ActiveWindow + if ( window->WidgetMiniViewState() == EPublishStart || + window->WidgetMiniViewState() == EPublishSuspend ) + { + // Incase when the widget is active and as in full as well as miniview. + // it will stop publishing + TRAP_IGNORE(window->SetWindowStateMiniViewL( EMiniViewEnabled )); + } } } - } - -// ============================================================================= -// CWidgetUiWindowManager::CheckIfWindowNeedsToBeClosed() -// return true for the widgets that needs to be closed -// -// ============================================================================= -// -TBool CWidgetUiWindowManager::CheckIfWindowNeedsToBeClosed(CWidgetUiWindow* aWindow) const - { - __ASSERT_DEBUG( aWindow, User::Invariant() ); + if ( windowToBeClosed) + { + return RemoveFromWindowList(windowToBeClosed); + } - if( aWindow == iActiveFsWindow ) - { - if ( aWindow->WidgetMiniViewState() == EPublishStart || - aWindow->WidgetMiniViewState() == EPublishSuspend ) - { - // Incase when the widget is active and as in full as well as miniview. - // it will stop publishing - TRAP_IGNORE(aWindow->SetWindowStateMiniViewL( EMiniViewEnabled )); - } - return EFalse; - } - return ETrue; + return EFalse; } - // ============================================================================= // CWidgetUiWindowManager::Exit() // Exit from widget and close widget window @@ -661,33 +673,36 @@ CWidgetUiWindow* window( GetWindow( aUid ) ); if( !window ) return; + + if ( window->WidgetExtension() ) + { + if ( window->WidgetExtension()->HandleCommandL( aCommand ) ) + return; + } + if( ( window->WidgetMiniViewState() == EMiniViewEnabled ) || ( window->WidgetMiniViewState() == EMiniViewNotEnabled ) ) { // The widget is not publishing. - if ( window->WidgetExtension() ) - { - if ( window->WidgetExtension()->HandleCommandL( aCommand ) ) - return; - } - - CloseWindow( window ); - if( window == iActiveFsWindow) - iActiveFsWindow = NULL; + TBool isOkToExit = CloseWindow( window ); + if ( isOkToExit) + iAppUi.Exit(); } else { - ExitPublishingWidget( aUid ); + // Since widget is in miniview we just push the widget app to background and + // set the window status + SendWidgetToBackground( aUid ); } } // ============================================================================= -// CWidgetUiWindowManager::ExitPublishingWidget() -// Exit from widget in full view when it is publishing +// CWidgetUiWindowManager::SendWidgetToBackground() +// Push the widget to background and set the window status // // ============================================================================= // -void CWidgetUiWindowManager::ExitPublishingWidget( const TUid& aUid ) +void CWidgetUiWindowManager::SendWidgetToBackground( const TUid& aUid ) { CWidgetUiWindow* window( GetWindow( aUid ) ); if( !window ) @@ -696,11 +711,13 @@ // make widgets act like separate applications by pushing to background // this way user is sent back to app shell or idle to run another widget iAppUi.SendAppToBackground(); - - if ( iWindowList.Count() == 0 ) + if ( window == iActiveFsWindow ) { - iAppUi.Exit(); //TODO Check if it is required for publishin widget - } + //make the active window NULL and also CurrentWindow as False + iActiveFsWindow->SetIsCurrentWindow(EFalse); + iActiveFsWindow = NULL; + } + window->Engine()->MakeVisible( EFalse ); window->SetWindowStateFullView( EFalse ); // Add registry info @@ -817,18 +834,39 @@ // ----------------------------------------------------------------------------- // CWidgetUiWindowManager::HandleOOMEventL -// called when out of memory message is received by app ui +// called to display notification for out of memory when message is received +// by app ui // // ----------------------------------------------------------------------------- // void CWidgetUiWindowManager::HandleOOMEventL( TBool /*aForeground*/ ) { + if ( iNotifyOOMFlagTimer) + return; + HBufC* message = StringLoader::LoadLC( R_WIDGETUI_OOM_EVENT ); - CAknConfirmationNote* note = new (ELeave) CAknConfirmationNote( ETrue ); - note->ExecuteLD(*message ); + + TInt NoteId (-1); + CAknGlobalNote* dialog = CAknGlobalNote::NewLC(); + NoteId = dialog->ShowNoteL( EAknGlobalInformationNote, *message); + User::After(KOOMNotificationDialogTimeOut); + dialog->CancelNoteL(NoteId); + + CleanupStack::PopAndDestroy(dialog); CleanupStack::PopAndDestroy( message );// message - CloseWindowsAsync( ETrue );// close all widgets + iNotifyOOMFlagTimer = CPeriodic::NewL(CActive::EPriorityLow); + iNotifyOOMFlagTimer->Start(KOOMNotificationDialogIntervalTimeOut,0,TCallBack(&doDestructOOMNotifyTimer,this)); + } + +TInt doDestructOOMNotifyTimer( TAny* ptr ) + { + CWidgetUiWindowManager* temp = static_cast(ptr); + if(temp) + { + temp->DeleteOOMNotifyTimer(); + } + return EFalse; } // ----------------------------------------------------------------------------- @@ -884,16 +922,40 @@ { CWidgetUiWindow* wdgt_window( GetWindow( aUid ) ); + if ( iNetworkMode == EUnknownMode ) + { + TInt HSOnlineMode = GetCenrepHSModeL(); + if (HSOnlineMode) + { + iNetworkMode = EOnlineMode; + } + else + { + iNetworkMode = EOfflineMode; + } + } + // Window can be null if WidgetUI has been killed due to low memory situation //__ASSERT_DEBUG( wdgt_window, User::Invariant() ); - if(!wdgt_window || !wdgt_window->GetBlanketPromptDisplayed()) - return; + if(!wdgt_window) + { + //LAUNCH WIDGET Window + CanWindowBeCreated(aUid,WidgetResume); + return; + } + // reload widget now moved to resume for miniview widgets, to be called + // after determining online/offline mode + if ( !(wdgt_window->IsWidgetLoaded() || wdgt_window->IsWidgetLoadStarted()) ) + { + wdgt_window->ReloadWidget(); + } + if( (wdgt_window ->WidgetMiniViewState() == EMiniViewEnabled) || (wdgt_window->WidgetMiniViewState() == EPublishSuspend) ) { - //HideWindow( iActiveFsWindow ); - //iActiveFsWindow = NULL; + //Widgets on HS cannnot be active + iActiveFsWindow = NULL; // Publish should start only after widget is resumed. wdgt_window->SetWindowStateMiniViewL(EPublishStart); @@ -904,7 +966,8 @@ wdgt_window->WidgetExtension()->HandleCommandL( (TInt)TBrCtlDefs::ECommandAppForeground + (TInt)TBrCtlDefs::ECommandIdBase); -#ifdef BRDO_WRT_HS_FF +#ifdef BRDO_WRT_HS_FF + wdgt_window->Engine()->MakeVisible( EFalse ); wdgt_window->Engine()->SetRect( iCpsPublisher->BitmapSize()); #endif } @@ -939,14 +1002,7 @@ if ( aWindow ) { // Hide the previously active widget. - aWindow->SetCurrentWindow(EFalse); - /* - if( iActiveFsWindow->WidgetMiniViewState() == EPublishSuspend ) - { - iClientSession.SetFullView( aWindow->Uid(), EFalse ); - aWindow->SetWindowStateFullView( EFalse ); - } - */ + aWindow->SetCurrentWindow(EFalse); } } @@ -1034,7 +1090,11 @@ // reset the display orientation when the widget is launched iAppUi.SetDisplayAuto(); - window->ReloadWidget(); + // reload widget only for full view widgets + if ( iClientSession.IsWidgetInFullView(aUid) ) + { + window->ReloadWidget(); + } return window; } @@ -1060,7 +1120,10 @@ void CWidgetUiWindowManager::ShowWindow( CWidgetUiWindow* aWindow ) { if ( !aWindow ) + { + iAppUi.SendAppToBackground(); return; + } if ( aWindow != iActiveFsWindow ) { HideWindow( iActiveFsWindow ); @@ -1070,117 +1133,225 @@ iActiveFsWindow->SetCurrentWindow( ETrue ); iActiveFsWindow->Engine()->MakeVisible( ETrue ); } +// ------------------------------------------------------------------------ +// CWidgetUiWindowManager::DeleteOOMNotifyTimer +// +// ------------------------------------------------------------------------ + +void CWidgetUiWindowManager::DeleteOOMNotifyTimer() + { + iNotifyOOMFlagTimer->Cancel(); + delete iNotifyOOMFlagTimer; + iNotifyOOMFlagTimer = NULL; + } + +void CWidgetUiWindowManager::StartHarvesterNotifyTimer() +{ + if(iNotifyHarvester) + DeleteHarvesterNotifyTimer(); + iNotifyHarvester = CPeriodic::NewL(CActive::EPriorityLow); + iNotifyHarvester->Start(KOOMHarvesterNotificationTimeOut,0,TCallBack(&doNotifyHarvester,this)); +} + +TInt doNotifyHarvester( TAny* ptr ) +{ + NotifyCommandHandled(); + CWidgetUiWindowManager* temp = static_cast(ptr); + if(temp) + temp->DeleteHarvesterNotifyTimer(); + return EFalse; +} + +void CWidgetUiWindowManager::DeleteHarvesterNotifyTimer() +{ + iNotifyHarvester->Cancel(); + delete iNotifyHarvester; + iNotifyHarvester = NULL; +} // ------------------------------------------------------------------------ -// CGlobalQueryHandlerAO::StartLD +// CWidgetUiWindowManager::GetCenrepHSModeL // -// Initialize AO. +// Determine the homescreen network mode (online/offline) from the cenrep // ------------------------------------------------------------------------ -CGlobalQueryHandlerAO* CGlobalQueryHandlerAO::StartLD( - CWidgetUiWindowManager& aManager, - CWidgetUiWindow& aWindow, - const TDesC& aMessage, - TInt aSoftkeys) +TInt CWidgetUiWindowManager::GetCenrepHSModeL() { - CGlobalQueryHandlerAO* self( new( ELeave ) CGlobalQueryHandlerAO( aManager, aWindow, aMessage, aSoftkeys) ); - TRAPD(error, self->ShowGlobalQueryDialogL ( aMessage, aSoftkeys )); - if ( error ) + TInt value( 0 ); + CRepository* rep( NULL ); + TRAPD( cenrepError, rep = CRepository::NewL( TUid::Uid( KCRUidActiveIdleLV ) ) ); + if ( KErrNone == cenrepError ) { - delete self; - User::Leave(error); + (void)rep->Get( KAIWebStatus, value ); } - self->SetActive(); - self->iScheduler.Start(); - return self; + delete rep; + + return value; } // ------------------------------------------------------------------------ -// CGlobalQueryHandlerAO::CGlobalQueryHandlerAO +// CWidgetUiWindowManager::FullViewWidgetsOpen // -// Constructor. +// Checks if any full view widgets are open // ------------------------------------------------------------------------ -CGlobalQueryHandlerAO::CGlobalQueryHandlerAO( - CWidgetUiWindowManager& aManager, - CWidgetUiWindow& aWindow, - const TDesC& aMessage, - TInt aSoftkeys):CActive( EPriorityHigh ), - iWindow ( aWindow ), - iManager(aManager), - iConfirmationText(aMessage.AllocL()) +TBool CWidgetUiWindowManager::FullViewWidgetsOpen() { - CActiveScheduler::Add( this ); + for ( TInt i = 0; i < iWindowList.Count(); ++i ) + { + CWidgetUiWindow* window( iWindowList[i] ); + if ( ( window->WidgetFullViewState() ) && ( !iClientSession.IsWidgetInMiniView( window->Uid() ) ) ) + { + return ETrue; + } + } + + return EFalse; } // ------------------------------------------------------------------------ -// CGlobalQueryHandlerAO::CGlobalQueryHandlerAO +// CWidgetUiWindowManager::NotifyConnecionChange // -// ISet network and platofrom access permission based on user response. +// Notify widgets of a network connection change // ------------------------------------------------------------------------ -void CGlobalQueryHandlerAO::RunL() +void CWidgetUiWindowManager::NotifyConnecionChange( TBool aConn ) { - if (iScheduler.IsStarted()) + iNetworkConnected = aConn; + for ( TInt i = 0; i < iWindowList.Count(); ++i ) { - iScheduler.AsyncStop(); + CWidgetUiWindow* window( iWindowList[i] ); + window->DetermineNetworkState(); } - - RWidgetRegistryClientSession clientSession = iManager.WidgetUIClientSession(); - if (iStatus == EAknSoftkeyOk) - { - clientSession.SetBlanketPermissionL( iWindow.Uid(), ETrue ); - } - else if ( iStatus == EAknSoftkeyCancel) - { - //iWindow.SetNetworkAccessGrant(EDeny); - clientSession.SetBlanketPermissionL( iWindow.Uid(), EFalse ); - //User::Leave( KErrAccessDenied ); - } - iWindow.SetBlanketPromptDisplayed(ETrue); - iManager.ResumeWidgetL(iWindow.Uid()); - delete this; } +#ifdef OOM_WIDGET_CLOSEALL // ------------------------------------------------------------------------ -// CGlobalQueryHandlerAO::DoCancel +// CWidgetUiWindowManager::CloseAllWidgetsUnderOOM // -// Do nothing. +// In case of OOM closes all widgets. // ------------------------------------------------------------------------ -void CGlobalQueryHandlerAO::DoCancel() +TBool CWidgetUiWindowManager::CloseAllWidgetsUnderOOM() { - if ( iGlobalConfirmationQuery ) + TInt temp(0); + TInt err(KErrNone); + CWidgetUiWindow* windowToBeClosed(NULL); + TTime currentTime; + currentTime.HomeTime(); + TTimeIntervalSeconds seconds; + TInt nCountWidgetClosed = 0; + TBool bAllWindowsClosed = ETrue; + + TInt nWidgetsCount = iWindowList.Count(); + for ( TInt i = (nWidgetsCount-1); i >= 0; i-- ) + { + CWidgetUiWindow* window = iWindowList[i]; + err = currentTime.SecondsFrom(iTimeLastWidgetOpen,seconds); + if ( err == KErrOverflow || seconds.Int() > KOOMWidgetCloseTimeOut) + { + windowToBeClosed = window; + if ( windowToBeClosed) + { + RemoveFromWindowList(windowToBeClosed); + nCountWidgetClosed++; + } + } + } + if(nWidgetsCount == nCountWidgetClosed) + { + bAllWindowsClosed = ETrue; + } + else { - iGlobalConfirmationQuery->CancelConfirmationQuery(); + bAllWindowsClosed = EFalse; } - iScheduler.AsyncStop(); + return bAllWindowsClosed; + } + +#endif //OOM_WIDGET_CLOSEALL + +void CWidgetUiWindowManager::SendAppToBackground() + { + iAppUi.SendAppToBackground(); + } + +CRequestRAM::CRequestRAM(CWidgetUiWindowManager* aWidgetUiWindowManager, const TUid& aUid, TUint32 aOperation): + CActive( EPriorityStandard ), + iOperation(aOperation), + iUid(aUid), + iWidgetUiWindowManager(aWidgetUiWindowManager) + { + } + +CRequestRAM* CRequestRAM::StartLD(CWidgetUiWindowManager* aWidgetUiWindowManager, const TUid& aUid, TUint32 aOperation) + { + CRequestRAM* self = new ( ELeave ) CRequestRAM(aWidgetUiWindowManager, aUid, aOperation); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +void CRequestRAM::ConstructL() + { + User::LeaveIfError(iOomSession.Connect()); + CActiveScheduler::Add( this ); +#ifdef FF_OOM_MONITOR2_COMPONENT + iOomSession.RequestOptionalRam(KMemoryToCreateWidgetWindow, KMemoryToCreateWidgetWindow, KUidWidgetOOMPlugin, iStatus); + SetActive(); +#else + TMemoryInfoV1Buf info; + UserHal::MemoryInfo (info); + TInt err = info().iFreeRamInBytes > KMemoryToCreateWidgetWindow ? KErrNone : KErrNoMemory; + SetActive(); + TRequestStatus* status = &iStatus; + User::RequestComplete(status, err); +#endif } -// ------------------------------------------------------------------------ -// CGlobalQueryHandlerAO::~CGlobalQueryHandlerAO -// -// Destructor. -// ------------------------------------------------------------------------ -CGlobalQueryHandlerAO::~CGlobalQueryHandlerAO() +void CRequestRAM::RunL() + { + if(iStatus >= 0) + { + iWidgetUiWindowManager->OpenOrCreateWindowL( iUid, LaunchMiniview ); + iWidgetUiWindowManager->ResumeWidgetL( iUid ); + iWidgetUiWindowManager->GetWindow(iUid)->SetTime(); +#ifdef OOM_WIDGET_CLOSEALL + iWidgetUiWindowManager->SetLastWidgetRestartTime( iWidgetUiWindowManager->GetWindow(iUid)->GetTime()); +#endif //OOM_WIDGET_CLOSEALL + + switch ( iOperation ) + { + case WidgetSelect: + { + iWidgetUiWindowManager->GetWindow(iUid)->IncrementClickCount(); + iWidgetUiWindowManager->OpenOrCreateWindowL( iUid, LaunchFullscreen ); + iWidgetUiWindowManager->GetWindow(iUid)->SetWindowStateMiniViewL(EPublishSuspend); + } + break; + case WidgetResume: + { + + } + break; + } + iWidgetUiWindowManager->StartHarvesterNotifyTimer(); + } + else + { + NotifyCommandHandled(); + iWidgetUiWindowManager->SendAppToBackground(); + iWidgetUiWindowManager->WidgetUIClientSession().SetActive( iUid, EFalse ); + } + delete this; + } + + +CRequestRAM::~CRequestRAM() { Cancel(); - delete iGlobalConfirmationQuery; - delete iConfirmationText; + iOomSession.Close(); } - -// --------------------------------------------------------- -// CGlobalQueryHandlerAO::ShowGlobalQueryDialogL() -// --------------------------------------------------------- -// -void CGlobalQueryHandlerAO::ShowGlobalQueryDialogL(const TDesC& aMessage, TInt aSoftkeys) +void CRequestRAM::DoCancel() { - iGlobalConfirmationQuery = CAknGlobalConfirmationQuery::NewL(); - iGlobalConfirmationQuery->ShowConfirmationQueryL - (iStatus, - aMessage, - aSoftkeys); - } + iOomSession.CancelRequestFreeMemory(); + } // End of file - - - - - diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetapp/src/WidgetUiWindowView.cpp --- a/widgets/widgetapp/src/WidgetUiWindowView.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetapp/src/WidgetUiWindowView.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -44,8 +44,6 @@ #endif // CONSTANTS - const TInt KRightSoftkeyPosition = 2; - const TInt KLeftSoftkeyPosition = 0; // EXTERNAL DATA STRUCTURES @@ -102,7 +100,7 @@ AppUi()->CurrentFixedToolbar()->SetToolbarVisibility(EFalse); } #endif - ShowActivatedObject(EFalse); + UpdateStatusPane(EFalse); // Navipane iNaviCont = (CAknNavigationControlContainer*)StatusPane()->ControlL( @@ -200,18 +198,18 @@ case EAknCmdExit: case EEikCmdExit: // Options->Exit case EAknSoftkeyExit: // Right Softkey (Exit or JS defined) - ShowActivatedObject(EFalse); // deactivates any open edit boxes + UpdateStatusPane(EFalse); // deactivates any open edit boxes iWindowManager.Exit( aCommand, iWindowManager.ActiveWindow()->Uid()); break; case EAknSoftkeyCancel: // cancel must be handled before hiding status pane iContainer->HandleCommandL( (TInt)TBrCtlDefs::ECommandCancel + (TInt)TBrCtlDefs::ECommandIdBase ); - ShowActivatedObject(EFalse); // deactivates any open edit boxes + UpdateStatusPane(EFalse); // deactivates any open edit boxes break; case EAknSoftkeyDone: // accept must be handled before hiding status pane iContainer->HandleCommandL( (TInt)TBrCtlDefs::ECommandAccept + (TInt)TBrCtlDefs::ECommandIdBase ); - ShowActivatedObject(EFalse); // deactivates any open edit boxes + UpdateStatusPane(EFalse); // deactivates any open edit boxes break; case ECmdMsk: if (editing) @@ -252,7 +250,7 @@ TUid /*aCustomMessageId*/, const TDesC8& /*aCustomMessage*/ ) { - StatusPane()->SwitchLayoutL(R_AVKON_STATUS_PANE_LAYOUT_SMALL); + //StatusPane()->SwitchLayoutL(R_AVKON_STATUS_PANE_LAYOUT_SMALL); //Cba()->MakeVisible(EFalse); @@ -289,46 +287,6 @@ } } -// --------------------------------------------------------------------------- -// CWidgetUiContentView::ShowActivatedObject -// Show the StatusPane and Softkeys - needed for text boxes -// Or just Softkeys for flash etc... -// -// --------------------------------------------------------------------------- -// -void CWidgetUiWindowView::ShowActivatedObject(TBool aVisible, TBool aShowStatusPane) - { - if (iActivatedObjectVisible == aVisible) - { - return; - } - iActivatedObjectVisible = aVisible; - iStatusPaneVisible = (aVisible && aShowStatusPane); - - if ( iWindowManager.ActiveWindow() ) - { - // Override Right Softkey with Cancel when editing - if (iActivatedObjectVisible) - { - iCbaVisible = Cba()->IsVisible();// hold state - TRAPD(err,Cba()->AddCommandToStackL(KRightSoftkeyPosition,R_WIDGETUI_WINDOW_VIEW_SOFTKEYS_CANCEL)); - if (err == KErrNone) - { - TRAP(err,Cba()->AddCommandToStackL(KLeftSoftkeyPosition,R_WIDGETUI_WINDOW_VIEW_SOFTKEYS_DONE)); - } - iWindowManager.ActiveWindow()->SetSoftkeysVisible(ETrue); - } - else - { - // remove the cancel softkey and hide softkeys if they were previously hidden - Cba()->RemoveCommandFromStack(KRightSoftkeyPosition,EAknSoftkeyCancel); - Cba()->RemoveCommandFromStack(KLeftSoftkeyPosition,EAknSoftkeyDone); - - iWindowManager.ActiveWindow()->SetSoftkeysVisible(iCbaVisible); - } - } - UpdateStatusPane(); - } // --------------------------------------------------------------------------- // CWidgetUiContentView::UpdateStatusPane @@ -336,8 +294,9 @@ // // --------------------------------------------------------------------------- // -void CWidgetUiWindowView::UpdateStatusPane() +void CWidgetUiWindowView::UpdateStatusPane( TBool aVisible ) { + iStatusPaneVisible = aVisible; #ifdef RD_SCALABLE_UI_V2 // no need for the status pane on touch phones if (PenEnabled()) @@ -443,4 +402,17 @@ iIsOptionsMenuActivated = EFalse; } +// --------------------------------------------------------------------------- +// CWidgetUiWindowView::UpdateToolbar +// --------------------------------------------------------------------------- +// +void CWidgetUiWindowView::UpdateToolbar(TBool aShow) + { +#ifdef RD_SCALABLE_UI_V2 + if(Layout_Meta_Data::IsLandscapeOrientation() && aShow) + AppUi()->CurrentFixedToolbar()->SetToolbarVisibility(ETrue); + else + AppUi()->CurrentFixedToolbar()->SetToolbarVisibility(EFalse); +#endif + } // End of File diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetapp/src/cpspublisher.cpp --- a/widgets/widgetapp/src/cpspublisher.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetapp/src/cpspublisher.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -46,23 +46,31 @@ _LIT8( KItem, "item" ); _LIT8( KAdd, "Add" ); -_LIT(KP,"ai3templatedwidget"); -_LIT(KCT,"wideimage"); +_LIT(KTemplateWidget,"ai3templatedwidget"); _LIT8( KImageKey, "image1"); _LIT8( KMask, "_mask"); -_LIT(KP1,"ai3homescreen"); -_LIT(KCT1,"wideimage"); +_LIT(KHomescreenId,"ai3homescreen"); +_LIT(KTemplateName,"wideimage"); _LIT( KImageContainer, "image_container" ); _LIT8( KWidth, "width"); _LIT8( KHeight, "height"); + +_LIT( KPublisherInfo, "publisher" ); +_LIT( KInfoType, "network" ); +_LIT( KDisConnected, "disconnected"); +_LIT( KConnected, "connected"); +_LIT8( KAPStatus, "apstatus"); + _LIT8( KFilter, "filter" ); _LIT8( KResults, "results"); _LIT8( KOperation, "operation" ); _LIT8( KRequestNotification, "RequestNotification" ); _LIT( KUpdate, "update" ); _LIT8( KChangeInfo, "change_info" ); +_LIT( KWRTPublisher, "wrt_publisher"); + const TInt KSkinGfxInnerRectShrink = 5; static void DoResetAndDestroy( TAny* aPtr ) @@ -171,8 +179,8 @@ { //Create filter criteria for requested entries in form of LIW map: CLiwDefaultMap* filter = CLiwDefaultMap::NewLC(); - filter->InsertL( KPublisherId, TLiwVariant( KP1 )); - filter->InsertL( KContentType, TLiwVariant( KCT1 )); + filter->InsertL( KPublisherId, TLiwVariant( KHomescreenId )); + filter->InsertL( KContentType, TLiwVariant( KTemplateName )); filter->InsertL( KContentId, TLiwVariant( KImageContainer )); return filter; } @@ -212,11 +220,25 @@ TSize CCpsPublisher::BitmapSize() { - return iSize; + if( iSize.iHeight == 0 || iSize.iWidth == 0 ) + { + // TODO: This is a work around to fix the problem in 'Loading Content' feature. + // Miniview does not have size when 'Loading Content' is showing. + return TSize(312, 82 ); + } + else + { + return iSize; + } } -void CCpsPublisher::PublishBitmapL( CFbsBitmap& aBitmap, const TDesC& aBundleName ) +void CCpsPublisher::PublishBitmapL( CFbsBitmap& aBitmap, const TDesC& aBundleId ) { +#ifdef _DEBUG + TSize bitmapSize = aBitmap.SizeInPixels(); + RDebug::Printf("CCpsPublisher::PublishBitmapL bitmap width %d height %d", bitmapSize.iWidth, bitmapSize.iHeight); +#endif + // Load the mask bitmap from skin if( !iMaskBitmap || aBitmap.SizeInPixels() != iMaskBitmap->SizeInPixels()) @@ -234,11 +256,85 @@ { maskHandle = iMaskBitmap->Handle(); } - RDebug::Printf("CCpsPublisher::PublishBitmapL"); - AddImageHandleL( KP() ,KCT(), aBundleName, +#ifdef _DEBUG + RDebug::Printf("CCpsPublisher::PublishBitmapL, bitmap handle 0x%x", handle); +#endif + AddImageHandleL( aBundleId, handle, maskHandle, KImageKey() ); } +void CCpsPublisher::NetworkConnectionCancelledL() + { + CLiwGenericParamList& inparam = iServiceHandler->InParamListL(); + CLiwGenericParamList& outparam = iServiceHandler->OutParamListL(); + + TLiwGenericParam type( KType, TLiwVariant( KCpData )); + type.PushL(); + inparam.AppendL( type ); + + CLiwDefaultMap* cpdatamap = CLiwDefaultMap::NewLC(); + CLiwDefaultMap* datamap = CLiwDefaultMap::NewLC(); + + // Create content map + cpdatamap->InsertL( KPublisherId, TLiwVariant( KHomescreenId )); + cpdatamap->InsertL( KContentType, TLiwVariant( KPublisherInfo )); + cpdatamap->InsertL( KContentId, TLiwVariant( KInfoType )); + // Create the data map + datamap->InsertL( KAPStatus, TLiwVariant( KDisConnected )); + cpdatamap->InsertL( KDataMap, TLiwVariant(datamap) ); + + TLiwGenericParam item( KItem, TLiwVariant( cpdatamap )); + item.PushL(); + + inparam.AppendL( item ); + + iCpsInterface->ExecuteCmdL( KAdd , inparam, outparam); + + CleanupStack::PopAndDestroy( &item ); + CleanupStack::PopAndDestroy( datamap ); + CleanupStack::PopAndDestroy( cpdatamap ); + CleanupStack::PopAndDestroy( &type ); + + outparam.Reset(); + inparam.Reset(); + } + +void CCpsPublisher::NetworkConnectionAllowedL() + { + CLiwGenericParamList& inparam = iServiceHandler->InParamListL(); + CLiwGenericParamList& outparam = iServiceHandler->OutParamListL(); + + TLiwGenericParam type( KType, TLiwVariant( KCpData )); + type.PushL(); + inparam.AppendL( type ); + + CLiwDefaultMap* cpdatamap = CLiwDefaultMap::NewLC(); + CLiwDefaultMap* datamap = CLiwDefaultMap::NewLC(); + + // Create content map + cpdatamap->InsertL( KPublisherId, TLiwVariant( KHomescreenId )); + cpdatamap->InsertL( KContentType, TLiwVariant( KPublisherInfo )); + cpdatamap->InsertL( KContentId, TLiwVariant( KInfoType )); + // Create the data map + datamap->InsertL( KAPStatus, TLiwVariant( KConnected )); + cpdatamap->InsertL( KDataMap, TLiwVariant(datamap) ); + + TLiwGenericParam item( KItem, TLiwVariant( cpdatamap )); + item.PushL(); + + inparam.AppendL( item ); + + iCpsInterface->ExecuteCmdL( KAdd , inparam, outparam); + + CleanupStack::PopAndDestroy( &item ); + CleanupStack::PopAndDestroy( datamap ); + CleanupStack::PopAndDestroy( cpdatamap ); + CleanupStack::PopAndDestroy( &type ); + + outparam.Reset(); + inparam.Reset(); + } + void CCpsPublisher::GetBitmapSizeL() { CLiwDefaultMap *outDataMap = CLiwDefaultMap::NewLC(); @@ -322,10 +418,8 @@ // // --------------------------------------------------------------------------- // -void CCpsPublisher::AddImageHandleL( - const TDesC& aPublisherId, const TDesC& aContentType, - const TDesC& aContentId, const TInt& aHandle, const TInt& aMaskHandle, - const TDesC8& aImageKey ) +void CCpsPublisher::AddImageHandleL( const TDesC& aBundleId, const TInt& aHandle, + const TInt& aMaskHandle, const TDesC8& aImageKey ) { __UHEAP_MARK; CLiwGenericParamList& inparam = iServiceHandler->InParamListL(); @@ -351,9 +445,9 @@ CleanupStack::PopAndDestroy( maskKey ); // Create content data map - cpdatamap->InsertL( KPublisherId, TLiwVariant( aPublisherId )); - cpdatamap->InsertL( KContentType, TLiwVariant( aContentType )); - cpdatamap->InsertL( KContentId, TLiwVariant( aContentId )); + cpdatamap->InsertL( KPublisherId, TLiwVariant( KWRTPublisher )); + cpdatamap->InsertL( KContentType, TLiwVariant( KTemplateWidget )); + cpdatamap->InsertL( KContentId, TLiwVariant( aBundleId )); cpdatamap->InsertL( KDataMap, TLiwVariant(map) ); TLiwGenericParam item( KItem, TLiwVariant( cpdatamap )); diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetinstaller/data/WidgetInstallerUI.rss --- a/widgets/widgetinstaller/data/WidgetInstallerUI.rss Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetinstaller/data/WidgetInstallerUI.rss Thu Aug 27 07:44:59 2009 +0300 @@ -49,3 +49,4 @@ RESOURCE TBUF r_widgetui_uninstall_canceled { buf = qtn_swins_widget_uninst_cancel; } RESOURCE TBUF r_widgetui_install_canceled { buf = qtn_swins_widget_install_cancel; } RESOURCE TBUF r_widgetui_finalize_install { buf = qtn_swins_widget_finalize_install; } +RESOURCE TBUF r_widgetui_uninstall_hs_prompt { buf = qtn_swins_widget_uninstall_hs_prompt; } diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetinstaller/group/WidgetInstallerUI.mmp --- a/widgets/widgetinstaller/group/WidgetInstallerUI.mmp Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetinstaller/group/WidgetInstallerUI.mmp Thu Aug 27 07:44:59 2009 +0300 @@ -59,6 +59,7 @@ // Includes USERINCLUDE ../Inc +USERINCLUDE ../../../Inc MW_LAYER_SYSTEMINCLUDE MW_LAYER_LIBC_SYSTEMINCLUDE @@ -88,5 +89,6 @@ LIBRARY bitgdi.lib LIBRARY WidgetRegistryClient.lib LIBRARY charconv.lib +LIBRARY apparc.lib // End of file diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetinstaller/inc/WidgetUIHandler.h --- a/widgets/widgetinstaller/inc/WidgetUIHandler.h Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetinstaller/inc/WidgetUIHandler.h Thu Aug 27 07:44:59 2009 +0300 @@ -116,8 +116,8 @@ * information about the application to be uninstalled. The user may cancel the * uninstallation at this stage. This dialog must be shown in TrustedUI mode. */ - TBool DisplayUninstallL( const TDesC& aWidgetName ); - + TBool DisplayUninstallL( const TDesC& aWidgetName, TBool aWidgetinHomeScreen ); + /** * Prompt user to select a drive to install the widget * @param aDrive - returns user's drive selection diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetinstaller/inc/WidgetUIOperationsWatcher.h --- a/widgets/widgetinstaller/inc/WidgetUIOperationsWatcher.h Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetinstaller/inc/WidgetUIOperationsWatcher.h Thu Aug 27 07:44:59 2009 +0300 @@ -29,6 +29,7 @@ #include #include #include +#include // RApaLsSession #include "cuicanceltimer.h" #include "WidgetUIHandler.h" #include "IconConverter.h" @@ -253,6 +254,12 @@ */ void RestoreL(); + /** + *In the process of uninstallation if widget is running the widget should be first closed and then uninstalled + *@since 5.0 + */ + void HandleWidgetCommandL( RApaLsSession& aSession,const TDesC& aWidget,const TUid& aUid,TUint32 aOperation ); + private: // Data // A few state variables with the normal case complexity being @@ -299,6 +306,9 @@ CTaskManager* iTaskManager; // TODO: To be investigated //CommonUI::CCUICancelTimer* iCanceller; + + TFileName iWidgetName; // save the widget name during overwrite (only for HS widgets) + TBool iWidgetInHS; // indicates whether the widget was in HS }; } diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetinstaller/loc/WidgetInstallerUI.loc --- a/widgets/widgetinstaller/loc/WidgetInstallerUI.loc Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetinstaller/loc/WidgetInstallerUI.loc Thu Aug 27 07:44:59 2009 +0300 @@ -95,3 +95,9 @@ // l: popup_note_wait_window // r: 3.2 #define qtn_swins_widget_finalize_install "Finalizing installation" + +// d: Text in confirmation query in widget installer. +// d: Asks for the permission from the user to continue uninstallation of the widget in question (=%U). +// l: popup_note_window +// r: 3.2 +#define qtn_swins_widget_uninstall_hs_prompt "Removing %U will clear it from both the system and the homeScreen.Continue?" diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetinstaller/src/WidgetUIConfigHandler.cpp --- a/widgets/widgetinstaller/src/WidgetUIConfigHandler.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetinstaller/src/WidgetUIConfigHandler.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -215,7 +215,7 @@ // iProperties[EPropertyDescriptionNokiaPromptNeeded].id = EBlanketPermGranted; iProperties[EPropertyDescriptionNokiaPromptNeeded].name.Set( KBlanketPermGranted ); - iProperties[EPropertyDescriptionNokiaPromptNeeded].type = EWidgetPropTypeBool; + iProperties[EPropertyDescriptionNokiaPromptNeeded].type = EWidgetPropTypeInt; iProperties[EPropertyDescriptionNokiaPromptNeeded].flags = CONFIG_NOKIA_MAY; } diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetinstaller/src/WidgetUIHandler.cpp --- a/widgets/widgetinstaller/src/WidgetUIHandler.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetinstaller/src/WidgetUIHandler.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -190,7 +190,7 @@ // @since 3.1 // ============================================================================ // -TBool CWidgetUIHandler::DisplayUninstallL( const TDesC& aWidgetName ) +TBool CWidgetUIHandler::DisplayUninstallL( const TDesC& aWidgetName , TBool aWidgetinHomeScreen ) { iShowingDialog = ETrue; @@ -199,7 +199,9 @@ TBool result( EFalse ); - HBufC* prompt = StringLoader::LoadLC( R_WIDGETUI_UNINSTALL_PROMPT, aWidgetName ); + HBufC* prompt = StringLoader::LoadLC( aWidgetinHomeScreen ? R_WIDGETUI_UNINSTALL_HS_PROMPT : + R_WIDGETUI_UNINSTALL_PROMPT , aWidgetName ); + if ( iCommonDialogs->ShowConfirmationQueryL( *prompt, R_AVKON_SOFTKEYS_YES_NO ) ) { result = ETrue; diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetinstaller/src/WidgetUIOperationsWatcher.cpp --- a/widgets/widgetinstaller/src/WidgetUIOperationsWatcher.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetinstaller/src/WidgetUIOperationsWatcher.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -26,9 +26,10 @@ #include #include #include - +#include +#include - +#include #include "WidgetUIOperationsWatcher.h" #include "WidgetUIConfigHandler.h" // info.plist parser #include "WidgetRegistrationManager.h" // interface to "shell" @@ -90,7 +91,8 @@ // CWidgetUIOperationsWatcher::CWidgetUIOperationsWatcher() : CActive( CActive::EPriorityStandard ), - iPropertyValues( EWidgetPropertyIdCount ) + iPropertyValues( EWidgetPropertyIdCount ), + iWidgetInHS( EFalse ) { CActiveScheduler::Add( this ); } @@ -437,11 +439,22 @@ *(iPropertyValues[EUid]) = iRegistry.GetWidgetUidL( *(iPropertyValues[EBundleIdentifier])); found = ETrue; - if ( iRegistry.IsWidgetRunning( - TUid::Uid( *(iPropertyValues[EUid]) )) ) + TUid aUid = TUid::Uid( *(iPropertyValues[EUid]) ); + iWidgetInHS = iRegistry.IsWidgetInMiniView( aUid ); + if ( iRegistry.IsWidgetRunning( aUid ) ) { - iUIHandler->CloseProgressDialogL(); - User::Leave( KErrInUse ); + //Runnning widget should be first closed + RApaLsSession apaLsSession; + apaLsSession.Connect(); + TApaAppInfo info; + + User::LeaveIfError( apaLsSession.GetAppInfo( info, aUid ) ); + iWidgetName = info.iFullName; + HBufC *widgetName = iWidgetName.AllocLC(); + HandleWidgetCommandL(apaLsSession, *widgetName, aUid, Deactivate); + + CleanupStack::PopAndDestroy( widgetName ); + apaLsSession.Close(); } // get original install dir from registry in case user // decides to "overrite" to another memory location @@ -729,7 +742,6 @@ { TUid uid = TUid::Uid( *(iPropertyValues[EUid]) ); iRegistry.DeRegisterWidgetL( uid ); - iAppManager->DeregisterWidgetL( uid ); } // TODO if registration steps fail does it leave inconsistent state??? @@ -746,6 +758,19 @@ { // delete backup (void)iFileMgr->RmDir( iBackupDir ); + + // if widget was in home screen, add it back to home screen + if ( iWidgetInHS ) + { + RApaLsSession apaLsSession; + apaLsSession.Connect(); + + HBufC* widgetName = iWidgetName.AllocLC(); + HandleWidgetCommandL(apaLsSession, *widgetName, TUid::Uid( *(iPropertyValues[EUid]) ), WidgetRestart); + CleanupStack::PopAndDestroy( widgetName ); + + apaLsSession.Close(); + } } iUIHandler->CloseFinalizeDialogL(); @@ -908,15 +933,7 @@ // save client status to use in finish uninstall iRequestStatus = &aRequestStatus; - - // TODO currently don't uninstall if running but in future should - // stop widget and then uninstall - if ( iRegistry.IsWidgetRunning( aUid ) ) - { - FinishUninstallL( KErrInUse ); - return; - } - + TBuf bundleName; iRegistry.GetWidgetBundleName( aUid, bundleName ); @@ -925,10 +942,26 @@ FinishUninstallL( KErrCorrupt ); return; } - + + TBool widgetinHomeScreen(EFalse); + widgetinHomeScreen = iRegistry.IsWidgetInMiniView( aUid ); // prompt user to uninstall - if( iUIHandler->DisplayUninstallL( bundleName ) ) + if( iUIHandler->DisplayUninstallL( bundleName,widgetinHomeScreen ) ) { + if(iRegistry.IsWidgetRunning( aUid )) + //Runnning widget should be first closed + { + RApaLsSession apaLsSession; + apaLsSession.Connect(); + TApaAppInfo info; + + User::LeaveIfError( apaLsSession.GetAppInfo( info, aUid ) ); + HBufC* widgetName = info.iFullName.AllocLC(); + HandleWidgetCommandL(apaLsSession,*widgetName,aUid,Deactivate); + + CleanupStack::PopAndDestroy( widgetName ); + apaLsSession.Close(); + } iUIHandler->DisplayUninstallInProgressL(); TBuf widgetPath; iRegistry.GetWidgetPath( aUid, widgetPath ); @@ -1262,4 +1295,45 @@ CleanupStack::Pop(task); } + +// ============================================================================ +// +// CWidgetUIOperationsWatcher::HandleWidgetCommandL +// +// ============================================================================ +void CWidgetUIOperationsWatcher::HandleWidgetCommandL( RApaLsSession& aSession,const TDesC& aWidget,const TUid& aUid,TUint32 aOperation ) + { + const TInt size( 2* aWidget.Length() + 3*sizeof( TUint32 ) ); + + // Message format is + CApaCommandLine* cmd( CApaCommandLine::NewLC() ); + HBufC8* opaque( HBufC8::NewLC( size ) ); + + RDesWriteStream stream; + TPtr8 des( opaque->Des() ); + + stream.Open( des ); + CleanupClosePushL( stream ); + + // Generate the command. + stream.WriteUint32L( aUid.iUid ); + stream.WriteUint32L( aWidget.Length() ); + stream.WriteL( reinterpret_cast< const TUint8* >( aWidget.Ptr() ), + aWidget.Size() ); + + stream.WriteInt32L( aOperation ); + + CleanupStack::PopAndDestroy( &stream ); + + // Generate command. + cmd->SetCommandL( EApaCommandBackgroundAndWithoutViews ); + cmd->SetOpaqueDataL( *opaque ); + + CleanupStack::PopAndDestroy( opaque ); + + cmd->SetExecutableNameL( KLauncherApp ); + + User::LeaveIfError( aSession.StartApp( *cmd ) ); + CleanupStack::PopAndDestroy( cmd ); + } // End of File diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetlauncher/group/WidgetLauncher.mmp --- a/widgets/widgetlauncher/group/WidgetLauncher.mmp Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetlauncher/group/WidgetLauncher.mmp Thu Aug 27 07:44:59 2009 +0300 @@ -26,7 +26,7 @@ uid 0 0x10282821 //SwEvent needed for TApaTask -CAPABILITY SwEvent +CAPABILITY SwEvent WriteDeviceData VENDORID VID_DEFAULT MW_LAYER_SYSTEMINCLUDE @@ -43,3 +43,4 @@ library apparc.lib library apgrfx.lib library ws32.lib +library oommonitor.lib diff -r 10e98eab6f85 -r a359256acfc6 widgets/widgetlauncher/src/WidgetLauncher.cpp --- a/widgets/widgetlauncher/src/WidgetLauncher.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/widgets/widgetlauncher/src/WidgetLauncher.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -29,8 +29,15 @@ #include #include #include +#include +#include +#include +#include "Browser_platform_variant.hrh" // CONSTANTS +#define KUidWidgetOOMPlugin 0x10282855 +const TInt KMemoryToLaunchWidgetUi = 17*1024*1024; + // LOCAL FUNCTION DEFINITIONS // RDesWriteStream @@ -54,6 +61,13 @@ static void LaunchWidgetL( const TUid& aUid, TUint32 aOperation ); /** +* In case the widget cannot be launched because of OOM +* Notify harvester and Clear event Queue +* @return void +*/ +static void NotifyCommandAndCleanUp(); + +/** * Launch new widget. * * Launch new widget. @@ -147,9 +161,11 @@ TUid widgetAppUid( TUid::Uid( KWidgetAppUid ) ); RWsSession wsSession; + ROomMonitorSession monitorSession; TApaTaskList taskList( wsSession ); HBufC8* message( HBufC8::NewLC( KWidgetUiMaxMessageLength ) ); TPtr8 des( message->Des() ); + TInt err(KErrNone); RDesWriteStream stream( des ); CleanupClosePushL( stream ); @@ -163,6 +179,7 @@ // Create Window server session User::LeaveIfError( wsSession.Connect() ); + User::LeaveIfError( monitorSession.Connect() ); CleanupClosePushL( wsSession ); // Get the task list @@ -185,14 +202,50 @@ // TODO CONST if ( aOperation == LaunchFullscreen || aOperation == LaunchMiniview || - aOperation == WidgetSelect ) //WidgetUI has died -> re-launch + aOperation == WidgetSelect || + aOperation == WidgetResume || + aOperation == WidgetRestart ) //WidgetUI has died -> re-launch { - LaunchWidgetUIL( widgetAppUid, *message, aOperation ); + TInt bytesAvailaible(0); + if (aOperation != WidgetSelect && aOperation != LaunchFullscreen ) + { +#ifdef FF_OOM_MONITOR2_COMPONENT + err = monitorSession.RequestOptionalRam(KMemoryToLaunchWidgetUi, KMemoryToLaunchWidgetUi,KUidWidgetOOMPlugin, bytesAvailaible); +#else + TMemoryInfoV1Buf info; + UserHal::MemoryInfo(info); + err = info().iFreeRamInBytes > KMemoryToLaunchWidgetUi + KRAMGOODTHRESHOLD ? KErrNone : KErrNoMemory; +#endif + if( err == KErrNone) + { + LaunchWidgetUIL( widgetAppUid, *message, aOperation ); + } + } + else + { + //The modification is related to the manual starting of WRT widgets from HS. After noticing an issue when + //the user taps manually a WRT widget from the HS. + //If RAM is not available with RequestOptionalRam() API, the manual tapping does nothing + //and that is incorrect behaviour. Therefore if widgetSelect -event is sent to the launcher we are using RequestFreeMemory() instead of using RequestOptionalRam() API. + //This means that we apply mandatory RAM allocation when a widget is started manually from HS in order to make sure that RAM is released properly + err = monitorSession.RequestFreeMemory( KMemoryToLaunchWidgetUi ); + if( err == KErrNone) + { + LaunchWidgetUIL( widgetAppUid, *message, aOperation ); + } + } + if(err != KErrNone) + NotifyCommandAndCleanUp(); } + else + { + NotifyCommandAndCleanUp(); + } + } CleanupStack::PopAndDestroy( 2, message ); - + monitorSession.Close(); __UHEAP_MARKEND; } @@ -225,7 +278,7 @@ line->SetExecutableNameL( info.iFullName ); // TODO make const definitions. - if ( aOperation == 1 ) + if ( aOperation == 1 || aOperation == 3 ) { line->SetCommandL( EApaCommandBackground ); } @@ -235,6 +288,14 @@ CleanupStack::PopAndDestroy( 3, line ); } +void NotifyCommandAndCleanUp() + { + const TUid KMyPropertyCat = { 0x10282E5A }; + enum TMyPropertyKeys { EWidgetUIState = 109 }; + TInt state( 2 ); + RProperty::Set( KMyPropertyCat, EWidgetUIState , state ); + } + /* * E32Main: called by operating system to start the program */