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" ),
174 ATTRIBUTE("name" , string , "<unknown>" ),
178 static mrp_resource_mgr_ftbl_t audio_ftbl = {
187 mrp_resmgr_audio_t *mrp_resmgr_audio_create(mrp_resmgr_t *resmgr)
189 mrp_resmgr_audio_t *audio;
190 mrp_htbl_config_t cfg;
194 if ((audio = mrp_allocz(sizeof(mrp_resmgr_audio_t)))) {
195 resid = mrp_resource_definition_create(MRP_SYSCTL_AUDIO_RESOURCE,
198 mrp_lua_resclass_create_from_c(resid);
200 cfg.nentry = MRP_RESMGR_RESOURCE_MAX;
201 cfg.comp = hash_compare;
202 cfg.hash = hash_function;
204 cfg.nbucket = MRP_RESMGR_RESOURCE_BUCKETS;
206 audio->resmgr = resmgr;
207 audio->resid = resid;
208 audio->resources = mrp_htbl_create(&cfg);
210 for (i = 0; i < MRP_ZONE_MAX; i++)
211 mrp_list_init(audio->zones + i);
217 void mrp_resmgr_audio_destroy(mrp_resmgr_audio_t *audio)
224 static int audio_disable_cb(void *key, void *object, void *user_data)
226 audio_resource_t *ar = (audio_resource_t *)object;
227 disable_iterator_t *it = (disable_iterator_t *)user_data;
229 const char *appclass;
234 MRP_ASSERT(ar && it, "invalid argument");
236 if ((appclass = mrp_resource_get_application_class(ar->res))) {
237 if (( it->zoneid == ANY_ZONE || ar->zoneid == it->zoneid ) &&
238 (!strcmp(it->appclass, "*") || !strcmp(appclass, it->appclass)) )
242 case MRP_RESMGR_DISABLE_REQUISITE:
243 if (it->req && (it->req & ar->requisite) == it->req)
247 case MRP_RESMGR_DISABLE_APPID:
249 if (!strcmp(it->appid, "*"))
251 appid = get_appid_for_resource(ar->res);
252 if (appid && !strcmp(it->appid, appid))
258 disable = ar->disable & it->mask;
262 ar->disable |= it->mask;
267 ar->disable &= ~it->mask;
270 it->zones |= (((uint32_t)1) << ar->zoneid);
274 return MRP_HTBL_ITER_STOP;
279 return MRP_HTBL_ITER_MORE;
282 int mrp_resmgr_audio_disable(mrp_resmgr_audio_t *audio,
283 const char *zone_name,
284 const char *application_class,
286 mrp_resmgr_disable_t type,
290 const char *zone_names[MRP_ZONE_MAX + 1];
291 disable_iterator_t it;
293 uint32_t zone_id = ANY_ZONE;
297 MRP_ASSERT(audio && data && zone_name && application_class,
300 mrp_debug("zone_name='%s' application_class='%s' %s type=0x%02x data=%p"
302 zone_name ? zone_name : "<any zone>",
303 application_class ? application_class : "<any class>",
304 disable ? "disable" : "enable",
305 type, data, recalc_owner ? "true" : "false");
307 if (zone_name && strcmp(zone_name, "*")) {
308 if (mrp_zone_get_all_names(MRP_ZONE_MAX + 1, zone_names)) {
309 for (i = 0; zone_names[i]; i++) {
310 if (!strcmp(zone_name, zone_names[i])) {
316 if (zone_id == ANY_ZONE) {
317 mrp_log_error("system-controller: failed to disable audio: "
318 "can't find zone '%s'", zone_name);
323 memset(&it, 0, sizeof(it));
325 it.appclass = application_class;
326 it.disable = disable;
328 it.mask = BIT(type - 1);
334 case MRP_RESMGR_DISABLE_REQUISITE:
335 it.req = *(mrp_application_requisite_t *)data;
338 case MRP_RESMGR_DISABLE_APPID:
339 it.appid = (const char *)data;
343 mrp_log_error("system-controller: invalid type %d of "
344 "audio disable", type);
348 mrp_htbl_foreach(audio->resources, audio_disable_cb, &it);
351 for (z = 0; it.zones && z < MRP_ZONE_MAX; z++) {
352 mask = (((uint32_t)1) << z);
354 if ((mask & it.zones)) {
356 mrp_resource_owner_recalc(z);
365 int mrp_resmgr_audio_print(mrp_resmgr_audio_t *audio,
371 p += snprintf(p, e-p, __VA_ARGS__); \
378 mrp_list_hook_t *resources, *rentry, *rn;
379 audio_resource_t *ar;
383 char requisite[1024];
385 MRP_ASSERT(audio && buf && len > 0, "invalid argument");
390 if (zoneid < MRP_ZONE_MAX) {
391 resources = audio->zones + zoneid;
392 grantid = audio->grantids[zoneid];
399 PRINT(" Resource '%s' - grantid:%u\n",
400 MRP_SYSCTL_AUDIO_RESOURCE, grantid);
402 if (!resources || mrp_list_empty(resources))
403 PRINT(" No resources\n");
405 mrp_list_foreach_back(resources, rentry, rn) {
406 ar = mrp_list_entry(rentry, audio_resource_t, link);
408 mrp_resmgr_disable_print(ar->disable, disable,
410 mrp_application_requisite_print(ar->requisite, requisite,
414 "key:0x%08x %s %s grantid:%u requisite:%s disable:%s",
416 ar->interrupt ? "interrupt" : "base",
417 ar->acquire ? "acquire":"release",
422 for (i = 0; i < MRP_ARRAY_SIZE(audio_attrs) - 1; i++) {
423 if ((mrp_resource_read_attribute(ar->res, i, &a))) {
424 PRINT(" %s:", a.name);
427 case mqi_string: PRINT("'%s'",a.value.string); break;
428 case mqi_integer: PRINT("%d",a.value.integer); break;
429 case mqi_unsignd: PRINT("%u",a.value.unsignd); break;
430 case mqi_floating: PRINT("%lf",a.value.floating);break;
431 default: PRINT("<unsupported type>"); break;
437 } /* mrp_list_foreach_back - resources */
444 static int hash_compare(const void *key1, const void *key2)
453 static uint32_t hash_function(const void *key)
455 return (uint32_t)(key - (const void *)0);
458 static const char *get_appid_for_resource(mrp_resource_t *res)
463 if (!mrp_resource_read_attribute(res, APPID_ATTRIDX, &attr) ||
464 attr.type != mqi_string || !(appid = attr.value.string) )
470 static mrp_application_t *get_application_for_resource(mrp_resource_t *res)
472 const char *appid = get_appid_for_resource(res);
473 mrp_application_t *app = NULL;
475 if (!appid || !(app = mrp_application_find(appid)))
476 app = mrp_application_find(MRP_SYSCTL_APPID_DEFAULT);
481 static uint32_t get_priority_for_resource(mrp_resource_t *res)
484 uint32_t priority = 0;
486 if (mrp_resource_read_attribute(res, PRIORITY_ATTRIDX, &attr)) {
487 if (attr.type == mqi_integer && attr.value.integer >= 0)
488 priority = attr.value.integer;
494 static uint32_t get_class_priority_for_resource(mrp_resource_t *res)
497 uint32_t priority = 0;
499 if (mrp_resource_read_attribute(res, CLASSPRI_ATTRIDX, &attr)) {
500 if (attr.type == mqi_integer && attr.value.integer >= 0)
501 priority = attr.value.integer < 0 ? 0 : attr.value.integer;
507 static audio_resource_t *audio_resource_create(mrp_resmgr_audio_t *audio,
510 mrp_application_class_t *ac)
512 static uint32_t audioid;
514 const char *zonename;
516 const char *class_name;
517 mrp_resmgr_t *resmgr;
518 mrp_application_t *app;
519 audio_resource_t *ar;
522 MRP_ASSERT(audio && zone && res && ac, "invalid argument");
523 MRP_ASSERT(audio->resmgr, "confused with data structures");
525 resmgr = audio->resmgr;
526 zonename = mrp_zone_get_name(zone);
527 appid = get_appid_for_resource(res);
528 class_name = mrp_application_class_get_name(ac);
531 if (!(app = get_application_for_resource(res))) {
532 mrp_log_error("system-controller: failed to create audio resource: "
537 if (!(ar = mrp_allocz(sizeof(*ar)))) {
538 mrp_log_error("system-controller: failed to create audio resource: "
539 "can't allocate memory");
543 mrp_list_init(&ar->link);
546 ar->zoneid = mrp_zone_get_id(zone);
547 ar->audioid = audioid++;
548 ar->interrupt = strcmp(class_name, "player") && strcmp(class_name, "base");
549 ar->key = resource_key(ar);
550 ar->requisite = app->requisites.audio;
552 audio_insert_resource(ar);
554 mrp_debug("inserting resource to hash table: key=%p value=%p", res, ar);
555 mrp_resmgr_insert_resource(resmgr, zone, res, ar);
557 hk = NULL + ar->audioid;
558 mrp_debug("inserting audio to hash table: key=%p value=%p", hk, ar);
559 mrp_htbl_insert(audio->resources, hk, ar);
561 mrp_resmgr_notifier_queue_audio_event(audio->resmgr, ar->zoneid, zonename,
562 MRP_RESMGR_EVENTID_CREATE,
564 mrp_resmgr_notifier_flush_audio_events(audio->resmgr, ar->zoneid);
570 static void audio_resource_destroy(mrp_resmgr_audio_t *audio,
574 audio_resource_t *ar;
575 const char *zonename;
578 MRP_ASSERT(audio && res && zone, "invalid argument");
579 MRP_ASSERT(audio->resmgr, "confused with data structures");
581 if ((ar = mrp_resmgr_remove_resource(audio->resmgr, zone, res))) {
582 zonename = mrp_zone_get_name(zone);
583 appid = get_appid_for_resource(res);
585 mrp_resmgr_notifier_queue_audio_event(audio->resmgr,
586 ar->zoneid, zonename,
587 MRP_RESMGR_EVENTID_DESTROY,
590 mrp_htbl_remove(audio->resources, NULL + ar->audioid, false);
592 mrp_list_delete(&ar->link);
594 mrp_resmgr_notifier_flush_audio_events(audio->resmgr, ar->zoneid);
600 static audio_resource_t *audio_resource_lookup(mrp_resmgr_audio_t *audio,
603 audio_resource_t *ar;
605 MRP_ASSERT(audio && res, "invalid argument");
606 MRP_ASSERT(audio->resmgr, "confused with data structures");
608 ar = mrp_resmgr_lookup_resource(audio->resmgr, res);
613 static void audio_insert_resource(audio_resource_t *resource)
615 mrp_resmgr_audio_t *audio;
616 mrp_list_hook_t *resources, *insert_after, *n;
617 audio_resource_t *ar;
620 mrp_list_delete(&resource->link);
622 audio = resource->audio;
623 resources = audio->zones + resource->zoneid;
625 insert_after = resources; /* keep the compiler happy: foreach below
626 will do it anyways */
628 mrp_list_foreach_back(resources, insert_after, n) {
629 ar = mrp_list_entry(insert_after, audio_resource_t, link);
634 mrp_list_insert_after(insert_after, &resource->link);
637 static void audio_grant_resources(mrp_resmgr_audio_t *audio,
641 const char *zonename;
643 mrp_list_hook_t *resources, *rentry , *rn;
644 audio_resource_t *ar;
647 zoneid = mrp_zone_get_id(zone);
648 zonename = mrp_zone_get_name(zone);
650 /* We got a nonsense zone id */
651 if (zoneid >= MRP_ZONE_MAX) {
652 mrp_debug("invalid zoneid '%" PRIu32 "' is larger than MRP_ZONE_MAX (%d), "
653 "bailing", zoneid, MRP_ZONE_MAX);
658 zonename = "<unknown>";
660 resources = audio->zones + zoneid;
661 grantid = ++(audio->grantids[zoneid]);
663 mrp_list_foreach_back(resources, rentry, rn) {
664 ar = mrp_list_entry(rentry, audio_resource_t, link);
666 MRP_ASSERT(ar->res, "confused with data structures");
668 if (ar->acquire && !ar->disable) {
669 if (!(appid = get_appid_for_resource(ar->res)))
672 mrp_debug("preallocate audio resource for '%s' in zone '%s'",
675 ar->grantid = grantid;
677 mrp_resmgr_notifier_queue_audio_event(audio->resmgr,
679 MRP_RESMGR_EVENTID_PREALLOCATE,
682 if (!mrp_resource_is_shared(ar->res))
688 static void audio_queue_events(mrp_resmgr_audio_t *audio, mrp_zone_t *zone)
691 const char *zonename;
693 mrp_list_hook_t *resources, *rentry, *rn;
694 audio_resource_t *ar;
696 mrp_resmgr_eventid_t eventid;
699 zoneid = mrp_zone_get_id(zone);
700 zonename = mrp_zone_get_name(zone);
702 /* We got a nonsense zone id */
703 if (zoneid >= MRP_ZONE_MAX) {
704 mrp_debug("invalid zoneid '%" PRIu32 "' is larger than MRP_ZONE_MAX (%d), "
705 "bailing", zoneid, MRP_ZONE_MAX);
709 resources = audio->zones + zoneid;
710 grantid = audio->grantids[zoneid];
712 mrp_list_foreach_back(resources, rentry, rn) {
713 ar = mrp_list_entry(rentry, audio_resource_t, link);
714 grant = (grantid == ar->grantid);
716 if ((grant && !ar->grant) || (!grant && ar->grant)) {
717 eventid = grant ? MRP_RESMGR_EVENTID_GRANT :
718 MRP_RESMGR_EVENTID_REVOKE;
719 appid = get_appid_for_resource(ar->res);
721 mrp_resmgr_notifier_queue_audio_event(audio->resmgr,
732 static uint32_t resource_key(audio_resource_t *ar)
743 stamp = 0; /* for now */
744 priority = get_priority_for_resource(ar->res);
745 classpri = get_class_priority_for_resource(ar->res);
746 acquire = ar->acquire ? 1 : 0;
747 share = mrp_resource_is_shared(ar->res) ? 1 : 0;
748 interrupt = ar->interrupt ? 1 : 0;
750 key = ((stamp & STAMP_MASK ) << STAMP_POSITION ) |
751 ((priority & PRIORITY_MASK ) << PRIORITY_POSITION ) |
752 ((classpri & CLASSPRI_MASK ) << CLASSPRI_POSITION ) |
753 ((acquire & ACQUIRE_MASK ) << ACQUIRE_POSITION ) |
754 ((share & SHARE_MASK ) << SHARE_POSITION ) |
755 ((interrupt & INTERRUPT_MASK) << INTERRUPT_POSITION) ;
761 static void audio_notify(mrp_resource_event_t event,
763 mrp_application_class_t *ac,
767 mrp_resmgr_audio_t *audio = (mrp_resmgr_audio_t *)userdata;
768 const char *zonename = mrp_zone_get_name(zone);
769 audio_resource_t *ar;
771 MRP_ASSERT(zone && ac && res && audio, "invalid argument");
775 case MRP_RESOURCE_EVENT_CREATED:
776 mrp_debug("audio resource in zone '%s' created", zonename);
777 audio_resource_create(audio, zone, res, ac);
780 case MRP_RESOURCE_EVENT_DESTROYED:
781 mrp_debug("audio resource in zone '%s' destroyed", zonename);
782 audio_resource_destroy(audio, zone, res);
785 case MRP_RESOURCE_EVENT_ACQUIRE:
786 mrp_debug("audio resource in zone '%s' is acquiring", zonename);
787 if (!(ar = audio_resource_lookup(audio, res)))
788 goto no_audio_resource;
792 ar->key = resource_key(ar);
793 audio_insert_resource(ar);
797 case MRP_RESOURCE_EVENT_RELEASE:
798 mrp_debug("audio resource in zone '%s' is released", zonename);
799 if (!(ar = audio_resource_lookup(audio, res)))
800 goto no_audio_resource;
804 ar->key = resource_key(ar);
805 audio_insert_resource(ar);
810 mrp_debug("resource lookup in hash table failed: key=%p", res);
811 mrp_log_error("system-controller: can't find audio resource "
812 "in zone '%s'", zonename);
816 mrp_log_error("system-controller: invalid event %d at audio "
817 "notification (zone '%s')", event, zonename);
822 static void audio_init(mrp_zone_t *zone, void *userdata)
824 mrp_resmgr_audio_t *audio = (mrp_resmgr_audio_t *)userdata;
826 const char *zonename;
828 MRP_ASSERT(zone && audio, "invalid argument");
830 zoneid = mrp_zone_get_id(zone);
831 zonename = mrp_zone_get_name(zone);
833 /* We got a nonsense zone id */
834 if (zoneid >= MRP_ZONE_MAX) {
835 mrp_debug("invalid zoneid '%" PRIu32 "' is larger than MRP_ZONE_MAX (%d), "
836 "bailing", zoneid, MRP_ZONE_MAX);
841 zonename = "<unknown>";
843 mrp_debug("audio init in zone '%s'", zonename);
845 mrp_resmgr_notifier_queue_audio_event(audio->resmgr, zoneid, zonename,
846 MRP_RESMGR_EVENTID_INIT,
848 audio_grant_resources(audio, zone);
850 mrp_resmgr_notifier_flush_audio_events(audio->resmgr, zoneid);
853 static bool audio_allocate(mrp_zone_t *zone,
857 mrp_resmgr_audio_t *audio = (mrp_resmgr_audio_t *)userdata;
859 const char *zonename;
861 audio_resource_t *ar;
865 MRP_ASSERT(zone && res && audio && audio->resmgr, "invalid argument");
867 zoneid = mrp_zone_get_id(zone);
869 /* We got a nonsense zone id */
870 if (zoneid >= MRP_ZONE_MAX) {
871 mrp_debug("invalid zoneid '%" PRIu32 "' is larger than MRP_ZONE_MAX (%d), "
872 "bailing", zoneid, MRP_ZONE_MAX);
876 grantid = audio->grantids[zoneid];
878 if (!(zonename = mrp_zone_get_name(zone)))
879 zonename = "<unknown>";
880 if (!(appid = get_appid_for_resource(res)))
883 if ((ar = audio_resource_lookup(audio, res))) {
884 allocated = (ar->grantid == grantid);
886 mrp_debug("audio allocation for '%s' in zone '%s' %s",
887 zonename, appid, allocated ? "succeeded":"failed");
892 mrp_log_error("system-controller: attempt to allocate untracked "
893 "resource '%s' in zone '%s'", appid, zonename);
898 static void audio_free(mrp_zone_t *zone, mrp_resource_t *res, void *userdata)
900 mrp_resmgr_audio_t *audio = (mrp_resmgr_audio_t *)userdata;
901 const char *zonename;
903 audio_resource_t *ar;
905 MRP_ASSERT(zone && res && audio, "invalid argument");
907 if (!(zonename = mrp_zone_get_name(zone)))
908 zonename = "<unknown>";
909 if (!(appid = get_appid_for_resource(res)))
912 mrp_debug("free audio of '%s' in zone '%s'", appid, zonename);
914 if ((ar = audio_resource_lookup(audio, res)))
918 static bool audio_advice(mrp_zone_t *zone,mrp_resource_t *res,void *userdata)
920 mrp_resmgr_audio_t *audio = (mrp_resmgr_audio_t *)userdata;
921 const char *zonename;
924 MRP_ASSERT(zone && res && audio, "invalid argument");
926 if (!(zonename = mrp_zone_get_name(zone)))
927 zonename = "<unknown>";
928 if (!(appid = get_appid_for_resource(res)))
931 mrp_debug("audio advice for '%s' in zone '%s'", appid, zonename);
936 static void audio_commit(mrp_zone_t *zone, void *userdata)
938 mrp_resmgr_audio_t *audio = (mrp_resmgr_audio_t *)userdata;
939 const char *zonename;
942 MRP_ASSERT(zone && audio && audio->resmgr, "invalid argument");
944 zoneid = mrp_zone_get_id(zone);
946 /* We got a nonsense zone id */
947 if (zoneid >= MRP_ZONE_MAX) {
948 mrp_debug("invalid zoneid '%" PRIu32 "' is larger than MRP_ZONE_MAX (%d), "
949 "bailing", zoneid, MRP_ZONE_MAX);
953 if (!(zonename = mrp_zone_get_name(zone)))
954 zonename = "<unknown>";
956 mrp_debug("audio commit in zone '%s'", zonename);
958 audio_queue_events(audio, zone);
959 mrp_resmgr_notifier_flush_audio_events(audio->resmgr, zoneid);