blob: eb9c22801a1993574f0cb61b11bc5a6b31f81b99 [file] [log] [blame]
Andy Hung06f3aba2019-12-03 16:36:42 -08001/*
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#pragma once
18
Andy Hungce9b6632020-04-28 20:15:17 -070019#include <android-base/thread_annotations.h>
Andy Hung0f7ad8c2020-01-03 13:24:34 -080020#include "AnalyticsActions.h"
21#include "AnalyticsState.h"
Andy Hungce9b6632020-04-28 20:15:17 -070022#include "TimedAction.h"
Andy Hung0f7ad8c2020-01-03 13:24:34 -080023#include "Wrap.h"
Andy Hung06f3aba2019-12-03 16:36:42 -080024
25namespace android::mediametrics {
26
27class AudioAnalytics
28{
29public:
30 AudioAnalytics();
31 ~AudioAnalytics();
32
Andy Hung06f3aba2019-12-03 16:36:42 -080033 /**
34 * Returns success if AudioAnalytics recognizes item.
35 *
36 * AudioAnalytics requires the item key to start with "audio.".
37 *
38 * A trusted source can create a new key, an untrusted source
39 * can only modify the key if the uid will match that authorized
40 * on the existing key.
41 *
42 * \param item the item to be submitted.
43 * \param isTrusted whether the transaction comes from a trusted source.
44 * In this case, a trusted source is verified by binder
45 * UID to be a system service by MediaMetrics service.
46 * Do not use true if you haven't really checked!
Andy Hung0f7ad8c2020-01-03 13:24:34 -080047 *
48 * \return NO_ERROR on success,
49 * PERMISSION_DENIED if the item cannot be put into the AnalyticsState,
50 * BAD_VALUE if the item key does not start with "audio.".
Andy Hung06f3aba2019-12-03 16:36:42 -080051 */
Ray Essickf27e9872019-12-07 06:28:46 -080052 status_t submit(const std::shared_ptr<const mediametrics::Item>& item, bool isTrusted);
Andy Hung06f3aba2019-12-03 16:36:42 -080053
54 /**
55 * Returns a pair consisting of the dump string, and the number of lines in the string.
56 *
57 * The number of lines in the returned pair is used as an optimization
58 * for subsequent line limiting.
59 *
60 * The TimeMachine and the TransactionLog are dumped separately under
61 * different locks, so may not be 100% consistent with the last data
62 * delivered.
63 *
64 * \param lines the maximum number of lines in the string returned.
Andy Hung709b91e2020-04-04 14:23:36 -070065 * \param sinceNs the nanoseconds since Unix epoch to start dump (0 shows all)
66 * \param prefix the desired key prefix to match (nullptr shows all)
Andy Hung06f3aba2019-12-03 16:36:42 -080067 */
Andy Hung709b91e2020-04-04 14:23:36 -070068 std::pair<std::string, int32_t> dump(
69 int32_t lines = INT32_MAX, int64_t sinceNs = 0, const char *prefix = nullptr) const;
70
71 void clear() {
72 // underlying state is locked.
73 mPreviousAnalyticsState->clear();
74 mAnalyticsState->clear();
75 }
Andy Hung06f3aba2019-12-03 16:36:42 -080076
77private:
Andy Hung0f7ad8c2020-01-03 13:24:34 -080078
79 /**
80 * Checks for any pending actions for a particular item.
81 *
82 * \param item to check against the current AnalyticsActions.
83 */
84 void checkActions(const std::shared_ptr<const mediametrics::Item>& item);
85
Andy Hungea186fa2020-01-09 18:13:15 -080086 // HELPER METHODS
87 /**
88 * Return the audio thread associated with an audio track name.
89 * e.g. "audio.track.32" -> "audio.thread.10" if the associated
90 * threadId for the audio track is 10.
91 */
92 std::string getThreadFromTrack(const std::string& track) const;
93
Andy Hungce9b6632020-04-28 20:15:17 -070094 const bool mDeliverStatistics __unused = true;
95
Andy Hung0f7ad8c2020-01-03 13:24:34 -080096 // Actions is individually locked
97 AnalyticsActions mActions;
98
99 // AnalyticsState is individually locked, and we use SharedPtrWrap
100 // to allow safe access even if the shared pointer changes underneath.
101
102 SharedPtrWrap<AnalyticsState> mAnalyticsState;
103 SharedPtrWrap<AnalyticsState> mPreviousAnalyticsState;
Andy Hungce9b6632020-04-28 20:15:17 -0700104
105 TimedAction mTimedAction; // locked internally
106
107 // DeviceUse is a nested class which handles audio device usage accounting.
108 // We define this class at the end to ensure prior variables all properly constructed.
109 // TODO: Track / Thread interaction
110 // TODO: Consider statistics aggregation.
111 class DeviceUse {
112 public:
113 explicit DeviceUse(AudioAnalytics &audioAnalytics) : mAudioAnalytics{audioAnalytics} {}
114
115 // Called every time an endAudioIntervalGroup message is received.
116 void endAudioIntervalGroup(
117 const std::shared_ptr<const android::mediametrics::Item> &item,
118 bool isTrack) const;
119 private:
120 AudioAnalytics &mAudioAnalytics;
121 } mDeviceUse{*this};
122
123 // DeviceConnected is a nested class which handles audio device connection
124 // We define this class at the end to ensure prior variables all properly constructed.
125 // TODO: Track / Thread interaction
126 // TODO: Consider statistics aggregation.
127 class DeviceConnection {
128 public:
129 explicit DeviceConnection(AudioAnalytics &audioAnalytics)
130 : mAudioAnalytics{audioAnalytics} {}
131
132 // Called every time an endAudioIntervalGroup message is received.
133 void a2dpConnected(
134 const std::shared_ptr<const android::mediametrics::Item> &item);
135
136 // Called when we have an AudioFlinger createPatch
137 void createPatch(
138 const std::shared_ptr<const android::mediametrics::Item> &item);
139
140 // When the timer expires.
141 void expire();
142
143 private:
144 AudioAnalytics &mAudioAnalytics;
145
146 mutable std::mutex mLock;
147 int64_t mA2dpTimeConnectedNs GUARDED_BY(mLock) = 0;
148 int32_t mA2dpConnectedAttempts GUARDED_BY(mLock) = 0;
149 int32_t mA2dpConnectedSuccesses GUARDED_BY(mLock) = 0;
150 int32_t mA2dpConnectedFailures GUARDED_BY(mLock) = 0;
151 } mDeviceConnection{*this};
Andy Hung06f3aba2019-12-03 16:36:42 -0800152};
153
154} // namespace android::mediametrics