1*ec779b8eSAndroid Build Coastguard Worker /* 2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2020 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 #pragma once 18*ec779b8eSAndroid Build Coastguard Worker 19*ec779b8eSAndroid Build Coastguard Worker #include <binder/IActivityManager.h> 20*ec779b8eSAndroid Build Coastguard Worker #include <binder/IPCThreadState.h> 21*ec779b8eSAndroid Build Coastguard Worker #include <binder/IServiceManager.h> 22*ec779b8eSAndroid Build Coastguard Worker #include <media/MediaMetricsItem.h> 23*ec779b8eSAndroid Build Coastguard Worker 24*ec779b8eSAndroid Build Coastguard Worker #include <mutex> 25*ec779b8eSAndroid Build Coastguard Worker 26*ec779b8eSAndroid Build Coastguard Worker namespace android { 27*ec779b8eSAndroid Build Coastguard Worker 28*ec779b8eSAndroid Build Coastguard Worker /** 29*ec779b8eSAndroid Build Coastguard Worker * TrackMetrics handles the AudioFlinger track metrics. 30*ec779b8eSAndroid Build Coastguard Worker * 31*ec779b8eSAndroid Build Coastguard Worker * We aggregate metrics for a particular device for proper analysis. 32*ec779b8eSAndroid Build Coastguard Worker * This includes power, performance, and usage metrics. 33*ec779b8eSAndroid Build Coastguard Worker * 34*ec779b8eSAndroid Build Coastguard Worker * This class is thread-safe with a lock for safety. There is no risk of deadlock 35*ec779b8eSAndroid Build Coastguard Worker * as this class only executes external one-way calls in Mediametrics and does not 36*ec779b8eSAndroid Build Coastguard Worker * call any other AudioFlinger class. 37*ec779b8eSAndroid Build Coastguard Worker * 38*ec779b8eSAndroid Build Coastguard Worker * Terminology: 39*ec779b8eSAndroid Build Coastguard Worker * An AudioInterval is a contiguous playback segment. 40*ec779b8eSAndroid Build Coastguard Worker * An AudioIntervalGroup is a group of continuous playback segments on the same device. 41*ec779b8eSAndroid Build Coastguard Worker * 42*ec779b8eSAndroid Build Coastguard Worker * We currently deliver metrics based on an AudioIntervalGroup. 43*ec779b8eSAndroid Build Coastguard Worker */ 44*ec779b8eSAndroid Build Coastguard Worker class TrackMetrics final { 45*ec779b8eSAndroid Build Coastguard Worker 46*ec779b8eSAndroid Build Coastguard Worker 47*ec779b8eSAndroid Build Coastguard Worker public: TrackMetrics(std::string metricsId,bool isOut,int clientUid)48*ec779b8eSAndroid Build Coastguard Worker TrackMetrics(std::string metricsId, bool isOut, int clientUid) 49*ec779b8eSAndroid Build Coastguard Worker : mMetricsId(std::move(metricsId)) 50*ec779b8eSAndroid Build Coastguard Worker , mIsOut(isOut) 51*ec779b8eSAndroid Build Coastguard Worker , mUid(clientUid) 52*ec779b8eSAndroid Build Coastguard Worker {} // we don't log a constructor item, we wait for more info in logConstructor(). 53*ec779b8eSAndroid Build Coastguard Worker ~TrackMetrics()54*ec779b8eSAndroid Build Coastguard Worker ~TrackMetrics() { 55*ec779b8eSAndroid Build Coastguard Worker logEndInterval(); 56*ec779b8eSAndroid Build Coastguard Worker std::lock_guard l(mLock); 57*ec779b8eSAndroid Build Coastguard Worker deliverCumulativeMetrics(AMEDIAMETRICS_PROP_EVENT_VALUE_ENDAUDIOINTERVALGROUP); 58*ec779b8eSAndroid Build Coastguard Worker // we don't log a destructor item here. 59*ec779b8eSAndroid Build Coastguard Worker } 60*ec779b8eSAndroid Build Coastguard Worker 61*ec779b8eSAndroid Build Coastguard Worker // Called under the following circumstances 62*ec779b8eSAndroid Build Coastguard Worker // 1) when we are added to the Thread 63*ec779b8eSAndroid Build Coastguard Worker // 2) when we have a createPatch in the Thread. logBeginInterval(const std::string & devices)64*ec779b8eSAndroid Build Coastguard Worker void logBeginInterval(const std::string& devices) { 65*ec779b8eSAndroid Build Coastguard Worker std::lock_guard l(mLock); 66*ec779b8eSAndroid Build Coastguard Worker if (mDevices != devices) { 67*ec779b8eSAndroid Build Coastguard Worker deliverCumulativeMetrics(AMEDIAMETRICS_PROP_EVENT_VALUE_ENDAUDIOINTERVALGROUP); 68*ec779b8eSAndroid Build Coastguard Worker mDevices = devices; 69*ec779b8eSAndroid Build Coastguard Worker resetIntervalGroupMetrics(); 70*ec779b8eSAndroid Build Coastguard Worker deliverDeviceMetrics( 71*ec779b8eSAndroid Build Coastguard Worker AMEDIAMETRICS_PROP_EVENT_VALUE_BEGINAUDIOINTERVALGROUP, devices.c_str()); 72*ec779b8eSAndroid Build Coastguard Worker } 73*ec779b8eSAndroid Build Coastguard Worker ++mIntervalCount; 74*ec779b8eSAndroid Build Coastguard Worker const auto& mActivityManager = getActivityManager(); 75*ec779b8eSAndroid Build Coastguard Worker if (mActivityManager) { 76*ec779b8eSAndroid Build Coastguard Worker if (mIsOut) { 77*ec779b8eSAndroid Build Coastguard Worker mActivityManager->logFgsApiBegin(AUDIO_API, 78*ec779b8eSAndroid Build Coastguard Worker mUid, 79*ec779b8eSAndroid Build Coastguard Worker IPCThreadState::self() -> getCallingPid()); 80*ec779b8eSAndroid Build Coastguard Worker } else { 81*ec779b8eSAndroid Build Coastguard Worker mActivityManager->logFgsApiBegin(MICROPHONE_API, 82*ec779b8eSAndroid Build Coastguard Worker mUid, 83*ec779b8eSAndroid Build Coastguard Worker IPCThreadState::self() -> getCallingPid()); 84*ec779b8eSAndroid Build Coastguard Worker } 85*ec779b8eSAndroid Build Coastguard Worker } 86*ec779b8eSAndroid Build Coastguard Worker } 87*ec779b8eSAndroid Build Coastguard Worker 88*ec779b8eSAndroid Build Coastguard Worker void logConstructor(pid_t creatorPid, uid_t creatorUid, int32_t internalTrackId, 89*ec779b8eSAndroid Build Coastguard Worker const std::string& traits = {}, 90*ec779b8eSAndroid Build Coastguard Worker audio_stream_type_t streamType = AUDIO_STREAM_DEFAULT) const { 91*ec779b8eSAndroid Build Coastguard Worker // Once this item is logged by the server, the client can add properties. 92*ec779b8eSAndroid Build Coastguard Worker // no lock required, all local or const variables. 93*ec779b8eSAndroid Build Coastguard Worker mediametrics::LogItem item(mMetricsId); 94*ec779b8eSAndroid Build Coastguard Worker item.setPid(creatorPid) 95*ec779b8eSAndroid Build Coastguard Worker .setUid(creatorUid) 96*ec779b8eSAndroid Build Coastguard Worker .set(AMEDIAMETRICS_PROP_ALLOWUID, (int32_t)creatorUid) 97*ec779b8eSAndroid Build Coastguard Worker .set(AMEDIAMETRICS_PROP_EVENT, 98*ec779b8eSAndroid Build Coastguard Worker AMEDIAMETRICS_PROP_PREFIX_SERVER AMEDIAMETRICS_PROP_EVENT_VALUE_CTOR) 99*ec779b8eSAndroid Build Coastguard Worker .set(AMEDIAMETRICS_PROP_INTERNALTRACKID, internalTrackId) 100*ec779b8eSAndroid Build Coastguard Worker .set(AMEDIAMETRICS_PROP_TRAITS, traits); 101*ec779b8eSAndroid Build Coastguard Worker // log streamType from the service, since client doesn't know chosen streamType. 102*ec779b8eSAndroid Build Coastguard Worker if (streamType != AUDIO_STREAM_DEFAULT) { 103*ec779b8eSAndroid Build Coastguard Worker item.set(AMEDIAMETRICS_PROP_STREAMTYPE, toString(streamType).c_str()); 104*ec779b8eSAndroid Build Coastguard Worker } 105*ec779b8eSAndroid Build Coastguard Worker item.record(); 106*ec779b8eSAndroid Build Coastguard Worker } 107*ec779b8eSAndroid Build Coastguard Worker 108*ec779b8eSAndroid Build Coastguard Worker // Called when we are removed from the Thread. logEndInterval()109*ec779b8eSAndroid Build Coastguard Worker void logEndInterval() { 110*ec779b8eSAndroid Build Coastguard Worker std::lock_guard l(mLock); 111*ec779b8eSAndroid Build Coastguard Worker if (mLastVolumeChangeTimeNs != 0) { 112*ec779b8eSAndroid Build Coastguard Worker logVolume_l(mVolume); // flush out the last volume. 113*ec779b8eSAndroid Build Coastguard Worker mLastVolumeChangeTimeNs = 0; 114*ec779b8eSAndroid Build Coastguard Worker } 115*ec779b8eSAndroid Build Coastguard Worker const auto& mActivityManager = getActivityManager(); 116*ec779b8eSAndroid Build Coastguard Worker if (mActivityManager) { 117*ec779b8eSAndroid Build Coastguard Worker if (mIsOut) { 118*ec779b8eSAndroid Build Coastguard Worker mActivityManager->logFgsApiEnd(AUDIO_API, 119*ec779b8eSAndroid Build Coastguard Worker mUid, 120*ec779b8eSAndroid Build Coastguard Worker IPCThreadState::self() -> getCallingPid()); 121*ec779b8eSAndroid Build Coastguard Worker } else { 122*ec779b8eSAndroid Build Coastguard Worker mActivityManager->logFgsApiEnd(MICROPHONE_API, 123*ec779b8eSAndroid Build Coastguard Worker mUid, 124*ec779b8eSAndroid Build Coastguard Worker IPCThreadState::self() -> getCallingPid()); 125*ec779b8eSAndroid Build Coastguard Worker } 126*ec779b8eSAndroid Build Coastguard Worker } 127*ec779b8eSAndroid Build Coastguard Worker } 128*ec779b8eSAndroid Build Coastguard Worker logInvalidate()129*ec779b8eSAndroid Build Coastguard Worker void logInvalidate() const { 130*ec779b8eSAndroid Build Coastguard Worker // no lock required, all local or const variables. 131*ec779b8eSAndroid Build Coastguard Worker mediametrics::LogItem(mMetricsId) 132*ec779b8eSAndroid Build Coastguard Worker .set(AMEDIAMETRICS_PROP_EVENT, 133*ec779b8eSAndroid Build Coastguard Worker AMEDIAMETRICS_PROP_EVENT_VALUE_INVALIDATE) 134*ec779b8eSAndroid Build Coastguard Worker .record(); 135*ec779b8eSAndroid Build Coastguard Worker } 136*ec779b8eSAndroid Build Coastguard Worker logLatencyAndStartup(double latencyMs,double startupMs)137*ec779b8eSAndroid Build Coastguard Worker void logLatencyAndStartup(double latencyMs, double startupMs) { 138*ec779b8eSAndroid Build Coastguard Worker mediametrics::LogItem(mMetricsId) 139*ec779b8eSAndroid Build Coastguard Worker .set(AMEDIAMETRICS_PROP_LATENCYMS, latencyMs) 140*ec779b8eSAndroid Build Coastguard Worker .set(AMEDIAMETRICS_PROP_STARTUPMS, startupMs) 141*ec779b8eSAndroid Build Coastguard Worker .record(); 142*ec779b8eSAndroid Build Coastguard Worker std::lock_guard l(mLock); 143*ec779b8eSAndroid Build Coastguard Worker mDeviceLatencyMs.add(latencyMs); 144*ec779b8eSAndroid Build Coastguard Worker mDeviceStartupMs.add(startupMs); 145*ec779b8eSAndroid Build Coastguard Worker } 146*ec779b8eSAndroid Build Coastguard Worker updateMinMaxVolume_l(int64_t durationNs,double deviceVolume)147*ec779b8eSAndroid Build Coastguard Worker void updateMinMaxVolume_l(int64_t durationNs, double deviceVolume) 148*ec779b8eSAndroid Build Coastguard Worker REQUIRES(mLock) { 149*ec779b8eSAndroid Build Coastguard Worker if (deviceVolume > mMaxVolume) { 150*ec779b8eSAndroid Build Coastguard Worker mMaxVolume = deviceVolume; 151*ec779b8eSAndroid Build Coastguard Worker mMaxVolumeDurationNs = durationNs; 152*ec779b8eSAndroid Build Coastguard Worker } else if (deviceVolume == mMaxVolume) { 153*ec779b8eSAndroid Build Coastguard Worker mMaxVolumeDurationNs += durationNs; 154*ec779b8eSAndroid Build Coastguard Worker } 155*ec779b8eSAndroid Build Coastguard Worker if (deviceVolume < mMinVolume) { 156*ec779b8eSAndroid Build Coastguard Worker mMinVolume = deviceVolume; 157*ec779b8eSAndroid Build Coastguard Worker mMinVolumeDurationNs = durationNs; 158*ec779b8eSAndroid Build Coastguard Worker } else if (deviceVolume == mMinVolume) { 159*ec779b8eSAndroid Build Coastguard Worker mMinVolumeDurationNs += durationNs; 160*ec779b8eSAndroid Build Coastguard Worker } 161*ec779b8eSAndroid Build Coastguard Worker } 162*ec779b8eSAndroid Build Coastguard Worker 163*ec779b8eSAndroid Build Coastguard Worker // may be called multiple times during an interval logVolume(float volume)164*ec779b8eSAndroid Build Coastguard Worker void logVolume(float volume) { 165*ec779b8eSAndroid Build Coastguard Worker std::lock_guard l(mLock); 166*ec779b8eSAndroid Build Coastguard Worker logVolume_l(volume); 167*ec779b8eSAndroid Build Coastguard Worker } 168*ec779b8eSAndroid Build Coastguard Worker 169*ec779b8eSAndroid Build Coastguard Worker // Use absolute numbers returned by AudioTrackShared. logUnderruns(size_t count,size_t frames)170*ec779b8eSAndroid Build Coastguard Worker void logUnderruns(size_t count, size_t frames) { 171*ec779b8eSAndroid Build Coastguard Worker std::lock_guard l(mLock); 172*ec779b8eSAndroid Build Coastguard Worker mUnderrunCount = count; 173*ec779b8eSAndroid Build Coastguard Worker mUnderrunFrames = frames; 174*ec779b8eSAndroid Build Coastguard Worker // Consider delivering a message here (also be aware of excessive spam). 175*ec779b8eSAndroid Build Coastguard Worker } 176*ec779b8eSAndroid Build Coastguard Worker 177*ec779b8eSAndroid Build Coastguard Worker private: 178*ec779b8eSAndroid Build Coastguard Worker 179*ec779b8eSAndroid Build Coastguard Worker // no lock required - all arguments and constants. deliverDeviceMetrics(const char * eventName,const char * devices)180*ec779b8eSAndroid Build Coastguard Worker void deliverDeviceMetrics(const char *eventName, const char *devices) const { 181*ec779b8eSAndroid Build Coastguard Worker mediametrics::LogItem(mMetricsId) 182*ec779b8eSAndroid Build Coastguard Worker .set(AMEDIAMETRICS_PROP_EVENT, eventName) 183*ec779b8eSAndroid Build Coastguard Worker .set(mIsOut ? AMEDIAMETRICS_PROP_OUTPUTDEVICES 184*ec779b8eSAndroid Build Coastguard Worker : AMEDIAMETRICS_PROP_INPUTDEVICES, devices) 185*ec779b8eSAndroid Build Coastguard Worker .record(); 186*ec779b8eSAndroid Build Coastguard Worker } 187*ec779b8eSAndroid Build Coastguard Worker logVolume_l(float volume)188*ec779b8eSAndroid Build Coastguard Worker void logVolume_l(float volume) REQUIRES(mLock) { 189*ec779b8eSAndroid Build Coastguard Worker const int64_t timeNs = systemTime(); 190*ec779b8eSAndroid Build Coastguard Worker const int64_t durationNs = mLastVolumeChangeTimeNs == 0 191*ec779b8eSAndroid Build Coastguard Worker ? 0 : timeNs - mLastVolumeChangeTimeNs; 192*ec779b8eSAndroid Build Coastguard Worker if (durationNs > 0) { 193*ec779b8eSAndroid Build Coastguard Worker // See West's algorithm for weighted averages 194*ec779b8eSAndroid Build Coastguard Worker // https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance 195*ec779b8eSAndroid Build Coastguard Worker mDeviceVolume += (mVolume - mDeviceVolume) * durationNs 196*ec779b8eSAndroid Build Coastguard Worker / (durationNs + mDeviceTimeNs); 197*ec779b8eSAndroid Build Coastguard Worker mDeviceTimeNs += durationNs; 198*ec779b8eSAndroid Build Coastguard Worker mCumulativeTimeNs += durationNs; 199*ec779b8eSAndroid Build Coastguard Worker } 200*ec779b8eSAndroid Build Coastguard Worker updateMinMaxVolume_l(durationNs, mVolume); // always update. 201*ec779b8eSAndroid Build Coastguard Worker mVolume = volume; 202*ec779b8eSAndroid Build Coastguard Worker mLastVolumeChangeTimeNs = timeNs; 203*ec779b8eSAndroid Build Coastguard Worker } 204*ec779b8eSAndroid Build Coastguard Worker deliverCumulativeMetrics(const char * eventName)205*ec779b8eSAndroid Build Coastguard Worker void deliverCumulativeMetrics(const char *eventName) const REQUIRES(mLock) { 206*ec779b8eSAndroid Build Coastguard Worker if (mIntervalCount > 0) { 207*ec779b8eSAndroid Build Coastguard Worker mediametrics::LogItem item(mMetricsId); 208*ec779b8eSAndroid Build Coastguard Worker item.set(AMEDIAMETRICS_PROP_CUMULATIVETIMENS, mCumulativeTimeNs) 209*ec779b8eSAndroid Build Coastguard Worker .set(AMEDIAMETRICS_PROP_DEVICETIMENS, mDeviceTimeNs) 210*ec779b8eSAndroid Build Coastguard Worker .set(AMEDIAMETRICS_PROP_EVENT, eventName) 211*ec779b8eSAndroid Build Coastguard Worker .set(AMEDIAMETRICS_PROP_INTERVALCOUNT, (int32_t)mIntervalCount); 212*ec779b8eSAndroid Build Coastguard Worker if (mIsOut) { 213*ec779b8eSAndroid Build Coastguard Worker item.set(AMEDIAMETRICS_PROP_DEVICEVOLUME, mDeviceVolume) 214*ec779b8eSAndroid Build Coastguard Worker .set(AMEDIAMETRICS_PROP_DEVICEMAXVOLUMEDURATIONNS, mMaxVolumeDurationNs) 215*ec779b8eSAndroid Build Coastguard Worker .set(AMEDIAMETRICS_PROP_DEVICEMAXVOLUME, mMaxVolume) 216*ec779b8eSAndroid Build Coastguard Worker .set(AMEDIAMETRICS_PROP_DEVICEMINVOLUMEDURATIONNS, mMinVolumeDurationNs) 217*ec779b8eSAndroid Build Coastguard Worker .set(AMEDIAMETRICS_PROP_DEVICEMINVOLUME, mMinVolume); 218*ec779b8eSAndroid Build Coastguard Worker } 219*ec779b8eSAndroid Build Coastguard Worker if (mDeviceLatencyMs.getN() > 0) { 220*ec779b8eSAndroid Build Coastguard Worker item.set(AMEDIAMETRICS_PROP_DEVICELATENCYMS, mDeviceLatencyMs.getMean()) 221*ec779b8eSAndroid Build Coastguard Worker .set(AMEDIAMETRICS_PROP_DEVICESTARTUPMS, mDeviceStartupMs.getMean()); 222*ec779b8eSAndroid Build Coastguard Worker } 223*ec779b8eSAndroid Build Coastguard Worker if (mUnderrunCount > 0) { 224*ec779b8eSAndroid Build Coastguard Worker item.set(AMEDIAMETRICS_PROP_UNDERRUN, 225*ec779b8eSAndroid Build Coastguard Worker (int32_t)(mUnderrunCount - mUnderrunCountSinceIntervalGroup)) 226*ec779b8eSAndroid Build Coastguard Worker .set(AMEDIAMETRICS_PROP_UNDERRUNFRAMES, 227*ec779b8eSAndroid Build Coastguard Worker (int64_t)(mUnderrunFrames - mUnderrunFramesSinceIntervalGroup)); 228*ec779b8eSAndroid Build Coastguard Worker } 229*ec779b8eSAndroid Build Coastguard Worker item.record(); 230*ec779b8eSAndroid Build Coastguard Worker } 231*ec779b8eSAndroid Build Coastguard Worker } 232*ec779b8eSAndroid Build Coastguard Worker resetIntervalGroupMetrics()233*ec779b8eSAndroid Build Coastguard Worker void resetIntervalGroupMetrics() REQUIRES(mLock) { 234*ec779b8eSAndroid Build Coastguard Worker // mDevices is not reset by resetIntervalGroupMetrics. 235*ec779b8eSAndroid Build Coastguard Worker 236*ec779b8eSAndroid Build Coastguard Worker mIntervalCount = 0; 237*ec779b8eSAndroid Build Coastguard Worker // mCumulativeTimeNs is not reset by resetIntervalGroupMetrics. 238*ec779b8eSAndroid Build Coastguard Worker mDeviceTimeNs = 0; 239*ec779b8eSAndroid Build Coastguard Worker 240*ec779b8eSAndroid Build Coastguard Worker mVolume = 0.f; 241*ec779b8eSAndroid Build Coastguard Worker mDeviceVolume = 0.f; 242*ec779b8eSAndroid Build Coastguard Worker mLastVolumeChangeTimeNs = 0; // last time volume logged, cleared on endInterval 243*ec779b8eSAndroid Build Coastguard Worker mMinVolume = AMEDIAMETRICS_INITIAL_MIN_VOLUME; 244*ec779b8eSAndroid Build Coastguard Worker mMaxVolume = AMEDIAMETRICS_INITIAL_MAX_VOLUME; 245*ec779b8eSAndroid Build Coastguard Worker mMinVolumeDurationNs = 0; 246*ec779b8eSAndroid Build Coastguard Worker mMaxVolumeDurationNs = 0; 247*ec779b8eSAndroid Build Coastguard Worker 248*ec779b8eSAndroid Build Coastguard Worker mDeviceLatencyMs.reset(); 249*ec779b8eSAndroid Build Coastguard Worker mDeviceStartupMs.reset(); 250*ec779b8eSAndroid Build Coastguard Worker 251*ec779b8eSAndroid Build Coastguard Worker mUnderrunCountSinceIntervalGroup = mUnderrunCount; 252*ec779b8eSAndroid Build Coastguard Worker mUnderrunFramesSinceIntervalGroup = mUnderrunFrames; 253*ec779b8eSAndroid Build Coastguard Worker // do not reset mUnderrunCount - it keeps continuously running for tracks. 254*ec779b8eSAndroid Build Coastguard Worker } 255*ec779b8eSAndroid Build Coastguard Worker 256*ec779b8eSAndroid Build Coastguard Worker // Meyer's singleton is thread-safe. getActivityManager()257*ec779b8eSAndroid Build Coastguard Worker static const sp<IActivityManager>& getActivityManager() { 258*ec779b8eSAndroid Build Coastguard Worker static const auto activityManager = []() -> sp<IActivityManager> { 259*ec779b8eSAndroid Build Coastguard Worker const sp<IServiceManager> sm(defaultServiceManager()); 260*ec779b8eSAndroid Build Coastguard Worker if (sm != nullptr) { 261*ec779b8eSAndroid Build Coastguard Worker return interface_cast<IActivityManager>(sm->checkService(String16("activity"))); 262*ec779b8eSAndroid Build Coastguard Worker } 263*ec779b8eSAndroid Build Coastguard Worker return nullptr; 264*ec779b8eSAndroid Build Coastguard Worker }(); 265*ec779b8eSAndroid Build Coastguard Worker return activityManager; 266*ec779b8eSAndroid Build Coastguard Worker } 267*ec779b8eSAndroid Build Coastguard Worker 268*ec779b8eSAndroid Build Coastguard Worker const std::string mMetricsId; 269*ec779b8eSAndroid Build Coastguard Worker const bool mIsOut; // if true, than a playback track, otherwise used for record. 270*ec779b8eSAndroid Build Coastguard Worker 271*ec779b8eSAndroid Build Coastguard Worker static constexpr int AUDIO_API = 5; 272*ec779b8eSAndroid Build Coastguard Worker static constexpr int MICROPHONE_API = 6; 273*ec779b8eSAndroid Build Coastguard Worker const int mUid; 274*ec779b8eSAndroid Build Coastguard Worker 275*ec779b8eSAndroid Build Coastguard Worker mutable std::mutex mLock; 276*ec779b8eSAndroid Build Coastguard Worker 277*ec779b8eSAndroid Build Coastguard Worker // Devices in the interval group. 278*ec779b8eSAndroid Build Coastguard Worker std::string mDevices GUARDED_BY(mLock); 279*ec779b8eSAndroid Build Coastguard Worker 280*ec779b8eSAndroid Build Coastguard Worker // Number of intervals and playing time 281*ec779b8eSAndroid Build Coastguard Worker int32_t mIntervalCount GUARDED_BY(mLock) = 0; 282*ec779b8eSAndroid Build Coastguard Worker int64_t mCumulativeTimeNs GUARDED_BY(mLock) = 0; // total time. 283*ec779b8eSAndroid Build Coastguard Worker int64_t mDeviceTimeNs GUARDED_BY(mLock) = 0; // time on device. 284*ec779b8eSAndroid Build Coastguard Worker 285*ec779b8eSAndroid Build Coastguard Worker // Average volume 286*ec779b8eSAndroid Build Coastguard Worker double mVolume GUARDED_BY(mLock) = 0.f; // last set volume. 287*ec779b8eSAndroid Build Coastguard Worker double mDeviceVolume GUARDED_BY(mLock) = 0.f; // running average volume. 288*ec779b8eSAndroid Build Coastguard Worker int64_t mLastVolumeChangeTimeNs GUARDED_BY(mLock) = 0; 289*ec779b8eSAndroid Build Coastguard Worker 290*ec779b8eSAndroid Build Coastguard Worker // Min/Max volume 291*ec779b8eSAndroid Build Coastguard Worker double mMinVolume GUARDED_BY(mLock) = AMEDIAMETRICS_INITIAL_MIN_VOLUME; 292*ec779b8eSAndroid Build Coastguard Worker double mMaxVolume GUARDED_BY(mLock) = AMEDIAMETRICS_INITIAL_MAX_VOLUME; 293*ec779b8eSAndroid Build Coastguard Worker int64_t mMinVolumeDurationNs GUARDED_BY(mLock) = 0; 294*ec779b8eSAndroid Build Coastguard Worker int64_t mMaxVolumeDurationNs GUARDED_BY(mLock) = 0; 295*ec779b8eSAndroid Build Coastguard Worker 296*ec779b8eSAndroid Build Coastguard Worker // latency and startup for each interval. 297*ec779b8eSAndroid Build Coastguard Worker audio_utils::Statistics<double> mDeviceLatencyMs GUARDED_BY(mLock); 298*ec779b8eSAndroid Build Coastguard Worker audio_utils::Statistics<double> mDeviceStartupMs GUARDED_BY(mLock); 299*ec779b8eSAndroid Build Coastguard Worker 300*ec779b8eSAndroid Build Coastguard Worker // underrun count and frames 301*ec779b8eSAndroid Build Coastguard Worker int64_t mUnderrunCount GUARDED_BY(mLock) = 0; 302*ec779b8eSAndroid Build Coastguard Worker int64_t mUnderrunFrames GUARDED_BY(mLock) = 0; 303*ec779b8eSAndroid Build Coastguard Worker int64_t mUnderrunCountSinceIntervalGroup GUARDED_BY(mLock) = 0; 304*ec779b8eSAndroid Build Coastguard Worker int64_t mUnderrunFramesSinceIntervalGroup GUARDED_BY(mLock) = 0; 305*ec779b8eSAndroid Build Coastguard Worker }; 306*ec779b8eSAndroid Build Coastguard Worker 307*ec779b8eSAndroid Build Coastguard Worker } // namespace android 308