Native puller API: libstatspulled
Create a new library for the native puller callback API. The library has 2 main interfaces: register_stats_pull_atom_callback, which is used to register a callback, and stats_pull_atom_callback_t, which is the callback for the puller. It also exposes pulled_stats_event_list, which is a struct wrapper around a vector of stats_event. Test: make libstatspull Bug: 142969725 Change-Id: I14fe4dc523d6f81fdeaa3fe6fad3e95aeecfe92e
This commit is contained in:
parent
b4fa891b01
commit
c03d009697
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// Copyright (C) 2019 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
// ==========================================================
|
||||
// Native library to register a pull atom callback with statsd
|
||||
// ==========================================================
|
||||
cc_library_shared {
|
||||
name: "libstatspull",
|
||||
srcs: [
|
||||
":statsd_aidl",
|
||||
"stats_pull_atom_callback.cpp",
|
||||
],
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
],
|
||||
export_include_dirs: ["include"],
|
||||
shared_libs: [
|
||||
//TODO: use libbinder_ndk.
|
||||
"libbinder",
|
||||
"libstatssocket",
|
||||
"libservices",
|
||||
],
|
||||
static_libs: [
|
||||
"liblog",
|
||||
"libutils",
|
||||
]
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
joeo@google.com
|
||||
muhammadq@google.com
|
||||
ruchirr@google.com
|
||||
singhtejinder@google.com
|
||||
tsaichristine@google.com
|
||||
yaochen@google.com
|
||||
yro@google.com
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (C) 2019, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Metadata for registering a stats_pull_atom_callback.
|
||||
* All fields are optional, and defaults will be used for unspecified fields.
|
||||
*/
|
||||
typedef struct pull_atom_metadata {
|
||||
int64_t cool_down_ns;
|
||||
int64_t timeout_ns;
|
||||
int32_t* additive_fields;
|
||||
int32_t additive_fields_size;
|
||||
} pull_atom_metadata;
|
||||
|
||||
typedef struct pulled_stats_event_list pulled_stats_event_list;
|
||||
|
||||
typedef bool (*stats_pull_atom_callback_t)(int32_t atom_tag, pulled_stats_event_list* data,
|
||||
const void* cookie);
|
||||
|
||||
struct stats_event* add_stats_event_to_pull_data(pulled_stats_event_list* pull_data);
|
||||
void register_stats_pull_atom_callback(int32_t atom_tag, stats_pull_atom_callback_t* callback,
|
||||
pull_atom_metadata* metadata, const void* cookie);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright (C) 2019, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <stats_event.h>
|
||||
#include <stats_pull_atom_callback.h>
|
||||
|
||||
#include <android/os/BnPullAtomCallback.h>
|
||||
#include <android/os/IPullAtomResultReceiver.h>
|
||||
#include <android/os/IStatsManager.h>
|
||||
#include <android/util/StatsEvent.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include "include/stats_pull_atom_callback.h"
|
||||
|
||||
struct pulled_stats_event_list {
|
||||
std::vector<stats_event*> data;
|
||||
};
|
||||
|
||||
struct stats_event* add_stats_event_to_pull_data(pulled_stats_event_list* pull_data) {
|
||||
struct stats_event* event = stats_event_obtain();
|
||||
pull_data->data.push_back(event);
|
||||
return event;
|
||||
}
|
||||
|
||||
static const int64_t DEFAULT_COOL_DOWN_NS = 1000000000LL; // 1 second.
|
||||
static const int64_t DEFAULT_TIMEOUT_NS = 10000000000LL; // 10 seconds.
|
||||
|
||||
class StatsPullAtomCallbackInternal : public android::os::BnPullAtomCallback {
|
||||
public:
|
||||
StatsPullAtomCallbackInternal(const stats_pull_atom_callback_t* callback, const void* cookie,
|
||||
const int64_t coolDownNs, const int64_t timeoutNs,
|
||||
const std::vector<int32_t> additiveFields)
|
||||
: mCallback(callback),
|
||||
mCookie(cookie),
|
||||
mCoolDownNs(coolDownNs),
|
||||
mTimeoutNs(timeoutNs),
|
||||
mAdditiveFields(additiveFields) {}
|
||||
|
||||
::android::binder::Status onPullAtom(
|
||||
int32_t atomTag,
|
||||
const ::android::sp<::android::os::IPullAtomResultReceiver>& resultReceiver) override {
|
||||
pulled_stats_event_list statsEventList;
|
||||
bool success = (*mCallback)(atomTag, &statsEventList, mCookie);
|
||||
std::vector<android::util::StatsEvent> output;
|
||||
// TODO convert stats_event into parcelable stats_event.
|
||||
resultReceiver->pullFinished(atomTag, success, output);
|
||||
for (int i = 0; i < statsEventList.data.size(); i++) {
|
||||
stats_event_release(statsEventList.data[i]);
|
||||
}
|
||||
return android::binder::Status::ok();
|
||||
}
|
||||
|
||||
const int64_t& getCoolDownNs() const { return mCoolDownNs; }
|
||||
const int64_t& getTimeoutNs() const { return mTimeoutNs; }
|
||||
const std::vector<int32_t>& getAdditiveFields() const { return mAdditiveFields; }
|
||||
|
||||
private:
|
||||
const stats_pull_atom_callback_t* mCallback;
|
||||
const void* mCookie;
|
||||
const int64_t mCoolDownNs;
|
||||
const int64_t mTimeoutNs;
|
||||
const std::vector<int32_t> mAdditiveFields;
|
||||
};
|
||||
|
||||
static std::mutex pullAtomMutex;
|
||||
static android::sp<android::os::IStatsManager> sStatsd = nullptr;
|
||||
|
||||
static std::map<int32_t, android::sp<StatsPullAtomCallbackInternal>> mPullers;
|
||||
static android::sp<android::os::IStatsManager> getStatsServiceLocked();
|
||||
|
||||
class StatsDeathRecipient : public android::IBinder::DeathRecipient {
|
||||
public:
|
||||
StatsDeathRecipient() = default;
|
||||
~StatsDeathRecipient() override = default;
|
||||
|
||||
// android::IBinder::DeathRecipient override:
|
||||
void binderDied(const android::wp<android::IBinder>& /* who */) override {
|
||||
std::lock_guard<std::mutex> lock(pullAtomMutex);
|
||||
if (sStatsd) {
|
||||
sStatsd = nullptr;
|
||||
}
|
||||
android::sp<android::os::IStatsManager> statsService = getStatsServiceLocked();
|
||||
if (statsService == nullptr) {
|
||||
return;
|
||||
}
|
||||
for (auto it : mPullers) {
|
||||
statsService->registerNativePullAtomCallback(it.first, it.second->getCoolDownNs(),
|
||||
it.second->getTimeoutNs(),
|
||||
it.second->getAdditiveFields(), it.second);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static android::sp<StatsDeathRecipient> statsDeathRecipient = new StatsDeathRecipient();
|
||||
|
||||
static android::sp<android::os::IStatsManager> getStatsServiceLocked() {
|
||||
if (!sStatsd) {
|
||||
// Fetch statsd.
|
||||
const android::sp<android::IBinder> binder =
|
||||
android::defaultServiceManager()->checkService(android::String16("stats"));
|
||||
if (!binder) {
|
||||
return nullptr;
|
||||
}
|
||||
binder->linkToDeath(statsDeathRecipient);
|
||||
sStatsd = android::interface_cast<android::os::IStatsManager>(binder);
|
||||
}
|
||||
return sStatsd;
|
||||
}
|
||||
|
||||
void register_stats_pull_atom_callback(int32_t atom_tag, stats_pull_atom_callback_t* callback,
|
||||
pull_atom_metadata* metadata, void* cookie) {
|
||||
int64_t coolDownNs = metadata == nullptr ? DEFAULT_COOL_DOWN_NS : metadata->cool_down_ns;
|
||||
int64_t timeoutNs = metadata == nullptr ? DEFAULT_TIMEOUT_NS : metadata->timeout_ns;
|
||||
|
||||
std::vector<int32_t> additiveFields;
|
||||
if (metadata != nullptr && metadata->additive_fields != nullptr) {
|
||||
additiveFields.assign(metadata->additive_fields,
|
||||
metadata->additive_fields + metadata->additive_fields_size);
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lg(pullAtomMutex);
|
||||
const android::sp<android::os::IStatsManager> statsService = getStatsServiceLocked();
|
||||
if (statsService == nullptr) {
|
||||
// Error - statsd not available
|
||||
return;
|
||||
}
|
||||
|
||||
android::sp<StatsPullAtomCallbackInternal> callbackBinder = new StatsPullAtomCallbackInternal(
|
||||
callback, cookie, coolDownNs, timeoutNs, additiveFields);
|
||||
mPullers[atom_tag] = callbackBinder;
|
||||
statsService->registerNativePullAtomCallback(atom_tag, coolDownNs, timeoutNs, additiveFields,
|
||||
callbackBinder);
|
||||
}
|
Loading…
Reference in New Issue