2 * Copyright (c) 2012, Intel Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Intel Corporation nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #include <murphy/common.h>
37 #include <murphy-db/mqi.h>
39 #include <murphy/resource/config-api.h>
40 #include <murphy/resource/manager-api.h>
41 #include <murphy/resource/client-api.h>
45 #include "wayland/wayland.h"
46 #include "application/application.h"
48 #define ANY_ZONE (~((uint32_t)0))
60 #define BIT(i) ((uint32_t)1 << (i))
61 #define MASK(w) (((uint32_t)1 << (w)) - 1)
62 #define MAX(w) (((uint32_t)1 << (w)))
65 #define PRIORITY_BITS 8
66 #define CLASSPRI_BITS 8
67 #define ACQUIRE_BITS 1
69 #define INTERRUPT_BITS 1
71 #define STAMP_POSITION 0
72 #define PRIORITY_POSITION (STAMP_POSITION + STAMP_BITS)
73 #define CLASSPRI_POSITION (PRIORITY_POSITION + PRIORITY_BITS)
74 #define ACQUIRE_POSITION (CLASSPRI_POSITION + CLASSPRI_BITS)
75 #define SHARE_POSITION (ACQUIRE_POSITION + ACQUIRE_BITS)
76 #define INTERRUPT_POSITION (SHARE_POSITION + SHARE_BITS)
78 #define STAMP_MASK MASK(STAMP_BITS)
79 #define PRIORITY_MASK MASK(PRIORITY_BITS)
80 #define CLASSPRI_MASK MASK(CLASSPRI_BITS)
81 #define ACQUIRE_MASK MASK(ACQUIRE_BITS)
82 #define SHARE_MASK MASK(SHARE_BITS)
83 #define INTERRUPT_MASK MASK(INTERRUPT_BITS)
85 #define STAMP_MAX MAX(STAMP_BITS)
86 #define PRIORITY_MAX MAX(PRIORITY_BITS)
87 #define CLASSPRI_MAX MAX(CLASSPRI_BITS)
88 #define ACQUIRE_MAX MAX(ACQUIRE_BITS)
89 #define SHARE_MAX MAX(SHARE_BITS)
90 #define INTERRUPT_MAX MAX(INTERRUPT_BITS)
93 #define ATTRIBUTE(n,t,v) {n, MRP_RESOURCE_RW, mqi_##t, {.t=v}}
94 #define ATTR_END {NULL, 0, 0, {.string=NULL}}
96 typedef struct audio_resource_s audio_resource_t;
97 typedef struct disable_iterator_s disable_iterator_t;
99 struct audio_resource_s {
100 mrp_list_hook_t link;
101 mrp_resmgr_audio_t *audio;
104 uint32_t audioid; /* unique id. Not to confuse with resource-set id */
111 mrp_application_requisite_t requisite;
112 mrp_resmgr_disable_t disable;
115 struct disable_iterator_s {
117 const char *appclass;
119 mrp_resmgr_disable_t type;
123 mrp_application_requisite_t req;
129 static int hash_compare(const void *, const void *);
130 static uint32_t hash_function(const void *);
132 static const char *get_appid_for_resource(mrp_resource_t *);
133 static mrp_application_t *get_application_for_resource(mrp_resource_t *);
134 static uint32_t get_priority_for_resource(mrp_resource_t *);
135 static uint32_t get_class_priority_for_resource(mrp_resource_t *);
138 static audio_resource_t *audio_resource_create(mrp_resmgr_audio_t *,
139 mrp_zone_t *,mrp_resource_t *,
140 mrp_application_class_t *);
141 static void audio_resource_destroy(mrp_resmgr_audio_t *, mrp_zone_t *,
143 static audio_resource_t *audio_resource_lookup(mrp_resmgr_audio_t *,
146 static void audio_insert_resource(audio_resource_t *);
147 static void audio_grant_resources(mrp_resmgr_audio_t *, mrp_zone_t *);
148 static void audio_queue_events(mrp_resmgr_audio_t *, mrp_zone_t *);
150 static uint32_t resource_key(audio_resource_t *);
152 static void audio_notify(mrp_resource_event_t, mrp_zone_t *,
153 mrp_application_class_t *, mrp_resource_t *, void *);
154 static void audio_init(mrp_zone_t *, void *);
155 static bool audio_allocate(mrp_zone_t *, mrp_resource_t *, void *);
156 static void audio_free(mrp_zone_t *, mrp_resource_t *, void *);
157 static bool audio_advice(mrp_zone_t *, mrp_resource_t *, void *);
158 static void audio_commit(mrp_zone_t *, void *);
160 #define PRIORITY_ATTRIDX 0
161 #define CLASSPRI_ATTRIDX 1
162 #define APPID_ATTRIDX 2
163 #define ROLE_ATTRIDX 3
164 #define PID_ATTRIDX 4
165 #define POLICY_ATTRIDX 5
167 static mrp_attr_def_t audio_attrs[] = {
168 ATTRIBUTE("priority" , integer, 0 ),
169 ATTRIBUTE("classpri" , integer, -1 ),
170 ATTRIBUTE("appid" , string , "<undefined>"),
171 ATTRIBUTE("role" , string , "music" ),
172 ATTRIBUTE("pid" , string , "<unknown>" ),
173 ATTRIBUTE("policy" , string , "relaxed" ),
177 static mrp_resource_mgr_ftbl_t audio_ftbl = {
186 mrp_resmgr_audio_t *mrp_resmgr_audio_create(mrp_resmgr_t *resmgr)
188 mrp_resmgr_audio_t *audio;
189 mrp_htbl_config_t cfg;
193 if ((audio = mrp_allocz(sizeof(mrp_resmgr_audio_t)))) {
194 resid = mrp_resource_definition_create(MRP_SYSCTL_AUDIO_RESOURCE,
197 mrp_lua_resclass_create_from_c(resid);
199 cfg.nentry = MRP_RESMGR_RESOURCE_MAX;
200 cfg.comp = hash_compare;
201 cfg.hash = hash_function;
203 cfg.nbucket = MRP_RESMGR_RESOURCE_BUCKETS;
205 audio->resmgr = resmgr;
206 audio->resid = resid;
207 audio->resources = mrp_htbl_create(&cfg);
209 for (i = 0; i < MRP_ZONE_MAX; i++)
210 mrp_list_init(audio->zones + i);
216 void mrp_resmgr_audio_destroy(mrp_resmgr_audio_t *audio)
223 static int audio_disable_cb(void *key, void *object, void *user_data)
225 audio_resource_t *ar = (audio_resource_t *)object;
226 disable_iterator_t *it = (disable_iterator_t *)user_data;
228 const char *appclass;
233 MRP_ASSERT(ar && it, "invalid argument");
235 if ((appclass = mrp_resource_get_application_class(ar->res))) {
236 if (( it->zoneid == ANY_ZONE || ar->zoneid == it->zoneid ) &&
237 (!strcmp(it->appclass, "*") || !strcmp(appclass, it->appclass)) )
241 case MRP_RESMGR_DISABLE_REQUISITE:
242 if (it->req && (it->req & ar->requisite) == it->req)
246 case MRP_RESMGR_DISABLE_APPID:
248 if (!strcmp(it->appid, "*"))
250 appid = get_appid_for_resource(ar->res);
251 if (appid && !strcmp(it->appid, appid))
257 disable = ar->disable & it->mask;
261 ar->disable |= it->mask;
266 ar->disable &= ~it->mask;
269 it->zones |= (((uint32_t)1) << ar->zoneid);
273 return MRP_HTBL_ITER_STOP;
278 return MRP_HTBL_ITER_MORE;
281 int mrp_resmgr_audio_disable(mrp_resmgr_audio_t *audio,
282 const char *zone_name,
283 const char *application_class,
285 mrp_resmgr_disable_t type,
289 const char *zone_names[MRP_ZONE_MAX + 1];
290 disable_iterator_t it;
292 uint32_t zone_id = ANY_ZONE;
296 MRP_ASSERT(audio && data && zone_name && application_class,
299 mrp_debug("zone_name='%s' application_class='%s' %s type=0x%02x data=%p"
301 zone_name ? zone_name : "<any zone>",
302 application_class ? application_class : "<any class>",
303 disable ? "disable" : "enable",
304 type, data, recalc_owner ? "true" : "false");
306 if (zone_name && strcmp(zone_name, "*")) {
307 if (mrp_zone_get_all_names(MRP_ZONE_MAX + 1, zone_names)) {
308 for (i = 0; zone_names[i]; i++) {
309 if (!strcmp(zone_name, zone_names[i])) {
315 if (zone_id == ANY_ZONE) {
316 mrp_log_error("system-controller: failed to disable audio: "
317 "can't find zone '%s'", zone_name);
322 memset(&it, 0, sizeof(it));
324 it.appclass = application_class;
325 it.disable = disable;
327 it.mask = BIT(type - 1);
333 case MRP_RESMGR_DISABLE_REQUISITE:
334 it.req = *(mrp_application_requisite_t *)data;
337 case MRP_RESMGR_DISABLE_APPID:
338 it.appid = (const char *)data;
342 mrp_log_error("system-controller: invalid type %d of "
343 "audio disable", type);
347 mrp_htbl_foreach(audio->resources, audio_disable_cb, &it);
350 for (z = 0; it.zones && z < MRP_ZONE_MAX; z++) {
351 mask = (((uint32_t)1) << z);
353 if ((mask & it.zones)) {
355 mrp_resource_owner_recalc(z);
364 int mrp_resmgr_audio_print(mrp_resmgr_audio_t *audio,
370 p += snprintf(p, e-p, __VA_ARGS__); \
377 mrp_list_hook_t *resources, *rentry, *rn;
378 audio_resource_t *ar;
382 char requisite[1024];
384 MRP_ASSERT(audio && buf && len > 0, "invalid argument");
389 if (zoneid < MRP_ZONE_MAX) {
390 resources = audio->zones + zoneid;
391 grantid = audio->grantids[zoneid];
398 PRINT(" Resource '%s' - grantid:%u\n",
399 MRP_SYSCTL_AUDIO_RESOURCE, grantid);
401 if (!resources || mrp_list_empty(resources))
402 PRINT(" No resources\n");
404 mrp_list_foreach_back(resources, rentry, rn) {
405 ar = mrp_list_entry(rentry, audio_resource_t, link);
407 mrp_resmgr_disable_print(ar->disable, disable,
409 mrp_application_requisite_print(ar->requisite, requisite,
413 "key:0x%08x %s %s grantid:%u requisite:%s disable:%s",
415 ar->interrupt ? "interrupt" : "base",
416 ar->acquire ? "acquire":"release",
421 for (i = 0; i < MRP_ARRAY_SIZE(audio_attrs) - 1; i++) {
422 if ((mrp_resource_read_attribute(ar->res, i, &a))) {
423 PRINT(" %s:", a.name);
426 case mqi_string: PRINT("'%s'",a.value.string); break;
427 case mqi_integer: PRINT("%d",a.value.integer); break;
428 case mqi_unsignd: PRINT("%u",a.value.unsignd); break;
429 case mqi_floating: PRINT("%lf",a.value.floating);break;
430 default: PRINT("<unsupported type>"); break;
436 } /* mrp_list_foreach_back - resources */
443 static int hash_compare(const void *key1, const void *key2)
452 static uint32_t hash_function(const void *key)
454 return (uint32_t)(key - (const void *)0);
457 static const char *get_appid_for_resource(mrp_resource_t *res)
462 if (!mrp_resource_read_attribute(res, APPID_ATTRIDX, &attr) ||
463 attr.type != mqi_string || !(appid = attr.value.string) )
469 static mrp_application_t *get_application_for_resource(mrp_resource_t *res)
471 const char *appid = get_appid_for_resource(res);
472 mrp_application_t *app = NULL;
474 if (!appid || !(app = mrp_application_find(appid)))
475 app = mrp_application_find(MRP_SYSCTL_APPID_DEFAULT);
480 static uint32_t get_priority_for_resource(mrp_resource_t *res)
483 uint32_t priority = 0;
485 if (mrp_resource_read_attribute(res, PRIORITY_ATTRIDX, &attr)) {
486 if (attr.type == mqi_integer && attr.value.integer >= 0)
487 priority = attr.value.integer;
493 static uint32_t get_class_priority_for_resource(mrp_resource_t *res)
496 uint32_t priority = 0;
498 if (mrp_resource_read_attribute(res, CLASSPRI_ATTRIDX, &attr)) {
499 if (attr.type == mqi_integer && attr.value.integer >= 0)
500 priority = attr.value.integer < 0 ? 0 : attr.value.integer;
506 static audio_resource_t *audio_resource_create(mrp_resmgr_audio_t *audio,
509 mrp_application_class_t *ac)
511 static uint32_t audioid;
513 const char *zonename;
515 const char *class_name;
516 mrp_resmgr_t *resmgr;
517 mrp_application_t *app;
518 audio_resource_t *ar;
521 MRP_ASSERT(audio && zone && res && ac, "invalid argument");
522 MRP_ASSERT(audio->resmgr, "confused with data structures");
524 resmgr = audio->resmgr;
525 zonename = mrp_zone_get_name(zone);
526 appid = get_appid_for_resource(res);
527 class_name = mrp_application_class_get_name(ac);
530 if (!(app = get_application_for_resource(res))) {
531 mrp_log_error("system-controller: failed to create audio resource: "
536 if (!(ar = mrp_allocz(sizeof(*ar)))) {
537 mrp_log_error("system-controller: failed to create audio resource: "
538 "can't allocate memory");
542 mrp_list_init(&ar->link);
545 ar->zoneid = mrp_zone_get_id(zone);
546 ar->audioid = audioid++;
547 ar->interrupt = strcmp(class_name, "player") && strcmp(class_name, "base");
548 ar->key = resource_key(ar);
549 ar->requisite = app->requisites.audio;
551 audio_insert_resource(ar);
553 mrp_debug("inserting resource to hash table: key=%p value=%p", res, ar);
554 mrp_resmgr_insert_resource(resmgr, zone, res, ar);
556 hk = NULL + ar->audioid;
557 mrp_debug("inserting audio to hash table: key=%p value=%p", hk, ar);
558 mrp_htbl_insert(audio->resources, hk, ar);
560 mrp_resmgr_notifier_queue_audio_event(audio->resmgr, ar->zoneid, zonename,
561 MRP_RESMGR_EVENTID_CREATE,
563 mrp_resmgr_notifier_flush_audio_events(audio->resmgr, ar->zoneid);
569 static void audio_resource_destroy(mrp_resmgr_audio_t *audio,
573 audio_resource_t *ar;
574 const char *zonename;
577 MRP_ASSERT(audio && res && zone, "invalid argument");
578 MRP_ASSERT(audio->resmgr, "confused with data structures");
580 if ((ar = mrp_resmgr_remove_resource(audio->resmgr, zone, res))) {
581 zonename = mrp_zone_get_name(zone);
582 appid = get_appid_for_resource(res);
584 mrp_resmgr_notifier_queue_audio_event(audio->resmgr,
585 ar->zoneid, zonename,
586 MRP_RESMGR_EVENTID_DESTROY,
589 mrp_htbl_remove(audio->resources, NULL + ar->audioid, false);
591 mrp_list_delete(&ar->link);
593 mrp_resmgr_notifier_flush_audio_events(audio->resmgr, ar->zoneid);
599 static audio_resource_t *audio_resource_lookup(mrp_resmgr_audio_t *audio,
602 audio_resource_t *ar;
604 MRP_ASSERT(audio && res, "invalid argument");
605 MRP_ASSERT(audio->resmgr, "confused with data structures");
607 ar = mrp_resmgr_lookup_resource(audio->resmgr, res);
612 static void audio_insert_resource(audio_resource_t *resource)
614 mrp_resmgr_audio_t *audio;
615 mrp_list_hook_t *resources, *insert_after, *n;
616 audio_resource_t *ar;
619 mrp_list_delete(&resource->link);
621 audio = resource->audio;
622 resources = audio->zones + resource->zoneid;
624 insert_after = resources; /* keep the compiler happy: foreach below
625 will do it anyways */
627 mrp_list_foreach_back(resources, insert_after, n) {
628 ar = mrp_list_entry(insert_after, audio_resource_t, link);
633 mrp_list_insert_after(insert_after, &resource->link);
636 static void audio_grant_resources(mrp_resmgr_audio_t *audio,
640 const char *zonename;
642 mrp_list_hook_t *resources, *rentry , *rn;
643 audio_resource_t *ar;
646 zoneid = mrp_zone_get_id(zone);
647 zonename = mrp_zone_get_name(zone);
649 /* We got a nonsense zone id */
650 if (zoneid >= MRP_ZONE_MAX) {
651 mrp_debug("invalid zoneid '%" PRIu32 "' is larger than MRP_ZONE_MAX (%d), "
652 "bailing", zoneid, MRP_ZONE_MAX);
657 zonename = "<unknown>";
659 resources = audio->zones + zoneid;
660 grantid = ++(audio->grantids[zoneid]);
662 mrp_list_foreach_back(resources, rentry, rn) {
663 ar = mrp_list_entry(rentry, audio_resource_t, link);
665 MRP_ASSERT(ar->res, "confused with data structures");
667 if (ar->acquire && !ar->disable) {
668 if (!(appid = get_appid_for_resource(ar->res)))
671 mrp_debug("preallocate audio resource for '%s' in zone '%s'",
674 ar->grantid = grantid;
676 mrp_resmgr_notifier_queue_audio_event(audio->resmgr,
678 MRP_RESMGR_EVENTID_PREALLOCATE,
681 if (!mrp_resource_is_shared(ar->res))
687 static void audio_queue_events(mrp_resmgr_audio_t *audio, mrp_zone_t *zone)
690 const char *zonename;
692 mrp_list_hook_t *resources, *rentry, *rn;
693 audio_resource_t *ar;
695 mrp_resmgr_eventid_t eventid;
698 zoneid = mrp_zone_get_id(zone);
699 zonename = mrp_zone_get_name(zone);
701 /* We got a nonsense zone id */
702 if (zoneid >= MRP_ZONE_MAX) {
703 mrp_debug("invalid zoneid '%" PRIu32 "' is larger than MRP_ZONE_MAX (%d), "
704 "bailing", zoneid, MRP_ZONE_MAX);
708 resources = audio->zones + zoneid;
709 grantid = audio->grantids[zoneid];
711 mrp_list_foreach_back(resources, rentry, rn) {
712 ar = mrp_list_entry(rentry, audio_resource_t, link);
713 grant = (grantid == ar->grantid);
715 if ((grant && !ar->grant) || (!grant && ar->grant)) {
716 eventid = grant ? MRP_RESMGR_EVENTID_GRANT :
717 MRP_RESMGR_EVENTID_REVOKE;
718 appid = get_appid_for_resource(ar->res);
720 mrp_resmgr_notifier_queue_audio_event(audio->resmgr,
731 static uint32_t resource_key(audio_resource_t *ar)
742 stamp = 0; /* for now */
743 priority = get_priority_for_resource(ar->res);
744 classpri = get_class_priority_for_resource(ar->res);
745 acquire = ar->acquire ? 1 : 0;
746 share = mrp_resource_is_shared(ar->res) ? 1 : 0;
747 interrupt = ar->interrupt ? 1 : 0;
749 key = ((stamp & STAMP_MASK ) << STAMP_POSITION ) |
750 ((priority & PRIORITY_MASK ) << PRIORITY_POSITION ) |
751 ((classpri & CLASSPRI_MASK ) << CLASSPRI_POSITION ) |
752 ((acquire & ACQUIRE_MASK ) << ACQUIRE_POSITION ) |
753 ((share & SHARE_MASK ) << SHARE_POSITION ) |
754 ((interrupt & INTERRUPT_MASK) << INTERRUPT_POSITION) ;
760 static void audio_notify(mrp_resource_event_t event,
762 mrp_application_class_t *ac,
766 mrp_resmgr_audio_t *audio = (mrp_resmgr_audio_t *)userdata;
767 const char *zonename = mrp_zone_get_name(zone);
768 audio_resource_t *ar;
770 MRP_ASSERT(zone && ac && res && audio, "invalid argument");
774 case MRP_RESOURCE_EVENT_CREATED:
775 mrp_debug("audio resource in zone '%s' created", zonename);
776 audio_resource_create(audio, zone, res, ac);
779 case MRP_RESOURCE_EVENT_DESTROYED:
780 mrp_debug("audio resource in zone '%s' destroyed", zonename);
781 audio_resource_destroy(audio, zone, res);
784 case MRP_RESOURCE_EVENT_ACQUIRE:
785 mrp_debug("audio resource in zone '%s' is acquiring", zonename);
786 if (!(ar = audio_resource_lookup(audio, res)))
787 goto no_audio_resource;
791 ar->key = resource_key(ar);
792 audio_insert_resource(ar);
796 case MRP_RESOURCE_EVENT_RELEASE:
797 mrp_debug("audio resource in zone '%s' is released", zonename);
798 if (!(ar = audio_resource_lookup(audio, res)))
799 goto no_audio_resource;
803 ar->key = resource_key(ar);
804 audio_insert_resource(ar);
809 mrp_debug("resource lookup in hash table failed: key=%p", res);
810 mrp_log_error("system-controller: can't find audio resource "
811 "in zone '%s'", zonename);
815 mrp_log_error("system-controller: invalid event %d at audio "
816 "notification (zone '%s')", event, zonename);
821 static void audio_init(mrp_zone_t *zone, void *userdata)
823 mrp_resmgr_audio_t *audio = (mrp_resmgr_audio_t *)userdata;
825 const char *zonename;
827 MRP_ASSERT(zone && audio, "invalid argument");
829 zoneid = mrp_zone_get_id(zone);
830 zonename = mrp_zone_get_name(zone);
832 /* We got a nonsense zone id */
833 if (zoneid >= MRP_ZONE_MAX) {
834 mrp_debug("invalid zoneid '%" PRIu32 "' is larger than MRP_ZONE_MAX (%d), "
835 "bailing", zoneid, MRP_ZONE_MAX);
840 zonename = "<unknown>";
842 mrp_debug("audio init in zone '%s'", zonename);
844 mrp_resmgr_notifier_queue_audio_event(audio->resmgr, zoneid, zonename,
845 MRP_RESMGR_EVENTID_INIT,
847 audio_grant_resources(audio, zone);
849 mrp_resmgr_notifier_flush_audio_events(audio->resmgr, zoneid);
852 static bool audio_allocate(mrp_zone_t *zone,
856 mrp_resmgr_audio_t *audio = (mrp_resmgr_audio_t *)userdata;
858 const char *zonename;
860 audio_resource_t *ar;
864 MRP_ASSERT(zone && res && audio && audio->resmgr, "invalid argument");
866 zoneid = mrp_zone_get_id(zone);
868 /* We got a nonsense zone id */
869 if (zoneid >= MRP_ZONE_MAX) {
870 mrp_debug("invalid zoneid '%" PRIu32 "' is larger than MRP_ZONE_MAX (%d), "
871 "bailing", zoneid, MRP_ZONE_MAX);
875 grantid = audio->grantids[zoneid];
877 if (!(zonename = mrp_zone_get_name(zone)))
878 zonename = "<unknown>";
879 if (!(appid = get_appid_for_resource(res)))
882 if ((ar = audio_resource_lookup(audio, res))) {
883 allocated = (ar->grantid == grantid);
885 mrp_debug("audio allocation for '%s' in zone '%s' %s",
886 zonename, appid, allocated ? "succeeded":"failed");
891 mrp_log_error("system-controller: attempt to allocate untracked "
892 "resource '%s' in zone '%s'", appid, zonename);
897 static void audio_free(mrp_zone_t *zone, mrp_resource_t *res, void *userdata)
899 mrp_resmgr_audio_t *audio = (mrp_resmgr_audio_t *)userdata;
900 const char *zonename;
902 audio_resource_t *ar;
904 MRP_ASSERT(zone && res && audio, "invalid argument");
906 if (!(zonename = mrp_zone_get_name(zone)))
907 zonename = "<unknown>";
908 if (!(appid = get_appid_for_resource(res)))
911 mrp_debug("free audio of '%s' in zone '%s'", appid, zonename);
913 if ((ar = audio_resource_lookup(audio, res)))
917 static bool audio_advice(mrp_zone_t *zone,mrp_resource_t *res,void *userdata)
919 mrp_resmgr_audio_t *audio = (mrp_resmgr_audio_t *)userdata;
920 const char *zonename;
923 MRP_ASSERT(zone && res && audio, "invalid argument");
925 if (!(zonename = mrp_zone_get_name(zone)))
926 zonename = "<unknown>";
927 if (!(appid = get_appid_for_resource(res)))
930 mrp_debug("audio advice for '%s' in zone '%s'", appid, zonename);
935 static void audio_commit(mrp_zone_t *zone, void *userdata)
937 mrp_resmgr_audio_t *audio = (mrp_resmgr_audio_t *)userdata;
938 const char *zonename;
941 MRP_ASSERT(zone && audio && audio->resmgr, "invalid argument");
943 zoneid = mrp_zone_get_id(zone);
945 /* We got a nonsense zone id */
946 if (zoneid >= MRP_ZONE_MAX) {
947 mrp_debug("invalid zoneid '%" PRIu32 "' is larger than MRP_ZONE_MAX (%d), "
948 "bailing", zoneid, MRP_ZONE_MAX);
952 if (!(zonename = mrp_zone_get_name(zone)))
953 zonename = "<unknown>";
955 mrp_debug("audio commit in zone '%s'", zonename);
957 audio_queue_events(audio, zone);
958 mrp_resmgr_notifier_flush_audio_events(audio->resmgr, zoneid);