1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker *
4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker *
8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker *
10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker */
16*ec779b8eSAndroid Build Coastguard Worker
17*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
18*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "statsd_audiotrack"
19*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
20*ec779b8eSAndroid Build Coastguard Worker
21*ec779b8eSAndroid Build Coastguard Worker #include <dirent.h>
22*ec779b8eSAndroid Build Coastguard Worker #include <inttypes.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <pthread.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <pwd.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <stdint.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <string.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <sys/stat.h>
28*ec779b8eSAndroid Build Coastguard Worker #include <sys/time.h>
29*ec779b8eSAndroid Build Coastguard Worker #include <sys/types.h>
30*ec779b8eSAndroid Build Coastguard Worker #include <unistd.h>
31*ec779b8eSAndroid Build Coastguard Worker
32*ec779b8eSAndroid Build Coastguard Worker #include <stats_media_metrics.h>
33*ec779b8eSAndroid Build Coastguard Worker
34*ec779b8eSAndroid Build Coastguard Worker #include "MediaMetricsService.h"
35*ec779b8eSAndroid Build Coastguard Worker #include "ValidateId.h"
36*ec779b8eSAndroid Build Coastguard Worker #include "frameworks/proto_logging/stats/message/mediametrics_message.pb.h"
37*ec779b8eSAndroid Build Coastguard Worker #include "iface_statsd.h"
38*ec779b8eSAndroid Build Coastguard Worker
39*ec779b8eSAndroid Build Coastguard Worker namespace android {
40*ec779b8eSAndroid Build Coastguard Worker
statsd_audiotrack(const std::shared_ptr<const mediametrics::Item> & item,const std::shared_ptr<mediametrics::StatsdLog> & statsdLog)41*ec779b8eSAndroid Build Coastguard Worker bool statsd_audiotrack(const std::shared_ptr<const mediametrics::Item>& item,
42*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr<mediametrics::StatsdLog>& statsdLog)
43*ec779b8eSAndroid Build Coastguard Worker {
44*ec779b8eSAndroid Build Coastguard Worker if (item == nullptr) return false;
45*ec779b8eSAndroid Build Coastguard Worker
46*ec779b8eSAndroid Build Coastguard Worker // these go into the statsd wrapper
47*ec779b8eSAndroid Build Coastguard Worker const nsecs_t timestamp_nanos = MediaMetricsService::roundTime(item->getTimestamp());
48*ec779b8eSAndroid Build Coastguard Worker const std::string package_name = item->getPkgName();
49*ec779b8eSAndroid Build Coastguard Worker const int64_t package_version_code = item->getPkgVersionCode();
50*ec779b8eSAndroid Build Coastguard Worker const int64_t media_apex_version = 0;
51*ec779b8eSAndroid Build Coastguard Worker
52*ec779b8eSAndroid Build Coastguard Worker // the rest into our own proto
53*ec779b8eSAndroid Build Coastguard Worker //
54*ec779b8eSAndroid Build Coastguard Worker ::android::stats::mediametrics_message::AudioTrackData metrics_proto;
55*ec779b8eSAndroid Build Coastguard Worker
56*ec779b8eSAndroid Build Coastguard Worker // flesh out the protobuf we'll hand off with our data
57*ec779b8eSAndroid Build Coastguard Worker //
58*ec779b8eSAndroid Build Coastguard Worker
59*ec779b8eSAndroid Build Coastguard Worker // Do not change this without changing AudioTrack.cpp collection.
60*ec779b8eSAndroid Build Coastguard Worker
61*ec779b8eSAndroid Build Coastguard Worker // optional string streamType;
62*ec779b8eSAndroid Build Coastguard Worker std::string stream_type;
63*ec779b8eSAndroid Build Coastguard Worker if (item->getString("android.media.audiotrack.streamtype", &stream_type)) {
64*ec779b8eSAndroid Build Coastguard Worker metrics_proto.set_stream_type(stream_type);
65*ec779b8eSAndroid Build Coastguard Worker }
66*ec779b8eSAndroid Build Coastguard Worker
67*ec779b8eSAndroid Build Coastguard Worker // optional string contentType;
68*ec779b8eSAndroid Build Coastguard Worker std::string content_type;
69*ec779b8eSAndroid Build Coastguard Worker if (item->getString("android.media.audiotrack.type", &content_type)) {
70*ec779b8eSAndroid Build Coastguard Worker metrics_proto.set_content_type(content_type);
71*ec779b8eSAndroid Build Coastguard Worker }
72*ec779b8eSAndroid Build Coastguard Worker
73*ec779b8eSAndroid Build Coastguard Worker // optional string trackUsage;
74*ec779b8eSAndroid Build Coastguard Worker std::string track_usage;
75*ec779b8eSAndroid Build Coastguard Worker if (item->getString("android.media.audiotrack.usage", &track_usage)) {
76*ec779b8eSAndroid Build Coastguard Worker metrics_proto.set_track_usage(track_usage);
77*ec779b8eSAndroid Build Coastguard Worker }
78*ec779b8eSAndroid Build Coastguard Worker
79*ec779b8eSAndroid Build Coastguard Worker // optional int32 sampleRate;
80*ec779b8eSAndroid Build Coastguard Worker int32_t sample_rate = -1;
81*ec779b8eSAndroid Build Coastguard Worker if (item->getInt32("android.media.audiotrack.sampleRate", &sample_rate)) {
82*ec779b8eSAndroid Build Coastguard Worker metrics_proto.set_sample_rate(sample_rate);
83*ec779b8eSAndroid Build Coastguard Worker }
84*ec779b8eSAndroid Build Coastguard Worker
85*ec779b8eSAndroid Build Coastguard Worker // optional int64 channelMask;
86*ec779b8eSAndroid Build Coastguard Worker int64_t channel_mask = -1;
87*ec779b8eSAndroid Build Coastguard Worker if (item->getInt64("android.media.audiotrack.channelMask", &channel_mask)) {
88*ec779b8eSAndroid Build Coastguard Worker metrics_proto.set_channel_mask(channel_mask);
89*ec779b8eSAndroid Build Coastguard Worker }
90*ec779b8eSAndroid Build Coastguard Worker
91*ec779b8eSAndroid Build Coastguard Worker // optional int32 underrunFrames;
92*ec779b8eSAndroid Build Coastguard Worker int32_t underrun_frames = -1;
93*ec779b8eSAndroid Build Coastguard Worker if (item->getInt32("android.media.audiotrack.underrunFrames", &underrun_frames)) {
94*ec779b8eSAndroid Build Coastguard Worker metrics_proto.set_underrun_frames(underrun_frames);
95*ec779b8eSAndroid Build Coastguard Worker }
96*ec779b8eSAndroid Build Coastguard Worker
97*ec779b8eSAndroid Build Coastguard Worker // optional int32 glitch.startup;
98*ec779b8eSAndroid Build Coastguard Worker int32_t startup_glitch = -1;
99*ec779b8eSAndroid Build Coastguard Worker // Not currently sent from client.
100*ec779b8eSAndroid Build Coastguard Worker if (item->getInt32("android.media.audiotrack.glitch.startup", &startup_glitch)) {
101*ec779b8eSAndroid Build Coastguard Worker metrics_proto.set_startup_glitch(startup_glitch);
102*ec779b8eSAndroid Build Coastguard Worker }
103*ec779b8eSAndroid Build Coastguard Worker
104*ec779b8eSAndroid Build Coastguard Worker // portId (int32)
105*ec779b8eSAndroid Build Coastguard Worker int32_t port_id = -1;
106*ec779b8eSAndroid Build Coastguard Worker if (item->getInt32("android.media.audiotrack.portId", &port_id)) {
107*ec779b8eSAndroid Build Coastguard Worker metrics_proto.set_port_id(port_id);
108*ec779b8eSAndroid Build Coastguard Worker }
109*ec779b8eSAndroid Build Coastguard Worker // encoding (string)
110*ec779b8eSAndroid Build Coastguard Worker std::string encoding;
111*ec779b8eSAndroid Build Coastguard Worker if (item->getString("android.media.audiotrack.encoding", &encoding)) {
112*ec779b8eSAndroid Build Coastguard Worker metrics_proto.set_encoding(encoding);
113*ec779b8eSAndroid Build Coastguard Worker }
114*ec779b8eSAndroid Build Coastguard Worker // frameCount (int32)
115*ec779b8eSAndroid Build Coastguard Worker int32_t frame_count = -1;
116*ec779b8eSAndroid Build Coastguard Worker if (item->getInt32("android.media.audiotrack.frameCount", &frame_count)) {
117*ec779b8eSAndroid Build Coastguard Worker metrics_proto.set_frame_count(frame_count);
118*ec779b8eSAndroid Build Coastguard Worker }
119*ec779b8eSAndroid Build Coastguard Worker // attributes (string)
120*ec779b8eSAndroid Build Coastguard Worker std::string attributes;
121*ec779b8eSAndroid Build Coastguard Worker if (item->getString("android.media.audiotrack.attributes", &attributes)) {
122*ec779b8eSAndroid Build Coastguard Worker metrics_proto.set_attributes(attributes);
123*ec779b8eSAndroid Build Coastguard Worker }
124*ec779b8eSAndroid Build Coastguard Worker
125*ec779b8eSAndroid Build Coastguard Worker std::string serialized;
126*ec779b8eSAndroid Build Coastguard Worker if (!metrics_proto.SerializeToString(&serialized)) {
127*ec779b8eSAndroid Build Coastguard Worker ALOGE("Failed to serialize audiotrack metrics");
128*ec779b8eSAndroid Build Coastguard Worker return false;
129*ec779b8eSAndroid Build Coastguard Worker }
130*ec779b8eSAndroid Build Coastguard Worker
131*ec779b8eSAndroid Build Coastguard Worker // Android S
132*ec779b8eSAndroid Build Coastguard Worker // log_session_id (string)
133*ec779b8eSAndroid Build Coastguard Worker std::string logSessionId;
134*ec779b8eSAndroid Build Coastguard Worker (void)item->getString("android.media.audiotrack.logSessionId", &logSessionId);
135*ec779b8eSAndroid Build Coastguard Worker const auto log_session_id = mediametrics::ValidateId::get()->validateId(logSessionId);
136*ec779b8eSAndroid Build Coastguard Worker
137*ec779b8eSAndroid Build Coastguard Worker const stats::media_metrics::BytesField bf_serialized( serialized.c_str(), serialized.size());
138*ec779b8eSAndroid Build Coastguard Worker const int result = stats::media_metrics::stats_write(
139*ec779b8eSAndroid Build Coastguard Worker stats::media_metrics::MEDIAMETRICS_AUDIOTRACK_REPORTED,
140*ec779b8eSAndroid Build Coastguard Worker timestamp_nanos, package_name.c_str(), package_version_code,
141*ec779b8eSAndroid Build Coastguard Worker media_apex_version,
142*ec779b8eSAndroid Build Coastguard Worker bf_serialized,
143*ec779b8eSAndroid Build Coastguard Worker log_session_id.c_str());
144*ec779b8eSAndroid Build Coastguard Worker std::stringstream log;
145*ec779b8eSAndroid Build Coastguard Worker log << "result:" << result << " {"
146*ec779b8eSAndroid Build Coastguard Worker << " mediametrics_audiotrack_reported:"
147*ec779b8eSAndroid Build Coastguard Worker << stats::media_metrics::MEDIAMETRICS_AUDIOTRACK_REPORTED
148*ec779b8eSAndroid Build Coastguard Worker << " timestamp_nanos:" << timestamp_nanos
149*ec779b8eSAndroid Build Coastguard Worker << " package_name:" << package_name
150*ec779b8eSAndroid Build Coastguard Worker << " package_version_code:" << package_version_code
151*ec779b8eSAndroid Build Coastguard Worker << " media_apex_version:" << media_apex_version
152*ec779b8eSAndroid Build Coastguard Worker
153*ec779b8eSAndroid Build Coastguard Worker << " stream_type:" << stream_type
154*ec779b8eSAndroid Build Coastguard Worker << " content_type:" << content_type
155*ec779b8eSAndroid Build Coastguard Worker << " track_usage:" << track_usage
156*ec779b8eSAndroid Build Coastguard Worker << " sample_rate:" << sample_rate
157*ec779b8eSAndroid Build Coastguard Worker << " channel_mask:" << channel_mask
158*ec779b8eSAndroid Build Coastguard Worker << " underrun_frames:" << underrun_frames
159*ec779b8eSAndroid Build Coastguard Worker << " startup_glitch:" << startup_glitch
160*ec779b8eSAndroid Build Coastguard Worker << " port_id:" << port_id
161*ec779b8eSAndroid Build Coastguard Worker << " encoding:" << encoding
162*ec779b8eSAndroid Build Coastguard Worker << " frame_count:" << frame_count
163*ec779b8eSAndroid Build Coastguard Worker
164*ec779b8eSAndroid Build Coastguard Worker << " attributes:" << attributes
165*ec779b8eSAndroid Build Coastguard Worker
166*ec779b8eSAndroid Build Coastguard Worker << " log_session_id:" << log_session_id
167*ec779b8eSAndroid Build Coastguard Worker << " }";
168*ec779b8eSAndroid Build Coastguard Worker statsdLog->log(stats::media_metrics::MEDIAMETRICS_AUDIOTRACK_REPORTED, log.str());
169*ec779b8eSAndroid Build Coastguard Worker return true;
170*ec779b8eSAndroid Build Coastguard Worker }
171*ec779b8eSAndroid Build Coastguard Worker
172*ec779b8eSAndroid Build Coastguard Worker } // namespace android
173