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 <android-base/strings.h>
21 #include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
22 #include <log/log.h>
23 #include <pixelstats/OrientationCollector.h>
24 #include <pixelstats/WlcReporter.h>
25
26 #define GOOGLE_PTMC_ID 0x72
27 #define ID_UNKNOWN 0
28
29 using android::base::ReadFileToString;
30 using android::frameworks::stats::V1_0::IStats;
31 using android::frameworks::stats::V1_0::VendorAtom;
32
33 namespace android {
34 namespace hardware {
35 namespace google {
36 namespace pixel {
37
WlcStatus()38 WlcReporter::WlcStatus::WlcStatus()
39 : is_charging(false), check_charger_vendor_id(false), check_vendor_id_attempts(0) {}
40
checkAndReport(bool online,const char * ptmc_uevent)41 void WlcReporter::checkAndReport(bool online, const char *ptmc_uevent) {
42 bool wireless_charging = online;
43 bool started_wireless_charging = wireless_charging && !wlc_status_.is_charging;
44 wlc_status_.is_charging = wireless_charging;
45
46 if (started_wireless_charging) {
47 reportOrientation();
48 wlc_status_.check_vendor_id_attempts = 0;
49 wlc_status_.check_charger_vendor_id = true;
50 }
51 if (!wireless_charging) {
52 wlc_status_.check_charger_vendor_id = false;
53 }
54 if (wireless_charging) {
55 checkVendorId(ptmc_uevent);
56 }
57 }
58
checkVendorId(const char * ptmc_uevent)59 void WlcReporter::checkVendorId(const char *ptmc_uevent) {
60 if (!ptmc_uevent || !wlc_status_.check_charger_vendor_id) {
61 return;
62 }
63 if (reportVendor(ptmc_uevent)) {
64 wlc_status_.check_charger_vendor_id = false;
65 }
66 }
67
reportVendor(const char * ptmc_uevent)68 bool WlcReporter::reportVendor(const char *ptmc_uevent) {
69 int ptmcId = readPtmcId(ptmc_uevent);
70 if (ptmcId == ID_UNKNOWN) {
71 if (++(wlc_status_.check_vendor_id_attempts) < kMaxVendorIdAttempts) {
72 return false;
73 } /* else if ptmc not ready after retry assume ptmc not supported by charger */
74 }
75 sp<IStats> stats_client = IStats::tryGetService();
76 std::vector<VendorAtom::Value> values(1);
77
78 if (stats_client == nullptr) {
79 ALOGE("logWlc get IStats fail.");
80 return true;
81 }
82
83 int vendorCharger = (ptmcId == GOOGLE_PTMC_ID)
84 ? PixelAtoms::WirelessChargingStats::VENDOR_GOOGLE
85 : PixelAtoms::WirelessChargingStats::VENDOR_UNKNOWN;
86 VendorAtom::Value tmp;
87 tmp.intValue(vendorCharger);
88 values[PixelAtoms::WirelessChargingStats::kChargerVendorFieldNumber - kVendorAtomOffset] = tmp;
89
90 // Send vendor atom to IStats HAL
91 VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
92 .atomId = PixelAtoms::Ids::WIRELESS_CHARGING_STATS,
93 .values = values};
94 Return<void> retStat = stats_client->reportVendorAtom(event);
95 if (!retStat.isOk()) {
96 ALOGE("Unable to report WLC_STATS to Stats service");
97 }
98 return true;
99 }
100
readPtmcId(const char * ptmc_uevent)101 int WlcReporter::readPtmcId(const char *ptmc_uevent) {
102 int id;
103 if (sscanf(ptmc_uevent, "POWER_SUPPLY_PTMC_ID=%x", &id) != 1) {
104 return ID_UNKNOWN;
105 }
106 return id;
107 }
108
109 /* Reference to frameworks/native/libs/ui/include/ui/DisplayInfo.h
110 * translate orientation value from sensor to enum define in
111 * pixelatoms.proto
112 */
translateDeviceOrientationToAtomValue(int orientation)113 int WlcReporter::translateDeviceOrientationToAtomValue(int orientation) {
114 switch (orientation) {
115 case 0:
116 return PixelAtoms::DeviceOrientation::ORIENTATION_0;
117 case 1:
118 return PixelAtoms::DeviceOrientation::ORIENTATION_90;
119 case 2:
120 return PixelAtoms::DeviceOrientation::ORIENTATION_180;
121 case 3:
122 return PixelAtoms::DeviceOrientation::ORIENTATION_270;
123 default:
124 return PixelAtoms::DeviceOrientation::ORIENTATION_UNKNOWN;
125 }
126 }
127
reportOrientation()128 void WlcReporter::reportOrientation() {
129 sp<IStats> stats_client = IStats::tryGetService();
130
131 if (stats_client == nullptr) {
132 ALOGE("logWlc get IStats fail.");
133 return;
134 }
135 std::vector<VendorAtom::Value> values(1);
136
137
138 int orientationFromSensor;
139 sp<OrientationCollector> orientationCollector;
140 orientationCollector = OrientationCollector::createOrientationCollector();
141 if (orientationCollector != nullptr) {
142 orientationCollector->pollOrientation(&orientationFromSensor);
143 VendorAtom::Value tmp;
144 tmp.intValue(translateDeviceOrientationToAtomValue(orientationFromSensor));
145 values[PixelAtoms::DeviceOrientation::kOrientationFieldNumber - kVendorAtomOffset] = tmp;
146
147 VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
148 .atomId = PixelAtoms::Ids::DEVICE_ORIENTATION,
149 .values = values};
150 Return<void> retOrientation = stats_client->reportVendorAtom(event);
151 if (!retOrientation.isOk())
152 ALOGE("Unable to report Orientation to Stats service");
153 orientationCollector->disableOrientationSensor();
154 }
155 }
156
157 } // namespace pixel
158 } // namespace google
159 } // namespace hardware
160 } // namespace android
161