Home | History | Annotate | Download | only in mediaanalytics
      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_audiothread"
     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 
     40 bool statsd_audiothread(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::AudioThreadData metrics_proto;
     54 
     55 #define	MM_PREFIX "android.media.audiothread."
     56 
     57     // flesh out the protobuf we'll hand off with our data
     58     //
     59     char *mytype = NULL;
     60     if (item->getCString(MM_PREFIX "type", &mytype)) {
     61         metrics_proto.set_type(mytype);
     62     }
     63     int32_t framecount = -1;
     64     if (item->getInt32(MM_PREFIX "framecount", &framecount)) {
     65         metrics_proto.set_framecount(framecount);
     66     }
     67     int32_t samplerate = -1;
     68     if (item->getInt32(MM_PREFIX "samplerate", &samplerate)) {
     69         metrics_proto.set_samplerate(samplerate);
     70     }
     71     char *workhist = NULL;
     72     if (item->getCString(MM_PREFIX "workMs.hist", &workhist)) {
     73         metrics_proto.set_work_millis_hist(workhist);
     74     }
     75     char *latencyhist = NULL;
     76     if (item->getCString(MM_PREFIX "latencyMs.hist", &latencyhist)) {
     77         metrics_proto.set_latency_millis_hist(latencyhist);
     78     }
     79     char *warmuphist = NULL;
     80     if (item->getCString(MM_PREFIX "warmupMs.hist", &warmuphist)) {
     81         metrics_proto.set_warmup_millis_hist(warmuphist);
     82     }
     83     int64_t underruns = -1;
     84     if (item->getInt64(MM_PREFIX "underruns", &underruns)) {
     85         metrics_proto.set_underruns(underruns);
     86     }
     87     int64_t overruns = -1;
     88     if (item->getInt64(MM_PREFIX "overruns", &overruns)) {
     89         metrics_proto.set_overruns(overruns);
     90     }
     91     int64_t activeMs = -1;
     92     if (item->getInt64(MM_PREFIX "activeMs", &activeMs)) {
     93         metrics_proto.set_active_millis(activeMs);
     94     }
     95     int64_t durationMs = -1;
     96     if (item->getInt64(MM_PREFIX "durationMs", &durationMs)) {
     97         metrics_proto.set_duration_millis(durationMs);
     98     }
     99 
    100     // item->setInt32(MM_PREFIX "id", (int32_t)mId); // IO handle
    101     int32_t id = -1;
    102     if (item->getInt32(MM_PREFIX "id", &id)) {
    103         metrics_proto.set_id(id);
    104     }
    105     // item->setInt32(MM_PREFIX "portId", (int32_t)mPortId);
    106     int32_t port_id = -1;
    107     if (item->getInt32(MM_PREFIX "portId", &id)) {
    108         metrics_proto.set_port_id(port_id);
    109     }
    110     // item->setCString(MM_PREFIX "type", threadTypeToString(mType));
    111     char *type = NULL;
    112     if (item->getCString(MM_PREFIX "type", &type)) {
    113         metrics_proto.set_type(type);
    114     }
    115     // item->setInt32(MM_PREFIX "sampleRate", (int32_t)mSampleRate);
    116     int32_t sample_rate = -1;
    117     if (item->getInt32(MM_PREFIX "sampleRate", &sample_rate)) {
    118         metrics_proto.set_sample_rate(sample_rate);
    119     }
    120     // item->setInt64(MM_PREFIX "channelMask", (int64_t)mChannelMask);
    121     int32_t channel_mask = -1;
    122     if (item->getInt32(MM_PREFIX "channelMask", &channel_mask)) {
    123         metrics_proto.set_channel_mask(channel_mask);
    124     }
    125     // item->setCString(MM_PREFIX "encoding", toString(mFormat).c_str());
    126     char *encoding = NULL;
    127     if (item->getCString(MM_PREFIX "encoding", &encoding)) {
    128         metrics_proto.set_encoding(encoding);
    129     }
    130     // item->setInt32(MM_PREFIX "frameCount", (int32_t)mFrameCount);
    131     int32_t frame_count = -1;
    132     if (item->getInt32(MM_PREFIX "frameCount", &frame_count)) {
    133         metrics_proto.set_frame_count(frame_count);
    134     }
    135     // item->setCString(MM_PREFIX "outDevice", toString(mOutDevice).c_str());
    136     char *outDevice = NULL;
    137     if (item->getCString(MM_PREFIX "outDevice", &outDevice)) {
    138         metrics_proto.set_output_device(outDevice);
    139     }
    140     // item->setCString(MM_PREFIX "inDevice", toString(mInDevice).c_str());
    141     char *inDevice = NULL;
    142     if (item->getCString(MM_PREFIX "inDevice", &inDevice)) {
    143         metrics_proto.set_input_device(inDevice);
    144     }
    145     // item->setDouble(MM_PREFIX "ioJitterMs.mean", mIoJitterMs.getMean());
    146     double iojitters_ms_mean = -1;
    147     if (item->getDouble(MM_PREFIX "ioJitterMs.mean", &iojitters_ms_mean)) {
    148         metrics_proto.set_io_jitter_mean_millis(iojitters_ms_mean);
    149     }
    150     // item->setDouble(MM_PREFIX "ioJitterMs.std", mIoJitterMs.getStdDev());
    151     double iojitters_ms_std = -1;
    152     if (item->getDouble(MM_PREFIX "ioJitterMs.std", &iojitters_ms_std)) {
    153         metrics_proto.set_io_jitter_stddev_millis(iojitters_ms_std);
    154     }
    155     // item->setDouble(MM_PREFIX "processTimeMs.mean", mProcessTimeMs.getMean());
    156     double process_time_ms_mean = -1;
    157     if (item->getDouble(MM_PREFIX "processTimeMs.mean", &process_time_ms_mean)) {
    158         metrics_proto.set_process_time_mean_millis(process_time_ms_mean);
    159     }
    160     // item->setDouble(MM_PREFIX "processTimeMs.std", mProcessTimeMs.getStdDev());
    161     double process_time_ms_std = -1;
    162     if (item->getDouble(MM_PREFIX "processTimeMs.std", &process_time_ms_std)) {
    163         metrics_proto.set_process_time_stddev_millis(process_time_ms_std);
    164     }
    165     // item->setDouble(MM_PREFIX "timestampJitterMs.mean", tsjitter.getMean());
    166     double timestamp_jitter_ms_mean = -1;
    167     if (item->getDouble(MM_PREFIX "timestampJitterMs.mean", &timestamp_jitter_ms_mean)) {
    168         metrics_proto.set_timestamp_jitter_mean_millis(timestamp_jitter_ms_mean);
    169     }
    170     // item->setDouble(MM_PREFIX "timestampJitterMs.std", tsjitter.getStdDev());
    171     double timestamp_jitter_ms_stddev = -1;
    172     if (item->getDouble(MM_PREFIX "timestampJitterMs.std", &timestamp_jitter_ms_stddev)) {
    173         metrics_proto.set_timestamp_jitter_stddev_millis(timestamp_jitter_ms_stddev);
    174     }
    175     // item->setDouble(MM_PREFIX "latencyMs.mean", mLatencyMs.getMean());
    176     double latency_ms_mean = -1;
    177     if (item->getDouble(MM_PREFIX "latencyMs.mean", &latency_ms_mean)) {
    178         metrics_proto.set_latency_mean_millis(latency_ms_mean);
    179     }
    180     // item->setDouble(MM_PREFIX "latencyMs.std", mLatencyMs.getStdDev());
    181     double latency_ms_stddev = -1;
    182     if (item->getDouble(MM_PREFIX "latencyMs.std", &latency_ms_stddev)) {
    183         metrics_proto.set_latency_stddev_millis(latency_ms_stddev);
    184     }
    185 
    186 
    187     std::string serialized;
    188     if (!metrics_proto.SerializeToString(&serialized)) {
    189         ALOGE("Failed to serialize audiothread metrics");
    190         return false;
    191     }
    192 
    193     if (enabled_statsd) {
    194         android::util::BytesField bf_serialized( serialized.c_str(), serialized.size());
    195         (void)android::util::stats_write(android::util::MEDIAMETRICS_AUDIOTHREAD_REPORTED,
    196                                    timestamp, pkgName.c_str(), pkgVersionCode,
    197                                    mediaApexVersion,
    198                                    bf_serialized);
    199 
    200     } else {
    201         ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
    202     }
    203 
    204     // must free the strings that we were given
    205     free(mytype);
    206     free(workhist);
    207     free(latencyhist);
    208     free(warmuphist);
    209     free(type);
    210     free(encoding);
    211     free(inDevice);
    212     free(outDevice);
    213 
    214     return true;
    215 }
    216 
    217 };
    218