1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "statsd_audiotrack"
19 #include <utils/Log.h>
20 
21 #include <dirent.h>
22 #include <inttypes.h>
23 #include <pthread.h>
24 #include <pwd.h>
25 #include <stdint.h>
26 #include <string.h>
27 #include <sys/stat.h>
28 #include <sys/time.h>
29 #include <sys/types.h>
30 #include <unistd.h>
31 
32 #include <statslog.h>
33 
34 #include "MediaAnalyticsService.h"
35 #include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
36 #include "iface_statsd.h"
37 
38 namespace android {
39 
statsd_audiotrack(MediaAnalyticsItem * item)40 bool statsd_audiotrack(MediaAnalyticsItem *item)
41 {
42     if (item == NULL) return false;
43 
44     // these go into the statsd wrapper
45     nsecs_t timestamp = item->getTimestamp();
46     std::string pkgName = item->getPkgName();
47     int64_t pkgVersionCode = item->getPkgVersionCode();
48     int64_t mediaApexVersion = 0;
49 
50 
51     // the rest into our own proto
52     //
53     ::android::stats::mediametrics::AudioTrackData metrics_proto;
54 
55     // flesh out the protobuf we'll hand off with our data
56     //
57 
58     // static constexpr char kAudioTrackStreamType[] = "android.media.audiotrack.streamtype";
59     // optional string streamType;
60     std::string streamtype;
61     if (item->getString("android.media.audiotrack.streamtype", &streamtype)) {
62         metrics_proto.set_stream_type(std::move(streamtype));
63     }
64 
65     // static constexpr char kAudioTrackContentType[] = "android.media.audiotrack.type";
66     // optional string contentType;
67     std::string contenttype;
68     if (item->getString("android.media.audiotrack.type", &contenttype)) {
69         metrics_proto.set_content_type(std::move(contenttype));
70     }
71 
72     // static constexpr char kAudioTrackUsage[] = "android.media.audiotrack.usage";
73     // optional string trackUsage;
74     std::string trackusage;
75     if (item->getString("android.media.audiotrack.usage", &trackusage)) {
76         metrics_proto.set_track_usage(std::move(trackusage));
77     }
78 
79     // static constexpr char kAudioTrackSampleRate[] = "android.media.audiotrack.samplerate";
80     // optional int32 samplerate;
81     int32_t samplerate = -1;
82     if (item->getInt32("android.media.audiotrack.samplerate", &samplerate)) {
83         metrics_proto.set_sample_rate(samplerate);
84     }
85 
86     // static constexpr char kAudioTrackChannelMask[] = "android.media.audiotrack.channelmask";
87     // optional int64 channelMask;
88     int64_t channelMask = -1;
89     if (item->getInt64("android.media.audiotrack.channelmask", &channelMask)) {
90         metrics_proto.set_channel_mask(channelMask);
91     }
92 
93     // NB: These are not yet exposed as public Java API constants.
94     // static constexpr char kAudioTrackUnderrunFrames[] = "android.media.audiotrack.underrunframes";
95     // optional int32 underrunframes;
96     int32_t underrunframes = -1;
97     if (item->getInt32("android.media.audiotrack.underrunframes", &underrunframes)) {
98         metrics_proto.set_underrun_frames(underrunframes);
99     }
100 
101     // static constexpr char kAudioTrackStartupGlitch[] = "android.media.audiotrack.glitch.startup";
102     // optional int32 startupglitch;
103     int32_t startupglitch = -1;
104     if (item->getInt32("android.media.audiotrack.glitch.startup", &startupglitch)) {
105         metrics_proto.set_startup_glitch(startupglitch);
106     }
107 
108     // portId (int32)
109     int32_t port_id = -1;
110     if (item->getInt32("android.media.audiotrack.portId", &port_id)) {
111         metrics_proto.set_port_id(port_id);
112     }
113     // encoding (string)
114     std::string encoding;
115     if (item->getString("android.media.audiotrack.encoding", &encoding)) {
116         metrics_proto.set_encoding(std::move(encoding));
117     }
118     // frameCount (int32)
119     int32_t frame_count = -1;
120     if (item->getInt32("android.media.audiotrack.frameCount", &frame_count)) {
121         metrics_proto.set_frame_count(frame_count);
122     }
123     // attributes (string)
124     std::string attributes;
125     if (item->getString("android.media.audiotrack.attributes", &attributes)) {
126         metrics_proto.set_attributes(std::move(attributes));
127     }
128 
129     std::string serialized;
130     if (!metrics_proto.SerializeToString(&serialized)) {
131         ALOGE("Failed to serialize audiotrack metrics");
132         return false;
133     }
134 
135     if (enabled_statsd) {
136         android::util::BytesField bf_serialized( serialized.c_str(), serialized.size());
137         (void)android::util::stats_write(android::util::MEDIAMETRICS_AUDIOTRACK_REPORTED,
138                                    timestamp, pkgName.c_str(), pkgVersionCode,
139                                    mediaApexVersion,
140                                    bf_serialized);
141 
142     } else {
143         ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
144     }
145 
146     return true;
147 }
148 
149 };
150