Merge "Usb: capture and upload Suez metric VendorUsbDataSessionEvent" into main
This commit is contained in:
commit
2685dda06f
3 changed files with 101 additions and 5 deletions
|
@ -52,7 +52,7 @@ cc_binary {
|
||||||
"android.frameworks.stats-V2-ndk",
|
"android.frameworks.stats-V2-ndk",
|
||||||
"pixelatoms-cpp",
|
"pixelatoms-cpp",
|
||||||
"libbinder_ndk",
|
"libbinder_ndk",
|
||||||
|
"libprotobuf-cpp-lite",
|
||||||
],
|
],
|
||||||
static_libs: [
|
static_libs: [
|
||||||
"libpixelusb-aidl",
|
"libpixelusb-aidl",
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "Usb.h"
|
#include "Usb.h"
|
||||||
|
|
||||||
#include <aidl/android/frameworks/stats/IStats.h>
|
#include <aidl/android/frameworks/stats/IStats.h>
|
||||||
|
#include <pixelusb/CommonUtils.h>
|
||||||
#include <pixelusb/UsbGadgetAidlCommon.h>
|
#include <pixelusb/UsbGadgetAidlCommon.h>
|
||||||
#include <pixelstats/StatsHelper.h>
|
#include <pixelstats/StatsHelper.h>
|
||||||
|
|
||||||
|
@ -54,6 +55,9 @@ using android::base::Trim;
|
||||||
using android::hardware::google::pixel::getStatsService;
|
using android::hardware::google::pixel::getStatsService;
|
||||||
using android::hardware::google::pixel::PixelAtoms::VendorUsbPortOverheat;
|
using android::hardware::google::pixel::PixelAtoms::VendorUsbPortOverheat;
|
||||||
using android::hardware::google::pixel::reportUsbPortOverheat;
|
using android::hardware::google::pixel::reportUsbPortOverheat;
|
||||||
|
using android::hardware::google::pixel::PixelAtoms::VendorUsbDataSessionEvent;
|
||||||
|
using android::hardware::google::pixel::reportUsbDataSessionEvent;
|
||||||
|
using android::hardware::google::pixel::usb::BuildVendorUsbDataSessionEvent;
|
||||||
|
|
||||||
namespace aidl {
|
namespace aidl {
|
||||||
namespace android {
|
namespace android {
|
||||||
|
@ -98,6 +102,8 @@ void queryVersionHelper(android::hardware::usb::Usb *usb,
|
||||||
std::vector<PortStatus> *currentPortStatus);
|
std::vector<PortStatus> *currentPortStatus);
|
||||||
AltModeData::DisplayPortAltModeData constructAltModeData(string hpd, string pin_assignment,
|
AltModeData::DisplayPortAltModeData constructAltModeData(string hpd, string pin_assignment,
|
||||||
string link_status, string vdo);
|
string link_status, string vdo);
|
||||||
|
void queryUsbDataSession(android::hardware::usb::Usb *usb,
|
||||||
|
std::vector<PortStatus> *currentPortStatus);
|
||||||
|
|
||||||
#define USB_STATE_MAX_LEN 20
|
#define USB_STATE_MAX_LEN 20
|
||||||
|
|
||||||
|
@ -957,6 +963,7 @@ void queryVersionHelper(android::hardware::usb::Usb *usb,
|
||||||
queryMoistureDetectionStatus(currentPortStatus);
|
queryMoistureDetectionStatus(currentPortStatus);
|
||||||
queryPowerTransferStatus(currentPortStatus);
|
queryPowerTransferStatus(currentPortStatus);
|
||||||
queryNonCompliantChargerStatus(currentPortStatus);
|
queryNonCompliantChargerStatus(currentPortStatus);
|
||||||
|
queryUsbDataSession(usb, currentPortStatus);
|
||||||
pthread_mutex_lock(&usb->mDisplayPortLock);
|
pthread_mutex_lock(&usb->mDisplayPortLock);
|
||||||
if (!usb->mDisplayPortFirstSetupDone &&
|
if (!usb->mDisplayPortFirstSetupDone &&
|
||||||
usb->getDisplayPortUsbPathHelper(&displayPortUsbPath) == Status::SUCCESS) {
|
usb->getDisplayPortUsbPathHelper(&displayPortUsbPath) == Status::SUCCESS) {
|
||||||
|
@ -1052,6 +1059,54 @@ void report_overheat_event(android::hardware::usb::Usb *usb) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void report_usb_data_session_event(android::hardware::usb::Usb *usb) {
|
||||||
|
std::vector<VendorUsbDataSessionEvent> events;
|
||||||
|
|
||||||
|
if (usb->mDataRole == PortDataRole::DEVICE) {
|
||||||
|
VendorUsbDataSessionEvent event;
|
||||||
|
BuildVendorUsbDataSessionEvent(false /* is_host */, std::chrono::steady_clock::now(),
|
||||||
|
usb->mDataSessionStart, &usb->mDeviceState.states,
|
||||||
|
&usb->mDeviceState.timestamps, &event);
|
||||||
|
events.push_back(event);
|
||||||
|
} else if (usb->mDataRole == PortDataRole::HOST) {
|
||||||
|
bool empty = true;
|
||||||
|
for (auto &entry : usb->mHostStateMap) {
|
||||||
|
// Host port will at least get an not_attached event after enablement,
|
||||||
|
// skip upload if no additional state is added.
|
||||||
|
if (entry.second.states.size() > 1) {
|
||||||
|
VendorUsbDataSessionEvent event;
|
||||||
|
BuildVendorUsbDataSessionEvent(true /* is_host */, std::chrono::steady_clock::now(),
|
||||||
|
usb->mDataSessionStart, &entry.second.states,
|
||||||
|
&entry.second.timestamps, &event);
|
||||||
|
events.push_back(event);
|
||||||
|
empty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// All host ports have no state update, upload an event to reflect it
|
||||||
|
if (empty && usb->mHostStateMap.size() > 0) {
|
||||||
|
VendorUsbDataSessionEvent event;
|
||||||
|
BuildVendorUsbDataSessionEvent(true /* is_host */, std::chrono::steady_clock::now(),
|
||||||
|
usb->mDataSessionStart,
|
||||||
|
&usb->mHostStateMap.begin()->second.states,
|
||||||
|
&usb->mHostStateMap.begin()->second.timestamps,
|
||||||
|
&event);
|
||||||
|
events.push_back(event);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const shared_ptr<IStats> stats_client = getStatsService();
|
||||||
|
if (!stats_client) {
|
||||||
|
ALOGE("Unable to get AIDL Stats service");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &event : events) {
|
||||||
|
reportUsbDataSessionEvent(stats_client, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct data {
|
struct data {
|
||||||
int uevent_fd;
|
int uevent_fd;
|
||||||
::aidl::android::hardware::usb::Usb *usb;
|
::aidl::android::hardware::usb::Usb *usb;
|
||||||
|
@ -1141,14 +1196,16 @@ static int registerEpollEntryByFile(Usb *usb, std::string name, int flags,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clearUsbDeviceState(struct Usb::usbDeviceState *device) {
|
static void clearUsbDeviceState(struct Usb::usbDeviceState *device) {
|
||||||
device->latestState.clear();
|
device->states.clear();
|
||||||
|
device->timestamps.clear();
|
||||||
device->portResetCount = 0;
|
device->portResetCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateUsbDeviceState(struct Usb::usbDeviceState *device, char *state) {
|
static void updateUsbDeviceState(struct Usb::usbDeviceState *device, char *state) {
|
||||||
ALOGI("Update USB device state: %s", state);
|
ALOGI("Update USB device state: %s", state);
|
||||||
|
|
||||||
device->latestState = state;
|
device->states.push_back(state);
|
||||||
|
device->timestamps.push_back(std::chrono::steady_clock::now());
|
||||||
|
|
||||||
if (!std::strcmp(state, "configured\n")) {
|
if (!std::strcmp(state, "configured\n")) {
|
||||||
device->portResetCount = 0;
|
device->portResetCount = 0;
|
||||||
|
@ -1168,6 +1225,37 @@ static void host_event(uint32_t /*epevents*/, struct Usb::payload *payload) {
|
||||||
updateUsbDeviceState(&payload->usb->mHostStateMap[payload->name], state);
|
updateUsbDeviceState(&payload->usb->mHostStateMap[payload->name], state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void queryUsbDataSession(android::hardware::usb::Usb *usb,
|
||||||
|
std::vector<PortStatus> *currentPortStatus) {
|
||||||
|
PortDataRole newDataRole = (*currentPortStatus)[0].currentDataRole;
|
||||||
|
PowerBrickStatus newPowerBrickStatus = (*currentPortStatus)[0].powerBrickStatus;
|
||||||
|
|
||||||
|
if (newDataRole != usb->mDataRole) {
|
||||||
|
// Upload metrics for the last non-powerbrick data session that has ended
|
||||||
|
if (usb->mDataRole != PortDataRole::NONE && !usb->mIsPowerBrickConnected) {
|
||||||
|
report_usb_data_session_event(usb);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up for the new data session
|
||||||
|
usb->mDataRole = newDataRole;
|
||||||
|
usb->mDataSessionStart = std::chrono::steady_clock::now();
|
||||||
|
usb->mIsPowerBrickConnected = (newPowerBrickStatus == PowerBrickStatus::CONNECTED);
|
||||||
|
if (newDataRole == PortDataRole::DEVICE) {
|
||||||
|
clearUsbDeviceState(&usb->mDeviceState);
|
||||||
|
} else if (newDataRole == PortDataRole::HOST) {
|
||||||
|
for (auto &entry : usb->mHostStateMap) {
|
||||||
|
clearUsbDeviceState(&entry.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PowerBrickStatus could flip from DISCONNECTED to CONNECTED during the same data
|
||||||
|
// session when BC1.2 SDP times out and falls back to DCP
|
||||||
|
if (newPowerBrickStatus == PowerBrickStatus::CONNECTED) {
|
||||||
|
usb->mIsPowerBrickConnected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void uevent_event(uint32_t /*epevents*/, struct Usb::payload *payload) {
|
static void uevent_event(uint32_t /*epevents*/, struct Usb::payload *payload) {
|
||||||
char msg[UEVENT_MSG_LEN + 2];
|
char msg[UEVENT_MSG_LEN + 2];
|
||||||
char *cp;
|
char *cp;
|
||||||
|
@ -1263,7 +1351,6 @@ static void uevent_event(uint32_t /*epevents*/, struct Usb::payload *payload) {
|
||||||
registerEpollEntryByFile(payload->usb, path, EPOLLPRI, host_event);
|
registerEpollEntryByFile(payload->usb, path, EPOLLPRI, host_event);
|
||||||
} else if (action == "unbind") {
|
} else if (action == "unbind") {
|
||||||
unregisterEpollEntry(payload->usb, path);
|
unregisterEpollEntry(payload->usb, path);
|
||||||
clearUsbDeviceState(&payload->usb->mHostStateMap[path]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <android-base/file.h>
|
#include <android-base/file.h>
|
||||||
#include <aidl/android/hardware/usb/BnUsb.h>
|
#include <aidl/android/hardware/usb/BnUsb.h>
|
||||||
#include <aidl/android/hardware/usb/BnUsbCallback.h>
|
#include <aidl/android/hardware/usb/BnUsbCallback.h>
|
||||||
|
#include <chrono>
|
||||||
#include <pixelusb/UsbOverheatEvent.h>
|
#include <pixelusb/UsbOverheatEvent.h>
|
||||||
#include <sys/eventfd.h>
|
#include <sys/eventfd.h>
|
||||||
#include <utils/Log.h>
|
#include <utils/Log.h>
|
||||||
|
@ -132,12 +133,20 @@ struct Usb : public BnUsb {
|
||||||
|
|
||||||
// USB device state monitoring
|
// USB device state monitoring
|
||||||
struct usbDeviceState {
|
struct usbDeviceState {
|
||||||
std::string latestState;
|
// Usb device state raw strings read from sysfs
|
||||||
|
std::vector<std::string> states;
|
||||||
|
// Timestamps of when the usb device states were captured
|
||||||
|
std::vector<std::chrono::steady_clock::time_point> timestamps;
|
||||||
int portResetCount;
|
int portResetCount;
|
||||||
};
|
};
|
||||||
struct usbDeviceState mDeviceState;
|
struct usbDeviceState mDeviceState;
|
||||||
// Map host device path name to usbDeviceState
|
// Map host device path name to usbDeviceState
|
||||||
std::map<std::string, struct usbDeviceState> mHostStateMap;
|
std::map<std::string, struct usbDeviceState> mHostStateMap;
|
||||||
|
// Cache relevant info for USB data session metrics collection when a session starts, including
|
||||||
|
// the data role, power brick status and the time when the session starts.
|
||||||
|
PortDataRole mDataRole;
|
||||||
|
bool mIsPowerBrickConnected;
|
||||||
|
std::chrono::steady_clock::time_point mDataSessionStart;
|
||||||
|
|
||||||
// File monitoring through epoll
|
// File monitoring through epoll
|
||||||
int mEpollFd;
|
int mEpollFd;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue