javaextensions/wma/mms/pushplugin/src.s60/s60mmsserverconnection.cpp
branchRCL_3
changeset 19 04becd199f91
child 35 85266cc22c7f
child 60 6c158198356e
equal deleted inserted replaced
16:f5050f1da672 19:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 #include "logger.h"
       
    20 #include "pushexception.h"
       
    21 #include "pusherrorcodes.h"
       
    22 #include "s60commonutils.h"
       
    23 #include "connectionlistener.h"
       
    24 #include "s60mmsserverconnection.h"
       
    25 #include "mmsserverconnectionfactory.h"
       
    26 
       
    27 _LIT16(KThreadName, "MmsServerThread");
       
    28 const TInt KAppIdStartIndex = 7 ;
       
    29 
       
    30 using namespace std;
       
    31 using namespace java::util;
       
    32 
       
    33 namespace java
       
    34 {
       
    35 namespace wma
       
    36 {
       
    37 
       
    38 OS_EXPORT S60MmsServerConnection::S60MmsServerConnection(const wstring& aUri,
       
    39         const wstring& aFilter)
       
    40         :CActive(EPriorityStandard), mUri(aUri), mFilter(aFilter),
       
    41         mActiveConnection(false), mIsAppLaunched(false),mListener(0)
       
    42 
       
    43 {
       
    44     JELOG2(EWMA);
       
    45     mAppId = aUri.substr(KAppIdStartIndex); // "mms://:"
       
    46     LOG1(EWMA,EInfo,"created MmsServerConnection on ID %S", mAppId.c_str());
       
    47     mOpenMonitor = java::util::Monitor::createMonitor();
       
    48 }
       
    49 
       
    50 ServerConnection* MmsServerConnection::getServerConnection(const wstring& aUri,
       
    51         const wstring& aFilter)
       
    52 {
       
    53     JELOG2(EWMA);
       
    54     S60MmsServerConnection* mmsConn = new S60MmsServerConnection(aUri,aFilter);
       
    55     return mmsConn;
       
    56 }
       
    57 
       
    58 S60MmsServerConnection::~S60MmsServerConnection()
       
    59 {
       
    60     JELOG2(EWMA);
       
    61     delete mOpenMonitor;
       
    62 }
       
    63 
       
    64 OS_EXPORT void S60MmsServerConnection::setOpen()
       
    65 {
       
    66     JELOG2(EWMA);
       
    67     mIsAppLaunched = true;
       
    68     MmsServerConnectionFactory::getFactory().setPendingMsgFlag(
       
    69         mUri, false);
       
    70 }
       
    71 
       
    72 OS_EXPORT void S60MmsServerConnection::open(ConnectionListener* aListener)
       
    73 {
       
    74     JELOG2(EWMA);
       
    75     mListener = aListener;
       
    76     if (!mIsAppLaunched)
       
    77     {
       
    78         TBuf<50> threadName;
       
    79         threadName.Append(KThreadName);
       
    80         threadName.Append('_');
       
    81         TTime time;
       
    82         time.HomeTime();
       
    83         threadName.AppendNum(time.Int64());
       
    84         mState = EReceivingMessageForNotify;
       
    85         int error = mThread.Create(threadName,
       
    86                                    reinterpret_cast<TThreadFunction>(listenThread),
       
    87                                    KDefaultStackSize, NULL, this);
       
    88         if (error != KErrNone)
       
    89         {
       
    90             ELOG1(EWMA,"S60MmsServerConnection Thread create failed : %d",error);
       
    91             string errTxt("ERROR!!! Open Failed");
       
    92             throw PushException(COMMON_SRV_CONN_PLUGIN_ERROR, errTxt, __FILE__,
       
    93                                 __FUNCTION__, __LINE__);
       
    94         }
       
    95 
       
    96         mThread.Resume();
       
    97         mOpenMonitor->wait();
       
    98         if (mError != KErrNone)
       
    99         {
       
   100             std::string errTxt("ERROR!!! Open Failed");
       
   101             throw PushException(COMMON_SRV_CONN_PLUGIN_ERROR, errTxt, __FILE__,
       
   102                                 __FUNCTION__, __LINE__);
       
   103         }
       
   104         mActiveConnection = true;
       
   105     }
       
   106 }
       
   107 
       
   108 void S60MmsServerConnection::InitializeL()
       
   109 {
       
   110     JELOG2(EWMA);
       
   111     mMmsApplicationAdapter = CMmsApplicationAdapter::NewL();
       
   112     mSession = CMsvSession::OpenSyncL(*this);
       
   113     mApplicationId = S60CommonUtils::wstringToDes(mAppId.c_str());
       
   114     TMsvId folderId;
       
   115     mMmsApplicationAdapter->RegisterL(*mApplicationId, folderId);
       
   116     TMsvId tmsvId = mMmsApplicationAdapter->FolderIdL(*mApplicationId);
       
   117     if (tmsvId != KErrNone)
       
   118     {
       
   119         // get the
       
   120         mClientEntry = mSession->GetEntryL(tmsvId);
       
   121         // Add listener to the created entry for that application Id
       
   122         mClientEntry->AddObserverL(*this);
       
   123     }
       
   124     int error = pthread_mutex_init(&mMutex, 0);
       
   125     if (error == 0)
       
   126     {
       
   127         error = pthread_cond_init(&mCondVar, 0);
       
   128     }
       
   129     if (0 != error)
       
   130     {
       
   131         User::Leave(error);
       
   132     }
       
   133 }
       
   134 
       
   135 int S60MmsServerConnection::listenThread(S60MmsServerConnection* aMmsSrvConn)
       
   136 {
       
   137     JELOG2(EWMA);
       
   138     int error;
       
   139     CTrapCleanup* tc = CTrapCleanup::New();
       
   140     // As there is no possibility of active scheduler being installed to this
       
   141     // thread prior to this , there is no need for any checks.
       
   142     CActiveScheduler* activeScheduler = new CActiveScheduler();
       
   143     CActiveScheduler::Install(activeScheduler);
       
   144     CActiveScheduler::Add(aMmsSrvConn);
       
   145     TRAP(error, aMmsSrvConn->InitializeL());
       
   146     if (error != KErrNone)
       
   147     {
       
   148         ELOG1(EWMA, "error Creating CRetrieveMobilePhoneBroadcastIdList =%d",
       
   149               error);
       
   150         aMmsSrvConn->mError = error;
       
   151         (aMmsSrvConn->mOpenMonitor)->notify();
       
   152         delete activeScheduler;
       
   153         delete tc;
       
   154         (aMmsSrvConn->mThread).Close();
       
   155         return 0;
       
   156     }
       
   157     aMmsSrvConn->iStatus = KRequestPending;
       
   158     aMmsSrvConn->SetActive();
       
   159     (aMmsSrvConn->mOpenMonitor)->notify();
       
   160     activeScheduler->Start();
       
   161     delete activeScheduler;
       
   162     delete tc;
       
   163     return 0;
       
   164 }
       
   165 
       
   166 void S60MmsServerConnection::HandleSessionEventL(TMsvSessionEvent,
       
   167         TAny*, TAny*, TAny*)
       
   168 {
       
   169 
       
   170 }
       
   171 
       
   172 void S60MmsServerConnection::HandleEntryEventL(TMsvEntryEvent aEvent,
       
   173         TAny* aArg1, TAny*, TAny*)
       
   174 {
       
   175     JELOG2(EWMA);
       
   176     if (mIsAppLaunched)
       
   177     {
       
   178         // midlet is already running, Server connection can read the messages
       
   179         return;
       
   180     }
       
   181 
       
   182     switch (aEvent)
       
   183     {
       
   184     case MMsvSessionObserver::EMsvEntriesChanged:
       
   185     case MMsvEntryObserver::EMsvEntryChanged:
       
   186     {
       
   187         CMsvEntrySelection* msvEntrySelection =
       
   188             static_cast<CMsvEntrySelection*>(aArg1);
       
   189         //Process each entry, one at a time.
       
   190         TInt count = msvEntrySelection->Count();
       
   191         CleanupStack::PushL(msvEntrySelection);
       
   192         for (TInt i = 0; i < count; i++)
       
   193         {
       
   194             TMsvId msvId = msvEntrySelection->At(i);
       
   195             CheckForValidMessageAndPushL(msvId);
       
   196 
       
   197         }// end of for loop
       
   198         CleanupStack::Pop(msvEntrySelection); // entries
       
   199     }
       
   200     break;
       
   201     default:
       
   202         //  Nothing to do
       
   203         break;
       
   204     }
       
   205 }
       
   206 //--------------------------------------------------------------------------------------------
       
   207 // CheckForValidMessageAndPush
       
   208 //--------------------------------------------------------------------------------------------
       
   209 void S60MmsServerConnection::CheckForValidMessageAndPushL(TMsvId aMsgId)
       
   210 {
       
   211     JELOG2(EWMA);
       
   212     if (!IsMmsReadyToReadL(aMsgId))
       
   213     {
       
   214 
       
   215         return; // message is not reday
       
   216     }
       
   217 
       
   218     TPtrC appId = mMmsApplicationAdapter->ApplicationIdL(aMsgId);
       
   219     if (mApplicationId->Compare(appId) == 0)
       
   220     {
       
   221         MmsRequestCompleted();
       
   222     }
       
   223 }
       
   224 
       
   225 TBool S60MmsServerConnection::IsMmsReadyToReadL(TMsvId aMsvId)
       
   226 {
       
   227     JELOG2(EWMA);
       
   228     TBool error = EFalse;
       
   229     CMsvEntry* csvEntry = mSession->GetEntryL(aMsvId);
       
   230     TMsvEntry tmsvEntry = csvEntry->Entry();
       
   231 
       
   232     if (tmsvEntry.iMtm != KUidMsgTypeMultimedia)
       
   233     {
       
   234         delete csvEntry;
       
   235         csvEntry = NULL;
       
   236     }
       
   237     // Check if the entry is ready to be read
       
   238     else if (!tmsvEntry.InPreparation())
       
   239     { //Not in preparation
       
   240         error = ETrue;
       
   241         delete csvEntry;
       
   242         csvEntry = NULL;
       
   243     }
       
   244     return error;
       
   245 }
       
   246 
       
   247 void S60MmsServerConnection::DoCancel()
       
   248 {
       
   249     JELOG2(EWMA);
       
   250     // Only cancel the appropriate asynchronous request
       
   251     TRequestStatus *status = &iStatus;
       
   252     mThread.RequestComplete(status, KErrCancel);
       
   253 }
       
   254 
       
   255 OS_EXPORT wstring S60MmsServerConnection::getUri() const
       
   256 {
       
   257     JELOG2(EWMA);
       
   258     return mUri;
       
   259 }
       
   260 
       
   261 OS_EXPORT void S60MmsServerConnection::setFilter(const std::wstring& aFilter)
       
   262 {
       
   263     JELOG2(EWMA);
       
   264     mFilter = aFilter;
       
   265 }
       
   266 
       
   267 OS_EXPORT wstring S60MmsServerConnection::getFilter() const
       
   268 {
       
   269     JELOG2(EWMA);
       
   270     return mFilter;
       
   271 }
       
   272 
       
   273 void S60MmsServerConnection::close()
       
   274 {
       
   275     JELOG2(EWMA);
       
   276     // the close and RunL are synchronized to make it SMP safe.
       
   277     if (mActiveConnection)
       
   278     {
       
   279         pthread_mutex_lock(&mMutex);
       
   280         mActiveConnection = false;
       
   281         mState = ENotifyingClose;
       
   282         MmsRequestCompleted();
       
   283         pthread_cond_wait(&mCondVar, &mMutex);
       
   284         pthread_mutex_unlock(&mMutex);
       
   285         pthread_mutex_destroy(&mMutex);
       
   286         pthread_cond_destroy(&mCondVar);
       
   287     }
       
   288     mIsAppLaunched = false;
       
   289     delete mApplicationId;
       
   290     mApplicationId = 0;
       
   291 }
       
   292 
       
   293 TInt S60MmsServerConnection::RunError(TInt aError)
       
   294 {
       
   295     JELOG2(EWMA);
       
   296     mListener->error(mUri, aError, "Error Receiving MultiMedia Message");
       
   297     pthread_cond_signal(&mCondVar);
       
   298     pthread_mutex_unlock(&mMutex);
       
   299     return KErrNone;
       
   300 }
       
   301 
       
   302 void S60MmsServerConnection::RunL()
       
   303 {
       
   304     JELOG2(EWMA);
       
   305     pthread_mutex_lock(&mMutex);
       
   306     switch (mState)
       
   307     {
       
   308     case EReceivingMessageForNotify:
       
   309     case EReceivingMessageForListen:
       
   310     {
       
   311         mState = ENotifyingReadMessageSucceeded;
       
   312         MmsServerConnectionFactory::getFactory().setPendingMsgFlag(
       
   313             mUri, true);
       
   314         mListener->msgArrived();
       
   315         break;
       
   316     }
       
   317     case ENotifyingReadMessageSucceeded:
       
   318     {
       
   319         break;
       
   320     }
       
   321     case ENotifyingClose:
       
   322     {
       
   323         mClientEntry->RemoveObserver(*this);
       
   324         if (mMmsApplicationAdapter)
       
   325         {
       
   326             mMmsApplicationAdapter->UnregisterL(*mApplicationId);
       
   327             delete mMmsApplicationAdapter;
       
   328             mMmsApplicationAdapter = NULL;
       
   329         }
       
   330         if (mClientEntry)
       
   331         {
       
   332             delete mClientEntry;
       
   333             mClientEntry = NULL;
       
   334         }
       
   335         if (mSession)
       
   336         {
       
   337             delete mSession;
       
   338             mSession = NULL;
       
   339         }
       
   340         pthread_cond_signal(&mCondVar);
       
   341         CActiveScheduler::Stop();
       
   342         break;
       
   343     }
       
   344     default:
       
   345     {
       
   346         ELOG(EWMA,"MMS : Not a Valid Case");
       
   347     }
       
   348     }
       
   349     if (mState != ENotifyingClose)
       
   350     {
       
   351         iStatus = KRequestPending;
       
   352         SetActive();
       
   353     }
       
   354     pthread_mutex_unlock(&mMutex);
       
   355 }
       
   356 
       
   357 //-----------------------------------------------------------------------------
       
   358 // MmsRequestCompleted
       
   359 // Start a push midlet register for the mms push
       
   360 //-----------------------------------------------------------------------------
       
   361 void S60MmsServerConnection::MmsRequestCompleted()
       
   362 {
       
   363     if (IsActive())
       
   364     {
       
   365         TRequestStatus *status = &iStatus;
       
   366         mThread.RequestComplete(status, KErrNone);
       
   367     }
       
   368 }
       
   369 
       
   370 }//end of namespace wma
       
   371 }//end of namespace java
       
   372