blob: 3a8a9c1f803586264028ddd234040a9cf14961d4 [file] [log] [blame]
Chris Waddellca0dd182022-11-25 17:15:30 +00001#define LOG_TAG "UsecaseValidator"
2// #define LOG_NDEBUG 0
3
4#include <inttypes.h>
5
6#include <utils/Log.h>
7
8#include "media/UsecaseValidator.h"
9#include "media/UsecaseLookup.h"
10
11namespace android {
12namespace media {
13namespace {
14
15class UsecaseValidatorImpl : public UsecaseValidator {
16 public:
17 UsecaseValidatorImpl() {}
18
19 /**
20 * Register a new mixer/stream.
21 * Called when the stream is opened at the HAL and communicates
22 * immutable stream attributes like flags, sampling rate, format.
23 */
24 status_t registerStream(audio_io_handle_t streamId,
25 const audio_config_base_t& audioConfig __attribute__((unused)),
26 const audio_output_flags_t outputFlags) override {
27 ALOGV("%s output: %d flags: %#x", __func__, streamId, outputFlags);
28
29 // Check if FAST or MMAP output flag has been set.
30 bool outputFlagGame = outputFlags & (AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_MMAP_NOIRQ);
31 m_lookup.addStream(streamId, outputFlagGame);
32 return OK;
33 };
34
35 /**
36 * Unregister a stream/mixer.
37 * Called when the stream is closed.
38 */
39 status_t unregisterStream(audio_io_handle_t streamId) override {
40 ALOGV("%s output: %d", __func__, streamId);
41
42 m_lookup.removeStream(streamId);
43 return OK;
44 };
45
46 /**
47 * Indicates that some playback activity started on the stream.
48 * Called each time an audio track starts or resumes.
49 */
50 error::Result<audio_attributes_t> startClient(audio_io_handle_t streamId,
51 audio_port_handle_t portId, const content::AttributionSourceState& attributionSource,
52 const audio_attributes_t& attributes,
53 const AttributesChangedCallback *callback __attribute__((unused))) override {
54 ALOGV("%s output: %d portId: %d usage: %d pid: %d package: %s",
55 __func__, streamId, portId, attributes.usage, attributionSource.pid,
56 attributionSource.packageName.value_or("").c_str());
57
58 m_lookup.addTrack(streamId, portId);
59
60 return verifyAudioAttributes(streamId, attributionSource, attributes);
61 };
62
63 /**
64 * Indicates that some playback activity stopped on the stream.
65 * Called each time an audio track stops or pauses.
66 */
67 status_t stopClient(audio_io_handle_t streamId, audio_port_handle_t portId) override {
68 ALOGV("%s output: %d portId: %d", __func__, streamId, portId);
69
70 m_lookup.removeTrack(streamId, portId);
71 return OK;
72 };
73
74 /**
75 * Called to verify and update audio attributes for a track that is connected
76 * to the specified stream.
77 */
78 error::Result<audio_attributes_t> verifyAudioAttributes(audio_io_handle_t streamId,
79 const content::AttributionSourceState& attributionSource,
80 const audio_attributes_t& attributes) override {
81 ALOGV("%s output: %d usage: %d pid: %d package: %s",
82 __func__, streamId, attributes.usage, attributionSource.pid,
83 attributionSource.packageName.value_or("").c_str());
84
85 audio_attributes_t attrRet = attributes;
86
87 // Check if attribute usage media or unknown has been set.
88 bool isUsageValid = this->isUsageValid(attributes);
89
90 if (isUsageValid && m_lookup.isGameStream(streamId)) {
91 ALOGI("%s update usage: %d to AUDIO_USAGE_GAME for output: %d pid: %d package: %s",
92 __func__, attributes.usage, streamId, attributionSource.pid,
93 attributionSource.packageName.value_or("").c_str());
94 // Set attribute usage Game.
95 attrRet.usage = AUDIO_USAGE_GAME;
96 }
97
98 return {attrRet};
99 };
100
101 protected:
102 /**
103 * Check if attribute usage valid.
104 */
105 bool isUsageValid(const audio_attributes_t& attr) {
106 ALOGV("isUsageValid attr.usage: %d", attr.usage);
107 switch (attr.usage) {
108 case AUDIO_USAGE_MEDIA:
109 case AUDIO_USAGE_UNKNOWN:
110 return true;
111 default:
112 break;
113 }
114 return false;
115 }
116
117 protected:
118 UsecaseLookup m_lookup;
119};
120
121} // namespace
122
123std::unique_ptr<UsecaseValidator> createUsecaseValidator() {
124 return std::make_unique<UsecaseValidatorImpl>();
125}
126
127} // namespace media
128} // namespace android