From 22c3fc2ae2ba2125bc3af55ab8e6de4bc4102ac6 Mon Sep 17 00:00:00 2001 From: Loïc Collignon Date: Thu, 15 Nov 2018 15:45:30 +0100 Subject: Fix issues with session and policies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a policy does a 'ramp-down' on an audio role, it never does the 'ramp-up' when closing the role that triggered the policy. Also, session handling was very buggy and had to be reworked to allow the policy to do its job. Bug: SPEC-1949 Bug: SPEC-1950 Change-Id: I668044201c9addbc185ea953c6e3239abfda91c5 Signed-off-by: Loïc Collignon --- ahl-binding/role.cpp | 86 ++++++++++++++++++---------------------------------- 1 file changed, 29 insertions(+), 57 deletions(-) (limited to 'ahl-binding/role.cpp') diff --git a/ahl-binding/role.cpp b/ahl-binding/role.cpp index 0da9304..3a4dd0e 100644 --- a/ahl-binding/role.cpp +++ b/ahl-binding/role.cpp @@ -15,10 +15,13 @@ * limitations under the License. */ +#include #include "role.hpp" #include "jsonc_utils.hpp" #include "ahl-binding.hpp" +using session_t = std::vector; + role_t::role_t(json_object* j) { jcast(uid_, j, "uid"); @@ -111,50 +114,7 @@ const std::vector& role_t::interrupts() const int role_t::apply_policy(afb_req_t req) { - if(interrupts_.size()) - { - const interrupt_t& i = interrupts_[0]; - /*if (i.type() == "mute") - { - } - else if (i.type() == "continue") - { - } - else if (i.type() == "cancel") - { - } - else */if (i.type() == "ramp") - { - for(const auto& r: ahl_binding_t::instance().roles()) - { - if (r.opened() && priority_ > r.priority()) - { - // { "ramp" : { "uid" : "ramp-slow", "volume" : 30 } } - json_object* arg = json_object_new_object(); - json_object_object_add(arg, "ramp", i.args()); - json_object_get(i.args()); - json_object* result = nullptr; - - AFB_API_DEBUG(ahl_binding_t::instance().handle(), "Call '%s'/'%s' '%s", - r.hal().c_str(), r.stream().c_str(), json_object_to_json_string(arg)); - - if(afb_api_call_sync(ahl_binding_t::instance().handle(), r.hal().c_str(), r.stream().c_str(), arg, &result, nullptr, nullptr)) - { - afb_req_fail(req, "Failed to call 'ramp' action on stream", nullptr); - return -1; - } - AFB_API_DEBUG(ahl_binding_t::instance().handle(), "POLICY: Applying a ramp to '%s' stream because '%s' is opened and have higher priority!", - r.stream().c_str(), stream_.c_str()); - } - } - } - else - { - afb_req_fail(req, "Unkown interrupt uid!", nullptr); - return -1; - } - } - return 0; + return interrupts_.size() ? interrupts_[0].apply(req, *this) : 0; } void role_t::invoke(afb_req_t req) @@ -200,22 +160,20 @@ void role_t::open(afb_req_t r, json_object* o) if (!apply_policy(r)) { - afb_req_context_set( - r, - this, - [](void* arg) - { - role_t * role = (role_t*) arg; - - if (role->opened_) + afb_req_context(r, + 0, // Do not replace previous context if any + [](void* arg) -> void* { return new session_t(); }, + [](void* arg) { + afb_api_t api = ahl_binding_t::instance().handle(); + session_t* opened_roles = reinterpret_cast(arg); + for(role_t* role : *opened_roles) { - afb_api_t api = ahl_binding_t::instance().handle(); - AFB_API_DEBUG(api, "Released role %s\n", role->uid_.c_str()); role->opened_ = false; + if(role->interrupts_.size()) role->interrupts_[0].clear(); // send a mute command to the HAL. We cannot reuse the do_mute function, - // because in the context here, the afb_req_t is no longer valid. + // because in the context here, the afb_request is no longer valid. json_object* a = json_object_new_object(); json_object_object_add(a, "mute", json_object_new_boolean(true)); @@ -227,10 +185,17 @@ void role_t::open(afb_req_t r, json_object* o) NULL, NULL); } - } + delete opened_roles; + }, + nullptr ); + opened_ = true; + // Add the current role to the session + session_t* context = reinterpret_cast(afb_req_context_get(r)); + if(context) context->push_back(this); + json_object* result = json_object_new_object(); json_object_object_add(result, "device_uri", json_object_new_string(device_uri_.c_str())); @@ -246,13 +211,20 @@ void role_t::close(afb_req_t r, json_object* o) return; } - if(!afb_req_context_get(r)) + session_t* context = reinterpret_cast(afb_req_context_get(r)); + if(!context) { afb_req_fail(r, "Stream is opened by another client!", nullptr); return; } + // Remove the current role from the session. + std::string uid = uid_; + std::remove_if(context->begin(), context->end(), [uid](role_t* r) { return r->uid_ == uid; }); + context->push_back(this); + opened_ = false; + if(interrupts_.size()) interrupts_[0].clear(); afb_req_success(r, nullptr, "Stream closed!"); } -- cgit 1.2.3-korg