Merge changes from topic "tej_pull_lazy"
* changes: Create libstatspull_lazy Create libstatssocket_lazy
This commit is contained in:
commit
eb6a9ceb2f
13 changed files with 720 additions and 2 deletions
|
|
@ -1,6 +1,7 @@
|
|||
joeo@google.com
|
||||
jeffreyhuang@google.com
|
||||
jtnguyen@google.com
|
||||
muhammadq@google.com
|
||||
ruchirr@google.com
|
||||
sharaienko@google.com
|
||||
singhtejinder@google.com
|
||||
tsaichristine@google.com
|
||||
yaochen@google.com
|
||||
|
|
|
|||
44
libstats/pull_lazy/Android.bp
Normal file
44
libstats/pull_lazy/Android.bp
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
// Lazy loading version of libstatspull that can be used by code
|
||||
// that is running before the statsd APEX is mounted and
|
||||
// libstatspull.so is available.
|
||||
cc_library_static {
|
||||
name: "libstatspull_lazy",
|
||||
header_libs: [
|
||||
"libstatspull_headers",
|
||||
"libstatssocket_headers",
|
||||
],
|
||||
export_header_lib_headers: [
|
||||
"libstatspull_headers",
|
||||
],
|
||||
apex_available: ["//apex_available:platform"],
|
||||
srcs: ["libstatspull_lazy.cpp"],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "libstatspull_lazy_test",
|
||||
srcs: [
|
||||
"tests/libstatspull_lazy_test.cpp",
|
||||
],
|
||||
static_libs: [
|
||||
"libstatspull_lazy",
|
||||
"libstatssocket_lazy",
|
||||
],
|
||||
shared_libs: ["liblog"],
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
],
|
||||
test_suites: ["device-tests", "mts-statsd"],
|
||||
test_config: "libstatspull_lazy_test.xml",
|
||||
// TODO(b/153588990): Remove when the build system properly separates.
|
||||
// 32bit and 64bit architectures.
|
||||
compile_multilib: "both",
|
||||
multilib: {
|
||||
lib64: {
|
||||
suffix: "64",
|
||||
},
|
||||
lib32: {
|
||||
suffix: "32",
|
||||
},
|
||||
},
|
||||
}
|
||||
7
libstats/pull_lazy/TEST_MAPPING
Normal file
7
libstats/pull_lazy/TEST_MAPPING
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"presubmit" : [
|
||||
{
|
||||
"name" : "libstatspull_lazy_test"
|
||||
}
|
||||
]
|
||||
}
|
||||
190
libstats/pull_lazy/libstatspull_lazy.cpp
Normal file
190
libstats/pull_lazy/libstatspull_lazy.cpp
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* Copyright (C) 2021 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 "libstatspull_lazy.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <stdatomic.h>
|
||||
|
||||
#include "log/log.h"
|
||||
|
||||
#include "stats_pull_atom_callback.h"
|
||||
|
||||
// This file provides a lazy interface to libstatspull.so to address early boot dependencies.
|
||||
// Specifically bootanimation, surfaceflinger, and lmkd run before the statsd APEX is loaded and
|
||||
// libstatspull.so is in the statsd APEX.
|
||||
|
||||
// Method pointers to libstatspull methods are held in an array which simplifies checking
|
||||
// all pointers are initialized.
|
||||
enum MethodIndex {
|
||||
// PullAtomMetadata APIs in stats_pull_atom_callback.h.
|
||||
k_AStatsManager_PullAtomMetadata_obtain,
|
||||
k_AStatsManager_PullAtomMetadata_release,
|
||||
k_AStatsManager_PullAtomMetadata_setCoolDownMillis,
|
||||
k_AStatsManager_PullAtomMetadata_getCoolDownMillis,
|
||||
k_AStatsManager_PullAtomMetadata_setTimeoutMillis,
|
||||
k_AStatsManager_PullAtomMetadata_getTimeoutMillis,
|
||||
k_AStatsManager_PullAtomMetadata_setAdditiveFields,
|
||||
k_AStatsManager_PullAtomMetadata_getNumAdditiveFields,
|
||||
k_AStatsManager_PullAtomMetadata_getAdditiveFields,
|
||||
|
||||
// AStatsEventList APIs in stats_pull_atom_callback.h
|
||||
k_AStatsEventList_addStatsEvent,
|
||||
|
||||
// PullAtomCallback APIs in stats_pull_atom_callback.h
|
||||
k_AStatsManager_setPullAtomCallback,
|
||||
k_AStatsManager_clearPullAtomCallback,
|
||||
|
||||
// Marker for count of methods
|
||||
k_MethodCount
|
||||
};
|
||||
|
||||
// Table of methods pointers in libstatspull APIs.
|
||||
static void* g_Methods[k_MethodCount];
|
||||
|
||||
//
|
||||
// Libstatspull lazy loading.
|
||||
//
|
||||
|
||||
static atomic_bool gPreventLibstatspullLoading = false; // Allows tests to block loading.
|
||||
|
||||
void PreventLibstatspullLazyLoadingForTests() {
|
||||
gPreventLibstatspullLoading.store(true);
|
||||
}
|
||||
|
||||
static void* LoadLibstatspull(int dlopen_flags) {
|
||||
if (gPreventLibstatspullLoading.load()) {
|
||||
return nullptr;
|
||||
}
|
||||
return dlopen("libstatspull.so", dlopen_flags);
|
||||
}
|
||||
|
||||
//
|
||||
// Initialization and symbol binding.
|
||||
|
||||
static void BindSymbol(void* handle, const char* name, enum MethodIndex index) {
|
||||
void* symbol = dlsym(handle, name);
|
||||
LOG_ALWAYS_FATAL_IF(symbol == nullptr, "Failed to find symbol '%s' in libstatspull.so: %s",
|
||||
name, dlerror());
|
||||
g_Methods[index] = symbol;
|
||||
}
|
||||
|
||||
static void InitializeOnce() {
|
||||
void* handle = LoadLibstatspull(RTLD_NOW);
|
||||
LOG_ALWAYS_FATAL_IF(handle == nullptr, "Failed to load libstatspull.so: %s", dlerror());
|
||||
|
||||
#undef BIND_SYMBOL
|
||||
#define BIND_SYMBOL(name) BindSymbol(handle, #name, k_##name);
|
||||
// PullAtomMetadata APIs in stats_pull_atom_callback.h.
|
||||
BIND_SYMBOL(AStatsManager_PullAtomMetadata_obtain);
|
||||
BIND_SYMBOL(AStatsManager_PullAtomMetadata_release);
|
||||
BIND_SYMBOL(AStatsManager_PullAtomMetadata_setCoolDownMillis);
|
||||
BIND_SYMBOL(AStatsManager_PullAtomMetadata_getCoolDownMillis);
|
||||
BIND_SYMBOL(AStatsManager_PullAtomMetadata_setTimeoutMillis);
|
||||
BIND_SYMBOL(AStatsManager_PullAtomMetadata_getTimeoutMillis);
|
||||
BIND_SYMBOL(AStatsManager_PullAtomMetadata_setAdditiveFields);
|
||||
BIND_SYMBOL(AStatsManager_PullAtomMetadata_getNumAdditiveFields);
|
||||
BIND_SYMBOL(AStatsManager_PullAtomMetadata_getAdditiveFields);
|
||||
|
||||
// AStatsEventList APIs in stats_pull_atom_callback.h
|
||||
BIND_SYMBOL(AStatsEventList_addStatsEvent);
|
||||
|
||||
// PullAtomCallback APIs in stats_pull_atom_callback.h
|
||||
BIND_SYMBOL(AStatsManager_setPullAtomCallback);
|
||||
BIND_SYMBOL(AStatsManager_clearPullAtomCallback);
|
||||
|
||||
#undef BIND_SYMBOL
|
||||
|
||||
// Check every symbol is bound.
|
||||
for (int i = 0; i < k_MethodCount; ++i) {
|
||||
LOG_ALWAYS_FATAL_IF(g_Methods[i] == nullptr,
|
||||
"Uninitialized method in libstatspull_lazy at index: %d", i);
|
||||
}
|
||||
}
|
||||
|
||||
static void EnsureInitialized() {
|
||||
static std::once_flag initialize_flag;
|
||||
std::call_once(initialize_flag, InitializeOnce);
|
||||
}
|
||||
|
||||
#define INVOKE_METHOD(name, args...) \
|
||||
do { \
|
||||
EnsureInitialized(); \
|
||||
void* method = g_Methods[k_##name]; \
|
||||
return reinterpret_cast<decltype(&name)>(method)(args); \
|
||||
} while (0)
|
||||
|
||||
//
|
||||
// Forwarding for methods in stats_pull_atom_callback.h.
|
||||
//
|
||||
|
||||
AStatsManager_PullAtomMetadata* AStatsManager_PullAtomMetadata_obtain() {
|
||||
INVOKE_METHOD(AStatsManager_PullAtomMetadata_obtain);
|
||||
}
|
||||
|
||||
void AStatsManager_PullAtomMetadata_release(AStatsManager_PullAtomMetadata* metadata) {
|
||||
INVOKE_METHOD(AStatsManager_PullAtomMetadata_release, metadata);
|
||||
}
|
||||
|
||||
void AStatsManager_PullAtomMetadata_setCoolDownMillis(AStatsManager_PullAtomMetadata* metadata,
|
||||
int64_t cool_down_millis) {
|
||||
INVOKE_METHOD(AStatsManager_PullAtomMetadata_setCoolDownMillis, metadata, cool_down_millis);
|
||||
}
|
||||
|
||||
int64_t AStatsManager_PullAtomMetadata_getCoolDownMillis(AStatsManager_PullAtomMetadata* metadata) {
|
||||
INVOKE_METHOD(AStatsManager_PullAtomMetadata_getCoolDownMillis, metadata);
|
||||
}
|
||||
|
||||
void AStatsManager_PullAtomMetadata_setTimeoutMillis(AStatsManager_PullAtomMetadata* metadata,
|
||||
int64_t timeout_millis) {
|
||||
INVOKE_METHOD(AStatsManager_PullAtomMetadata_setTimeoutMillis, metadata, timeout_millis);
|
||||
}
|
||||
|
||||
int64_t AStatsManager_PullAtomMetadata_getTimeoutMillis(AStatsManager_PullAtomMetadata* metadata) {
|
||||
INVOKE_METHOD(AStatsManager_PullAtomMetadata_getTimeoutMillis, metadata);
|
||||
}
|
||||
|
||||
void AStatsManager_PullAtomMetadata_setAdditiveFields(AStatsManager_PullAtomMetadata* metadata,
|
||||
int32_t* additive_fields,
|
||||
int32_t num_fields) {
|
||||
INVOKE_METHOD(AStatsManager_PullAtomMetadata_setAdditiveFields, metadata, additive_fields,
|
||||
num_fields);
|
||||
}
|
||||
|
||||
int32_t AStatsManager_PullAtomMetadata_getNumAdditiveFields(
|
||||
AStatsManager_PullAtomMetadata* metadata) {
|
||||
INVOKE_METHOD(AStatsManager_PullAtomMetadata_getNumAdditiveFields, metadata);
|
||||
}
|
||||
|
||||
void AStatsManager_PullAtomMetadata_getAdditiveFields(AStatsManager_PullAtomMetadata* metadata,
|
||||
int32_t* fields) {
|
||||
INVOKE_METHOD(AStatsManager_PullAtomMetadata_getAdditiveFields, metadata, fields);
|
||||
}
|
||||
|
||||
AStatsEvent* AStatsEventList_addStatsEvent(AStatsEventList* pull_data) {
|
||||
INVOKE_METHOD(AStatsEventList_addStatsEvent, pull_data);
|
||||
}
|
||||
|
||||
void AStatsManager_setPullAtomCallback(int32_t atom_tag, AStatsManager_PullAtomMetadata* metadata,
|
||||
AStatsManager_PullAtomCallback callback, void* cookie) {
|
||||
INVOKE_METHOD(AStatsManager_setPullAtomCallback, atom_tag, metadata, callback, cookie);
|
||||
}
|
||||
|
||||
void AStatsManager_clearPullAtomCallback(int32_t atom_tag) {
|
||||
INVOKE_METHOD(AStatsManager_clearPullAtomCallback, atom_tag);
|
||||
}
|
||||
19
libstats/pull_lazy/libstatspull_lazy.h
Normal file
19
libstats/pull_lazy/libstatspull_lazy.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2021 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
|
||||
|
||||
extern "C" void PreventLibstatspullLazyLoadingForTests();
|
||||
37
libstats/pull_lazy/libstatspull_lazy_test.xml
Normal file
37
libstats/pull_lazy/libstatspull_lazy_test.xml
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 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.
|
||||
-->
|
||||
<configuration description="Runs libstatspull_lazy_test.">
|
||||
<option name="test-suite-tag" value="apct" />
|
||||
<option name="test-suite-tag" value="apct-native" />
|
||||
<option name="test-suite-tag" value="mts" />
|
||||
|
||||
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
|
||||
|
||||
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
|
||||
<option name="cleanup" value="true" />
|
||||
<option name="push" value="libstatspull_lazy_test->/data/local/tmp/libstatspull_lazy_test" />
|
||||
<option name="append-bitness" value="true" />
|
||||
</target_preparer>
|
||||
|
||||
<test class="com.android.tradefed.testtype.GTest" >
|
||||
<option name="native-test-device-path" value="/data/local/tmp" />
|
||||
<option name="module-name" value="libstatspull_lazy_test" />
|
||||
</test>
|
||||
|
||||
<object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
|
||||
<option name="mainline-module-package-name" value="com.google.android.os.statsd" />
|
||||
</object>
|
||||
</configuration>
|
||||
58
libstats/pull_lazy/tests/libstatspull_lazy_test.cpp
Normal file
58
libstats/pull_lazy/tests/libstatspull_lazy_test.cpp
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 2021 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 "../libstatspull_lazy.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "stats_pull_atom_callback.h"
|
||||
//#include "stats_event.h"
|
||||
|
||||
// The tests here are just for the case when libstatspull.so cannot be loaded by
|
||||
// libstatspull_lazy.
|
||||
class LibstatspullLazyTest : public ::testing::Test {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
::testing::Test::SetUp();
|
||||
PreventLibstatspullLazyLoadingForTests();
|
||||
}
|
||||
};
|
||||
|
||||
static const char* kLoadFailed = "Failed to load libstatspull.so";
|
||||
|
||||
TEST_F(LibstatspullLazyTest, NoLibstatspullForPullAtomMetadata) {
|
||||
AStatsManager_PullAtomMetadata* metadata = NULL;
|
||||
EXPECT_DEATH(AStatsManager_PullAtomMetadata_obtain(), kLoadFailed);
|
||||
EXPECT_DEATH(AStatsManager_PullAtomMetadata_release(metadata), kLoadFailed);
|
||||
EXPECT_DEATH(AStatsManager_PullAtomMetadata_setCoolDownMillis(metadata, 0), kLoadFailed);
|
||||
EXPECT_DEATH(AStatsManager_PullAtomMetadata_getCoolDownMillis(metadata), kLoadFailed);
|
||||
EXPECT_DEATH(AStatsManager_PullAtomMetadata_setTimeoutMillis(metadata, 0), kLoadFailed);
|
||||
EXPECT_DEATH(AStatsManager_PullAtomMetadata_getTimeoutMillis(metadata), kLoadFailed);
|
||||
EXPECT_DEATH(AStatsManager_PullAtomMetadata_setAdditiveFields(metadata, NULL, 0), kLoadFailed);
|
||||
EXPECT_DEATH(AStatsManager_PullAtomMetadata_getNumAdditiveFields(metadata), kLoadFailed);
|
||||
EXPECT_DEATH(AStatsManager_PullAtomMetadata_getAdditiveFields(metadata, NULL), kLoadFailed);
|
||||
}
|
||||
|
||||
TEST_F(LibstatspullLazyTest, NoLibstatspullForAStatsEventList) {
|
||||
AStatsEventList* event_list = NULL;
|
||||
EXPECT_DEATH(AStatsEventList_addStatsEvent(event_list), kLoadFailed);
|
||||
}
|
||||
|
||||
TEST_F(LibstatspullLazyTest, NoLibstatspullForPullAtomCallback) {
|
||||
AStatsManager_PullAtomCallback callback = NULL;
|
||||
EXPECT_DEATH(AStatsManager_setPullAtomCallback(0, NULL, callback, NULL), kLoadFailed);
|
||||
EXPECT_DEATH(AStatsManager_clearPullAtomCallback(0), kLoadFailed);
|
||||
}
|
||||
40
libstats/socket_lazy/Android.bp
Normal file
40
libstats/socket_lazy/Android.bp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// Lazy loading version of libstatssocket that can be used by code
|
||||
// that is running before the statsd APEX is mounted and
|
||||
// libstatssocket.so is available.
|
||||
cc_library_static {
|
||||
name: "libstatssocket_lazy",
|
||||
header_libs: [
|
||||
"libstatssocket_headers",
|
||||
],
|
||||
export_header_lib_headers: [
|
||||
"libstatssocket_headers",
|
||||
],
|
||||
apex_available: ["//apex_available:platform"],
|
||||
srcs: ["libstatssocket_lazy.cpp"],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "libstatssocket_lazy_test",
|
||||
srcs: [
|
||||
"tests/libstatssocket_lazy_test.cpp",
|
||||
],
|
||||
static_libs: ["libstatssocket_lazy"],
|
||||
shared_libs: ["liblog"],
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
],
|
||||
test_suites: ["device-tests", "mts-statsd"],
|
||||
test_config: "libstatssocket_lazy_test.xml",
|
||||
// TODO(b/153588990): Remove when the build system properly separates.
|
||||
// 32bit and 64bit architectures.
|
||||
compile_multilib: "both",
|
||||
multilib: {
|
||||
lib64: {
|
||||
suffix: "64",
|
||||
},
|
||||
lib32: {
|
||||
suffix: "32",
|
||||
},
|
||||
},
|
||||
}
|
||||
7
libstats/socket_lazy/TEST_MAPPING
Normal file
7
libstats/socket_lazy/TEST_MAPPING
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"presubmit" : [
|
||||
{
|
||||
"name" : "libstatssocket_lazy_test"
|
||||
}
|
||||
]
|
||||
}
|
||||
201
libstats/socket_lazy/libstatssocket_lazy.cpp
Normal file
201
libstats/socket_lazy/libstatssocket_lazy.cpp
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
* Copyright (C) 2021 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 "libstatssocket_lazy.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <stdatomic.h>
|
||||
|
||||
#include "log/log.h"
|
||||
|
||||
#include "stats_event.h"
|
||||
#include "stats_socket.h"
|
||||
|
||||
// This file provides a lazy interface to libstatssocket.so to address early boot dependencies.
|
||||
// Specifically bootanimation, surfaceflinger, and lmkd run before the statsd APEX is loaded and
|
||||
// libstatssocket.so is in the statsd APEX.
|
||||
|
||||
// Method pointers to libstatssocket methods are held in an array which simplifies checking
|
||||
// all pointers are initialized.
|
||||
enum MethodIndex {
|
||||
// Stats Event APIs in stats_event.h.
|
||||
k_AStatsEvent_obtain,
|
||||
k_AStatsEvent_build,
|
||||
k_AStatsEvent_write,
|
||||
k_AStatsEvent_release,
|
||||
k_AStatsEvent_setAtomId,
|
||||
k_AStatsEvent_writeInt32,
|
||||
k_AStatsEvent_writeInt64,
|
||||
k_AStatsEvent_writeFloat,
|
||||
k_AStatsEvent_writeBool,
|
||||
k_AStatsEvent_writeByteArray,
|
||||
k_AStatsEvent_writeString,
|
||||
k_AStatsEvent_writeAttributionChain,
|
||||
k_AStatsEvent_addBoolAnnotation,
|
||||
k_AStatsEvent_addInt32Annotation,
|
||||
|
||||
// Stats Socket APIs in stats_socket.h.
|
||||
k_AStatsSocket_close,
|
||||
|
||||
// Marker for count of methods
|
||||
k_MethodCount
|
||||
};
|
||||
|
||||
// Table of methods pointers in libstatssocket APIs.
|
||||
static void* g_Methods[k_MethodCount];
|
||||
|
||||
//
|
||||
// Libstatssocket lazy loading.
|
||||
//
|
||||
|
||||
static atomic_bool gPreventLibstatssocketLoading = false; // Allows tests to block loading.
|
||||
|
||||
void PreventLibstatssocketLazyLoadingForTests() {
|
||||
gPreventLibstatssocketLoading.store(true);
|
||||
}
|
||||
|
||||
static void* LoadLibstatssocket(int dlopen_flags) {
|
||||
if (gPreventLibstatssocketLoading.load()) {
|
||||
return nullptr;
|
||||
}
|
||||
return dlopen("libstatssocket.so", dlopen_flags);
|
||||
}
|
||||
|
||||
//
|
||||
// Initialization and symbol binding.
|
||||
|
||||
static void BindSymbol(void* handle, const char* name, enum MethodIndex index) {
|
||||
void* symbol = dlsym(handle, name);
|
||||
LOG_ALWAYS_FATAL_IF(symbol == nullptr, "Failed to find symbol '%s' in libstatssocket.so: %s",
|
||||
name, dlerror());
|
||||
g_Methods[index] = symbol;
|
||||
}
|
||||
|
||||
static void InitializeOnce() {
|
||||
void* handle = LoadLibstatssocket(RTLD_NOW);
|
||||
LOG_ALWAYS_FATAL_IF(handle == nullptr, "Failed to load libstatssocket.so: %s", dlerror());
|
||||
|
||||
#undef BIND_SYMBOL
|
||||
#define BIND_SYMBOL(name) BindSymbol(handle, #name, k_##name);
|
||||
// Methods in stats_event.h.
|
||||
BIND_SYMBOL(AStatsEvent_obtain);
|
||||
BIND_SYMBOL(AStatsEvent_build);
|
||||
BIND_SYMBOL(AStatsEvent_write);
|
||||
BIND_SYMBOL(AStatsEvent_release);
|
||||
BIND_SYMBOL(AStatsEvent_setAtomId);
|
||||
BIND_SYMBOL(AStatsEvent_writeInt32);
|
||||
BIND_SYMBOL(AStatsEvent_writeInt64);
|
||||
BIND_SYMBOL(AStatsEvent_writeFloat);
|
||||
BIND_SYMBOL(AStatsEvent_writeBool);
|
||||
BIND_SYMBOL(AStatsEvent_writeByteArray);
|
||||
BIND_SYMBOL(AStatsEvent_writeString);
|
||||
BIND_SYMBOL(AStatsEvent_writeAttributionChain);
|
||||
BIND_SYMBOL(AStatsEvent_addBoolAnnotation);
|
||||
BIND_SYMBOL(AStatsEvent_addInt32Annotation);
|
||||
|
||||
// Methods in stats_socket.h.
|
||||
BIND_SYMBOL(AStatsSocket_close);
|
||||
#undef BIND_SYMBOL
|
||||
|
||||
// Check every symbol is bound.
|
||||
for (int i = 0; i < k_MethodCount; ++i) {
|
||||
LOG_ALWAYS_FATAL_IF(g_Methods[i] == nullptr,
|
||||
"Uninitialized method in libstatssocket_lazy at index: %d", i);
|
||||
}
|
||||
}
|
||||
|
||||
static void EnsureInitialized() {
|
||||
static std::once_flag initialize_flag;
|
||||
std::call_once(initialize_flag, InitializeOnce);
|
||||
}
|
||||
|
||||
#define INVOKE_METHOD(name, args...) \
|
||||
do { \
|
||||
EnsureInitialized(); \
|
||||
void* method = g_Methods[k_##name]; \
|
||||
return reinterpret_cast<decltype(&name)>(method)(args); \
|
||||
} while (0)
|
||||
|
||||
//
|
||||
// Forwarding for methods in stats_event.h.
|
||||
//
|
||||
|
||||
AStatsEvent* AStatsEvent_obtain() {
|
||||
INVOKE_METHOD(AStatsEvent_obtain);
|
||||
}
|
||||
|
||||
void AStatsEvent_build(AStatsEvent* event) {
|
||||
INVOKE_METHOD(AStatsEvent_build, event);
|
||||
}
|
||||
|
||||
int AStatsEvent_write(AStatsEvent* event) {
|
||||
INVOKE_METHOD(AStatsEvent_write, event);
|
||||
}
|
||||
|
||||
void AStatsEvent_release(AStatsEvent* event) {
|
||||
INVOKE_METHOD(AStatsEvent_release, event);
|
||||
}
|
||||
|
||||
void AStatsEvent_setAtomId(AStatsEvent* event, uint32_t atomId) {
|
||||
INVOKE_METHOD(AStatsEvent_setAtomId, event, atomId);
|
||||
}
|
||||
|
||||
void AStatsEvent_writeInt32(AStatsEvent* event, int32_t value) {
|
||||
INVOKE_METHOD(AStatsEvent_writeInt32, event, value);
|
||||
}
|
||||
|
||||
void AStatsEvent_writeInt64(AStatsEvent* event, int64_t value) {
|
||||
INVOKE_METHOD(AStatsEvent_writeInt64, event, value);
|
||||
}
|
||||
|
||||
void AStatsEvent_writeFloat(AStatsEvent* event, float value) {
|
||||
INVOKE_METHOD(AStatsEvent_writeFloat, event, value);
|
||||
}
|
||||
|
||||
void AStatsEvent_writeBool(AStatsEvent* event, bool value) {
|
||||
INVOKE_METHOD(AStatsEvent_writeBool, event, value);
|
||||
}
|
||||
|
||||
void AStatsEvent_writeByteArray(AStatsEvent* event, const uint8_t* buf, size_t numBytes) {
|
||||
INVOKE_METHOD(AStatsEvent_writeByteArray, event, buf, numBytes);
|
||||
}
|
||||
|
||||
void AStatsEvent_writeString(AStatsEvent* event, const char* value) {
|
||||
INVOKE_METHOD(AStatsEvent_writeString, event, value);
|
||||
}
|
||||
|
||||
void AStatsEvent_writeAttributionChain(AStatsEvent* event, const uint32_t* uids,
|
||||
const char* const* tags, uint8_t numNodes) {
|
||||
INVOKE_METHOD(AStatsEvent_writeAttributionChain, event, uids, tags, numNodes);
|
||||
}
|
||||
|
||||
void AStatsEvent_addBoolAnnotation(AStatsEvent* event, uint8_t annotationId, bool value) {
|
||||
INVOKE_METHOD(AStatsEvent_addBoolAnnotation, event, annotationId, value);
|
||||
}
|
||||
|
||||
void AStatsEvent_addInt32Annotation(AStatsEvent* event, uint8_t annotationId, int32_t value) {
|
||||
INVOKE_METHOD(AStatsEvent_addInt32Annotation, event, annotationId, value);
|
||||
}
|
||||
|
||||
//
|
||||
// Forwarding for methods in stats_socket.h.
|
||||
//
|
||||
|
||||
void AStatsSocket_close() {
|
||||
INVOKE_METHOD(AStatsSocket_close);
|
||||
}
|
||||
19
libstats/socket_lazy/libstatssocket_lazy.h
Normal file
19
libstats/socket_lazy/libstatssocket_lazy.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2021 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
|
||||
|
||||
extern "C" void PreventLibstatssocketLazyLoadingForTests();
|
||||
37
libstats/socket_lazy/libstatssocket_lazy_test.xml
Normal file
37
libstats/socket_lazy/libstatssocket_lazy_test.xml
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 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.
|
||||
-->
|
||||
<configuration description="Runs libstatssocket_lazy_test.">
|
||||
<option name="test-suite-tag" value="apct" />
|
||||
<option name="test-suite-tag" value="apct-native" />
|
||||
<option name="test-suite-tag" value="mts" />
|
||||
|
||||
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
|
||||
|
||||
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
|
||||
<option name="cleanup" value="true" />
|
||||
<option name="push" value="libstatssocket_lazy_test->/data/local/tmp/libstatssocket_lazy_test" />
|
||||
<option name="append-bitness" value="true" />
|
||||
</target_preparer>
|
||||
|
||||
<test class="com.android.tradefed.testtype.GTest" >
|
||||
<option name="native-test-device-path" value="/data/local/tmp" />
|
||||
<option name="module-name" value="libstatssocket_lazy_test" />
|
||||
</test>
|
||||
|
||||
<object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
|
||||
<option name="mainline-module-package-name" value="com.google.android.os.statsd" />
|
||||
</object>
|
||||
</configuration>
|
||||
58
libstats/socket_lazy/tests/libstatssocket_lazy_test.cpp
Normal file
58
libstats/socket_lazy/tests/libstatssocket_lazy_test.cpp
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 2021 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 "../libstatssocket_lazy.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "stats_event.h"
|
||||
#include "stats_socket.h"
|
||||
|
||||
// The tests here are just for the case when libstatssocket.so cannot be loaded by
|
||||
// libstatssocket_lazy.
|
||||
class LibstatssocketLazyTest : public ::testing::Test {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
::testing::Test::SetUp();
|
||||
PreventLibstatssocketLazyLoadingForTests();
|
||||
}
|
||||
};
|
||||
|
||||
static const char* kLoadFailed = "Failed to load libstatssocket.so";
|
||||
|
||||
TEST_F(LibstatssocketLazyTest, NoLibstatssocketForStatsEvent) {
|
||||
AStatsEvent* event = NULL;
|
||||
EXPECT_DEATH(AStatsEvent_obtain(), kLoadFailed);
|
||||
EXPECT_DEATH(AStatsEvent_build(event), kLoadFailed);
|
||||
EXPECT_DEATH(AStatsEvent_write(event), kLoadFailed);
|
||||
EXPECT_DEATH(AStatsEvent_release(event), kLoadFailed);
|
||||
|
||||
EXPECT_DEATH(AStatsEvent_setAtomId(event, 0), kLoadFailed);
|
||||
EXPECT_DEATH(AStatsEvent_writeInt32(event, 0), kLoadFailed);
|
||||
EXPECT_DEATH(AStatsEvent_writeInt64(event, 0), kLoadFailed);
|
||||
EXPECT_DEATH(AStatsEvent_writeFloat(event, 0), kLoadFailed);
|
||||
EXPECT_DEATH(AStatsEvent_writeBool(event, false), kLoadFailed);
|
||||
EXPECT_DEATH(AStatsEvent_writeByteArray(event, NULL, 0), kLoadFailed);
|
||||
EXPECT_DEATH(AStatsEvent_writeString(event, NULL), kLoadFailed);
|
||||
EXPECT_DEATH(AStatsEvent_writeAttributionChain(event, NULL, NULL, 0), kLoadFailed);
|
||||
|
||||
EXPECT_DEATH(AStatsEvent_addBoolAnnotation(event, 0, false), kLoadFailed);
|
||||
EXPECT_DEATH(AStatsEvent_addInt32Annotation(event, 0, 0), kLoadFailed);
|
||||
}
|
||||
|
||||
TEST_F(LibstatssocketLazyTest, NoLibstatssocketForStatsSocket) {
|
||||
EXPECT_DEATH(AStatsSocket_close(), kLoadFailed);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue