예제 #1
0
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;
}
예제 #3
0
/*
 * 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());
		}
	}
}
예제 #4
0
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;
	}
}
예제 #5
0
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;
	}
}
예제 #6
0
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;
	}
}
예제 #7
0
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;
	}
}
예제 #9
0
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;
}
예제 #11
0
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");
	}
}
예제 #12
0
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");
	}
}
예제 #13
0
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();
		}
	}
}
예제 #15
0
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;
	}
}
예제 #16
0
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();
}
예제 #17
0
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);
}
예제 #18
0
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;
	}
}
예제 #19
0
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;
}
예제 #22
0
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;
}
예제 #25
0
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;
}
예제 #26
0
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();
	}
}
예제 #27
0
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));
			}
		}
	}
}
예제 #28
0
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);
}
예제 #29
0
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();
			}
		}
	}
}