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 #define LOG_TAG "pixelstats-wlc"
18 
19 #include <android-base/file.h>
20 #include <log/log.h>
21 #include <pixelstats/OrientationCollector.h>
22 #include <pixelstats/WlcReporter.h>
23 
24 #define POWER_SUPPLY_SYSFS_PATH "/sys/class/power_supply/wireless/online"
25 #define POWER_SUPPLY_PTMC_PATH "/sys/class/power_supply/wireless/ptmc_id"
26 #define GOOGLE_PTMC_ID 72
27 
28 using android::base::ReadFileToString;
29 using android::frameworks::stats::V1_0::IStats;
30 using android::frameworks::stats::V1_0::VendorAtom;
31 
32 namespace android {
33 namespace hardware {
34 namespace google {
35 namespace pixel {
36 
checkAndReport(bool isWirelessChargingLast)37 bool WlcReporter::checkAndReport(bool isWirelessChargingLast) {
38     bool wireless_charging = isWlcOnline();
39     if (wireless_charging && !isWirelessChargingLast) {
40         doLog();
41     }
42     return wireless_charging;
43 }
44 
readFileToInt(const char * const path,int * val)45 bool WlcReporter::readFileToInt(const char *const path, int *val) {
46     std::string file_contents;
47 
48     if (!ReadFileToString(path, &file_contents)) {
49         ALOGE("Unable to read %s - %s", path, strerror(errno));
50         return false;
51     } else if (sscanf(file_contents.c_str(), "%d", val) != 1) {
52         ALOGE("Unable to convert %s (%s) to int - %s", path, file_contents.c_str(),
53               strerror(errno));
54         return false;
55     }
56     return true;
57 }
58 
readPtmcId()59 int WlcReporter::readPtmcId() {
60     int id = 0;
61     readFileToInt(POWER_SUPPLY_PTMC_PATH, &id);
62     return id;
63 }
64 
65 /*  Reference to frameworks/native/libs/ui/include/ui/DisplayInfo.h
66  *  translate orientation value from sensor to enum define in
67  *  pixelatoms.proto
68  */
translateDeviceOrientationToAtomValue(int orientation)69 int WlcReporter::translateDeviceOrientationToAtomValue(int orientation) {
70     switch (orientation) {
71         case 0:
72             return PixelAtoms::DeviceOrientation::ORIENTATION_0;
73         case 1:
74             return PixelAtoms::DeviceOrientation::ORIENTATION_90;
75         case 2:
76             return PixelAtoms::DeviceOrientation::ORIENTATION_180;
77         case 3:
78             return PixelAtoms::DeviceOrientation::ORIENTATION_270;
79         default:
80             return PixelAtoms::DeviceOrientation::ORIENTATION_UNKNOWN;
81     }
82 }
83 
doLog()84 void WlcReporter::doLog() {
85     sp<IStats> stats_client = IStats::tryGetService();
86 
87     if (stats_client == nullptr) {
88         ALOGE("logWlc get IStats fail.");
89         return;
90     }
91     std::vector<VendorAtom::Value> values(1);
92 
93     int vendoriCharger = (readPtmcId() == GOOGLE_PTMC_ID)
94                                  ? PixelAtoms::WirelessChargingStats::VENDOR_GOOGLE
95                                  : PixelAtoms::WirelessChargingStats::VENDOR_UNKNOWN;
96     VendorAtom::Value tmp;
97     tmp.intValue(vendoriCharger);
98     values[PixelAtoms::WirelessChargingStats::kChargerVendorFieldNumber - kVendorAtomOffset] = tmp;
99 
100     // Send vendor atom to IStats HAL
101     VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
102                         .atomId = PixelAtoms::Ids::WIRELESS_CHARGING_STATS,
103                         .values = values};
104     Return<void> retStat = stats_client->reportVendorAtom(event);
105     if (!retStat.isOk())
106         ALOGE("Unable to report WLC_STATS to Stats service");
107 
108     int orientationFromSensor;
109     sp<OrientationCollector> orientationCollector;
110     orientationCollector = OrientationCollector::createOrientationCollector();
111     if (orientationCollector != nullptr) {
112         orientationCollector->pollOrientation(&orientationFromSensor);
113         VendorAtom::Value tmp;
114         tmp.intValue(translateDeviceOrientationToAtomValue(orientationFromSensor));
115         values[PixelAtoms::DeviceOrientation::kOrientationFieldNumber - kVendorAtomOffset] = tmp;
116 
117         VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
118                             .atomId = PixelAtoms::Ids::DEVICE_ORIENTATION,
119                             .values = values};
120         Return<void> retOrientation = stats_client->reportVendorAtom(event);
121         if (!retOrientation.isOk())
122             ALOGE("Unable to report Orientation to Stats service");
123         orientationCollector->disableOrientationSensor();
124     }
125 }
126 
isWlcSupported()127 bool WlcReporter::isWlcSupported() {
128     std::string file_contents;
129 
130     if (!ReadFileToString(POWER_SUPPLY_SYSFS_PATH, &file_contents)) {
131         ALOGV("Unable to read %s - %s", POWER_SUPPLY_SYSFS_PATH, strerror(errno));
132         return false;
133     } else {
134         return true;
135     }
136 }
137 
isWlcOnline()138 bool WlcReporter::isWlcOnline() {
139     std::string file_contents;
140 
141     if (!ReadFileToString(POWER_SUPPLY_SYSFS_PATH, &file_contents)) {
142         ALOGE("Unable to read %s - %s", POWER_SUPPLY_SYSFS_PATH, strerror(errno));
143         return false;
144     }
145     ALOGV("isWlcOnline value: %s", file_contents.c_str());
146     return file_contents == "1\n";
147 }
148 
149 }  // namespace pixel
150 }  // namespace google
151 }  // namespace hardware
152 }  // namespace android
153