/*
* Copyright (c) 2007-2010 Sebastian Brannstrom, Lars Persson, EmbedDev AB
*
* 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:
* EmbedDev AB - initial contribution.
*
* Contributors:
*
* Description:
*
*/
#include <commdb.h>
#include "PodcastModel.h"
#include "FeedEngine.h"
#include "SoundEngine.h"
#include "SettingsEngine.h"
#include "ShowEngine.h"
#include "connectionengine.h"
#include <cmdestination.h>
#include <cmmanager.h>
#include <bautils.h>
const TInt KDefaultGranu = 5;
_LIT(KDBFileName, "podcatcher.sqlite");
_LIT(KDBTemplateFileName, "podcatcher.sqlite.template");
EXPORT_C CPodcastModel* CPodcastModel::NewL()
{
CPodcastModel* self = new (ELeave) CPodcastModel;
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
CPodcastModel::~CPodcastModel()
{
delete iFeedEngine;
delete iSoundEngine;
delete iSettingsEngine;
delete iShowEngine;
delete iIapNameArray;
iIapIdArray.Close();
delete iSNAPNameArray;
iSNAPIdArray.Close();
delete iCommDB;
sqlite3_close(iDB);
iFsSession.Close();
iActiveShowList.ResetAndDestroy();
iActiveShowList.Close();
delete iConnectionEngine;
iCmManager.Close();
delete iImageHandler;
}
CPodcastModel::CPodcastModel()
{
}
void CPodcastModel::ConstructL()
{
DP("CPodcastModel::ConstructL BEGIN");
User::LeaveIfError(iFsSession.Connect());
iCommDB = CCommsDatabase::NewL (EDatabaseTypeUnspecified);
//iCommDB ->ShowHiddenRecords(); // magic
iIapNameArray = new (ELeave) CDesCArrayFlat(KDefaultGranu);
iSNAPNameArray = new (ELeave) CDesCArrayFlat(KDefaultGranu);
iCmManager.OpenL();
iImageHandler = CImageHandler::NewL(FsSession());
UpdateIAPListL();
UpdateSNAPListL();
iSettingsEngine = CSettingsEngine::NewL(*this);
iConnectionEngine = CConnectionEngine::NewL(*this);
iFeedEngine = CFeedEngine::NewL(*this);
iShowEngine = CShowEngine::NewL(*this);
iSoundEngine = CSoundEngine::NewL(*this);
DP("CPodcastModel::ConstructL END");
}
EXPORT_C void CPodcastModel::UpdateIAPListL()
{
iIapNameArray->Reset();
iIapIdArray.Reset();
CCommsDbTableView* table = iCommDB->OpenTableLC (TPtrC (IAP));
TInt ret = table->GotoFirstRecord ();
TPodcastIAPItem IAPItem;
TBuf <KCommsDbSvrMaxFieldLength> bufName;
while (ret == KErrNone) // There was a first record
{
table->ReadUintL(TPtrC(COMMDB_ID), IAPItem.iIapId);
table->ReadTextL (TPtrC(COMMDB_NAME), bufName);
table->ReadTextL (TPtrC(IAP_BEARER_TYPE), IAPItem.iBearerType);
table->ReadTextL (TPtrC(IAP_SERVICE_TYPE), IAPItem.iServiceType);
iIapIdArray.Append(IAPItem);
iIapNameArray->AppendL(bufName);
ret = table->GotoNextRecord();
}
CleanupStack::PopAndDestroy(); // Close table
}
EXPORT_C void CPodcastModel::UpdateSNAPListL()
{
DP("CPodcastModel::UpdateSNAPListL BEGIN");
iSNAPNameArray->Reset();
iSNAPIdArray.Reset();
RCmDestination destination;
TPodcastIAPItem IAPItem;
RArray<TUint32> destArray;
CleanupClosePushL(destArray);
iCmManager.AllDestinationsL(destArray);
TInt cnt = destArray.Count();
DP1("destArray.Count==%d", cnt);
for(TInt loop = 0;loop<cnt;loop++)
{
destination = iCmManager.DestinationL (destArray[loop]);
CleanupClosePushL(destination);
if(!destination.IsHidden())
{
IAPItem.iIapId = destArray[loop];
HBufC* name = destination.NameLC();
DP1(" destination.NameLC==%S", name);
iSNAPNameArray->AppendL(*name);
CleanupStack::PopAndDestroy(name);
iSNAPIdArray.Append(IAPItem);
}
CleanupStack::PopAndDestroy();//close destination
}
CleanupStack::PopAndDestroy();// close destArray
DP("CPodcastModel::UpdateSNAPListL END");
}
EXPORT_C CDesCArrayFlat* CPodcastModel::IAPNames()
{
return iIapNameArray;
}
EXPORT_C RArray<TPodcastIAPItem>& CPodcastModel::IAPIds()
{
return iIapIdArray;
}
EXPORT_C CDesCArrayFlat* CPodcastModel::SNAPNames()
{
return iSNAPNameArray;
}
EXPORT_C RArray<TPodcastIAPItem>& CPodcastModel::SNAPIds()
{
return iSNAPIdArray;
}
RFs& CPodcastModel::FsSession()
{
return iFsSession;
}
EXPORT_C void CPodcastModel::SetPlayingPodcast(CShowInfo* aPodcast)
{
iPlayingPodcast = aPodcast;
}
EXPORT_C CShowInfo* CPodcastModel::PlayingPodcast()
{
return iPlayingPodcast;
}
EXPORT_C CFeedEngine& CPodcastModel::FeedEngine()
{
return *iFeedEngine;
}
EXPORT_C CShowEngine& CPodcastModel::ShowEngine()
{
return *iShowEngine;
}
EXPORT_C CSoundEngine& CPodcastModel::SoundEngine()
{
return *iSoundEngine;
}
EXPORT_C CSettingsEngine& CPodcastModel::SettingsEngine()
{
return *iSettingsEngine;
}
EXPORT_C CConnectionEngine& CPodcastModel::ConnectionEngine()
{
return *iConnectionEngine;
}
EXPORT_C void CPodcastModel::PlayPausePodcastL(CShowInfo* aPodcast, TBool aPlayOnInit)
{
// special treatment if this podcast is already active
if (iPlayingPodcast->Uid() == aPodcast->Uid() && SoundEngine().State() > ESoundEngineOpening ) {
if (aPodcast->PlayState() == EPlaying) {
SoundEngine().Pause();
aPodcast->SetPosition(iSoundEngine->Position());
aPodcast->SetPlayState(EPlayed);
aPodcast->SetPlayState(EPlayed);
} else {
iSoundEngine->Play();
}
} else {
// switching file, so save position
iSoundEngine->Pause();
if (iPlayingPodcast != NULL) {
iPlayingPodcast->SetPosition(iSoundEngine->Position());
}
iSoundEngine->Stop(EFalse);
// we play video podcasts through the external player
if(aPodcast != NULL && aPodcast->ShowType() != EVideoPodcast) {
DP1("Starting: %S", &(aPodcast->FileName()));
TRAPD( error, iSoundEngine->OpenFileL(aPodcast->FileName(), aPlayOnInit) );
if (error != KErrNone) {
DP1("Error: %d", error);
} else {
iSoundEngine->SetPosition(aPodcast->Position().Int64() / 1000000);
}
}
iPlayingPodcast = aPodcast;
}
}
EXPORT_C CFeedInfo* CPodcastModel::ActiveFeedInfo()
{
return iActiveFeed;
}
EXPORT_C void CPodcastModel::SetActiveFeedInfo(CFeedInfo* aFeedInfo)
{
iActiveFeed = aFeedInfo;
}
EXPORT_C RShowInfoArray& CPodcastModel::ActiveShowList()
{
return iActiveShowList;
}
void CPodcastModel::SetActiveShowList(RShowInfoArray& aShowArray)
{
iActiveShowList.ResetAndDestroy();
TInt cnt = aShowArray.Count();
for(TInt loop = 0;loop < cnt; loop++)
{
iActiveShowList.Append(aShowArray[loop]);
}
}
sqlite3* CPodcastModel::DB()
{
if (iDB == NULL) {
TFileName dbFileName;
iFsSession.PrivatePath(dbFileName);
dbFileName.Append(KDBFileName);
DP1("DB is at %S", &dbFileName);
if (!BaflUtils::FileExists(iFsSession, dbFileName)) {
TFileName dbTemplate;
iFsSession.PrivatePath(dbTemplate);
dbTemplate.Append(KDBTemplateFileName);
DP1("No DB found, copying template from %S", &dbTemplate);
BaflUtils::CopyFile(iFsSession, dbTemplate,dbFileName);
iIsFirstStartup = ETrue;
}
TBuf8<KMaxFileName> filename8;
filename8.Copy(dbFileName);
int rc = rc = sqlite3_open((const char*) filename8.PtrZ(), &iDB);
if( rc != SQLITE_OK){
DP("Error loading DB");
User::Panic(_L("Podcatcher"), 10);
}
}
return iDB;
}
void CPodcastModel::SetProxyUsageIfNeededL(RHTTPSession& aSession)
{
TBool useProxy = EFalse;
HBufC* serverName = NULL;
TUint32 port = 0;
TRAPD(err,GetProxyInformationForConnectionL(useProxy, serverName, port));
if (err == KErrNone && useProxy)
{
CleanupStack::PushL(serverName);
TBuf8<128> proxyAddr;
proxyAddr.Append(*serverName);
proxyAddr.Append(':');
proxyAddr.AppendNum(port);
RStringF prxAddr = aSession.StringPool().OpenFStringL(proxyAddr);
CleanupClosePushL(prxAddr);
THTTPHdrVal prxUsage(aSession.StringPool().StringF(HTTP::EUseProxy,RHTTPSession::GetTable()));
aSession.ConnectionInfo().SetPropertyL(
aSession.StringPool().StringF(HTTP::EProxyUsage,RHTTPSession::GetTable()),
aSession.StringPool().StringF(HTTP::EUseProxy,RHTTPSession::GetTable()));
aSession.ConnectionInfo().SetPropertyL(aSession.StringPool().StringF(HTTP::EProxyAddress,RHTTPSession::GetTable()), prxAddr);
CleanupStack::PopAndDestroy(&prxAddr);
CleanupStack::PopAndDestroy(serverName);
}
}
void CPodcastModel::GetProxyInformationForConnectionL(TBool& aIsUsed, HBufC*& aProxyServerName, TUint32& aPort)
{
TInt iapId = GetIapId();
CCommsDbTableView* table = iCommDB->OpenViewMatchingUintLC(TPtrC(IAP), TPtrC(COMMDB_ID), iapId);
TUint32 iapService;
HBufC* iapServiceType;
table->ReadUintL(TPtrC(IAP_SERVICE), iapService);
iapServiceType = table->ReadLongTextLC(TPtrC(IAP_SERVICE_TYPE));
CCommsDbTableView* proxyTableView = iCommDB->OpenViewOnProxyRecordLC(iapService, *iapServiceType);
TInt err = proxyTableView->GotoFirstRecord();
if( err != KErrNone)
{
User::Leave(KErrNotFound);
}
proxyTableView->ReadBoolL(TPtrC(PROXY_USE_PROXY_SERVER), aIsUsed);
if(aIsUsed)
{
HBufC* serverName = proxyTableView->ReadLongTextLC(TPtrC(PROXY_SERVER_NAME));
proxyTableView->ReadUintL(TPtrC(PROXY_PORT_NUMBER), aPort);
aProxyServerName = serverName->AllocL();
CleanupStack::PopAndDestroy(serverName);
}
CleanupStack::PopAndDestroy(proxyTableView);
CleanupStack::PopAndDestroy(iapServiceType);
CleanupStack::PopAndDestroy(table);
}
TInt CPodcastModel::GetIapId()
{
_LIT(KSetting, "IAP\\Id");
TUint32 iapId = 0;
iConnectionEngine->Connection().GetIntSetting(KSetting, iapId);
return iapId;
}
EXPORT_C void CPodcastModel::GetAllShowsL()
{
iActiveShowList.ResetAndDestroy();
iShowEngine->GetAllShowsL(iActiveShowList);
}
EXPORT_C void CPodcastModel::GetNewShowsL()
{
iActiveShowList.ResetAndDestroy();
iShowEngine->GetNewShowsL(iActiveShowList);
}
EXPORT_C void CPodcastModel::GetShowsDownloadedL()
{
iActiveShowList.ResetAndDestroy();
iShowEngine->GetShowsDownloadedL(iActiveShowList);
}
EXPORT_C void CPodcastModel::GetShowsDownloadingL()
{
iActiveShowList.ResetAndDestroy();
iShowEngine->GetShowsDownloadingL(iActiveShowList);
}
EXPORT_C void CPodcastModel::GetShowsByFeedL(TUint aFeedUid)
{
iActiveShowList.ResetAndDestroy();
iShowEngine->GetShowsByFeedL(iActiveShowList, aFeedUid);
}
EXPORT_C void CPodcastModel::MarkSelectionPlayedL()
{
for (int i=0;i<iActiveShowList.Count();i++) {
if(iActiveShowList[i]->PlayState() != EPlayed) {
iActiveShowList[i]->SetPlayState(EPlayed);
iShowEngine->UpdateShowL(*iActiveShowList[i]);
}
}
}
TInt CPodcastModel::FindActiveShowByUid(TUint aUid)
{
for (int i=0;i<iActiveShowList.Count();i++) {
if (iActiveShowList[i]->Uid() == aUid) {
return i;
}
}
return KErrNotFound;
}
EXPORT_C TBool CPodcastModel::IsFirstStartup()
{
return iIsFirstStartup;
}
void CPodcastModel::ImageOperationCompleteL(TInt /*aError*/, TUint /*aHandle*/)
{
}
EXPORT_C CImageHandler& CPodcastModel::ImageHandler()
{
return *iImageHandler;
}