Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dc021d8c authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "MetricsCollector: Do not store entire InputDeviceInfo for space efficiency" into main

parents a36c6f60 0dd48ae2
Loading
Loading
Loading
Loading
+22 −15
Original line number Diff line number Diff line
@@ -64,14 +64,13 @@ int32_t linuxBusToInputDeviceBusEnum(int32_t linuxBus, bool isUsiStylus) {
class : public InputDeviceMetricsLogger {
    nanoseconds getCurrentTime() override { return nanoseconds(systemTime(SYSTEM_TIME_MONOTONIC)); }

    void logInputDeviceUsageReported(const InputDeviceInfo& info,
    void logInputDeviceUsageReported(const MetricsDeviceInfo& info,
                                     const DeviceUsageReport& report) override {
        const int32_t durationMillis =
                std::chrono::duration_cast<std::chrono::milliseconds>(report.usageDuration).count();
        const static std::vector<int32_t> empty;
        const auto& identifier = info.getIdentifier();

        ALOGD_IF(DEBUG, "Usage session reported for device: %s", identifier.name.c_str());
        ALOGD_IF(DEBUG, "Usage session reported for device id: %d", info.deviceId);
        ALOGD_IF(DEBUG, "    Total duration: %dms", durationMillis);
        ALOGD_IF(DEBUG, "    Source breakdown:");

@@ -96,11 +95,9 @@ class : public InputDeviceMetricsLogger {
            ALOGD_IF(DEBUG, "        - uid: %s\t duration: %dms", uid.toString().c_str(),
                     durMillis);
        }
        util::stats_write(util::INPUTDEVICE_USAGE_REPORTED, identifier.vendor, identifier.product,
                          identifier.version,
                          linuxBusToInputDeviceBusEnum(identifier.bus,
                                                       info.getUsiVersion().has_value()),
                          durationMillis, sources, durationsPerSource, uids, durationsPerUid);
        util::stats_write(util::INPUTDEVICE_USAGE_REPORTED, info.vendor, info.product, info.version,
                          linuxBusToInputDeviceBusEnum(info.bus, info.isUsiStylus), durationMillis,
                          sources, durationsPerSource, uids, durationsPerUid);
    }
} sStatsdLogger;

@@ -116,7 +113,7 @@ bool isIgnoredInputDeviceId(int32_t deviceId) {

} // namespace

InputDeviceUsageSource getUsageSourceForKeyArgs(const InputDeviceInfo& info,
InputDeviceUsageSource getUsageSourceForKeyArgs(int32_t keyboardType,
                                                const NotifyKeyArgs& keyArgs) {
    if (!isFromSource(keyArgs.source, AINPUT_SOURCE_KEYBOARD)) {
        return InputDeviceUsageSource::UNKNOWN;
@@ -132,7 +129,7 @@ InputDeviceUsageSource getUsageSourceForKeyArgs(const InputDeviceInfo& info,
        return InputDeviceUsageSource::GAMEPAD;
    }

    if (info.getKeyboardType() == AINPUT_KEYBOARD_TYPE_ALPHABETIC) {
    if (keyboardType == AINPUT_KEYBOARD_TYPE_ALPHABETIC) {
        return InputDeviceUsageSource::KEYBOARD;
    }

@@ -232,8 +229,8 @@ void InputDeviceMetricsCollector::notifyConfigurationChanged(

void InputDeviceMetricsCollector::notifyKey(const NotifyKeyArgs& args) {
    reportCompletedSessions();
    const SourceProvider getSources = [&args](const InputDeviceInfo& info) {
        return std::set{getUsageSourceForKeyArgs(info, args)};
    const SourceProvider getSources = [&args](const MetricsDeviceInfo& info) {
        return std::set{getUsageSourceForKeyArgs(info.keyboardType, args)};
    };
    onInputDeviceUsage(DeviceId{args.deviceId}, nanoseconds(args.eventTime), getSources);

@@ -291,13 +288,23 @@ void InputDeviceMetricsCollector::dump(std::string& dump) {
}

void InputDeviceMetricsCollector::onInputDevicesChanged(const std::vector<InputDeviceInfo>& infos) {
    std::map<DeviceId, InputDeviceInfo> newDeviceInfos;
    std::map<DeviceId, MetricsDeviceInfo> newDeviceInfos;

    for (const InputDeviceInfo& info : infos) {
        if (isIgnoredInputDeviceId(info.getId())) {
            continue;
        }
        newDeviceInfos.emplace(info.getId(), info);
        const auto& i = info.getIdentifier();
        newDeviceInfos.emplace(info.getId(),
                               MetricsDeviceInfo{
                                       .deviceId = info.getId(),
                                       .vendor = i.vendor,
                                       .product = i.product,
                                       .version = i.version,
                                       .bus = i.bus,
                                       .isUsiStylus = info.getUsiVersion().has_value(),
                                       .keyboardType = info.getKeyboardType(),
                               });
    }

    for (auto [deviceId, info] : mLoggedDeviceInfos) {
@@ -311,7 +318,7 @@ void InputDeviceMetricsCollector::onInputDevicesChanged(const std::vector<InputD
}

void InputDeviceMetricsCollector::onInputDeviceRemoved(DeviceId deviceId,
                                                       const InputDeviceInfo& info) {
                                                       const MetricsDeviceInfo& info) {
    auto it = mActiveUsageSessions.find(deviceId);
    if (it == mActiveUsageSessions.end()) {
        return;
+19 −5
Original line number Diff line number Diff line
@@ -79,7 +79,7 @@ enum class InputDeviceUsageSource : int32_t {
};

/** Returns the InputDeviceUsageSource that corresponds to the key event. */
InputDeviceUsageSource getUsageSourceForKeyArgs(const InputDeviceInfo&, const NotifyKeyArgs&);
InputDeviceUsageSource getUsageSourceForKeyArgs(int32_t keyboardType, const NotifyKeyArgs&);

/** Returns the InputDeviceUsageSources that correspond to the motion event. */
std::set<InputDeviceUsageSource> getUsageSourcesForMotionArgs(const NotifyMotionArgs&);
@@ -110,7 +110,19 @@ public:
        UidUsageBreakdown uidBreakdown;
    };

    virtual void logInputDeviceUsageReported(const InputDeviceInfo&, const DeviceUsageReport&) = 0;
    // A subset of information from the InputDeviceInfo class that is used for metrics collection,
    // used to avoid copying and storing all of the fields and strings in InputDeviceInfo.
    struct MetricsDeviceInfo {
        int32_t deviceId;
        int32_t vendor;
        int32_t product;
        int32_t version;
        int32_t bus;
        bool isUsiStylus;
        int32_t keyboardType;
    };
    virtual void logInputDeviceUsageReported(const MetricsDeviceInfo&,
                                             const DeviceUsageReport&) = 0;
    virtual ~InputDeviceMetricsLogger() = default;
};

@@ -153,8 +165,9 @@ private:
    }

    using Uid = gui::Uid;
    using MetricsDeviceInfo = InputDeviceMetricsLogger::MetricsDeviceInfo;

    std::map<DeviceId, InputDeviceInfo> mLoggedDeviceInfos;
    std::map<DeviceId, MetricsDeviceInfo> mLoggedDeviceInfos;

    using Interaction = std::tuple<DeviceId, std::chrono::nanoseconds, std::set<Uid>>;
    SyncQueue<Interaction> mInteractionsQueue;
@@ -188,8 +201,9 @@ private:
    std::map<DeviceId, ActiveSession> mActiveUsageSessions;

    void onInputDevicesChanged(const std::vector<InputDeviceInfo>& infos);
    void onInputDeviceRemoved(DeviceId deviceId, const InputDeviceInfo& info);
    using SourceProvider = std::function<std::set<InputDeviceUsageSource>(const InputDeviceInfo&)>;
    void onInputDeviceRemoved(DeviceId deviceId, const MetricsDeviceInfo& info);
    using SourceProvider =
            std::function<std::set<InputDeviceUsageSource>(const MetricsDeviceInfo&)>;
    void onInputDeviceUsage(DeviceId deviceId, std::chrono::nanoseconds eventTime,
                            const SourceProvider& getSources);
    void onInputDeviceInteraction(const Interaction&);
+17 −18
Original line number Diff line number Diff line
@@ -66,21 +66,14 @@ InputDeviceIdentifier generateTestIdentifier(int32_t id = DEVICE_ID) {
}

InputDeviceInfo generateTestDeviceInfo(int32_t id = DEVICE_ID,
                                       uint32_t sources = TOUCHSCREEN | STYLUS,
                                       bool isAlphabetic = false) {
                                       uint32_t sources = TOUCHSCREEN | STYLUS) {
    auto info = InputDeviceInfo();
    info.initialize(id, /*generation=*/1, /*controllerNumber=*/1, generateTestIdentifier(id),
                    "alias", /*isExternal=*/false, /*hasMic=*/false, ADISPLAY_ID_NONE);
    info.addSource(sources);
    info.setKeyboardType(isAlphabetic ? AINPUT_KEYBOARD_TYPE_ALPHABETIC
                                      : AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC);
    return info;
}

const InputDeviceInfo ALPHABETIC_KEYBOARD_INFO =
        generateTestDeviceInfo(DEVICE_ID, KEY_SOURCES, /*isAlphabetic=*/true);
const InputDeviceInfo NON_ALPHABETIC_KEYBOARD_INFO =
        generateTestDeviceInfo(DEVICE_ID, KEY_SOURCES, /*isAlphabetic=*/false);
const InputDeviceInfo TOUCHSCREEN_STYLUS_INFO = generateTestDeviceInfo(DEVICE_ID);
const InputDeviceInfo SECOND_TOUCHSCREEN_STYLUS_INFO = generateTestDeviceInfo(DEVICE_ID_2);

@@ -106,7 +99,7 @@ TEST_P(DeviceClassificationFixture, ValidClassifications) {
    switch (usageSource) {
        case InputDeviceUsageSource::UNKNOWN: {
            ASSERT_EQ(InputDeviceUsageSource::UNKNOWN,
                      getUsageSourceForKeyArgs(generateTestDeviceInfo(),
                      getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_NONE,
                                               KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, TOUCHSCREEN)
                                                       .build()));

@@ -123,7 +116,7 @@ TEST_P(DeviceClassificationFixture, ValidClassifications) {

        case InputDeviceUsageSource::BUTTONS: {
            ASSERT_EQ(InputDeviceUsageSource::BUTTONS,
                      getUsageSourceForKeyArgs(NON_ALPHABETIC_KEYBOARD_INFO,
                      getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC,
                                               KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, KEY_SOURCES)
                                                       .keyCode(AKEYCODE_STYLUS_BUTTON_TAIL)
                                                       .build()));
@@ -132,7 +125,7 @@ TEST_P(DeviceClassificationFixture, ValidClassifications) {

        case InputDeviceUsageSource::KEYBOARD: {
            ASSERT_EQ(InputDeviceUsageSource::KEYBOARD,
                      getUsageSourceForKeyArgs(ALPHABETIC_KEYBOARD_INFO,
                      getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_ALPHABETIC,
                                               KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, KEY_SOURCES)
                                                       .build()));
            break;
@@ -140,13 +133,13 @@ TEST_P(DeviceClassificationFixture, ValidClassifications) {

        case InputDeviceUsageSource::DPAD: {
            ASSERT_EQ(InputDeviceUsageSource::DPAD,
                      getUsageSourceForKeyArgs(NON_ALPHABETIC_KEYBOARD_INFO,
                      getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC,
                                               KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, KEY_SOURCES)
                                                       .keyCode(AKEYCODE_DPAD_CENTER)
                                                       .build()));

            ASSERT_EQ(InputDeviceUsageSource::DPAD,
                      getUsageSourceForKeyArgs(ALPHABETIC_KEYBOARD_INFO,
                      getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_ALPHABETIC,
                                               KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, KEY_SOURCES)
                                                       .keyCode(AKEYCODE_DPAD_CENTER)
                                                       .build()));
@@ -155,13 +148,13 @@ TEST_P(DeviceClassificationFixture, ValidClassifications) {

        case InputDeviceUsageSource::GAMEPAD: {
            ASSERT_EQ(InputDeviceUsageSource::GAMEPAD,
                      getUsageSourceForKeyArgs(NON_ALPHABETIC_KEYBOARD_INFO,
                      getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC,
                                               KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, KEY_SOURCES)
                                                       .keyCode(AKEYCODE_BUTTON_A)
                                                       .build()));

            ASSERT_EQ(InputDeviceUsageSource::GAMEPAD,
                      getUsageSourceForKeyArgs(ALPHABETIC_KEYBOARD_INFO,
                      getUsageSourceForKeyArgs(AINPUT_KEYBOARD_TYPE_ALPHABETIC,
                                               KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, KEY_SOURCES)
                                                       .keyCode(AKEYCODE_BUTTON_A)
                                                       .build()));
@@ -358,7 +351,13 @@ protected:
                           std::optional<UidUsageBreakdown> uidBreakdown = {}) {
        ASSERT_GE(mLoggedUsageSessions.size(), 1u);
        const auto& [loggedInfo, report] = *mLoggedUsageSessions.begin();
        ASSERT_EQ(info.getIdentifier(), loggedInfo.getIdentifier());
        const auto& i = info.getIdentifier();
        ASSERT_EQ(info.getId(), loggedInfo.deviceId);
        ASSERT_EQ(i.vendor, loggedInfo.vendor);
        ASSERT_EQ(i.product, loggedInfo.product);
        ASSERT_EQ(i.version, loggedInfo.version);
        ASSERT_EQ(i.bus, loggedInfo.bus);
        ASSERT_EQ(info.getUsiVersion().has_value(), loggedInfo.isUsiStylus);
        ASSERT_EQ(duration, report.usageDuration);
        if (sourceBreakdown) {
            ASSERT_EQ(sourceBreakdown, report.sourceBreakdown);
@@ -389,12 +388,12 @@ protected:
    }

private:
    std::vector<std::tuple<InputDeviceInfo, DeviceUsageReport>> mLoggedUsageSessions;
    std::vector<std::tuple<MetricsDeviceInfo, DeviceUsageReport>> mLoggedUsageSessions;
    nanoseconds mCurrentTime{TIME};

    nanoseconds getCurrentTime() override { return mCurrentTime; }

    void logInputDeviceUsageReported(const InputDeviceInfo& info,
    void logInputDeviceUsageReported(const MetricsDeviceInfo& info,
                                     const DeviceUsageReport& report) override {
        mLoggedUsageSessions.emplace_back(info, report);
    }