DBus server: add specifiers for progress spinner (MB#2229)

Step information 'waiting' is appended into status for the
progress spinner. The spinner should be disabled unless 'waiting'
is explicitly appended in the status.
'waiting' means the dbus server is blocked and waiting for something,
typically IO events, such as sending data, waiting for response. Once
it is absent from status, the dbus server is done with waiting.

Change corresponding unit tests in the test-dbus.py for statuses
have been changed.
This commit is contained in:
Zhu, Yongsheng 2009-12-07 14:26:01 +08:00
parent 950fa6857e
commit 40db68c937
5 changed files with 62 additions and 5 deletions

View file

@ -182,7 +182,9 @@
<doc:doc><doc:description>Get session status. Individual source statuses are relevant and provided only when status is neither "queuing" nor "idle".</doc:description></doc:doc>
<arg type="s" name="status" direction="out">
<doc:doc><doc:summary>Session status</doc:summary></doc:doc>
<doc:doc><doc:description>Valid values include strings starting with "queueing", "idle" (ready to execute commands), "running", "aborting", "suspending", "done" (a sync was executed, individual source statuses for that sync are available, session is now inactive and cannot execute new commands). The strings may contain additional specifiers separated by a semicolons: "running;processing", "suspending;waiting". There may be several specifiers: "running;waiting;foo"</doc:description></doc:doc>
<doc:doc><doc:description>Valid values include strings starting with "queueing", "idle" (ready to execute commands), "running", "aborting", "suspending", "done" (a sync was executed, individual source statuses for that sync are available, session is now inactive and cannot execute new commands). The strings may contain additional specifiers separated by a semicolons: "running;waiting", "suspending;waiting". There may be several specifiers: "running;waiting;foo".
Specifier "waiting" means that the dbus server is waiting for some external events, typically IO events(like network transports, etc). If "waiting" is absent, then we've done the waiting.
</doc:description></doc:doc>
</arg>
<arg type="u" name="error" direction="out">
<doc:doc><doc:summary>Error code for current or last action (zero for no error).</doc:summary></doc:doc>

View file

@ -591,6 +591,8 @@ protected:
SyncSource &source,
int32_t extra1, int32_t extra2, int32_t extra3);
virtual void reportStepCmd(sysync::uInt16 stepCmd);
/**
* Implement checkForSuspend and checkForAbort.
* They will check whether dbus clients suspend
@ -861,6 +863,9 @@ class Session : public DBusObjectHelper,
/** current sync status */
SyncStatus m_syncStatus;
/** step info: whether engine is waiting for something */
bool m_stepIsWaiting;
/**
* Priority which determines position in queue.
* Lower is more important. PRI_DEFAULT is zero.
@ -1001,6 +1006,13 @@ public:
bool isSuspend() { return m_syncStatus == SYNC_SUSPEND; }
bool isAbort() { return m_syncStatus == SYNC_ABORT; }
/**
* step info for engine: whether the engine is blocked by something
* If yes, 'waiting' will be appended as specifiers in the status string.
* see GetStatus documentation.
*/
void setStepInfo(bool isWaiting);
private:
/** set m_syncFilter and m_sourceFilters to config */
virtual void setFilters(SyncConfig &config);
@ -1399,6 +1411,22 @@ void DBusSync::displaySourceProgress(sysync::TProgressEventEnum type,
m_session.sourceProgress(type, source, extra1, extra2, extra3);
}
void DBusSync::reportStepCmd(sysync::uInt16 stepCmd)
{
switch(stepCmd) {
case sysync::STEPCMD_SENDDATA:
case sysync::STEPCMD_RESENDDATA:
case sysync::STEPCMD_NEEDDATA:
//sending or waiting data
m_session.setStepInfo(true);
break;
default:
// otherwise, processing
m_session.setStepInfo(false);
break;
}
}
bool DBusSync::checkForSuspend()
{
return m_session.isSuspend() || SyncContext::checkForSuspend();
@ -1621,7 +1649,9 @@ void Session::getStatus(std::string &status,
SourceStatuses_t &sources)
{
status = syncStatusToString(m_syncStatus);
// TODO: append ";processing" or ";waiting"
if (m_stepIsWaiting) {
status += ";waiting";
}
error = m_error;
sources = m_sourceStatus;
@ -1700,6 +1730,7 @@ Session::Session(DBusServer &server,
m_tempConfig(false),
m_active(false),
m_syncStatus(SYNC_QUEUEING),
m_stepIsWaiting(false),
m_priority(PRI_DEFAULT),
m_progress(0),
m_progData(m_progress),
@ -1888,6 +1919,15 @@ void Session::setFilters(SyncConfig &config)
}
}
void Session::setStepInfo(bool isWaiting)
{
// if stepInfo doesn't change, then ignore it to avoid duplicate status info
if(m_stepIsWaiting != isWaiting) {
m_stepIsWaiting = isWaiting;
fireStatus(true);
}
}
/************************ ProgressData implementation *****************/
ProgressData::ProgressData(int32_t &progress)
: m_progress(progress),

View file

@ -2200,6 +2200,7 @@ SyncMLStatus SyncContext::doSync()
// and wait for response.
} else {
m_engine.SessionStep(session, stepCmd, &progressInfo);
reportStepCmd(stepCmd);
}
//During suspention we actually insert a STEPCMD_SUSPEND cmd

View file

@ -579,6 +579,15 @@ class SyncContext : public SyncConfig, public ConfigUserInterface {
SyncSource &source,
int32_t extra1, int32_t extra2, int32_t extra3);
/**
* report step command info
*
* Will be called after each step in step loop in SyncContext::doSync().
* This reports step command info.
* @param stepCmd step command enum value
*/
virtual void reportStepCmd(sysync::uInt16 stepCmd) {}
/**
* Called to find out whether user wants to abort sync.
*

View file

@ -1135,8 +1135,13 @@ class TestSessionAPIsReal(unittest.TestCase, DBusUtil):
# no error
self.failUnlessEqual(error, 0)
# keep order: session status must be unchanged or the next status
self.failUnless(statusPairs.has_key(status))
self.failUnless(statusPairs[status] >= statusPairs[lastStatus])
seps = status.split(';')
lastSeps = lastStatus.split(';')
self.failUnless(statusPairs.has_key(seps[0]))
self.failUnless(statusPairs[seps[0]] >= statusPairs[lastSeps[0]])
# check specifiers
if len(seps) > 1:
self.failUnlessEqual(seps[1], "waiting")
for sourcename, value in sources.items():
# no error
self.failUnlessEqual(value[2], 0)
@ -1177,7 +1182,7 @@ class TestSessionAPIsReal(unittest.TestCase, DBusUtil):
self.doSync()
hasSuspendingStatus = False
for item in DBusUtil.events:
if item[0] == "status" and item[1][0] == "suspending":
if item[0] == "status" and "suspending" in item[1][0] :
hasSuspendingStatus = True
break
self.failUnlessEqual(hasSuspendingStatus, True)