Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 06f3aba6 authored by Andy Hung's avatar Andy Hung
Browse files

MediaMetrics: Add AudioAnalytics

Test: mediametrics dumpsys, atest mediametrics_tests
Bug: 138583596
Change-Id: I56c82e6c685a9fae21581f14d3b370a8e352f3f3
parent 55aaf525
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ cc_library_shared {
    name: "libmediaanalyticsservice",

    srcs: [
        "AudioAnalytics.cpp",
        "iface_statsd.cpp",
        "MediaAnalyticsService.cpp",
        "statsd_audiopolicy.cpp",
+73 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "AudioAnalytics"
#include <utils/Log.h>

#include "AudioAnalytics.h"

#include <audio_utils/clock.h>                 // clock conversions

namespace android::mediametrics {

AudioAnalytics::AudioAnalytics()
{
    ALOGD("%s", __func__);
}

AudioAnalytics::~AudioAnalytics()
{
    ALOGD("%s", __func__);
}

status_t AudioAnalytics::submit(
        const std::shared_ptr<const MediaAnalyticsItem>& item, bool isTrusted)
{
    if (startsWith(item->getKey(), "audio.")) {
        return mTimeMachine.put(item, isTrusted)
                ?: mTransactionLog.put(item);
    }
    return BAD_VALUE;
}

std::pair<std::string, int32_t> AudioAnalytics::dump(int32_t lines) const
{
    std::stringstream ss;
    int32_t ll = lines;

    if (ll > 0) {
        ss << "TransactionLog:\n";
        --ll;
    }
    if (ll > 0) {
        auto [s, l] = mTransactionLog.dump(ll);
        ss << s;
        ll -= l;
    }
    if (ll > 0) {
        ss << "TimeMachine:\n";
        --ll;
    }
    if (ll > 0) {
        auto [s, l] = mTimeMachine.dump(ll);
        ss << s;
        ll -= l;
    }
    return { ss.str(), lines - ll };
}

} // namespace android
+68 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include "TimeMachine.h"
#include "TransactionLog.h"

namespace android::mediametrics {

class AudioAnalytics
{
public:
    AudioAnalytics();
    ~AudioAnalytics();

    // TODO: update with conditions for keys.
    /**
     * Returns success if AudioAnalytics recognizes item.
     *
     * AudioAnalytics requires the item key to start with "audio.".
     *
     * A trusted source can create a new key, an untrusted source
     * can only modify the key if the uid will match that authorized
     * on the existing key.
     *
     * \param item the item to be submitted.
     * \param isTrusted whether the transaction comes from a trusted source.
     *        In this case, a trusted source is verified by binder
     *        UID to be a system service by MediaMetrics service.
     *        Do not use true if you haven't really checked!
     */
    status_t submit(const std::shared_ptr<const MediaAnalyticsItem>& item, bool isTrusted);

    /**
     * Returns a pair consisting of the dump string, and the number of lines in the string.
     *
     * The number of lines in the returned pair is used as an optimization
     * for subsequent line limiting.
     *
     * The TimeMachine and the TransactionLog are dumped separately under
     * different locks, so may not be 100% consistent with the last data
     * delivered.
     *
     * \param lines the maximum number of lines in the string returned.
     */
    std::pair<std::string, int32_t> dump(int32_t lines = INT32_MAX) const;

private:
    // The following are locked internally
    TimeMachine mTimeMachine;
    TransactionLog mTransactionLog;
};

} // namespace android::mediametrics
+8 −0
Original line number Diff line number Diff line
@@ -159,6 +159,8 @@ status_t MediaAnalyticsService::submitInternal(MediaAnalyticsItem *item, bool re
    // now attach either the item or its dup to a const shared pointer
    std::shared_ptr<const MediaAnalyticsItem> sitem(release ? item : item->dup());

    (void)mAudioAnalytics.submit(sitem, isTrusted);

    extern bool dump2Statsd(const std::shared_ptr<const MediaAnalyticsItem>& item);
    (void)dump2Statsd(sitem);  // failure should be logged in function.
    saveItem(sitem);
@@ -263,6 +265,9 @@ status_t MediaAnalyticsService::dump(int fd, const Vector<String16>& args)
            mItems.clear();
            // shall we clear the summary data too?
        }
        // TODO: maybe consider a better way of dumping audio analytics info.
        constexpr int32_t linesToDump = 1000;
        result.append(mAudioAnalytics.dump(linesToDump).first.c_str());
    }

    write(fd, result.string(), result.size());
@@ -419,11 +424,14 @@ bool MediaAnalyticsService::isContentValid(const MediaAnalyticsItem *item, bool
    if (isTrusted) return true;
    // untrusted uids can only send us a limited set of keys
    const std::string &key = item->getKey();
    if (startsWith(key, "audio.")) return true;
    for (const char *allowedKey : {
                                     // legacy audio
                                     "audiopolicy",
                                     "audiorecord",
                                     "audiothread",
                                     "audiotrack",
                                     // other media
                                     "codec",
                                     "extractor",
                                     "nuplayer",
+4 −0
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@
#include <media/IMediaAnalyticsService.h>
#include <utils/String8.h>

#include "AudioAnalytics.h"

namespace android {

class MediaAnalyticsService : public BnMediaAnalyticsService
@@ -115,6 +117,8 @@ private:

    std::atomic<int64_t> mItemsSubmitted{}; // accessed outside of lock.

    mediametrics::AudioAnalytics mAudioAnalytics;

    std::mutex mLock;
    // statistics about our analytics
    int64_t mItemsFinalized = 0;        // GUARDED_BY(mLock)
Loading