diff --git a/usb/Android.bp b/usb/Android.bp index ccaa0011..40454afd 100644 --- a/usb/Android.bp +++ b/usb/Android.bp @@ -36,6 +36,7 @@ cc_binary { cflags: ["-Wall", "-Werror"], shared_libs: [ "libbase", + "libbinder", "libhidlbase", "liblog", "libutils", @@ -47,8 +48,20 @@ cc_binary { "android.hardware.usb.gadget@1.0", "android.hardware.usb.gadget@1.1", "android.hardware.usb.gadget@1.2", + "android.hardware.thermal@1.0", + "android.hardware.thermal@2.0", "libcutils", + "android.frameworks.stats-V1-ndk_platform", + "pixelatoms-cpp", + "libbinder_ndk", + ], + static_libs: [ + "libpixelusb", + "libpixelstats", + ], + export_shared_lib_headers: [ + "android.frameworks.stats-V1-ndk_platform", + "pixelatoms-cpp", ], - static_libs: ["libpixelusb"], proprietary: true, } diff --git a/usb/Usb.cpp b/usb/Usb.cpp index 3270c46b..caf4f57b 100644 --- a/usb/Usb.cpp +++ b/usb/Usb.cpp @@ -37,7 +37,14 @@ #include "Usb.h" #include "UsbGadget.h" +#include +#include + +using aidl::android::frameworks::stats::IStats; using android::base::GetProperty; +using android::hardware::google::pixel::getStatsService; +using android::hardware::google::pixel::PixelAtoms::VendorUsbPortOverheat; +using android::hardware::google::pixel::reportUsbPortOverheat; namespace android { namespace hardware { @@ -96,6 +103,13 @@ constexpr char kContaminantDetectionPath[] = "i2c-max77759tcpc/contaminant_detec constexpr char kStatusPath[] = "i2c-max77759tcpc/contaminant_detection_status"; constexpr char kTypecPath[] = "/sys/class/typec"; constexpr char kDisableContatminantDetection[] = "vendor.usb.contaminantdisable"; +constexpr char kOverheatStatsPath[] = "/sys/devices/platform/google,usbc_port_cooling_dev/"; +constexpr char kOverheatStatsDev[] = "DRIVER=google,usbc_port_cooling_dev"; +constexpr char kThermalZoneForTrip[] = "VIRTUAL-USB-THROTTLING"; +constexpr char kThermalZoneForTempReadPrimary[] = "usb_pwr_therm2"; +constexpr char kThermalZoneForTempReadSecondary1[] = "usb_pwr_therm"; +constexpr char kThermalZoneForTempReadSecondary2[] = "qi_therm"; +constexpr int kSamplingIntervalSec = 5; int32_t readFile(const std::string &filename, std::string *contents) { FILE *fp; @@ -327,7 +341,15 @@ Usb::Usb() : mLock(PTHREAD_MUTEX_INITIALIZER), mRoleSwitchLock(PTHREAD_MUTEX_INITIALIZER), mPartnerLock(PTHREAD_MUTEX_INITIALIZER), - mPartnerUp(false) { + mPartnerUp(false), + mOverheat(ZoneInfo(TemperatureType::USB_PORT, kThermalZoneForTrip, + ThrottlingSeverity::CRITICAL), + {ZoneInfo(TemperatureType::UNKNOWN, kThermalZoneForTempReadPrimary, + ThrottlingSeverity::NONE), + ZoneInfo(TemperatureType::UNKNOWN, kThermalZoneForTempReadSecondary1, + ThrottlingSeverity::NONE), + ZoneInfo(TemperatureType::UNKNOWN, kThermalZoneForTempReadSecondary2, + ThrottlingSeverity::NONE)}, kSamplingIntervalSec) { pthread_condattr_t attr; if (pthread_condattr_init(&attr)) { ALOGE("pthread_condattr_init failed: %s", strerror(errno)); @@ -525,7 +547,8 @@ bool canSwitchRoleHelper(const std::string &portName, PortRoleType /*type*/) { * The caller of this method would reconstruct the V1_0::PortStatus * object if required. */ -Status getPortStatusHelper(hidl_vec *currentPortStatus_1_2, HALVersion version) { +Status getPortStatusHelper(hidl_vec *currentPortStatus_1_2, HALVersion version, + android::hardware::usb::V1_3::implementation::Usb *usb) { std::unordered_map names; Status result = getTypeCPortNamesHelper(&names); int i = -1; @@ -586,6 +609,12 @@ Status getPortStatusHelper(hidl_vec *currentPortStatus_1_2, HALVersi (*currentPortStatus_1_2)[i].status_1_1.status.currentMode = V1_0::PortMode::NONE; } + // Query temperature for the first connect + if (port.second && !usb->mPluggedTemperatureCelsius) { + usb->mOverheat.getCurrentTemperature(kThermalZoneForTempReadPrimary, + &usb->mPluggedTemperatureCelsius); + ALOGV("USB Initial temperature: %f", usb->mPluggedTemperatureCelsius); + } ALOGI( "%d:%s connected:%d canChangeMode:%d canChagedata:%d canChangePower:%d " "supportedModes:%d", @@ -612,16 +641,16 @@ void queryVersionHelper(android::hardware::usb::V1_3::implementation::Usb *usb, pthread_mutex_lock(&usb->mLock); if (usb->mCallback_1_0 != NULL) { if (callback_V1_2 != NULL) { - status = getPortStatusHelper(currentPortStatus_1_2, HALVersion::V1_2); + status = getPortStatusHelper(currentPortStatus_1_2, HALVersion::V1_2, usb); if (status == Status::SUCCESS) queryMoistureDetectionStatus(currentPortStatus_1_2); } else if (callback_V1_1 != NULL) { - status = getPortStatusHelper(currentPortStatus_1_2, HALVersion::V1_1); + status = getPortStatusHelper(currentPortStatus_1_2, HALVersion::V1_1, usb); currentPortStatus_1_1.resize(currentPortStatus_1_2->size()); for (unsigned long i = 0; i < currentPortStatus_1_2->size(); i++) currentPortStatus_1_1[i] = (*currentPortStatus_1_2)[i].status_1_1; } else { - status = getPortStatusHelper(currentPortStatus_1_2, HALVersion::V1_0); + status = getPortStatusHelper(currentPortStatus_1_2, HALVersion::V1_0, usb); currentPortStatus.resize(currentPortStatus_1_2->size()); for (unsigned long i = 0; i < currentPortStatus_1_2->size(); i++) currentPortStatus[i] = (*currentPortStatus_1_2)[i].status_1_1.status; @@ -673,6 +702,39 @@ Return Usb::enableContaminantPresenceProtection(const hidl_string & /*port return Void(); } +void report_overheat_event(android::hardware::usb::V1_3::implementation::Usb *usb) { + VendorUsbPortOverheat overheat_info; + std::string contents; + + overheat_info.set_plug_temperature_deci_c(usb->mPluggedTemperatureCelsius * 10); + overheat_info.set_max_temperature_deci_c(usb->mOverheat.getMaxOverheatTemperature() * 10); + if (ReadFileToString(std::string(kOverheatStatsPath) + "trip_time", &contents)) { + overheat_info.set_time_to_overheat_secs(stoi(contents)); + } else { + ALOGE("Unable to read trip_time"); + return; + } + if (ReadFileToString(std::string(kOverheatStatsPath) + "hysteresis_time", &contents)) { + overheat_info.set_time_to_hysteresis_secs(stoi(contents)); + } else { + ALOGE("Unable to read hysteresis_time"); + return; + } + if (ReadFileToString(std::string(kOverheatStatsPath) + "cleared_time", &contents)) { + overheat_info.set_time_to_inactive_secs(stoi(contents)); + } else { + ALOGE("Unable to read cleared_time"); + return; + } + + const std::shared_ptr stats_client = getStatsService(); + if (!stats_client) { + ALOGE("Unable to get AIDL Stats service"); + } else { + reportUsbPortOverheat(stats_client, overheat_info); + } +} + struct data { int uevent_fd; android::hardware::usb::V1_3::implementation::Usb *usb; @@ -700,6 +762,10 @@ static void uevent_event(uint32_t /*epevents*/, struct data *payload) { payload->usb->mPartnerUp = true; pthread_cond_signal(&payload->usb->mPartnerCV); pthread_mutex_unlock(&payload->usb->mPartnerLock); + // Update Plugged temperature + payload->usb->mOverheat.getCurrentTemperature(kThermalZoneForTempReadPrimary, + &payload->usb->mPluggedTemperatureCelsius); + ALOGI("Usb Plugged temp: %f", payload->usb->mPluggedTemperatureCelsius); } else if (!strncmp(cp, "DEVTYPE=typec_", strlen("DEVTYPE=typec_")) || !strncmp(cp, "DRIVER=max77759tcpc", strlen("DRIVER=max77759tcpc"))) { @@ -725,6 +791,9 @@ static void uevent_event(uint32_t /*epevents*/, struct data *payload) { pthread_mutex_unlock(&payload->usb->mRoleSwitchLock); } break; + } else if (!strncmp(cp, kOverheatStatsDev, strlen(kOverheatStatsDev))) { + ALOGV("Overheat Cooling device suez update"); + report_overheat_event(payload->usb); } /* advance to after the next \0 */ while (*cp++) { diff --git a/usb/Usb.h b/usb/Usb.h index ab97bd05..23ed0111 100644 --- a/usb/Usb.h +++ b/usb/Usb.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #define UEVENT_MSG_LEN 2048 @@ -36,14 +37,18 @@ namespace usb { namespace V1_3 { namespace implementation { -using ::android::sp; +using ::android::base::WriteStringToFile; +using ::android::base::ReadFileToString; using ::android::hardware::hidl_array; using ::android::hardware::hidl_memory; using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; -using ::android::base::WriteStringToFile; +using ::android::hardware::google::pixel::usb::UsbOverheatEvent; +using ::android::hardware::google::pixel::usb::ZoneInfo; +using ::android::hardware::thermal::V2_0::TemperatureType; +using ::android::hardware::thermal::V2_0::ThrottlingSeverity; using ::android::hardware::usb::V1_0::PortRole; using ::android::hardware::usb::V1_0::PortRoleType; using ::android::hardware::usb::V1_0::PortDataRole; @@ -58,6 +63,7 @@ using ::android::hardware::usb::V1_1::PortMode_1_1; using ::android::hardware::usb::V1_1::PortStatus_1_1; using ::android::hidl::base::V1_0::DebugInfo; using ::android::hidl::base::V1_0::IBase; +using ::android::sp; enum class HALVersion{ V1_0, @@ -95,6 +101,11 @@ struct Usb : public IUsb { // Variable to signal partner coming back online after type switch bool mPartnerUp; + // Usb Overheat object for push suez event + UsbOverheatEvent mOverheat; + // Temperature when connected + float mPluggedTemperatureCelsius; + private: pthread_t mPoll; }; diff --git a/usb/android.hardware.usb@1.3-service.gs101.rc b/usb/android.hardware.usb@1.3-service.gs101.rc index 81ae2f9e..966726bb 100644 --- a/usb/android.hardware.usb@1.3-service.gs101.rc +++ b/usb/android.hardware.usb@1.3-service.gs101.rc @@ -1,7 +1,8 @@ service vendor.usb-hal-1-3 /vendor/bin/hw/android.hardware.usb@1.3-service.gs101 class hal user system - group system shell mtp + group system shell mtp wakelock + capabilities WAKE_ALARM BLOCK_SUSPEND on post-fs chown root system /sys/class/typec/port0/power_role