1 /*
2  * Copyright (C) 2020 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 
19 #include <android-base/thread_annotations.h>
20 #include <deque>
21 #include <media/MediaMetricsItem.h>
22 #include <mutex>
23 #include <thread>
24 
25 #include "StatsdLog.h"
26 
27 namespace android::mediametrics {
28 
29 
30 class AudioAnalytics;
31 
32 class AudioPowerUsage {
33 public:
34     AudioPowerUsage(AudioAnalytics *audioAnalytics, const std::shared_ptr<StatsdLog>& statsdLog);
35     ~AudioPowerUsage();
36 
37     void checkTrackRecord(const std::shared_ptr<const mediametrics::Item>& item, bool isTrack);
38     void checkMode(const std::shared_ptr<const mediametrics::Item>& item);
39     void checkVoiceVolume(const std::shared_ptr<const mediametrics::Item>& item);
40     void checkCreatePatch(const std::shared_ptr<const mediametrics::Item>& item);
41     void clear();
42 
43     /**
44      * Returns a pair consisting of the dump string, and the number of lines in the string.
45      *
46      * The number of lines in the returned pair is used as an optimization
47      * for subsequent line limiting.
48      *
49      * \param lines the maximum number of lines in the string returned.
50      */
51     std::pair<std::string, int32_t> dump(int32_t lines = INT32_MAX) const;
52 
53     // align with message AudioPowerUsageDataReported in frameworks/proto_logging/stats/atoms.proto
54     enum AudioType {
55         UNKNOWN_TYPE = 0,
56         VOICE_CALL_TYPE = 1,            // voice call
57         VOIP_CALL_TYPE = 2,             // voip call, including uplink and downlink
58         MEDIA_TYPE = 3,                 // music and system sound
59         RINGTONE_NOTIFICATION_TYPE = 4, // ringtone and notification
60         ALARM_TYPE = 5,                 // alarm type
61         // record type
62         CAMCORDER_TYPE = 6,             // camcorder
63         RECORD_TYPE = 7,                // other recording
64     };
65 
66     enum AudioDevice {
67         OUTPUT_EARPIECE         = 0x1,
68         OUTPUT_SPEAKER          = 0x2,
69         OUTPUT_WIRED_HEADSET    = 0x4,
70         OUTPUT_USB_HEADSET      = 0x8,
71         OUTPUT_BLUETOOTH_SCO    = 0x10,
72         OUTPUT_BLUETOOTH_A2DP   = 0x20,
73         OUTPUT_SPEAKER_SAFE     = 0x40,
74         OUTPUT_BLUETOOTH_BLE    = 0x80,
75         OUTPUT_DOCK             = 0x100,
76         OUTPUT_HDMI             = 0x200,
77 
78         INPUT_DEVICE_BIT        = 0x40000000,
79         INPUT_BUILTIN_MIC       = INPUT_DEVICE_BIT | 0x1, // non-negative positive int32.
80         INPUT_BUILTIN_BACK_MIC  = INPUT_DEVICE_BIT | 0x2,
81         INPUT_WIRED_HEADSET_MIC = INPUT_DEVICE_BIT | 0x4,
82         INPUT_USB_HEADSET_MIC   = INPUT_DEVICE_BIT | 0x8,
83         INPUT_BLUETOOTH_SCO     = INPUT_DEVICE_BIT | 0x10,
84         INPUT_BLUETOOTH_BLE     = INPUT_DEVICE_BIT | 0x20,
85     };
86 
87     static bool typeFromString(const std::string& type_string, int32_t& type);
88     static bool deviceFromString(const std::string& device_string, int32_t& device);
89     static int32_t deviceFromStringPairs(const std::string& device_strings);
90 private:
91     bool saveAsItem_l(int32_t device, int64_t duration, int32_t type, double average_vol,
92                       int64_t max_volume_duration, double max_volume,
93                       int64_t min_volume_duration, double min_volume)
94                       REQUIRES(mLock);
95     void sendItem(const std::shared_ptr<const mediametrics::Item>& item) const;
96     void collect();
97     bool saveAsItems_l(int32_t device, int64_t duration, int32_t type, double average_vol,
98                       int64_t max_volume_duration, double max_volume,
99                       int64_t min_volume_duration, double min_volume)
100                       REQUIRES(mLock);
101     void updateMinMaxVolumeAndDuration(
102             const int64_t cur_max_volume_duration_ns, const double cur_max_volume,
103             const int64_t cur_min_volume_duration_ns, const double cur_min_volume,
104             int64_t& f_max_volume_duration_ns, double& f_max_volume,
105             int64_t& f_min_volume_duration_ns, double& f_min_volume);
106     AudioAnalytics * const mAudioAnalytics;
107     const std::shared_ptr<StatsdLog> mStatsdLog;  // mStatsdLog is internally locked
108     const bool mDisabled;
109     const int32_t mIntervalHours;
110 
111     mutable std::mutex mLock;
112     std::deque<std::shared_ptr<mediametrics::Item>> mItems GUARDED_BY(mLock);
113 
114     double mVoiceVolume GUARDED_BY(mLock) = 0.;
115     double mDeviceVolume GUARDED_BY(mLock) = 0.;
116     double mMaxVoiceVolume GUARDED_BY(mLock) = AMEDIAMETRICS_INITIAL_MAX_VOLUME;
117     double mMinVoiceVolume GUARDED_BY(mLock) = AMEDIAMETRICS_INITIAL_MIN_VOLUME;
118     int64_t mMaxVoiceVolumeDurationNs GUARDED_BY(mLock) = 0;
119     int64_t mMinVoiceVolumeDurationNs GUARDED_BY(mLock) = 0;
120     int64_t mStartCallNs GUARDED_BY(mLock) = 0; // advisory only
121     int64_t mVolumeTimeNs GUARDED_BY(mLock) = 0;
122     int64_t mDeviceTimeNs GUARDED_BY(mLock) = 0;
123     int32_t mPrimaryDevice GUARDED_BY(mLock) = OUTPUT_SPEAKER;
GUARDED_BY(mLock)124     std::string mMode GUARDED_BY(mLock) {"AUDIO_MODE_NORMAL"};
125 };
126 
127 } // namespace android::mediametrics
128