void SyncSession::UpdateScheduledSyncActivity() { MojLogInfo(m_log, "updating scheduled sync activity on folder %s", AsJsonString(m_folderId).c_str()); PopClient::AccountPtr account = m_client.GetAccount(); MojObject accountId = account->GetAccountId(); ActivityBuilder ab; if(!account->IsManualSync()) { int interval = account->GetSyncFrequencyMins(); MojLogInfo(m_log, "setting sync interval to %d minutes", interval); m_builderFactory->BuildScheduledSync(ab, interval); MojObject actObj = ab.GetActivityObject();; MojLogInfo(m_log, "Replacing scheduled activity: %s", AsJsonString(actObj).c_str()); m_activities->ReplaceActivity(ab.GetName(), actObj); } else { MojString scheduledActName; m_builderFactory->GetScheduledSyncActivityName(scheduledActName); // Remove activity ActivityPtr activity = m_activities->GetOrCreateActivity(scheduledActName); activity->SetEndAction(Activity::EndAction_Cancel); } }
void ImapSessionCommand::AddActivity(const ActivityPtr& activity) { if(activity.get()) { m_commandActivitySet->AddActivity(activity); // Attempt to adopt immediately (async) to avoid blocking ActivityManager queue activity->Adopt(m_session.GetBusClient()); } }
void SyncSession::UpdateRetryActivity() { MojString retryActName; m_builderFactory->GetFolderRetrySyncActivityName(retryActName, m_folderId); // Cancel retry activity on successful sync ActivityPtr activity = m_activities->GetOrCreateActivity(retryActName); activity->SetEndAction(Activity::EndAction_Cancel); // We want to remove the retry activity last, only after we're sure that the // scheduled sync and watch activities have been created. activity->SetEndOrder(Activity::EndOrder_Last); }
TEST(ActivitySetTest, TestStart) { MockActivityService service; MockBusClient busClient; busClient.AddMockService(service); ActivityPtr activity = Activity::PrepareAdoptedActivity(1); MojRefCountedPtr<ActivitySet> actSet(new ActivitySet(busClient)); actSet->AddActivity(activity); Start(busClient, actSet); ASSERT_TRUE( activity->IsActive() ); }
MockActivitySlots(ActivityPtr activity) : m_expect(false), m_expectError(false), m_expectUpdate(false), m_updateSlot(this, &MockActivitySlots::Update), m_errorSlot(this, &MockActivitySlots::Error) { activity->SetSlots(m_updateSlot, m_errorSlot); }
UpdateAccountCommand::UpdateAccountCommand(ImapClient& client, ActivityPtr activity, bool credentialsChanged) : ImapClientCommand(client), m_activitySet(new ActivitySet(client)), m_credentialsChanged(credentialsChanged), m_getAccountTransportSlot(this, &UpdateAccountCommand::GetAccountTransportResponse), m_updateFolderActivitiesSlot(this, &UpdateAccountCommand::UpdateFolderActivitiesDone), m_endActivitiesSlot(this, &UpdateAccountCommand::ActivitiesEnded), m_notifySmtpSlot(this, &UpdateAccountCommand::NotifySmtpResponse) { // FIXME wait for adoption to complete // EndActivities will wait for us, but it's not as polite if(activity.get() && activity->CanAdopt()) { m_activitySet->AddActivity(activity); activity->Adopt(client); activity->SetEndOrder(Activity::EndOrder_Last); } }
TEST(ActivityTest, TestAdoptFailure) { MockActivityService mockActivityService; MockBusClient serviceClient; MojInt32 activityId = 1; ActivityPtr activity = Activity::PrepareAdoptedActivity(activityId); MojRefCountedPtr<MockActivitySlots> slots(new MockActivitySlots(activity)); activity->Adopt(serviceClient); MockRequestPtr req = serviceClient.GetLastRequest(); // Should handle the error and pass it along to the error slot slots->ExpectError(); MojObject response; req->ReplyNow(response, MojErrInternal); slots->Check(); }
void ActivitySet::AddActivity(const ActivityPtr& activity) { if(activity.get() == NULL) { throw MailException("AddActivity called with null activity", __FILE__, __LINE__); } // Only add if it's not already in the set if(FindActivitySlot(activity.get()) == m_activities.end()) { ActivitySlotPtr activityState(new ActivitySlot(this, activity)); m_activities.push_back(activityState); if(activity->IsStarting()) { m_starting.insert(activity); } else if(activity->IsEnding()) { m_ending.insert(activity); } } }
TEST(ActivityTest, TestActivityManagerOffline) { MockActivityService mockActivityService; MockBusClient serviceClient; mockActivityService.SetOffline(true); MojInt32 activityId = 1; ActivityPtr activity = Activity::PrepareAdoptedActivity(activityId); MojRefCountedPtr<MockActivitySlots> slots(new MockActivitySlots(activity)); activity->Adopt(serviceClient); MockRequestPtr req = serviceClient.GetLastRequest(); // Should handle the error and pass it along to the error slot slots->ExpectError(); mockActivityService.HandleRequest(req); slots->Check(); }
void SyncSession::AttachActivity(ActivityPtr activity) { if (activity.get()) { if (IsActive()) { m_activities->AddActivity(activity); } else if (IsEnding()) { m_queuedActivities->AddActivity(activity); } } }
TEST(ActivityTest, TestAdopt) { MockActivityService mockActivityService; MockBusClient serviceClient; MojInt32 activityId = 1; ActivityPtr activity = Activity::PrepareAdoptedActivity(activityId); ASSERT_TRUE( activity->CanAdopt() ); activity->Adopt(serviceClient); ASSERT_TRUE( !activity->CanAdopt() ); // Check adopt response MockRequestPtr req = serviceClient.GetLastRequest(); CheckRequest(req, "com.palm.activitymanager", "adopt"); ASSERT_EQ( activityId, GetActivityId(req->GetPayload()) ); // Reply to adopt mockActivityService.HandleRequest(req); ASSERT_TRUE( activity->IsActive() ); activity->Complete(serviceClient); }
void ImapSession::CommandComplete(Command* command) { m_commandManager->CommandComplete(command); if(m_reconnectRequested && m_state == State_OkToSync && m_commandManager->GetActiveCommandCount() == 0 && m_commandManager->GetPendingCommandCount() > 0) { // If requested (and no active commands), disconnect from the server after finishing this command MojLogInfo(m_log, "disconnecting and reconnecting to server"); Logout(); } else if(m_state == State_OkToSync && m_commandManager->GetPendingCommandCount() == 0 && m_commandManager->GetActiveCommandCount() == 0) { MojLogInfo(m_log, "no commands active or pending"); // Either disconnect or run IDLE command // TODO also check account settings if(IsValidId(m_folderId) && IsPushEnabled(m_folderId)) { m_shouldPush = CheckNetworkHealthForPush(); } else { m_shouldPush = false; } if(m_shouldPush) { //MojLogInfo(m_log, "running idle command for folderId %s", AsJsonString(m_folderId).c_str()); if(m_account->IsYahoo()) { m_idleCommand.reset(new IdleYahooCommand(*this, m_folderId)); m_idleMode = IdleMode_YahooPush; } else { m_idleCommand.reset(new IdleCommand(*this, m_folderId)); m_idleMode = IdleMode_IDLE; } // Create activity to maintain idle. // If the device is rebooted or IMAP crashes, the callback will restart idle. // The activity will get cancelled if the connection goes into retry mode. if(true) { ImapActivityFactory factory; ActivityBuilder ab; factory.BuildStartIdle(ab, m_client->GetAccountId(), m_folderId); // Create new activity only if one doesn't already exist if(GetActivitySet()->FindActivityByName(ab.GetName()).get() == NULL) { ActivityPtr activity = Activity::PrepareNewActivity(ab, true, true); activity->SetName(ab.GetName()); activity->SetEndAction(Activity::EndAction_Complete); activity->SetEndOrder(Activity::EndOrder_Last); GetActivitySet()->AddActivity(activity); // Start activity right away activity->Create(*m_client); } } m_idleStartTime = 0; SetState(State_PreparingToIdle); m_commandManager->RunCommand(m_idleCommand); } else if(GetNoopIdleTimeout() > 0) { // TODO: this code is currently disabled MojLogInfo(m_log, "running NOOP idle command"); m_idleCommand.reset(new NoopIdleCommand(*this, m_folderId, GetNoopIdleTimeout())); m_idleMode = IdleMode_NOOP; m_idleStartTime = 0; // Reset flag m_recentUserInteraction = false; SetState(State_PreparingToIdle); m_commandManager->RunCommand(m_idleCommand); } else { if(IsPushRequested(m_folderId) && !m_shouldPush) { MojLogInfo(m_log, "setting up scheduled sync instead of push"); // If we can't push, set up a scheduled sync ImapActivityFactory factory; ActivityBuilder ab; factory.BuildScheduledSync(ab, m_client->GetAccountId(), m_folderId, FALLBACK_SYNC_INTERVAL, false); GetActivitySet()->ReplaceActivity(ab.GetName(), ab.GetActivityObject()); } else { MojLogInfo(m_log, "nothing left to do; disconnecting"); } Logout(); } } else if(m_state == State_Disconnecting && m_commandManager->GetActiveCommandCount() == 0) { Disconnected(); } }