void MojoDBProxy::ActivityPurgeComplete(MojServiceMessage *msg, const MojObject& response, MojErr err) { LOG_TRACE("Entering function %s", __FUNCTION__); LOG_DEBUG("Purge of batch of old Activities complete"); /* If there was a transient error, re-call */ if (err != MojErrNone) { if (MojoCall::IsPermanentFailure(msg, response, err)) { LOG_ERROR(MSGID_ACTIVITIES_PURGE_FAILED, 0, "Purge of batch of old Activities failed: %s", MojoObjectJson(response).c_str()); m_call.reset(); } else { LOG_WARNING(MSGID_RETRY_ACTIVITY_PURGE, 0, "Purge of batch of old Activities failed, retrying: %s", MojoObjectJson(response).c_str()); m_call->Call(); } return; } if (!m_oldTokens.empty()) { PreparePurgeCall(); m_call->Call(); } else { LOG_DEBUG("Done purging old Activities"); #ifdef ACTIVITYMANAGER_CALL_CONFIGURATOR PrepareConfiguratorCall(); m_call->Call(); #else m_call.reset(); m_am->Enable(ActivityManager::CONFIGURATION_LOADED); #endif } }
MojoNewWhereMatcher::MatchResult MojoNewWhereMatcher::CheckClause( const MojObject& clause, const MojObject& response, MatchMode mode) const { LOG_AM_TRACE("Entering function %s", __FUNCTION__); if (clause.type() == MojObject::TypeArray) { return CheckClauses(clause, response, mode); } else if (clause.type() != MojObject::TypeObject) { throw std::runtime_error("Clauses must be either an object or array " "of objects"); } LOG_AM_DEBUG("Checking clause '%s' against response '%s' (%s)", MojoObjectJson(clause).c_str(), MojoObjectJson(response).c_str(), (mode == AndMode) ? "and" : "or"); if (clause.contains(_T("and"))) { MojObject andClause; clause.get(_T("and"), andClause); return CheckClause(andClause, response, AndMode); } else if (clause.contains(_T("or"))) { MojObject orClause; clause.get(_T("or"), orClause); return CheckClause(orClause, response, OrMode); } MojObject prop; bool found = clause.get(_T("prop"), prop); if (!found) { throw std::runtime_error("Clauses must contain \"and\", \"or\", " "or a comparison to make"); } MojObject op; found = clause.get(_T("op"), op); if (!found) { throw std::runtime_error("Clauses must specify a comparison operation " "to perform"); } MojObject val; found = clause.get(_T("val"), val); if (!found) { throw std::runtime_error("Clauses must specify a value to compare " "against"); } MatchResult result = CheckProperty(prop, response, op, val, mode); LOG_AM_DEBUG("Where Trigger: Clause %s %s", MojoObjectJson(clause).c_str(), (result == Matched) ? "matched" : "did not match"); return result; }
/* * networkStatusQuery * * { * "extended" : { * ... * "state" : "noservice" | "limited" | "service" * ... * } * } * */ void TelephonyProxy::NetworkStatusUpdate(MojServiceMessage *msg, const MojObject& response, MojErr err) { LOG_TRACE("Entering function %s", __FUNCTION__); LOG_DEBUG("Network status update message: %s", MojoObjectJson(response).c_str()); if (err != MojErrNone) { if (MojoCall::IsPermanentFailure(msg, response, err)) { LOG_WARNING(MSGID_TIL_NWSTATUS_QUERY_ERR,0, "TIL experienced an uncorrectable failure : %s", MojoObjectJson(response).c_str()); m_networkStatusQuery.reset(); } else { LOG_WARNING(MSGID_TIL_NWSTATUS_QUERY_RETRY, 0, "Subscription to TIL failed, retrying - %s", MojoObjectJson(response).c_str() ); m_networkStatusQuery->Call(); } return; } MojObject extended; bool found; found = response.get(_T("extended"), extended); if (!found) { /* Way to have 2 different formats for the same thing! First * response names the property "extended". All subsequent ones * name it "eventNetwork". */ found = response.get(_T("eventNetwork"), extended); } if (found) { MojString status; MojErr err2; err2 = extended.get(_T("state"), status, found); if (err2) { LOG_WARNING(MSGID_TIL_NWSTATE_ERR, 1 , PMLOGKFV("NWSTATE","%d",err2), "Error attempting to retrieve network state"); } else if (found) { if (status == "service") { m_haveTelephonyService = true; } else { m_haveTelephonyService = false; } UpdateTelephonyState(); } else { LOG_WARNING(MSGID_TIL_NO_NWSTATE, 0 , "Network status update message did not include network state: %s", MojoObjectJson(response).c_str()); } } }
bool MojoWhereMatcher::Match(const MojObject& response) { LOG_AM_TRACE("Entering function %s", __FUNCTION__); if (CheckClauses(m_where, response)) { LOG_AM_DEBUG("Where Matcher: Response %s matches", MojoObjectJson(response).c_str()); return true; } else { LOG_AM_DEBUG("Where Matcher: Response %s does not match", MojoObjectJson(response).c_str()); return false; } }
bool MojoWhereMatcher::Match(const MojObject& response) { MojLogTrace(s_log); if (CheckClauses(m_where, response)) { MojLogInfo(s_log, _T("Where Matcher: Response %s matches"), MojoObjectJson(response).c_str()); return true; } else { MojLogInfo(s_log, _T("Where Matcher: Response %s does not match"), MojoObjectJson(response).c_str()); return false; } }
bool MojoKeyMatcher::Match(const MojObject& response) { MojLogTrace(s_log); /* If those were the droids we were looking for, fire! */ if (response.contains(m_key)) { MojLogInfo(s_log, _T("Key Matcher: Key \"%s\" found in response %s"), m_key.data(), MojoObjectJson(response).c_str()); return true; } else { MojLogInfo(s_log, _T("Key Matcher: Key \"%s\" not found in response" "%s"), m_key.data(), MojoObjectJson(response).c_str()); return false; } }
bool MojoKeyMatcher::Match(const MojObject& response) { LOG_AM_TRACE("Entering function %s", __FUNCTION__); /* If those were the droids we were looking for, fire! */ if (response.contains(m_key)) { LOG_AM_DEBUG("Key Matcher: Key \"%s\" found in response %s", m_key.data(), MojoObjectJson(response).c_str()); return true; } else { LOG_AM_DEBUG("Key Matcher: Key \"%s\" not found in response %s", m_key.data(), MojoObjectJson(response).c_str()); return false; } }
bool MojoNewWhereMatcher::Match(const MojObject& response) { MojLogTrace(s_log); MatchResult result = CheckClause(m_where, response, AndMode); if (result == Matched) { MojLogInfo(s_log, _T("Where Matcher: Response %s matches"), MojoObjectJson(response).c_str()); return true; } else { MojLogInfo(s_log, _T("Where Matcher: Response %s does not match"), MojoObjectJson(response).c_str()); return false; } }
MojErr DevelCategoryHandler::Evict(MojServiceMessage *msg, MojObject &payload) { ACTIVITY_SERVICEMETHOD_BEGIN(); LOG_AM_TRACE("Entering function %s", __FUNCTION__); LOG_AM_DEBUG("Evict: %s", MojoObjectJson(payload).c_str()); MojErr err = MojErrNone; bool evictAll = false; payload.get(_T("evictAll"), evictAll); if (evictAll) { LOG_AM_DEBUG("EVICTING ALL ACTIVITIES FROM BACKGROUND QUEUE"); m_am->EvictAllBackgroundActivities(); } else { boost::shared_ptr<Activity> act; err = LookupActivity(msg, payload, act); MojErrCheck(err); LOG_AM_DEBUG(" EVICTING [Activity %llu] FROM BACKGROUND QUEUE",act->GetId()); m_am->EvictBackgroundActivity(act); } err = msg->replySuccess(); MojErrCheck(err); ACTIVITY_SERVICEMETHOD_END(msg); return MojErrNone; }
MojErr DevelCategoryHandler::PriorityControl(MojServiceMessage *msg, MojObject& payload) { ACTIVITY_SERVICEMETHOD_BEGIN(); MojLogTrace(s_log); MojLogInfo(s_log, _T("PriorityControl: %s"), MojoObjectJson(payload).c_str()); MojErr err; bool enabled = false; bool found = payload.get(_T("enabled"), enabled); if (!found) { err = msg->replyError(MojErrInvalidArg, _T("Must specify " "\"enabled\":true or \"enabled\":false")); MojErrCheck(err); return MojErrNone; } if (enabled) { m_resourceManager->Enable(); } else { m_resourceManager->Disable(); } err = msg->replySuccess(); MojErrCheck(err); ACTIVITY_SERVICEMETHOD_END(msg); return MojErrNone; }
void MojoWhereMatcher::ValidateClause(const MojObject& clause) const { MojLogTrace(s_log); MojLogInfo(s_log, _T("Validating where clause \"%s\""), MojoObjectJson(clause).c_str()); if (!clause.contains(_T("prop"))) { throw std::runtime_error("Each where clause must contain a property " "to operate on"); } MojObject prop; clause.get(_T("prop"), prop); ValidateKey(prop); if (!clause.contains(_T("op"))) { throw std::runtime_error("Each where clause must contain a test " "operation to perform"); } MojObject op; clause.get(_T("op"), op); ValidateOp(op); if (!clause.contains(_T("val"))) { throw std::runtime_error("Each where clause must contain a value to " "test against"); } }
void MojoWhereMatcher::ValidateClause(const MojObject& clause) const { LOG_AM_TRACE("Entering function %s", __FUNCTION__); LOG_AM_DEBUG("Validating where clause \"%s\"", MojoObjectJson(clause).c_str()); if (!clause.contains(_T("prop"))) { throw std::runtime_error("Each where clause must contain a property " "to operate on"); } MojObject prop; clause.get(_T("prop"), prop); ValidateKey(prop); if (!clause.contains(_T("op"))) { throw std::runtime_error("Each where clause must contain a test " "operation to perform"); } MojObject op; clause.get(_T("op"), op); ValidateOp(op); if (!clause.contains(_T("val"))) { throw std::runtime_error("Each where clause must contain a value to " "test against"); } }
void PowerdScheduler::HandleSystemTimeResponse(MojServiceMessage *msg, const MojObject& response, MojErr err) { LOG_AM_TRACE("Entering function %s", __FUNCTION__); LOG_AM_DEBUG("System Time response %s", MojoObjectJson(response).c_str()); if (err != MojErrNone) { if (MojoCall::IsPermanentFailure(msg, response, err)) { LOG_AM_WARNING(MSGID_SYS_TIME_RSP_FAIL,0, "System Time subscription experienced an uncorrectable failure: %s", MojoObjectJson(response).c_str()); m_systemTimeCall.reset(); } else { LOG_AM_WARNING(MSGID_GET_SYSTIME_RETRY,0, "System Time subscription failed, retrying: %s", MojoObjectJson(response).c_str()); MonitorSystemTime(); } return; } MojInt64 localOffset; bool found = response.get(_T("offset"), localOffset); if (!found) { LOG_AM_WARNING(MSGID_SYSTIME_NO_OFFSET,0, "System Time message is missing timezone offset"); } else { LOG_AM_DEBUG("System Time timezone offset: %lld", (long long)localOffset); localOffset *= 60; SetLocalOffset((off_t)localOffset); } /* The time changed response can also trip if the actual time(2) has * been updated, which should cause a recalculation also of the * interval schedules (at least if 'skip' is set) */ TimeChanged(); }
void PowerdPowerActivity::PowerUnlockedNotification(MojServiceMessage *msg, const MojObject& response, MojErr err, bool debounce) { LOG_AM_TRACE("Entering function %s", __FUNCTION__); if (err == MojErrNone) { LOG_AM_DEBUG("[Activity %llu] Power lock successfully %s", m_activity.lock()->GetId(), debounce ? "debounced" : "removed"); // reset the call *before* the unlocked notification; if // we end up requeuing the activity due to a transient, we may end // up sending a new call. m_call.reset(); m_currentState = PowerUnlocked; m_activity.lock()->PowerUnlockedNotification(); } else { LOG_AM_WARNING(MSGID_PWRULK_NOTI_ERR,1, PMLOGKFV("Activity","%llu",m_activity.lock()->GetId()), "Attempt to %s power lock failed, retrying. Error: %s", debounce ? "debounce" : "remove", MojoObjectJson(response).c_str()); m_call.reset(); /* Retry. XXX but if error is "Activity doesn't exist", it's done. */ MojErr err2; if (debounce) { err2 = CreateRemotePowerActivity(true); } else { err2 = RemoveRemotePowerActivity(); } if (err2) { LOG_AM_WARNING(MSGID_PWR_UNLOCK_CREATE_ERR,1, PMLOGKFV("Activity","%llu",m_activity.lock()->GetId()), "Failed to issue command to %s power lock", debounce ? "debounce" : "remove"); /* Not much to do at this point, let the Activity move on * so it doesn't hang. */ LOG_AM_WARNING(MSGID_PWR_UNLOCK_FAKE_NOTI,1, PMLOGKFV("Activity","%llu",m_activity.lock()->GetId()), "Faking power unlocked notification in Noti"); m_currentState = PowerUnlocked; m_activity.lock()->PowerUnlockedNotification(); } } }
void PowerdProxy::TriggerBatteryStatusResponse(MojServiceMessage *msg, const MojObject& response, MojErr err) { MojLogTrace(s_log); MojLogInfo(s_log, _T("Attempt to trigger battery status signal generated " "response: %s"), MojoObjectJson(response).c_str()); m_triggerBatteryStatus.reset(); if (err != MojErrNone) { MojLogWarning(s_log, _T("Failed to trigger battery status signal!")); return; } }
void PowerdScheduler::HandleTimeoutClearResponse(MojServiceMessage *msg, const MojObject& response, MojErr err) { LOG_AM_TRACE("Entering function %s", __FUNCTION__); LOG_AM_DEBUG("Timeout Clear response %s", MojoObjectJson(response).c_str()); if (err != MojErrNone) { if (MojoCall::IsPermanentFailure(msg, response, err)) { LOG_AM_WARNING(MSGID_SCH_WAKEUP_CANCEL_ERR ,0, "Failed to cancel scheduled wakeup: %s",MojoObjectJson(response).c_str()); } else { LOG_AM_WARNING(MSGID_SCH_WAKEUP_CANCEL_RETRY,0, "Failed to cancel scheduled wakeup, retrying: %s", MojoObjectJson(response).c_str()); m_call->Call(); return; } } else { LOG_AM_DEBUG("Successfully cancelled scheduled wakeup"); } m_call.reset(); }
void MojoDBProxy::ActivityConfiguratorComplete(MojServiceMessage *msg, const MojObject& response, MojErr err) { LOG_TRACE("Entering function %s", __FUNCTION__); LOG_DEBUG("Load of static Activity configuration complete"); if (err != MojErrNone) { LOG_WARNING(MSGID_ACTIVITY_CONFIG_LOAD_FAIL, 0, "Failed to load static Activity configuration: %s", MojoObjectJson(response).c_str()); } m_call.reset(); m_am->Enable(ActivityManager::CONFIGURATION_LOADED); }
void PowerdProxy::TriggerBatteryStatusResponse(MojServiceMessage *msg, const MojObject& response, MojErr err) { LOG_TRACE("Entering function %s", __FUNCTION__); LOG_DEBUG("Attempt to trigger battery status signal generated response: %s", MojoObjectJson(response).c_str()); m_triggerBatteryStatus.reset(); if (err != MojErrNone) { LOG_WARNING(MSGID_BATTERY_STATUS_ERR,0, "Failed to trigger battery status signal!"); return; } }
MojoNewWhereMatcher::MatchResult MojoNewWhereMatcher::CheckClauses( const MojObject& clauses, const MojObject& response, MatchMode mode) const { LOG_AM_TRACE("Entering function %s", __FUNCTION__); if (clauses.type() == MojObject::TypeObject) { return CheckClause(clauses, response, mode); } else if (clauses.type() != MojObject::TypeArray) { throw std::runtime_error("Multiple clauses must be specified as an " "array of clauses"); } LOG_AM_DEBUG("Checking clauses '%s' against response '%s' (%s)", MojoObjectJson(clauses).c_str(), MojoObjectJson(response).c_str(), (mode == AndMode) ? "and" : "or"); for (MojObject::ConstArrayIterator iter = clauses.arrayBegin(); iter != clauses.arrayEnd(); ++iter) { MatchResult result = CheckClause(*iter, response, mode); if (mode == AndMode) { if (result != Matched) { return NotMatched; } } else { if (result == Matched) { return Matched; } } } if (mode == AndMode) { return Matched; } else { return NotMatched; } }
int ConnectionManagerProxy::GetConfidence(const MojObject& spec) const { MojObject confidenceObj; bool found = spec.get(_T("networkConfidenceLevel"), confidenceObj); if (!found) { LOG_WARNING(MSGID_GET_NW_CONFIDENCE_FAIL, 0, "Failed to retreive network confidence from network description %s", MojoObjectJson(spec).c_str()); } else { return ConfidenceToInt(confidenceObj); } return ConnectionConfidenceUnknown; }
MojErr CallbackCategoryHandler::SchedulerTest(MojServiceMessage *msg, MojObject& payload) { ACTIVITY_SERVICEMETHOD_BEGIN(); MojLogTrace(s_log); MojLogInfo(s_log, _T("Callback: Scheduler Test Start: %s"), MojoObjectJson(payload).c_str()); m_testDriver->Start(payload); MojErr err = msg->replySuccess(); MojErrCheck(err); ACTIVITY_SERVICEMETHOD_END(msg); return MojErrNone; }
MojErr TestCategoryHandler::Leak(MojServiceMessage *msg, MojObject &payload) { ACTIVITY_SERVICEMETHOD_BEGIN(); MojLogTrace(s_log); MojLogInfo(s_log, _T("Leak: %s"), MojoObjectJson(payload).c_str()); MojErr err = MojErrNone; bool freeAll = false; payload.get(_T("freeAll"), freeAll); if (freeAll) { MojLogCritical(s_log, _T("RELEASING REFERENCES TO ALL INTENTIONALLY " "LEAKED ACTIVITIES")); while (!m_leakedActivities.empty()) { boost::shared_ptr<Activity> act = m_leakedActivities.front(); m_leakedActivities.pop_front(); MojLogCritical(s_log, _T("RELEASING REFERENCE TO [Activity %llu]"), act->GetId()); } } else { boost::shared_ptr<Activity> act; err = LookupActivity(msg, payload, act); MojErrCheck(err); MojLogCritical(s_log, _T("INTENTIONALLY LEAKING [Activity %llu]!!"), act->GetId()); m_leakedActivities.push_back(act); } err = msg->replySuccess(); MojErrCheck(err); ACTIVITY_SERVICEMETHOD_END(msg); return MojErrNone; }
MojErr DevelCategoryHandler::SetConcurrency(MojServiceMessage *msg, MojObject &payload) { ACTIVITY_SERVICEMETHOD_BEGIN(); MojLogTrace(s_log); MojLogInfo(s_log, _T("SetConcurrency: %s"), MojoObjectJson(payload).c_str()); bool unlimited = false; payload.get(_T("unlimited"), unlimited); MojUInt32 level; bool found = false; MojErr err = payload.get(_T("level"), level, found); MojErrCheck(err); if (unlimited || found) { m_am->SetBackgroundConcurrencyLevel(unlimited ? ActivityManager::UnlimitedBackgroundConcurrency : (unsigned int)level); err = msg->replySuccess(); MojErrCheck(err); } else { MojLogWarning(s_log, _T("Attempt to set background concurrency did " "not specify \"unlimited\":true or a \"level\"")); err = msg->replyError(MojErrInvalidArg, "Either \"unlimited\":true, " "or \"level\":<number concurrent Activities> must be specified"); MojErrCheck(err); } ACTIVITY_SERVICEMETHOD_END(msg); return MojErrNone; }
MojErr DevelCategoryHandler::Run(MojServiceMessage *msg, MojObject &payload) { ACTIVITY_SERVICEMETHOD_BEGIN(); MojLogTrace(s_log); MojLogInfo(s_log, _T("Run: %s"), MojoObjectJson(payload).c_str()); MojErr err = MojErrNone; bool runAll = false; payload.get(_T("runAll"), runAll); if (runAll) { MojLogCritical(s_log, _T("EVICTING ALL ACTIVITIES FROM BACKGROUND " "QUEUE")); m_am->RunAllReadyActivities(); } else { boost::shared_ptr<Activity> act; err = LookupActivity(msg, payload, act); MojErrCheck(err); MojLogCritical(s_log, _T("EVICTING [Activity %llu] FROM BACKGROUND " "QUEUE"), act->GetId()); m_am->RunReadyBackgroundActivity(act); } err = msg->replySuccess(); MojErrCheck(err); ACTIVITY_SERVICEMETHOD_END(msg); return MojErrNone; }
bool MojoWhereMatcher::CheckClause(const MojObject& clause, const MojObject& response) const { MojLogTrace(s_log); bool result; if (clause.type() != MojObject::TypeObject) { throw std::runtime_error("Clause must be an object with prop, op, " "and val properties"); } bool found; MojObject prop; found = clause.get(_T("prop"), prop); if (!found) { throw std::runtime_error("Property specifier not present in where " "clause"); } /* Value not present causes clause to be skipped. * XXX allow missing behaviour to be specified? */ MojObject propValue; found = GetObjectValue(prop, response, propValue); if (found) { MojObject clauseValue; found = clause.get(_T("val"), clauseValue); if (!found) { throw std::runtime_error("Value to compare against not present in " "where clause"); } found = false; MojString op; MojErr err = clause.get(_T("op"), op, found); if (err) { throw std::runtime_error("Error retrieving operation to use for " "where clause"); } else if (!found) { throw std::runtime_error("operation to use for comparison not " "present in where clause"); } if (op == "<") { result = (propValue < clauseValue); } else if (op == "<=") { result = (propValue <= clauseValue); } else if (op == "=") { result = (propValue == clauseValue); } else if (op == "!=") { result = (propValue != clauseValue); } else if (op == ">=") { result = (propValue >= clauseValue); } else if (op == ">") { result = (propValue > clauseValue); } else { throw std::runtime_error("Unknown comparison operator in where " "clause"); } } else { result = false; } MojLogInfo(s_log, _T("Where Trigger: Clause %s %s"), MojoObjectJson(clause).c_str(), result ? "matched" : "did not match"); return result; }
void MojoDBProxy::ActivityLoadResults(MojServiceMessage *msg, const MojObject& response, MojErr err) { LOG_TRACE("Entering function %s", __FUNCTION__); LOG_DEBUG("Processing Activities loaded from MojoDB"); /* Don't allow the Activity Manager to start up if the MojoDB load * fails ... */ if (err != MojErrNone) { if (MojoCall::IsPermanentFailure(msg, response, err)) { LOG_ERROR(MSGID_LOAD_ACTIVITIES_FROM_DB_FAIL, 0, "Uncorrectable error loading Activities from MojoDB: %s", MojoObjectJson(response).c_str()); #ifdef ACTIVITYMANAGER_REQUIRE_DB m_app->shutdown(); #else m_app->ready(); #endif } else { LOG_WARNING(MSGID_ACTIVITIES_LOAD_ERR, 0, "Error loading Activities from MojoDB, retrying: %s", MojoObjectJson(response).c_str()); m_call->Call(); } return; } /* Clear current call */ m_call.reset(); bool found; MojErr err2; MojObject results; found = response.get(_T("results"), results); if (found) { for (MojObject::ConstArrayIterator iter = results.arrayBegin(); iter != results.arrayEnd(); ++iter) { const MojObject& rep = *iter; MojInt64 activityId; bool found; found = rep.get(_T("activityId"), activityId); if (!found) { LOG_WARNING(MSGID_ACTIVITYID_NOT_FOUND, 0, "activityId not found loading Activities"); continue; } MojString id; MojErr err = rep.get(_T("_id"), id, found); if (err) { LOG_WARNING(MSGID_RETRIEVE_ID_FAIL, 0, "Error retrieving _id from results returned from MojoDB"); continue; } if (!found) { LOG_WARNING(MSGID_ID_NOT_FOUND, 0, "_id not found loading Activities from MojoDB"); continue; } MojInt64 rev; found = rep.get(_T("_rev"), rev); if (!found) { LOG_WARNING(MSGID_REV_NOT_FOUND, 0, "_rev not found loading Activities from MojoDB"); continue; } boost::shared_ptr<MojoDBPersistToken> pt = boost::make_shared<MojoDBPersistToken>(id, rev); boost::shared_ptr<Activity> act; try { act = m_json->CreateActivity(rep, Activity::PrivateBus, true); } catch (const std::exception& except) { LOG_WARNING(MSGID_CREATE_ACTIVITY_EXCEPTION, 1, PMLOGKS("Exception",except.what()), "Activity: %s", MojoObjectJson(rep).c_str()); m_oldTokens.push_back(pt); continue; } catch (...) { LOG_WARNING(MSGID_UNKNOWN_EXCEPTION, 0, "Activity : %s. Unknown exception decoding encoded", MojoObjectJson(rep).c_str()); m_oldTokens.push_back(pt); continue; } act->SetPersistToken(pt); /* Attempt to register this Activity's Id and Name, in order. */ try { m_am->RegisterActivityId(act); } catch (...) { LOG_ERROR(MSGID_ACTIVITY_ID_REG_FAIL, 1, PMLOGKFV("Activity","%llu", act->GetId()), ""); /* Another Activity is already registered. Determine which * is newer, and kill the older one. */ boost::shared_ptr<Activity> old = m_am->GetActivity( act->GetId()); boost::shared_ptr<MojoDBPersistToken> oldPt = boost::dynamic_pointer_cast<MojoDBPersistToken, PersistToken>(old->GetPersistToken()); if (pt->GetRev() > oldPt->GetRev()) { LOG_WARNING(MSGID_ACTIVITY_REPLACED, 4, PMLOGKFV("Activity","%llu",act->GetId()), PMLOGKFV("revision","%llu",(unsigned long long)pt->GetRev()), PMLOGKFV("old_Activity","%llu",old->GetId()), PMLOGKFV("old_revision","%llu",(unsigned long long)oldPt->GetRev()), ""); m_oldTokens.push_back(oldPt); m_am->UnregisterActivityName(old); m_am->ReleaseActivity(old); m_am->RegisterActivityId(act); } else { LOG_WARNING(MSGID_ACTIVITY_NOT_REPLACED, 4, PMLOGKFV("Activity","%llu",act->GetId()), PMLOGKFV("revision","%llu",(unsigned long long)pt->GetRev()), PMLOGKFV("old_Activity","%llu",old->GetId()), PMLOGKFV("old_revision","%llu",(unsigned long long)oldPt->GetRev()), ""); m_oldTokens.push_back(pt); m_am->ReleaseActivity(act); continue; } } try { m_am->RegisterActivityName(act); } catch (...) { LOG_ERROR(MSGID_ACTIVITY_NAME_REG_FAIL, 3, PMLOGKFV("Activity","%llu",act->GetId()), PMLOGKS("Creator_name",act->GetCreator().GetString().c_str()), PMLOGKS("Register_name",act->GetName().c_str()), ""); /* Another Activity is already registered. Determine which * is newer, and kill the older one. */ boost::shared_ptr<Activity> old = m_am->GetActivity( act->GetName(), act->GetCreator()); boost::shared_ptr<MojoDBPersistToken> oldPt = boost::dynamic_pointer_cast<MojoDBPersistToken, PersistToken>(old->GetPersistToken()); if (pt->GetRev() > oldPt->GetRev()) { LOG_WARNING(MSGID_ACTIVITY_REPLACED, 4, PMLOGKFV("Activity","%llu",act->GetId()), PMLOGKFV("revision","%llu",(unsigned long long)pt->GetRev()), PMLOGKFV("old_Activity","%llu",old->GetId()), PMLOGKFV("old_revision","%llu",(unsigned long long)oldPt->GetRev()), ""); m_oldTokens.push_back(oldPt); m_am->UnregisterActivityName(old); m_am->ReleaseActivity(old); m_am->RegisterActivityName(act); } else { LOG_WARNING(MSGID_ACTIVITY_NOT_REPLACED, 4, PMLOGKFV("Activity","%llu",act->GetId()), PMLOGKFV("revision","%llu",(unsigned long long)pt->GetRev()), PMLOGKFV("old_Activity","%llu",old->GetId()), PMLOGKFV("old_revision","%llu",(unsigned long long)oldPt->GetRev()), ""); m_oldTokens.push_back(pt); m_am->ReleaseActivity(act); continue; } } LOG_DEBUG("[Activity %llu] (\"%s\"): _id %s, rev %llu loaded", act->GetId(), act->GetName().c_str(), id.data(), (unsigned long long)rev); /* Request Activity be scheduled. It won't transition to running * until after the MojoDB load finishes (and the Activity Manager * moves to the ready() and start()ed states). */ m_am->StartActivity(act); } } MojString page; err2 = response.get(_T("page"), page, found); if (err2) { LOG_ERROR(MSGID_GET_PAGE_FAIL, 0, "Error getting page parameter in MojoDB query response"); return; } if (found) { LOG_DEBUG("Preparing to request next page (\"%s\") of Activities", page.data()); MojObject query; query.putString(_T("from"), ActivityKind); query.putString(_T("page"), page); MojObject params; params.put(_T("query"), query); m_call = boost::make_shared<MojoWeakPtrCall<MojoDBProxy> >( boost::dynamic_pointer_cast<MojoDBProxy, PersistProxy> (shared_from_this()), &MojoDBProxy::ActivityLoadResults, m_service, "palm://com.palm.db/find", params); m_call->Call(); } else { LOG_DEBUG("All Activities successfully loaded from MojoDB"); if (!m_oldTokens.empty()) { LOG_DEBUG("Beginning purge of old Activities from database"); PreparePurgeCall(); m_call->Call(); } else { #ifdef ACTIVITYMANAGER_CALL_CONFIGURATOR PrepareConfiguratorCall(); m_call->Call(); #else m_call.reset(); m_am->Enable(ActivityManager::CONFIGURATION_LOADED); #endif } m_app->ready(); } }
void PowerdProxy::ChargerStatusSignal(MojServiceMessage *msg, const MojObject& response, MojErr err) { LOG_TRACE("Entering function %s", __FUNCTION__); LOG_DEBUG("Received charger status signal: %s", MojoObjectJson(response).c_str()); if (err != MojErrNone) { m_chargerStatusSubscribed = false; if (MojoCall::IsPermanentFailure(msg, response, err)) { LOG_WARNING(MSGID_CHRGR_STATUS_SIG_FAIL,0, "Subscription to charger status signal experienced an uncorrectable failure: %s", MojoObjectJson(response).c_str()); m_chargerStatus.reset(); } else { LOG_WARNING(MSGID_CHRGR_SIG_ENABLE,0, "Subscription to charger status signal failed, resubscribing: %s", MojoObjectJson(response).c_str()); EnableChargerSignals(); } return; } if (!m_chargerStatusSubscribed) { m_chargerStatusSubscribed = true; TriggerChargerStatus(); } /* Not all responses will contain charger information... for example, * the initial subscription result. */ MojString chargerType; bool found = false; MojErr err2 = response.get(_T("type"), chargerType, found); if (err2) { LOG_ERROR(MSGID_CHRGR_SIG_NO_TYPE, 1,PMLOGKFV("ERROR","%d",err2), "Error retrieving charger type from charger status signal response"); return; } else if (found) { bool connected; found = response.get(_T("connected"), connected); if (!found) { LOG_WARNING(MSGID_CHRGR_NOT_CONNECTED,1,PMLOGKS("TYPE",chargerType.data()), "Charger type found, but not it's connected"); return; } if (chargerType == "usb") { m_usbChargerConnected = connected; } else if (chargerType == "inductive") { m_inductiveChargerConnected = connected; } else { LOG_WARNING(MSGID_CHRGR_TYPE_UNKNOWN, 1, PMLOGKS("TYPE",chargerType.data()), "Unknown charger type"); return; } found = false; MojString name; err2 = response.get(_T("name"), name, found); if (err2) { LOG_ERROR(MSGID_CHRGR_NO_NAME,2, PMLOGKS("TYPE",chargerType.data()), PMLOGKFV("ERR", "%d", err2), "Error retrieving the specific name of charger"); } else if (found) { if (name == "puck") { m_onPuck = connected; } } if (m_onPuck) { if (!m_dockedRequirementCore->IsMet()) { LOG_DEBUG("Device is now docked"); m_dockedRequirementCore->Met(); std::for_each(m_dockedRequirements.begin(), m_dockedRequirements.end(), boost::mem_fn(&Requirement::Met)); } } else { if (m_dockedRequirementCore->IsMet()) { LOG_DEBUG("Device is no longer docked"); m_dockedRequirementCore->Unmet(); std::for_each(m_dockedRequirements.begin(), m_dockedRequirements.end(), boost::mem_fn(&Requirement::Unmet)); } } if (m_inductiveChargerConnected || m_usbChargerConnected) { if (!m_chargingRequirementCore->IsMet()) { LOG_DEBUG("Device is now charging"); m_chargingRequirementCore->Met(); std::for_each(m_chargingRequirements.begin(), m_chargingRequirements.end(), boost::mem_fn(&Requirement::Met)); } } else { if (m_chargingRequirementCore->IsMet()) { LOG_DEBUG("Device is no longer charging"); m_chargingRequirementCore->Unmet(); std::for_each(m_chargingRequirements.begin(), m_chargingRequirements.end(), boost::mem_fn(&Requirement::Unmet)); } } } }
void MojoNewWhereMatcher::ValidateClause(const MojObject& clause) const { LOG_AM_TRACE("Entering function %s", __FUNCTION__); LOG_AM_DEBUG("Validating where clause \"%s\"", MojoObjectJson(clause).c_str()); bool found = false; if (clause.contains(_T("and"))) { found = true; MojObject andClauses; clause.get(_T("and"), andClauses); ValidateClauses(andClauses); } if (clause.contains(_T("or"))) { if (found) { throw std::runtime_error("Only one of \"and\", \"or\", or a valid " "clause including \"prop\", \"op\", and a \"val\"ue to " "compare against must be present in a clause"); } found = true; MojObject orClauses; clause.get(_T("or"), orClauses); ValidateClauses(orClauses); } if (!clause.contains(_T("prop"))) { if (!found) { throw std::runtime_error("Each where clause must contain \"or\", " "\"and\", or a \"prop\"erty to compare against"); } else { return; } } else if (found) { throw std::runtime_error("Only one of \"and\", \"or\", or a valid " "clause including \"prop\", \"op\", and a \"val\"ue to " "compare against must be present in a clause"); } MojObject prop; clause.get(_T("prop"), prop); ValidateKey(prop); if (!clause.contains(_T("val"))) { throw std::runtime_error("Each where clause must contain a value to " "test against"); } MojObject val; clause.get(_T("val"), val); if (!clause.contains(_T("op"))) { throw std::runtime_error("Each where clause must contain a test " "operation to perform"); } MojObject op; clause.get(_T("op"), op); ValidateOp(op, val); }
void PowerdProxy::BatteryStatusSignal(MojServiceMessage *msg, const MojObject& response, MojErr err) { LOG_TRACE("Entering function %s", __FUNCTION__); LOG_DEBUG("Received battery status signal: %s", MojoObjectJson(response).c_str()); if (err != MojErrNone) { m_batteryStatusSubscribed = false; if (MojoCall::IsPermanentFailure(msg, response, err)) { LOG_WARNING(MSGID_BATTERY_STATUS_SIG_FAIL,0, "Subscription to battery status signal experienced an uncorrectable failure: %s", MojoObjectJson(response).c_str()); m_batteryStatus.reset(); } else { LOG_WARNING(MSGID_BATTERY_SIG_ENABLE,0, "Subscription to battery status signal failed, resubscribing: %s", MojoObjectJson(response).c_str()); EnableBatterySignals(); } return; } if (!m_batteryStatusSubscribed) { m_batteryStatusSubscribed = true; TriggerBatteryStatus(); } MojInt64 batteryPercent; bool found = response.get(_T("percent"), batteryPercent); if (found) { MojInt64 oldBatteryPercent = m_batteryPercent; /* Set battery percent first, because as the requirements become met, * Activities may start and events might be generated which include * the state of the associated battery requirement. */ m_batteryPercent = batteryPercent; if (batteryPercent < oldBatteryPercent) { BatteryRequirement::MultiTable::iterator newWatermark = m_batteryRequirements.upper_bound(batteryPercent, BatteryRequirement::KeyComp()); /* Currently met requirements may wish to generate updates. * Some of those requirements are about to be unmet due to * battery drain. Do not generate separate udpates. */ std::for_each(m_batteryRequirements.begin(), newWatermark, boost::mem_fn(&Requirement::Updated)); std::for_each(newWatermark, m_batteryRequirements.upper_bound(oldBatteryPercent, BatteryRequirement::KeyComp()), boost::mem_fn(&Requirement::Unmet)); } else if (batteryPercent > oldBatteryPercent) { BatteryRequirement::MultiTable::iterator oldWatermark = m_batteryRequirements.upper_bound(oldBatteryPercent, BatteryRequirement::KeyComp()); /* Some unmet requirements are about to be met. For the * currently met ones, just generate an update */ std::for_each(m_batteryRequirements.begin(), oldWatermark, boost::mem_fn(&Requirement::Updated)); std::for_each(oldWatermark, m_batteryRequirements.upper_bound(batteryPercent, BatteryRequirement::KeyComp()), boost::mem_fn(&Requirement::Met)); } } }
void PowerdPowerActivity::PowerLockedNotification(MojServiceMessage *msg, const MojObject& response, MojErr err) { LOG_AM_TRACE("Entering function %s", __FUNCTION__); if (err == MojErrNone) { if (m_currentState != PowerLocked) { LOG_AM_DEBUG("[Activity %llu] Power lock successfully created", m_activity.lock()->GetId()); m_currentState = PowerLocked; m_activity.lock()->PowerLockedNotification(); } else { LOG_AM_DEBUG("[Activity %llu] Power lock successfully updated", m_activity.lock()->GetId()); } if (!m_timeout) { m_timeout = boost::make_shared<Timeout<PowerdPowerActivity> >( boost::dynamic_pointer_cast<PowerdPowerActivity, PowerActivity>( shared_from_this()), PowerActivityLockUpdateInterval, &PowerdPowerActivity::TimeoutNotification); } m_timeout->Arm(); m_call.reset(); } else { if (m_currentState != PowerLocked) { LOG_AM_WARNING(MSGID_PWRLK_NOTI_CREATE_FAIL,1, PMLOGKFV("Activity","%llu",m_activity.lock()->GetId()), "Attempt to create power lock failed, retrying. Error %s", MojoObjectJson(response).c_str()); } else { LOG_AM_WARNING(MSGID_PWRLK_NOTI_UPDATE_FAIL,1, PMLOGKFV("Activity","%llu",m_activity.lock()->GetId()), "Attempt to update power lock failed, retrying. Error %s", MojoObjectJson(response).c_str()); } m_call.reset(); /* Retry - powerd may have restarted. */ MojErr err2 = CreateRemotePowerActivity(); if (err2) { LOG_AM_WARNING(MSGID_PWR_LOCK_CREATE_FAIL,1, PMLOGKFV("Activity","%llu",m_activity.lock()->GetId()), "Failed to issue command to create power lock in Noti" ); /* If power was not currently locked, fake the create so the * Activity doesn't hang */ if (m_currentState != PowerLocked) { LOG_AM_WARNING(MSGID_PWR_LOCK_FAKE_NOTI,1, PMLOGKFV("Activity","%llu",m_activity.lock()->GetId()), "Faking power locked notification in noti"); m_currentState = PowerLocked; m_activity.lock()->PowerLockedNotification(); } } } }