summaryrefslogtreecommitdiff
path: root/pixelstats/include/pixelstats/UeventListener.h
blob: 5316afaaf0c8e45cdefb271c508a098920d2627b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
 * Copyright (C) 2018 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.
 */

#ifndef HARDWARE_GOOGLE_PIXEL_PIXELSTATS_UEVENTLISTENER_H
#define HARDWARE_GOOGLE_PIXEL_PIXELSTATS_UEVENTLISTENER_H

#include <aidl/android/frameworks/stats/IStats.h>
#include <android-base/chrono_utils.h>
#include <pixelstats/BatteryCapacityReporter.h>
#include <pixelstats/ChargeStatsReporter.h>

namespace android {
namespace hardware {
namespace google {
namespace pixel {

using aidl::android::frameworks::stats::IStats;

/**
 * A class to listen for uevents and report reliability events to
 * the PixelStats HAL.
 * Runs in a background thread if created with ListenForeverInNewThread().
 * Alternatively, process one message at a time with ProcessUevent().
 */
class UeventListener {
  public:
    struct UeventPaths {
        const char *const AudioUevent;
        const char *const SsocDetailsPath;
        const char *const OverheatPath;
        const char *const ChargeMetricsPath;
        const char *const TypeCPartnerUevent;
        const char *const TypeCPartnerVidPath;
        const char *const TypeCPartnerPidPath;
        const char *const WirelessChargerPtmcUevent;  // Deprecated.
        const char *const WirelessChargerPtmcPath;    // Deprecated.
    };
    constexpr static const char *const ssoc_details_path =
            "/sys/class/power_supply/battery/ssoc_details";
    constexpr static const char *const overheat_path_default =
            "/sys/devices/platform/soc/soc:google,overheat_mitigation";
    constexpr static const char *const charge_metrics_path_default =
            "/sys/class/power_supply/battery/charge_stats";
    constexpr static const char *const typec_partner_vid_path_default =
            "/sys/class/typec/port0-partner/identity/id_header";
    constexpr static const char *const typec_partner_pid_path_default =
            "/sys/class/typec/port0-partner/identity/product";
    constexpr static const char *const typec_partner_uevent_default = "DEVTYPE=typec_partner";

    UeventListener(const std::string audio_uevent, const std::string ssoc_details_path = "",
                   const std::string overheat_path = overheat_path_default,
                   const std::string charge_metrics_path = charge_metrics_path_default,
                   const std::string typec_partner_vid_path = typec_partner_vid_path_default,
                   const std::string typec_partner_pid_path = typec_partner_pid_path_default);
    UeventListener(const struct UeventPaths &paths);

    bool ProcessUevent();  // Process a single Uevent.
    void ListenForever();  // Process Uevents forever

  private:
    bool ReadFileToInt(const std::string &path, int *val);
    bool ReadFileToInt(const char *path, int *val);
    void ReportMicStatusUevents(const std::shared_ptr<IStats> &stats_client, const char *devpath,
                                const char *mic_status);
    void ReportMicBrokenOrDegraded(const std::shared_ptr<IStats> &stats_client, const int mic,
                                   const bool isBroken);
    void ReportUsbPortOverheatEvent(const std::shared_ptr<IStats> &stats_client,
                                    const char *driver);
    void ReportChargeStats(const std::shared_ptr<IStats> &stats_client, const std::string line,
                           const std::string wline_at, const std::string wline_ac,
                           const std::string pca_line);
    void ReportVoltageTierStats(const std::shared_ptr<IStats> &stats_client, const char *line,
                                const bool has_wireless, const std::string wfile_contents);
    void ReportChargeMetricsEvent(const std::shared_ptr<IStats> &stats_client, const char *driver);
    void ReportBatteryCapacityFGEvent(const std::shared_ptr<IStats> &stats_client,
                                      const char *subsystem);
    void ReportTypeCPartnerId(const std::shared_ptr<IStats> &stats_client);

    const std::string kAudioUevent;
    const std::string kBatterySSOCPath;
    const std::string kUsbPortOverheatPath;
    const std::string kChargeMetricsPath;
    const std::string kTypeCPartnerUevent;
    const std::string kTypeCPartnerVidPath;
    const std::string kTypeCPartnerPidPath;

    BatteryCapacityReporter battery_capacity_reporter_;
    ChargeStatsReporter charge_stats_reporter_;

    // Proto messages are 1-indexed and VendorAtom field numbers start at 2, so
    // store everything in the values array at the index of the field number
    // -2.
    const int kVendorAtomOffset = 2;

    int uevent_fd_;
    int log_fd_;
};

}  // namespace pixel
}  // namespace google
}  // namespace hardware
}  // namespace android

#endif  // HARDWARE_GOOGLE_PIXEL_PIXELSTATS_UEVENTLISTENER_H