1953608fabc2b1253850f9922b15fd1392bde784cAndy Hung/*
2953608fabc2b1253850f9922b15fd1392bde784cAndy Hung * Copyright (C) 2017 The Android Open Source Project
3953608fabc2b1253850f9922b15fd1392bde784cAndy Hung *
4953608fabc2b1253850f9922b15fd1392bde784cAndy Hung * Licensed under the Apache License, Version 2.0 (the "License");
5953608fabc2b1253850f9922b15fd1392bde784cAndy Hung * you may not use this file except in compliance with the License.
6953608fabc2b1253850f9922b15fd1392bde784cAndy Hung * You may obtain a copy of the License at
7953608fabc2b1253850f9922b15fd1392bde784cAndy Hung *
8953608fabc2b1253850f9922b15fd1392bde784cAndy Hung *      http://www.apache.org/licenses/LICENSE-2.0
9953608fabc2b1253850f9922b15fd1392bde784cAndy Hung *
10953608fabc2b1253850f9922b15fd1392bde784cAndy Hung * Unless required by applicable law or agreed to in writing, software
11953608fabc2b1253850f9922b15fd1392bde784cAndy Hung * distributed under the License is distributed on an "AS IS" BASIS,
12953608fabc2b1253850f9922b15fd1392bde784cAndy Hung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13953608fabc2b1253850f9922b15fd1392bde784cAndy Hung * See the License for the specific language governing permissions and
14953608fabc2b1253850f9922b15fd1392bde784cAndy Hung * limitations under the License.
15953608fabc2b1253850f9922b15fd1392bde784cAndy Hung */
16953608fabc2b1253850f9922b15fd1392bde784cAndy Hung
17953608fabc2b1253850f9922b15fd1392bde784cAndy Hung#ifndef ANDROID_HARDWARE_STREAM_POWER_LOG_H
18953608fabc2b1253850f9922b15fd1392bde784cAndy Hung#define ANDROID_HARDWARE_STREAM_POWER_LOG_H
19953608fabc2b1253850f9922b15fd1392bde784cAndy Hung
20953608fabc2b1253850f9922b15fd1392bde784cAndy Hung#include <audio_utils/clock.h>
21953608fabc2b1253850f9922b15fd1392bde784cAndy Hung#include <audio_utils/PowerLog.h>
22953608fabc2b1253850f9922b15fd1392bde784cAndy Hung#include <cutils/properties.h>
23953608fabc2b1253850f9922b15fd1392bde784cAndy Hung#include <system/audio.h>
24953608fabc2b1253850f9922b15fd1392bde784cAndy Hung
25953608fabc2b1253850f9922b15fd1392bde784cAndy Hungnamespace android {
26953608fabc2b1253850f9922b15fd1392bde784cAndy Hung
27953608fabc2b1253850f9922b15fd1392bde784cAndy Hungclass StreamPowerLog {
28953608fabc2b1253850f9922b15fd1392bde784cAndy Hungpublic:
29953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    StreamPowerLog() :
30953608fabc2b1253850f9922b15fd1392bde784cAndy Hung        mIsUserDebugOrEngBuild(is_userdebug_or_eng_build()),
31953608fabc2b1253850f9922b15fd1392bde784cAndy Hung        mPowerLog(nullptr),
32953608fabc2b1253850f9922b15fd1392bde784cAndy Hung        mFrameSize(0) {
33953608fabc2b1253850f9922b15fd1392bde784cAndy Hung        // use init() to set up the power log.
34953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    }
35953608fabc2b1253850f9922b15fd1392bde784cAndy Hung
36953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    ~StreamPowerLog() {
37953608fabc2b1253850f9922b15fd1392bde784cAndy Hung        power_log_destroy(mPowerLog); // OK for null mPowerLog
38953608fabc2b1253850f9922b15fd1392bde784cAndy Hung        mPowerLog = nullptr;
39953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    }
40953608fabc2b1253850f9922b15fd1392bde784cAndy Hung
41953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    // A one-time initialization (do not call twice) before using StreamPowerLog.
42953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    void init(uint32_t sampleRate, audio_channel_mask_t channelMask, audio_format_t format) {
43953608fabc2b1253850f9922b15fd1392bde784cAndy Hung        if (mPowerLog == nullptr) {
44953608fabc2b1253850f9922b15fd1392bde784cAndy Hung            // Note: A way to get channel count for both input and output channel masks
45953608fabc2b1253850f9922b15fd1392bde784cAndy Hung            // but does not check validity of the channel mask.
46953608fabc2b1253850f9922b15fd1392bde784cAndy Hung            const uint32_t channelCount = popcount(audio_channel_mask_get_bits(channelMask));
47953608fabc2b1253850f9922b15fd1392bde784cAndy Hung            mFrameSize = channelCount * audio_bytes_per_sample(format);
48953608fabc2b1253850f9922b15fd1392bde784cAndy Hung            if (mFrameSize > 0) {
49953608fabc2b1253850f9922b15fd1392bde784cAndy Hung                const size_t kPowerLogFramesPerEntry =
50953608fabc2b1253850f9922b15fd1392bde784cAndy Hung                        (long long)sampleRate * kPowerLogSamplingIntervalMs / 1000;
51953608fabc2b1253850f9922b15fd1392bde784cAndy Hung                mPowerLog = power_log_create(
52953608fabc2b1253850f9922b15fd1392bde784cAndy Hung                        sampleRate,
53953608fabc2b1253850f9922b15fd1392bde784cAndy Hung                        channelCount,
54953608fabc2b1253850f9922b15fd1392bde784cAndy Hung                        format,
55953608fabc2b1253850f9922b15fd1392bde784cAndy Hung                        kPowerLogEntries,
56953608fabc2b1253850f9922b15fd1392bde784cAndy Hung                        kPowerLogFramesPerEntry);
57953608fabc2b1253850f9922b15fd1392bde784cAndy Hung            }
58953608fabc2b1253850f9922b15fd1392bde784cAndy Hung        }
59953608fabc2b1253850f9922b15fd1392bde784cAndy Hung        // mPowerLog may be NULL (not the right build, format not accepted, etc.).
60953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    }
61953608fabc2b1253850f9922b15fd1392bde784cAndy Hung
62953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    // Dump the power log to fd.
63953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    void dump(int fd) const {
64953608fabc2b1253850f9922b15fd1392bde784cAndy Hung        // OK for null mPowerLog
65953608fabc2b1253850f9922b15fd1392bde784cAndy Hung        (void)power_log_dump(
66953608fabc2b1253850f9922b15fd1392bde784cAndy Hung                mPowerLog, fd, "      " /* prefix */, kPowerLogLines, 0 /* limit_ns */);
67953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    }
68953608fabc2b1253850f9922b15fd1392bde784cAndy Hung
69953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    // Log the audio data contained in buffer.
70953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    void log(const void *buffer, size_t sizeInBytes) const {
71953608fabc2b1253850f9922b15fd1392bde784cAndy Hung        if (mPowerLog != nullptr) { // mFrameSize is always nonzero if mPowerLog exists.
72953608fabc2b1253850f9922b15fd1392bde784cAndy Hung            power_log_log(
73953608fabc2b1253850f9922b15fd1392bde784cAndy Hung                    mPowerLog, buffer, sizeInBytes / mFrameSize, audio_utils_get_real_time_ns());
74953608fabc2b1253850f9922b15fd1392bde784cAndy Hung        }
75953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    }
76953608fabc2b1253850f9922b15fd1392bde784cAndy Hung
77953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    bool isUserDebugOrEngBuild() const {
78953608fabc2b1253850f9922b15fd1392bde784cAndy Hung        return mIsUserDebugOrEngBuild;
79953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    }
80953608fabc2b1253850f9922b15fd1392bde784cAndy Hung
81953608fabc2b1253850f9922b15fd1392bde784cAndy Hungprivate:
82953608fabc2b1253850f9922b15fd1392bde784cAndy Hung
83953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    static inline bool is_userdebug_or_eng_build() {
84953608fabc2b1253850f9922b15fd1392bde784cAndy Hung        char value[PROPERTY_VALUE_MAX];
85953608fabc2b1253850f9922b15fd1392bde784cAndy Hung        (void)property_get("ro.build.type", value, "unknown"); // ignore actual length
86953608fabc2b1253850f9922b15fd1392bde784cAndy Hung        return strcmp(value, "userdebug") == 0 || strcmp(value, "eng") == 0;
87953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    }
88953608fabc2b1253850f9922b15fd1392bde784cAndy Hung
89953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    // Audio signal power log configuration.
90953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    static const size_t kPowerLogLines = 40;
91953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    static const size_t kPowerLogSamplingIntervalMs = 50;
92953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    static const size_t kPowerLogEntries = (1 /* minutes */ * 60 /* seconds */ * 1000 /* msec */
93953608fabc2b1253850f9922b15fd1392bde784cAndy Hung            / kPowerLogSamplingIntervalMs);
94953608fabc2b1253850f9922b15fd1392bde784cAndy Hung
95953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    const bool mIsUserDebugOrEngBuild;
96953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    power_log_t *mPowerLog;
97953608fabc2b1253850f9922b15fd1392bde784cAndy Hung    size_t mFrameSize;
98953608fabc2b1253850f9922b15fd1392bde784cAndy Hung};
99953608fabc2b1253850f9922b15fd1392bde784cAndy Hung
100953608fabc2b1253850f9922b15fd1392bde784cAndy Hung} // namespace android
101953608fabc2b1253850f9922b15fd1392bde784cAndy Hung
102953608fabc2b1253850f9922b15fd1392bde784cAndy Hung#endif // ANDROID_HARDWARE_STREAM_POWER_LOG_H
103