diff options
| -rw-r--r-- | Android.mk | 11 | ||||
| -rw-r--r-- | cmds/statsd/Android.bp | 37 | ||||
| -rw-r--r-- | cmds/statsd/Android.mk | 130 | ||||
| -rw-r--r-- | cmds/statsd/src/LogEntryPrinter.cpp | 33 | ||||
| -rw-r--r-- | cmds/statsd/src/matchers/matcher_util.cpp | 81 | ||||
| -rw-r--r-- | cmds/statsd/src/matchers/matcher_util.h | 3 | ||||
| -rw-r--r-- | cmds/statsd/src/stats_events.proto | 137 | ||||
| -rw-r--r-- | core/java/android/util/StatsLog.java | 76 | ||||
| -rw-r--r-- | core/java/android/util/StatsLogKey.java | 48 | ||||
| -rw-r--r-- | core/java/android/util/StatsLogTag.java | 32 | ||||
| -rw-r--r-- | core/java/android/util/StatsLogValue.java | 54 | ||||
| -rw-r--r-- | core/jni/Android.bp | 15 | ||||
| -rw-r--r-- | core/jni/AndroidRuntime.cpp | 2 | ||||
| -rw-r--r-- | core/jni/android_util_StatsLog.cpp | 201 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/BatteryStatsService.java | 25 | ||||
| -rw-r--r-- | tools/stats_log_api_gen/Android.bp | 98 | ||||
| -rw-r--r-- | tools/stats_log_api_gen/Collation.cpp | 265 | ||||
| -rw-r--r-- | tools/stats_log_api_gen/Collation.h | 100 | ||||
| -rw-r--r-- | tools/stats_log_api_gen/main.cpp | 623 | ||||
| -rw-r--r-- | tools/stats_log_api_gen/test.proto | 112 | ||||
| -rw-r--r-- | tools/stats_log_api_gen/test_collation.cpp | 171 |
21 files changed, 567 insertions, 1687 deletions
diff --git a/Android.mk b/Android.mk index b5efd4752e0d..4a57020ab8d3 100644 --- a/Android.mk +++ b/Android.mk @@ -587,17 +587,6 @@ LOCAL_SRC_FILES += \ lowpan/java/android/net/lowpan/ILowpanManagerListener.aidl \ lowpan/java/android/net/lowpan/ILowpanManager.aidl -# StatsLog generated functions -statslog_src_dir := $(call intermediates-dir-for,JAVA_LIBRARIES,framework,,COMMON)/statslog -gen := $(statslog_src_dir)/android/util/StatsLog.java -$(gen): PRIVATE_PATH := $(LOCAL_PATH) -$(gen): PRIVATE_CUSTOM_TOOL = $(HOST_OUT_EXECUTABLES)/stats-log-api-gen --java $@ -$(gen): $(HOST_OUT_EXECUTABLES)/stats-log-api-gen - $(transform-generated-source) -LOCAL_GENERATED_SOURCES += $(gen) -statslog_src_dir:= -gen:= - # FRAMEWORKS_BASE_JAVA_SRC_DIRS comes from build/core/pathmap.mk LOCAL_AIDL_INCLUDES += \ $(FRAMEWORKS_BASE_JAVA_SRC_DIRS) \ diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp deleted file mode 100644 index 5586057a2e70..000000000000 --- a/cmds/statsd/Android.bp +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright (C) 2015 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. -// - -// ========================================================== -// Build the library for use on the host -// ========================================================== -cc_library_host_shared { - name: "libstats_proto_host", - srcs: [ - "src/stats_events.proto", - "src/stats_log.proto", - "src/statsd_config.proto", - ], - - shared_libs: [ - "libplatformprotos", - ], - - proto: { - type: "full", - export_proto_headers: true, - }, -} - diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk index d9c37ef0c9b8..4c95007b0c44 100644 --- a/cmds/statsd/Android.mk +++ b/cmds/statsd/Android.mk @@ -14,51 +14,22 @@ LOCAL_PATH:= $(call my-dir) +# ================ +# proto static lib +# ================ +include $(CLEAR_VARS) -statsd_common_src := \ - ../../core/java/android/os/IStatsCompanionService.aidl \ - ../../core/java/android/os/IStatsManager.aidl \ - src/stats_log.proto \ - src/statsd_config.proto \ - src/stats_events.proto \ - src/condition/CombinationConditionTracker.cpp \ - src/condition/condition_util.cpp \ - src/condition/SimpleConditionTracker.cpp \ - src/matchers/CombinationLogMatchingTracker.cpp \ - src/matchers/matcher_util.cpp \ - src/matchers/SimpleLogMatchingTracker.cpp \ - src/metrics/CountAnomalyTracker.cpp \ - src/metrics/CountMetricProducer.cpp \ - src/metrics/MetricsManager.cpp \ - src/metrics/metrics_manager_util.cpp \ - src/AnomalyMonitor.cpp \ - src/DropboxReader.cpp \ - src/DropboxWriter.cpp \ - src/KernelWakelockPuller.cpp \ - src/LogEntryPrinter.cpp \ - src/LogReader.cpp \ - src/StatsLogProcessor.cpp \ - src/StatsPullerManager.cpp \ - src/StatsService.cpp \ - src/stats_util.cpp \ - src/UidMap.cpp +LOCAL_MODULE := statsd_proto +LOCAL_MODULE_TAGS := optional -statsd_common_c_includes := \ - $(LOCAL_PATH)/src +LOCAL_SRC_FILES := $(call all-proto-files-under, src) -statsd_common_aidl_includes := \ - $(LOCAL_PATH)/../../core/java +LOCAL_PROTOC_FLAGS := +LOCAL_PROTOC_OPTIMIZE_TYPE := lite-static -statsd_common_shared_libraries := \ - libbase \ - libbinder \ - libcutils \ - libincident \ - liblog \ - libselinux \ - libutils \ - libservices \ - libandroidfw +include $(BUILD_STATIC_LIBRARY) + +STATSD_PROTO_INCLUDES := $(local-generated-sources-dir)/src/$(LOCAL_PATH) # ========= # statsd @@ -69,8 +40,9 @@ include $(CLEAR_VARS) LOCAL_MODULE := statsd LOCAL_SRC_FILES := \ - $(statsd_common_src) \ - src/main.cpp + ../../core/java/android/os/IStatsCompanionService.aidl \ + ../../core/java/android/os/IStatsManager.aidl \ + $(call all-cpp-files-under,src) \ LOCAL_CFLAGS += \ -Wall \ @@ -88,12 +60,24 @@ else LOCAL_CFLAGS += \ -Os endif -LOCAL_PROTOC_OPTIMIZE_TYPE := lite-static -LOCAL_AIDL_INCLUDES := $(statsd_common_c_includes) -LOCAL_C_INCLUDES += $(statsd_common_c_includes) +LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/../../core/java +LOCAL_C_INCLUDES += $(LOCAL_PATH)/src \ + STATSD_PROTO_INCLUDES -LOCAL_SHARED_LIBRARIES := $(statsd_common_shared_libraries) +LOCAL_STATIC_LIBRARIES := statsd_proto + +LOCAL_SHARED_LIBRARIES := \ + libbase \ + libbinder \ + libcutils \ + libincident \ + liblog \ + libselinux \ + libutils \ + libservices \ + libandroidfw \ + libprotobuf-cpp-lite \ LOCAL_MODULE_CLASS := EXECUTABLES @@ -101,7 +85,6 @@ LOCAL_MODULE_CLASS := EXECUTABLES include $(BUILD_EXECUTABLE) - # ============== # statsd_test # ============== @@ -112,8 +95,8 @@ LOCAL_MODULE := statsd_test LOCAL_COMPATIBILITY_SUITE := device-tests LOCAL_MODULE_TAGS := tests -LOCAL_AIDL_INCLUDES := $(statsd_common_c_includes) -LOCAL_C_INCLUDES += $(statsd_common_c_includes) +LOCAL_C_INCLUDES += $(LOCAL_PATH)/src \ + STATSD_PROTO_INCLUDES LOCAL_CFLAGS += \ -Wall \ @@ -124,25 +107,38 @@ LOCAL_CFLAGS += \ -Wno-unused-parameter LOCAL_SRC_FILES := \ - $(statsd_common_src) \ - tests/indexed_priority_queue_test.cpp \ - tests/LogReader_test.cpp \ - tests/MetricsManager_test.cpp \ - tests/UidMap_test.cpp \ - tests/LogEntryMatcher_test.cpp \ - tests/AnomalyMonitor_test.cpp \ - tests/ConditionTracker_test.cpp + src/stats_log.proto \ + src/statsd_config.proto \ + ../../core/java/android/os/IStatsCompanionService.aidl \ + ../../core/java/android/os/IStatsManager.aidl \ + src/StatsService.cpp \ + src/AnomalyMonitor.cpp \ + src/stats_util.cpp \ + src/LogEntryPrinter.cpp \ + src/LogReader.cpp \ + src/matchers/matcher_util.cpp \ + src/condition/SimpleConditionTracker.cpp \ + src/condition/CombinationConditionTracker.cpp \ + src/matchers/SimpleLogMatchingTracker.cpp \ + src/matchers/CombinationLogMatchingTracker.cpp \ + src/metrics/metrics_manager_util.cpp \ + src/metrics/CountMetricProducer.cpp \ + src/metrics/CountAnomalyTracker.cpp \ + src/condition/condition_util.cpp \ + src/UidMap.cpp \ + $(call all-cpp-files-under, tests) \ LOCAL_STATIC_LIBRARIES := \ - libgmock - -LOCAL_SHARED_LIBRARIES := $(statsd_common_shared_libraries) - -LOCAL_PROTOC_OPTIMIZE_TYPE := lite + libgmock \ + statsd_proto \ -statsd_common_src:= -statsd_common_aidl_includes:= -statsd_common_c_includes:= +LOCAL_SHARED_LIBRARIES := \ + libbase \ + libbinder \ + libcutils \ + liblog \ + libselinux \ + libutils \ + libprotobuf-cpp-lite \ include $(BUILD_NATIVE_TEST) - diff --git a/cmds/statsd/src/LogEntryPrinter.cpp b/cmds/statsd/src/LogEntryPrinter.cpp index 3b6f6791d7f4..63465b094da2 100644 --- a/cmds/statsd/src/LogEntryPrinter.cpp +++ b/cmds/statsd/src/LogEntryPrinter.cpp @@ -20,11 +20,6 @@ #include <log/logprint.h> #include <utils/Errors.h> -#include "matchers/matcher_util.h" - -#define PRINT_WITH_LIBLOG 0 -#define PRINT_WITH_LOG_EVENT_WRAPPER 1 - using namespace android; namespace android { @@ -49,24 +44,16 @@ LogEntryPrinter::~LogEntryPrinter() { } void LogEntryPrinter::OnLogEvent(const log_msg& msg) { - if (PRINT_WITH_LIBLOG) { - status_t err; - AndroidLogEntry entry; - char buf[1024]; - - err = android_log_processBinaryLogBuffer(&(const_cast<log_msg*>(&msg)->entry_v1), &entry, - m_tags, buf, sizeof(buf)); - if (err == NO_ERROR) { - android_log_printLogLine(m_format, m_out, &entry); - } else { - printf("log entry: %s\n", buf); - fflush(stdout); - } - } - - if (PRINT_WITH_LOG_EVENT_WRAPPER) { - LogEventWrapper event = parseLogEvent(msg); - printf("event: %s\n", event.toString().c_str()); + status_t err; + AndroidLogEntry entry; + char buf[1024]; + + err = android_log_processBinaryLogBuffer(&(const_cast<log_msg*>(&msg)->entry_v1), &entry, + m_tags, buf, sizeof(buf)); + if (err == NO_ERROR) { + android_log_printLogLine(m_format, m_out, &entry); + } else { + printf("log entry: %s\n", buf); fflush(stdout); } } diff --git a/cmds/statsd/src/matchers/matcher_util.cpp b/cmds/statsd/src/matchers/matcher_util.cpp index 3308f3aeb318..557c03228436 100644 --- a/cmds/statsd/src/matchers/matcher_util.cpp +++ b/cmds/statsd/src/matchers/matcher_util.cpp @@ -26,11 +26,8 @@ #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" #include "stats_util.h" -#include <sstream> - using std::set; using std::string; -using std::ostringstream; using std::unordered_map; using std::vector; @@ -38,42 +35,6 @@ namespace android { namespace os { namespace statsd { -string LogEventWrapper::toString() const { - std::ostringstream result; - result << "{ " << timestamp_ns << " (" << tagId << ")"; - for (int index = 1; ; index++) { - auto intVal = intMap.find(index); - auto strVal = strMap.find(index); - auto boolVal = boolMap.find(index); - auto floatVal = floatMap.find(index); - if (intVal != intMap.end()) { - result << " "; - result << std::to_string(index); - result << "->"; - result << std::to_string(intVal->second); - } else if (strVal != strMap.end()) { - result << " "; - result << std::to_string(index); - result << "->"; - result << strVal->second; - } else if (boolVal != boolMap.end()) { - result << " "; - result << std::to_string(index); - result << "->"; - result << std::to_string(boolVal->second); - } else if (floatVal != floatMap.end()) { - result << " "; - result << std::to_string(index); - result << "->"; - result << std::to_string(floatVal->second); - } else { - break; - } - } - result << " }"; - return result.str(); -} - LogEventWrapper parseLogEvent(log_msg msg) { LogEventWrapper wrapper; wrapper.timestamp_ns = msg.entry_v1.sec * NS_PER_SEC + msg.entry_v1.nsec; @@ -87,32 +48,38 @@ LogEventWrapper parseLogEvent(log_msg msg) { if (context) { memset(&elem, 0, sizeof(elem)); - // TODO: The log is actually structured inside one list. This is convenient - // because we'll be able to use it to put the attribution (WorkSource) block first - // without doing our own tagging scheme. Until that change is in, just drop the - // list-related log elements and the order we get there is our index-keyed data - // structure. - int32_t key = 1; + size_t index = 0; + int32_t key = -1; do { elem = android_log_read_next(context); switch ((int)elem.type) { case EVENT_TYPE_INT: - wrapper.intMap[key] = elem.data.int32; - key++; + if (index % 2 == 0) { + key = elem.data.int32; + } else { + wrapper.intMap[key] = elem.data.int32; + } + index++; break; case EVENT_TYPE_FLOAT: - wrapper.floatMap[key] = elem.data.float32; - key++; + if (index % 2 == 1) { + wrapper.floatMap[key] = elem.data.float32; + } + index++; break; case EVENT_TYPE_STRING: - // without explicit calling string() constructor, there will be an - // additional 0 in the end of the string. - wrapper.strMap[key] = string(elem.data.string); - key++; + if (index % 2 == 1) { + // without explicit calling string() constructor, there will be an + // additional 0 in the end of the string. + wrapper.strMap[key] = string(elem.data.string); + } + index++; break; case EVENT_TYPE_LONG: - wrapper.intMap[key] = elem.data.int64; - key++; + if (index % 2 == 1) { + wrapper.intMap[key] = elem.data.int64; + } + index++; break; case EVENT_TYPE_LIST: break; @@ -124,6 +91,10 @@ LogEventWrapper parseLogEvent(log_msg msg) { elem.complete = true; break; } + + if (elem.complete) { + break; + } } while ((elem.type != EVENT_TYPE_UNKNOWN) && !elem.complete); android_log_destroy(&context); diff --git a/cmds/statsd/src/matchers/matcher_util.h b/cmds/statsd/src/matchers/matcher_util.h index ac17bbe6e6e1..6d8e762382f0 100644 --- a/cmds/statsd/src/matchers/matcher_util.h +++ b/cmds/statsd/src/matchers/matcher_util.h @@ -20,7 +20,6 @@ #include <log/log_read.h> #include <log/logprint.h> #include <set> -#include <string> #include <unordered_map> #include <vector> #include "frameworks/base/cmds/statsd/src/stats_log.pb.h" @@ -37,8 +36,6 @@ typedef struct { std::unordered_map<int, std::string> strMap; std::unordered_map<int, bool> boolMap; std::unordered_map<int, float> floatMap; - - std::string toString() const; } LogEventWrapper; enum MatchingState { diff --git a/cmds/statsd/src/stats_events.proto b/cmds/statsd/src/stats_events.proto index cd00ba8e8898..1e1789574676 100644 --- a/cmds/statsd/src/stats_events.proto +++ b/cmds/statsd/src/stats_events.proto @@ -15,116 +15,49 @@ */ syntax = "proto2"; +option optimize_for = LITE_RUNTIME; -// TODO: Not the right package and class name package android.os.statsd; + option java_package = "com.android.os"; option java_outer_classname = "StatsEventProto"; -/** - * The master event class. This message defines all of the available - * raw stats log events from the Android system, also known as "atoms." - * - * This field contains a single oneof with all of the available messages. - * The stats-log-api-gen tool runs as part of the Android build and - * generates the android.util.StatsLog class, which contains the constants - * and methods that Android uses to log. - * - * This StatsEvent class is not actually built into the Android system. - * Instead, statsd on Android constructs these messages synthetically, - * in the format defined here and in stats_log.proto. - */ message StatsEvent { - oneof event { - ScreenStateChanged screen_state_changed = 1; - ProcessStateChanged process_state_changed = 2; - WakeLockChanged wakelock_changed = 3; - } -} - -/** - * A WorkSource represents the chained attribution of applications that - * resulted in a particular bit of work being done. - */ -message WorkSource { - // TODO -} - -/* - * ***************************************************************************** - * Below are all of the individual atoms that are logged by Android via statsd - * and Westworld. - * - * RULES: - * - The field ids for each atom must start at 1, and count upwards by 1. - * Skipping field ids is not allowed. - * - These form an API, so renaming, renumbering or removing fields is - * not allowed between android releases. (This is not currently enforced, - * but there will be a tool to enforce this restriction). - * - The types must be built-in protocol buffer types, namely, no sub-messages - * are allowed (yet). The bytes type is also not allowed. - * - The CamelCase name of the message type should match the - * underscore_separated name as defined in StatsEvent. - * - If an atom represents work that can be attributed to an app, there can - * be exactly one WorkSource field. It must be field number 1. - * - A field that is a uid should be a string field, tagged with the [xxx] - * annotation. The generated code on android will be represented by UIDs, - * and those UIDs will be translated in xxx to those strings. - * - * CONVENTIONS: - * - Events are past tense. e.g. ScreenStateChanged, not ScreenStateChange - * - If there is a UID, it goes first. Think in an object-oriented fashion. - * ***************************************************************************** - */ - -/** - * Logs when the screen state changes. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java - */ -message ScreenStateChanged { - // TODO: Use the real screen state. - enum State { - STATE_UNKNOWN = 0; - STATE_OFF = 1; - STATE_ON = 2; - STATE_DOZE = 3; - STATE_DOZE_SUSPEND = 4; - STATE_VR = 5; - } - // New screen state. - optional State display_state = 1; + oneof event { + // Screen state change. + ScreenStateChange screen_state_change = 2; + // Process state change. + ProcessStateChange process_state_change = 1112; + } } -/** - * Logs that the state of a process state, as per the activity manager has changed. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java - */ -message ProcessStateChanged { - // TODO: Use the real (mapped) process states. - optional int32 uid = 1; // TODO: should be a string tagged w/ uid annotation - - // The state. - optional int32 state = 2; +// Logs changes in screen state. This event is logged in +// frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java +message ScreenStateChange { + // Screen state enums follow the values defined in below file. + // frameworks/base/core/java/android/view/Display.java + enum State { + STATE_UNKNOWN = 0; + STATE_OFF = 1; + STATE_ON = 2; + STATE_DOZE = 3; + STATE_DOZE_SUSPEND = 4; + STATE_VR = 5; + } + // New screen state. + optional State display_state = 1; } -/** - * Logs that the state of a wakelock has changed. - * - * Logged from: - * TODO - */ -message WakeLockChanged { - // TODO: Add attribution instead of uid. - optional int32 uid = 1; - - // The wakelock tag (Called tag in the Java API, sometimes name elsewhere). - optional string tag = 2; - - // TODO: Use a constant instead of boolean? - optional bool state = 3; +// Logs changes in process state. This event is logged in +// frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java +message ProcessStateChange { + // Type of process event. + enum State { + START = 1; + CRASH = 2; + } + optional State state = 1; + + // UID associated with the package. + optional int32 uid = 2; } - diff --git a/core/java/android/util/StatsLog.java b/core/java/android/util/StatsLog.java new file mode 100644 index 000000000000..0be1a8cfabae --- /dev/null +++ b/core/java/android/util/StatsLog.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2007 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. + */ + +package android.util; + +/** + * Logging access for platform metrics. + * + * <p>This is <b>not</b> the main "logcat" debugging log ({@link android.util.Log})! + * These diagnostic stats are for system integrators, not application authors. + * + * <p>Stats use integer tag codes. + * They carry a payload of one or more int, long, or String values. + * @hide + */ +public class StatsLog { + /** @hide */ public StatsLog() {} + + private static final String TAG = "StatsLog"; + + // We assume that the native methods deal with any concurrency issues. + + /** + * Records an stats log message. + * @param tag The stats type tag code + * @param value A value to log + * @return The number of bytes written + */ + public static native int writeInt(int tag, int value); + + /** + * Records an stats log message. + * @param tag The stats type tag code + * @param value A value to log + * @return The number of bytes written + */ + public static native int writeLong(int tag, long value); + + /** + * Records an stats log message. + * @param tag The stats type tag code + * @param value A value to log + * @return The number of bytes written + */ + public static native int writeFloat(int tag, float value); + + /** + * Records an stats log message. + * @param tag The stats type tag code + * @param str A value to log + * @return The number of bytes written + */ + public static native int writeString(int tag, String str); + + /** + * Records an stats log message. + * @param tag The stats type tag code + * @param list A list of values to log. All values should + * be of type int, long, float or String. + * @return The number of bytes written + */ + public static native int writeArray(int tag, Object... list); +} diff --git a/core/java/android/util/StatsLogKey.java b/core/java/android/util/StatsLogKey.java new file mode 100644 index 000000000000..9ad0a23d00d6 --- /dev/null +++ b/core/java/android/util/StatsLogKey.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2017 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. + */ + +// THIS FILE IS AUTO-GENERATED. +// DO NOT MODIFY. + +package android.util; + +/** @hide */ +public class StatsLogKey { + private StatsLogKey() {} + + /** Constants for android.os.statsd.ScreenStateChange. */ + + /** display_state */ + public static final int SCREEN_STATE_CHANGE__DISPLAY_STATE = 1; + + /** Constants for android.os.statsd.ProcessStateChange. */ + + /** state */ + public static final int PROCESS_STATE_CHANGE__STATE = 1; + + /** uid */ + public static final int PROCESS_STATE_CHANGE__UID = 2; + + /** package_name */ + public static final int PROCESS_STATE_CHANGE__PACKAGE_NAME = 1002; + + /** package_version */ + public static final int PROCESS_STATE_CHANGE__PACKAGE_VERSION = 3; + + /** package_version_string */ + public static final int PROCESS_STATE_CHANGE__PACKAGE_VERSION_STRING = 4; + +} diff --git a/core/java/android/util/StatsLogTag.java b/core/java/android/util/StatsLogTag.java new file mode 100644 index 000000000000..5e5a82870aa0 --- /dev/null +++ b/core/java/android/util/StatsLogTag.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2017 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. + */ + +// THIS FILE IS AUTO-GENERATED. +// DO NOT MODIFY. + +package android.util; + +/** @hide */ +public class StatsLogTag { + private StatsLogTag() {} + + /** android.os.statsd.ScreenStateChange. */ + public static final int SCREEN_STATE_CHANGE = 2; + + /** android.os.statsd.ProcessStateChange. */ + public static final int PROCESS_STATE_CHANGE = 1112; + +} diff --git a/core/java/android/util/StatsLogValue.java b/core/java/android/util/StatsLogValue.java new file mode 100644 index 000000000000..05b9d9333bef --- /dev/null +++ b/core/java/android/util/StatsLogValue.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2017 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. + */ + +// THIS FILE IS AUTO-GENERATED. +// DO NOT MODIFY. + +package android.util; + +/** @hide */ +public class StatsLogValue { + private StatsLogValue() {} + + /** Constants for android.os.statsd.ScreenStateChange. */ + + /** display_state: STATE_UNKNOWN */ + public static final int SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_UNKNOWN = 0; + + /** display_state: STATE_OFF */ + public static final int SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF = 1; + + /** display_state: STATE_ON */ + public static final int SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON = 2; + + /** display_state: STATE_DOZE */ + public static final int SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_DOZE = 3; + + /** display_state: STATE_DOZE_SUSPEND */ + public static final int SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_DOZE_SUSPEND = 4; + + /** display_state: STATE_VR */ + public static final int SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_VR = 5; + + /** Constants for android.os.statsd.ProcessStateChange. */ + + /** state: START */ + public static final int PROCESS_STATE_CHANGE__STATE__START = 1; + + /** state: CRASH */ + public static final int PROCESS_STATE_CHANGE__STATE__CRASH = 2; + +} diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 928626b21475..256b920ee34a 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -1,13 +1,3 @@ - -genrule { - name: "android_util_StatsLog.cpp", - tools: ["stats-log-api-gen"], - cmd: "$(location stats-log-api-gen) --jni $(genDir)/android_util_StatsLog.cpp", - out: [ - "android_util_StatsLog.cpp", - ], -} - cc_library_shared { name: "libandroid_runtime", @@ -114,6 +104,7 @@ cc_library_shared { "android_nio_utils.cpp", "android_util_AssetManager.cpp", "android_util_Binder.cpp", + "android_util_StatsLog.cpp", "android_util_EventLog.cpp", "android_util_MemoryIntArray.cpp", "android_util_Log.cpp", @@ -280,13 +271,11 @@ cc_library_shared { "libhwbinder", "libvintf", "libnativewindow", + "libhwui", "libdl", - "libstatslog", ], - generated_sources: ["android_util_StatsLog.cpp"], - local_include_dirs: ["android/graphics"], export_include_dirs: [ ".", diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index da6d5aa88d47..820933b02e82 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -1324,10 +1324,10 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit), REG_JNI(register_android_os_SystemClock), REG_JNI(register_android_util_EventLog), + REG_JNI(register_android_util_StatsLog), REG_JNI(register_android_util_Log), REG_JNI(register_android_util_MemoryIntArray), REG_JNI(register_android_util_PathParser), - REG_JNI(register_android_util_StatsLog), REG_JNI(register_android_app_admin_SecurityLog), REG_JNI(register_android_content_AssetManager), REG_JNI(register_android_content_StringBlock), diff --git a/core/jni/android_util_StatsLog.cpp b/core/jni/android_util_StatsLog.cpp new file mode 100644 index 000000000000..c992365094f7 --- /dev/null +++ b/core/jni/android_util_StatsLog.cpp @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2007-2014 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 <fcntl.h> +#include <log/log_event_list.h> + +#include <log/log.h> + +#include <nativehelper/JNIHelp.h> +#include "core_jni_helpers.h" +#include "jni.h" + +#define UNUSED __attribute__((__unused__)) + +namespace android { + +static jclass gCollectionClass; +static jmethodID gCollectionAddID; + +static jclass gIntegerClass; +static jfieldID gIntegerValueID; + +static jclass gLongClass; +static jfieldID gLongValueID; + +static jclass gFloatClass; +static jfieldID gFloatValueID; + +static jclass gStringClass; + +/* + * In class android.util.StatsLog: + * static native int writeInt(int tag, int value) + */ +static jint android_util_StatsLog_write_Integer(JNIEnv* env UNUSED, + jobject clazz UNUSED, + jint tag, jint value) +{ + android_log_event_list ctx(tag); + ctx << (int32_t)value; + return ctx.write(LOG_ID_STATS); +} + +/* + * In class android.util.StatsLog: + * static native int writeLong(long tag, long value) + */ +static jint android_util_StatsLog_write_Long(JNIEnv* env UNUSED, + jobject clazz UNUSED, + jint tag, jlong value) +{ + android_log_event_list ctx(tag); + ctx << (int64_t)value; + return ctx.write(LOG_ID_STATS); +} + +/* + * In class android.util.StatsLog: + * static native int writeFloat(long tag, float value) + */ +static jint android_util_StatsLog_write_Float(JNIEnv* env UNUSED, + jobject clazz UNUSED, + jint tag, jfloat value) +{ + android_log_event_list ctx(tag); + ctx << (float)value; + return ctx.write(LOG_ID_STATS); +} + +/* + * In class android.util.StatsLog: + * static native int writeString(int tag, String value) + */ +static jint android_util_StatsLog_write_String(JNIEnv* env, + jobject clazz UNUSED, + jint tag, jstring value) { + android_log_event_list ctx(tag); + // Don't throw NPE -- I feel like it's sort of mean for a logging function + // to be all crashy if you pass in NULL -- but make the NULL value explicit. + if (value != NULL) { + const char *str = env->GetStringUTFChars(value, NULL); + ctx << str; + env->ReleaseStringUTFChars(value, str); + } else { + ctx << "NULL"; + } + return ctx.write(LOG_ID_STATS); +} + +/* + * In class android.util.StatsLog: + * static native int writeArray(long tag, Object... value) + */ +static jint android_util_StatsLog_write_Array(JNIEnv* env, jobject clazz, + jint tag, jobjectArray value) { + android_log_event_list ctx(tag); + + if (value == NULL) { + ctx << "[NULL]"; + return ctx.write(LOG_ID_STATS); + } + + jsize copied = 0, num = env->GetArrayLength(value); + for (; copied < num && copied < 255; ++copied) { + if (ctx.status()) break; + jobject item = env->GetObjectArrayElement(value, copied); + if (item == NULL) { + ctx << "NULL"; + } else if (env->IsInstanceOf(item, gStringClass)) { + const char *str = env->GetStringUTFChars((jstring) item, NULL); + ctx << str; + env->ReleaseStringUTFChars((jstring) item, str); + } else if (env->IsInstanceOf(item, gIntegerClass)) { + ctx << (int32_t)env->GetIntField(item, gIntegerValueID); + } else if (env->IsInstanceOf(item, gLongClass)) { + ctx << (int64_t)env->GetLongField(item, gLongValueID); + } else if (env->IsInstanceOf(item, gFloatClass)) { + ctx << (float)env->GetFloatField(item, gFloatValueID); + } else { + jniThrowException(env, + "java/lang/IllegalArgumentException", + "Invalid payload item type"); + return -1; + } + env->DeleteLocalRef(item); + } + return ctx.write(LOG_ID_STATS); +} + +/* + * JNI registration. + */ +static const JNINativeMethod gRegisterMethods[] = { + /* name, signature, funcPtr */ + { "writeInt", "(II)I", (void*) android_util_StatsLog_write_Integer }, + { "writeLong", "(IJ)I", (void*) android_util_StatsLog_write_Long }, + { "writeFloat", "(IF)I", (void*) android_util_StatsLog_write_Float }, + { "writeString", + "(ILjava/lang/String;)I", + (void*) android_util_StatsLog_write_String + }, + { "writeArray", + "(I[Ljava/lang/Object;)I", + (void*) android_util_StatsLog_write_Array + }, +}; + +static struct { const char *name; jclass *clazz; } gClasses[] = { + { "java/lang/Integer", &gIntegerClass }, + { "java/lang/Long", &gLongClass }, + { "java/lang/Float", &gFloatClass }, + { "java/lang/String", &gStringClass }, + { "java/util/Collection", &gCollectionClass }, +}; + +static struct { jclass *c; const char *name, *ft; jfieldID *id; } gFields[] = { + { &gIntegerClass, "value", "I", &gIntegerValueID }, + { &gLongClass, "value", "J", &gLongValueID }, + { &gFloatClass, "value", "F", &gFloatValueID }, +}; + +static struct { jclass *c; const char *name, *mt; jmethodID *id; } gMethods[] = { + { &gCollectionClass, "add", "(Ljava/lang/Object;)Z", &gCollectionAddID }, +}; + +int register_android_util_StatsLog(JNIEnv* env) { + for (int i = 0; i < NELEM(gClasses); ++i) { + jclass clazz = FindClassOrDie(env, gClasses[i].name); + *gClasses[i].clazz = MakeGlobalRefOrDie(env, clazz); + } + + for (int i = 0; i < NELEM(gFields); ++i) { + *gFields[i].id = GetFieldIDOrDie(env, + *gFields[i].c, gFields[i].name, gFields[i].ft); + } + + for (int i = 0; i < NELEM(gMethods); ++i) { + *gMethods[i].id = GetMethodIDOrDie(env, + *gMethods[i].c, gMethods[i].name, gMethods[i].mt); + } + + return RegisterMethodsOrDie( + env, + "android/util/StatsLog", + gRegisterMethods, NELEM(gRegisterMethods)); +} + +}; // namespace android diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 68ed9aecf31b..7c9cd00e9c41 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -297,12 +297,26 @@ public final class BatteryStatsService extends IBatteryStats.Stub void noteProcessStart(String name, int uid) { synchronized (mStats) { mStats.noteProcessStartLocked(name, uid); + + // TODO: remove this once we figure out properly where and how + // PROCESS_EVENT = 1112 + // KEY_STATE = 1 + // KEY_PACKAGE_NAME: 1002 + // KEY_UID: 2 + StatsLog.writeArray(1112, 1, 1, 1002, name, 2, uid); } } void noteProcessCrash(String name, int uid) { synchronized (mStats) { mStats.noteProcessCrashLocked(name, uid); + + // TODO: remove this once we figure out properly where and how + // PROCESS_EVENT = 1112 + // KEY_STATE = 1 + // KEY_PACKAGE_NAME: 1002 + // KEY_UID: 2 + StatsLog.writeArray(1112, 1, 2, 1002, name, 2, uid); } } @@ -320,9 +334,6 @@ public final class BatteryStatsService extends IBatteryStats.Stub void noteUidProcessState(int uid, int state) { synchronized (mStats) { - // TODO: remove this once we figure out properly where and how - StatsLog.write(StatsLog.PROCESS_STATE_CHANGED, uid, state); - mStats.noteUidProcessStateLocked(uid, state); } } @@ -537,10 +548,12 @@ public final class BatteryStatsService extends IBatteryStats.Stub enforceCallingPermission(); if (DBG) Slog.d(TAG, "begin noteScreenState"); synchronized (mStats) { - // TODO: remove this once we figure out properly where and how - StatsLog.write(StatsLog.SCREEN_STATE_CHANGED, state); - mStats.noteScreenStateLocked(state); + // TODO: remove this once we figure out properly where and how + // SCREEN_EVENT = 2 + // KEY_STATE: 1 + // State value: state. We can change this to our own def later. + StatsLog.writeArray(2, 1, state); } if (DBG) Slog.d(TAG, "end noteScreenState"); } diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp deleted file mode 100644 index a910c628a9e6..000000000000 --- a/tools/stats_log_api_gen/Android.bp +++ /dev/null @@ -1,98 +0,0 @@ -// -// Copyright (C) 2017 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. -// - -// ========================================================== -// Build the host executable: stats-log-api-gen -// ========================================================== -cc_binary_host { - name: "stats-log-api-gen", - srcs: [ - "Collation.cpp", - "main.cpp", - ], - - shared_libs: [ - "libstats_proto_host", - "libprotobuf-cpp-full", - ], - - proto: { - type: "full", - }, -} - -// ========================================================== -// Build the host test executable: stats-log-api-gen -// ========================================================== -cc_test_host { - name: "stats-log-api-gen-test", - cflags: [ - "-Wall", - "-Wextra", - "-Werror", - "-g", - "-DUNIT_TEST", - ], - srcs: [ - "Collation.cpp", - "test_collation.cpp", - "test.proto", - ], - - static_libs: [ - "libgmock_host", - ], - - shared_libs: [ - "libstats_proto_host", - ], - - proto: { - type: "full", - }, -} - -// ========================================================== -// Native library -// ========================================================== -genrule { - name: "statslog.h", - tools: ["stats-log-api-gen"], - cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog.h", - out: [ - "statslog.h", - ], -} - -genrule { - name: "statslog.cpp", - tools: ["stats-log-api-gen"], - cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog.cpp", - out: [ - "statslog.cpp", - ], -} - -cc_library_shared { - name: "libstatslog", - generated_sources: ["statslog.cpp"], - generated_headers: ["statslog.h"], - export_generated_headers: ["statslog.h"], - shared_libs: [ - "liblog", - ], -} - diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp deleted file mode 100644 index 5d2926821164..000000000000 --- a/tools/stats_log_api_gen/Collation.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (C) 2017, 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 "Collation.h" - -#include <stdio.h> -#include <map> - -namespace android { -namespace stats_log_api_gen { - -using google::protobuf::FieldDescriptor; -using google::protobuf::FileDescriptor; -using google::protobuf::SourceLocation; -using std::map; - - -// -// AtomDecl class -// - -AtomDecl::AtomDecl() - :code(0), - name() -{ -} - -AtomDecl::AtomDecl(const AtomDecl& that) - :code(that.code), - name(that.name), - message(that.message), - fields(that.fields) -{ -} - -AtomDecl::AtomDecl(int c, const string& n, const string& m) - :code(c), - name(n), - message(m) -{ -} - -AtomDecl::~AtomDecl() -{ -} - - -/** - * Print an error message for a FieldDescriptor, including the file name and line number. - */ -static void -print_error(const FieldDescriptor* field, const char* format, ...) -{ - const Descriptor* message = field->containing_type(); - const FileDescriptor* file = message->file(); - - SourceLocation loc; - if (field->GetSourceLocation(&loc)) { - // TODO: this will work if we can figure out how to pass --include_source_info to protoc - fprintf(stderr, "%s:%d: ", file->name().c_str(), loc.start_line); - } else { - fprintf(stderr, "%s: ", file->name().c_str()); - } - va_list args; - va_start(args, format); - vfprintf(stderr, format, args); - va_end (args); -} - -/** - * Convert a protobuf type into a java type. - */ -static java_type_t -java_type(const FieldDescriptor* field) -{ - int protoType = field->type(); - switch (protoType) { - case FieldDescriptor::TYPE_DOUBLE: - return JAVA_TYPE_DOUBLE; - case FieldDescriptor::TYPE_FLOAT: - return JAVA_TYPE_FLOAT; - case FieldDescriptor::TYPE_INT64: - return JAVA_TYPE_LONG; - case FieldDescriptor::TYPE_UINT64: - return JAVA_TYPE_LONG; - case FieldDescriptor::TYPE_INT32: - return JAVA_TYPE_INT; - case FieldDescriptor::TYPE_FIXED64: - return JAVA_TYPE_LONG; - case FieldDescriptor::TYPE_FIXED32: - return JAVA_TYPE_INT; - case FieldDescriptor::TYPE_BOOL: - return JAVA_TYPE_BOOLEAN; - case FieldDescriptor::TYPE_STRING: - return JAVA_TYPE_STRING; - case FieldDescriptor::TYPE_GROUP: - return JAVA_TYPE_UNKNOWN; - case FieldDescriptor::TYPE_MESSAGE: - // TODO: not the final package name - if (field->message_type()->full_name() == "android.os.statsd.WorkSource") { - return JAVA_TYPE_WORK_SOURCE; - } else { - return JAVA_TYPE_OBJECT; - } - case FieldDescriptor::TYPE_BYTES: - return JAVA_TYPE_BYTE_ARRAY; - case FieldDescriptor::TYPE_UINT32: - return JAVA_TYPE_INT; - case FieldDescriptor::TYPE_ENUM: - return JAVA_TYPE_INT; - case FieldDescriptor::TYPE_SFIXED32: - return JAVA_TYPE_INT; - case FieldDescriptor::TYPE_SFIXED64: - return JAVA_TYPE_LONG; - case FieldDescriptor::TYPE_SINT32: - return JAVA_TYPE_INT; - case FieldDescriptor::TYPE_SINT64: - return JAVA_TYPE_LONG; - default: - return JAVA_TYPE_UNKNOWN; - } -} - -/** - * Gather the info about the atoms. - */ -int -collate_atoms(const Descriptor* descriptor, Atoms* atoms) -{ - int errorCount = 0; - const bool dbg = false; - - for (int i=0; i<descriptor->field_count(); i++) { - const FieldDescriptor* atomField = descriptor->field(i); - - if (dbg) { - printf(" %s (%d)\n", atomField->name().c_str(), atomField->number()); - } - - // StatsEvent only has one oneof, which contains only messages. Don't allow other types. - if (atomField->type() != FieldDescriptor::TYPE_MESSAGE) { - print_error(atomField, - "Bad type for atom. StatsEvent can only have message type fields: %s\n", - atomField->name().c_str()); - errorCount++; - continue; - } - - const Descriptor* atom = atomField->message_type(); - - // Build a sorted list of the fields. Descriptor has them in source file order. - map<int,const FieldDescriptor*> fields; - for (int j=0; j<atom->field_count(); j++) { - const FieldDescriptor* field = atom->field(j); - fields[field->number()] = field; - } - - // Check that the parameters start at 1 and go up sequentially. - int expectedNumber = 1; - for (map<int,const FieldDescriptor*>::const_iterator it = fields.begin(); - it != fields.end(); it++) { - const int number = it->first; - const FieldDescriptor* field = it->second; - if (number != expectedNumber) { - print_error(field, "Fields must be numbered consecutively starting at 1:" - " '%s' is %d but should be %d\n", - field->name().c_str(), number, expectedNumber); - errorCount++; - expectedNumber = number; - continue; - } - expectedNumber++; - } - - // Check that only allowed types are present. Remove any invalid ones. - for (map<int,const FieldDescriptor*>::const_iterator it = fields.begin(); - it != fields.end(); it++) { - const FieldDescriptor* field = it->second; - - java_type_t javaType = java_type(field); - - if (javaType == JAVA_TYPE_UNKNOWN) { - print_error(field, "Unkown type for field: %s\n", field->name().c_str()); - errorCount++; - continue; - } else if (javaType == JAVA_TYPE_OBJECT) { - // Allow WorkSources, but only at position 1. - print_error(field, "Message type not allowed for field: %s\n", - field->name().c_str()); - errorCount++; - continue; - } else if (javaType == JAVA_TYPE_BYTE_ARRAY) { - print_error(field, "Raw bytes type not allowed for field: %s\n", - field->name().c_str()); - errorCount++; - continue; - } - - } - - // Check that if there's a WorkSource, it's at position 1. - for (map<int,const FieldDescriptor*>::const_iterator it = fields.begin(); - it != fields.end(); it++) { - int number = it->first; - if (number != 1) { - const FieldDescriptor* field = it->second; - java_type_t javaType = java_type(field); - if (javaType == JAVA_TYPE_WORK_SOURCE) { - print_error(field, "WorkSource fields must have field id 1, in message: '%s'\n", - atom->name().c_str()); - errorCount++; - } - } - } - - AtomDecl atomDecl(atomField->number(), atomField->name(), atom->name()); - - // Build the type signature - vector<java_type_t> signature; - for (map<int,const FieldDescriptor*>::const_iterator it = fields.begin(); - it != fields.end(); it++) { - const FieldDescriptor* field = it->second; - java_type_t javaType = java_type(field); - - atomDecl.fields.push_back(AtomField(field->name(), javaType)); - signature.push_back(javaType); - } - - atoms->signatures.insert(signature); - atoms->decls.insert(atomDecl); - } - - if (dbg) { - printf("signatures = [\n"); - for (set<vector<java_type_t>>::const_iterator it = atoms->signatures.begin(); - it != atoms->signatures.end(); it++) { - printf(" "); - for (vector<java_type_t>::const_iterator jt = it->begin(); jt != it->end(); jt++) { - printf(" %d", (int)*jt); - } - printf("\n"); - } - printf("]\n"); - } - - return errorCount; -} - -} // namespace stats_log_api_gen -} // namespace android - - diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h deleted file mode 100644 index 50af7ea2d335..000000000000 --- a/tools/stats_log_api_gen/Collation.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2017, 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. - */ - -#ifndef ANDROID_STATS_LOG_API_GEN_COLLATION_H -#define ANDROID_STATS_LOG_API_GEN_COLLATION_H - - -#include <google/protobuf/descriptor.h> - -#include <set> -#include <vector> - -namespace android { -namespace stats_log_api_gen { - -using std::set; -using std::string; -using std::vector; -using google::protobuf::Descriptor; - -/** - * The types for atom parameters. - */ -typedef enum { - JAVA_TYPE_UNKNOWN = 0, - - JAVA_TYPE_WORK_SOURCE = 1, - JAVA_TYPE_BOOLEAN = 2, - JAVA_TYPE_INT = 3, - JAVA_TYPE_LONG = 4, - JAVA_TYPE_FLOAT = 5, - JAVA_TYPE_DOUBLE = 6, - JAVA_TYPE_STRING = 7, - - JAVA_TYPE_OBJECT = -1, - JAVA_TYPE_BYTE_ARRAY = -2, -} java_type_t; - - -/** - * The name and type for an atom field. - */ -struct AtomField { - string name; - java_type_t javaType; - - inline AtomField() :name(), javaType(JAVA_TYPE_UNKNOWN) {} - inline AtomField(const AtomField& that) :name(that.name), javaType(that.javaType) {} - inline AtomField(string n, java_type_t jt) :name(n), javaType(jt) {} - inline ~AtomField() {} -}; - -/** - * The name and code for an atom. - */ -struct AtomDecl { - int code; - string name; - - string message; - vector<AtomField> fields; - - AtomDecl(); - AtomDecl(const AtomDecl& that); - AtomDecl(int code, const string& name, const string& message); - ~AtomDecl(); - - inline bool operator<(const AtomDecl& that) const { - return (code == that.code) ? (name < that.name) : (code < that.code); - } -}; - -struct Atoms { - set<vector<java_type_t>> signatures; - set<AtomDecl> decls; -}; - -/** - * Gather the information about the atoms. Returns the number of errors. - */ -int collate_atoms(const Descriptor* descriptor, Atoms* atoms); - -} // namespace stats_log_api_gen -} // namespace android - - -#endif // ANDROID_STATS_LOG_API_GEN_COLLATION_H diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp deleted file mode 100644 index aaea4f6fe749..000000000000 --- a/tools/stats_log_api_gen/main.cpp +++ /dev/null @@ -1,623 +0,0 @@ - - -#include "Collation.h" - -#include "frameworks/base/cmds/statsd/src/stats_events.pb.h" - -#include <set> -#include <vector> - -#include <getopt.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -using namespace google::protobuf; -using namespace std; - -namespace android { -namespace stats_log_api_gen { - -using android::os::statsd::StatsEvent; - -// TODO: Support WorkSources - -/** - * Turn lower and camel case into upper case with underscores. - */ -static string -make_constant_name(const string& str) -{ - string result; - const int N = str.size(); - bool underscore_next = false; - for (int i=0; i<N; i++) { - char c = str[i]; - if (c >= 'A' && c <= 'Z') { - if (underscore_next) { - result += '_'; - underscore_next = false; - } - } else if (c >= 'a' && c <= 'z') { - c = 'A' + c - 'a'; - underscore_next = true; - } else if (c == '_') { - underscore_next = false; - } - result += c; - } - return result; -} - -static const char* -cpp_type_name(java_type_t type) -{ - switch (type) { - case JAVA_TYPE_BOOLEAN: - return "bool"; - case JAVA_TYPE_INT: - return "int32_t"; - case JAVA_TYPE_LONG: - return "int64_t"; - case JAVA_TYPE_FLOAT: - return "float"; - case JAVA_TYPE_DOUBLE: - return "double"; - case JAVA_TYPE_STRING: - return "char const*"; - default: - return "UNKNOWN"; - } -} - -static const char* -java_type_name(java_type_t type) -{ - switch (type) { - case JAVA_TYPE_BOOLEAN: - return "boolean"; - case JAVA_TYPE_INT: - return "int"; - case JAVA_TYPE_LONG: - return "long"; - case JAVA_TYPE_FLOAT: - return "float"; - case JAVA_TYPE_DOUBLE: - return "double"; - case JAVA_TYPE_STRING: - return "java.lang.String"; - default: - return "UNKNOWN"; - } -} - -static int -write_stats_log_cpp(FILE* out, const Atoms& atoms) -{ - int errorCount; - - // Print prelude - fprintf(out, "// This file is autogenerated\n"); - fprintf(out, "\n"); - - fprintf(out, "#include <log/log_event_list.h>\n"); - fprintf(out, "#include <log/log.h>\n"); - fprintf(out, "#include <statslog.h>\n"); - fprintf(out, "\n"); - - fprintf(out, "namespace android {\n"); - fprintf(out, "namespace util {\n"); - - // Print write methods - fprintf(out, "\n"); - for (set<vector<java_type_t>>::const_iterator signature = atoms.signatures.begin(); - signature != atoms.signatures.end(); signature++) { - int argIndex; - - fprintf(out, "void\n"); - fprintf(out, "stats_write(int code"); - argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { - fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex); - argIndex++; - } - fprintf(out, ")\n"); - - fprintf(out, "{\n"); - argIndex = 1; - fprintf(out, " android_log_event_list event(code);\n"); - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { - if (*arg == JAVA_TYPE_STRING) { - fprintf(out, " if (arg%d == NULL) {\n", argIndex); - fprintf(out, " arg%d = \"\";\n", argIndex); - fprintf(out, " }\n"); - } - fprintf(out, " event << arg%d;\n", argIndex); - argIndex++; - } - - fprintf(out, " event.write(LOG_ID_STATS);\n"); - fprintf(out, "}\n"); - fprintf(out, "\n"); - } - - // Print footer - fprintf(out, "\n"); - fprintf(out, "} // namespace util\n"); - fprintf(out, "} // namespace android\n"); - - return 0; -} - - -static int -write_stats_log_header(FILE* out, const Atoms& atoms) -{ - int errorCount; - - // Print prelude - fprintf(out, "// This file is autogenerated\n"); - fprintf(out, "\n"); - fprintf(out, "#pragma once\n"); - fprintf(out, "\n"); - fprintf(out, "#include <stdint.h>\n"); - fprintf(out, "\n"); - - fprintf(out, "namespace android {\n"); - fprintf(out, "namespace util {\n"); - fprintf(out, "\n"); - fprintf(out, "/*\n"); - fprintf(out, " * API For logging statistics events.\n"); - fprintf(out, " */\n"); - fprintf(out, "\n"); - fprintf(out, "/**\n"); - fprintf(out, " * Constants for event codes.\n"); - fprintf(out, " */\n"); - fprintf(out, "enum {\n"); - - size_t i = 0; - // Print constants - for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - string constant = make_constant_name(atom->name); - fprintf(out, "\n"); - fprintf(out, " /**\n"); - fprintf(out, " * %s %s\n", atom->message.c_str(), atom->name.c_str()); - fprintf(out, " * Usage: stats_write(StatsLog.%s", constant.c_str()); - for (vector<AtomField>::const_iterator field = atom->fields.begin(); - field != atom->fields.end(); field++) { - fprintf(out, ", %s %s", cpp_type_name(field->javaType), field->name.c_str()); - } - fprintf(out, ");\n"); - fprintf(out, " */\n"); - char const* const comma = (i == atoms.decls.size() - 1) ? "" : ","; - fprintf(out, " %s = %d%s\n", constant.c_str(), atom->code, comma); - i++; - } - fprintf(out, "\n"); - fprintf(out, "};\n"); - fprintf(out, "\n"); - - // Print write methods - fprintf(out, "//\n"); - fprintf(out, "// Write methods\n"); - fprintf(out, "//\n"); - for (set<vector<java_type_t>>::const_iterator signature = atoms.signatures.begin(); - signature != atoms.signatures.end(); signature++) { - - fprintf(out, "void stats_write(int code"); - int argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { - fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex); - argIndex++; - } - fprintf(out, ");\n"); - } - - fprintf(out, "\n"); - fprintf(out, "} // namespace util\n"); - fprintf(out, "} // namespace android\n"); - - return 0; -} - -static int -write_stats_log_java(FILE* out, const Atoms& atoms) -{ - int errorCount; - - // Print prelude - fprintf(out, "// This file is autogenerated\n"); - fprintf(out, "\n"); - fprintf(out, "package android.util;\n"); - fprintf(out, "\n"); - fprintf(out, "\n"); - fprintf(out, "/**\n"); - fprintf(out, " * API For logging statistics events.\n"); - fprintf(out, " * @hide\n"); - fprintf(out, " */\n"); - fprintf(out, "public final class StatsLog {\n"); - fprintf(out, " // Constants for event codes.\n"); - - // Print constants - for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - string constant = make_constant_name(atom->name); - fprintf(out, "\n"); - fprintf(out, " /**\n"); - fprintf(out, " * %s %s\n", atom->message.c_str(), atom->name.c_str()); - fprintf(out, " * Usage: StatsLog.write(StatsLog.%s", constant.c_str()); - for (vector<AtomField>::const_iterator field = atom->fields.begin(); - field != atom->fields.end(); field++) { - fprintf(out, ", %s %s", java_type_name(field->javaType), field->name.c_str()); - } - fprintf(out, ");\n"); - fprintf(out, " */\n"); - fprintf(out, " public static final int %s = %d;\n", constant.c_str(), atom->code); - } - fprintf(out, "\n"); - - // Print write methods - fprintf(out, " // Write methods\n"); - for (set<vector<java_type_t>>::const_iterator signature = atoms.signatures.begin(); - signature != atoms.signatures.end(); signature++) { - fprintf(out, " public static native void write(int code"); - int argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { - fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex); - argIndex++; - } - fprintf(out, ");\n"); - } - - fprintf(out, "}\n"); - - return 0; -} - -static const char* -jni_type_name(java_type_t type) -{ - switch (type) { - case JAVA_TYPE_BOOLEAN: - return "jboolean"; - case JAVA_TYPE_INT: - return "jint"; - case JAVA_TYPE_LONG: - return "jlong"; - case JAVA_TYPE_FLOAT: - return "jfloat"; - case JAVA_TYPE_DOUBLE: - return "jdouble"; - case JAVA_TYPE_STRING: - return "jstring"; - default: - return "UNKNOWN"; - } -} - -static string -jni_function_name(const vector<java_type_t>& signature) -{ - string result("StatsLog_write"); - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - switch (*arg) { - case JAVA_TYPE_BOOLEAN: - result += "_boolean"; - break; - case JAVA_TYPE_INT: - result += "_int"; - break; - case JAVA_TYPE_LONG: - result += "_long"; - break; - case JAVA_TYPE_FLOAT: - result += "_float"; - break; - case JAVA_TYPE_DOUBLE: - result += "_double"; - break; - case JAVA_TYPE_STRING: - result += "_String"; - break; - default: - result += "_UNKNOWN"; - break; - } - } - return result; -} - -static const char* -java_type_signature(java_type_t type) -{ - switch (type) { - case JAVA_TYPE_BOOLEAN: - return "Z"; - case JAVA_TYPE_INT: - return "I"; - case JAVA_TYPE_LONG: - return "J"; - case JAVA_TYPE_FLOAT: - return "F"; - case JAVA_TYPE_DOUBLE: - return "D"; - case JAVA_TYPE_STRING: - return "Ljava/lang/String;"; - default: - return "UNKNOWN"; - } -} - -static string -jni_function_signature(const vector<java_type_t>& signature) -{ - string result("(I"); - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - result += java_type_signature(*arg); - } - result += ")V"; - return result; -} - -static int -write_stats_log_jni(FILE* out, const Atoms& atoms) -{ - int errorCount; - - // Print prelude - fprintf(out, "// This file is autogenerated\n"); - fprintf(out, "\n"); - - fprintf(out, "#include <statslog.h>\n"); - fprintf(out, "\n"); - fprintf(out, "#include <nativehelper/JNIHelp.h>\n"); - fprintf(out, "#include \"core_jni_helpers.h\"\n"); - fprintf(out, "#include \"jni.h\"\n"); - fprintf(out, "\n"); - fprintf(out, "#define UNUSED __attribute__((__unused__))\n"); - fprintf(out, "\n"); - - fprintf(out, "namespace android {\n"); - fprintf(out, "\n"); - - // Print write methods - for (set<vector<java_type_t>>::const_iterator signature = atoms.signatures.begin(); - signature != atoms.signatures.end(); signature++) { - int argIndex; - - fprintf(out, "static void\n"); - fprintf(out, "%s(JNIEnv* env, jobject clazz UNUSED, jint code", - jni_function_name(*signature).c_str()); - argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { - fprintf(out, ", %s arg%d", jni_type_name(*arg), argIndex); - argIndex++; - } - fprintf(out, ")\n"); - - fprintf(out, "{\n"); - - // Prepare strings - argIndex = 1; - bool hadString = false; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { - if (*arg == JAVA_TYPE_STRING) { - fprintf(out, " const char* str%d;\n", argIndex); - fprintf(out, " if (arg%d != NULL) {\n", argIndex); - fprintf(out, " str%d = env->GetStringUTFChars(arg%d, NULL);\n", - argIndex, argIndex); - fprintf(out, " } else {\n"); - fprintf(out, " str%d = NULL;\n", argIndex); - fprintf(out, " }\n"); - hadString = true; - } - argIndex++; - } - - // Emit this to quiet the unused parameter warning if there were no strings. - if (!hadString) { - fprintf(out, " (void)env;\n"); - } - - // stats_write call - argIndex = 1; - fprintf(out, " android::util::stats_write(code"); - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { - const char* argName = (*arg == JAVA_TYPE_STRING) ? "str" : "arg"; - fprintf(out, ", (%s)%s%d", cpp_type_name(*arg), argName, argIndex); - argIndex++; - } - fprintf(out, ");\n"); - - // Clean up strings - argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { - if (*arg == JAVA_TYPE_STRING) { - fprintf(out, " if (str%d != NULL) {\n", argIndex); - fprintf(out, " env->ReleaseStringUTFChars(arg%d, str%d);\n", - argIndex, argIndex); - fprintf(out, " }\n"); - } - argIndex++; - } - - fprintf(out, "}\n"); - fprintf(out, "\n"); - } - - // Print registration function table - fprintf(out, "/*\n"); - fprintf(out, " * JNI registration.\n"); - fprintf(out, " */\n"); - fprintf(out, "static const JNINativeMethod gRegisterMethods[] = {\n"); - for (set<vector<java_type_t>>::const_iterator signature = atoms.signatures.begin(); - signature != atoms.signatures.end(); signature++) { - fprintf(out, " { \"write\", \"%s\", (void*)%s },\n", - jni_function_signature(*signature).c_str(), - jni_function_name(*signature).c_str()); - } - fprintf(out, "};\n"); - fprintf(out, "\n"); - - // Print registration function - fprintf(out, "int register_android_util_StatsLog(JNIEnv* env) {\n"); - fprintf(out, " return RegisterMethodsOrDie(\n"); - fprintf(out, " env,\n"); - fprintf(out, " \"android/util/StatsLog\",\n"); - fprintf(out, " gRegisterMethods, NELEM(gRegisterMethods));\n"); - fprintf(out, "}\n"); - - fprintf(out, "\n"); - fprintf(out, "} // namespace android\n"); - - return 0; -} - - -static void -print_usage() -{ - fprintf(stderr, "usage: stats-log-api-gen OPTIONS\n"); - fprintf(stderr, "\n"); - fprintf(stderr, "OPTIONS\n"); - fprintf(stderr, " --cpp FILENAME the header file to output\n"); - fprintf(stderr, " --header FILENAME the cpp file to output\n"); - fprintf(stderr, " --help this message\n"); - fprintf(stderr, " --java FILENAME the java file to output\n"); - fprintf(stderr, " --jni FILENAME the jni file to output\n"); -} - -/** - * Do the argument parsing and execute the tasks. - */ -static int -run(int argc, char const*const* argv) -{ - string cppFilename; - string headerFilename; - string javaFilename; - string jniFilename; - - int index = 1; - while (index < argc) { - if (0 == strcmp("--help", argv[index])) { - print_usage(); - return 0; - } else if (0 == strcmp("--cpp", argv[index])) { - index++; - if (index >= argc) { - print_usage(); - return 1; - } - cppFilename = argv[index]; - } else if (0 == strcmp("--header", argv[index])) { - index++; - if (index >= argc) { - print_usage(); - return 1; - } - headerFilename = argv[index]; - } else if (0 == strcmp("--java", argv[index])) { - index++; - if (index >= argc) { - print_usage(); - return 1; - } - javaFilename = argv[index]; - } else if (0 == strcmp("--jni", argv[index])) { - index++; - if (index >= argc) { - print_usage(); - return 1; - } - jniFilename = argv[index]; - } - index++; - } - - if (cppFilename.size() == 0 - && headerFilename.size() == 0 - && javaFilename.size() == 0 - && jniFilename.size() == 0) { - print_usage(); - return 1; - } - - // Collate the parameters - Atoms atoms; - int errorCount = collate_atoms(StatsEvent::descriptor(), &atoms); - if (errorCount != 0) { - return 1; - } - - // Write the .cpp file - if (cppFilename.size() != 0) { - FILE* out = fopen(cppFilename.c_str(), "w"); - if (out == NULL) { - fprintf(stderr, "Unable to open file for write: %s\n", cppFilename.c_str()); - return 1; - } - errorCount = android::stats_log_api_gen::write_stats_log_cpp(out, atoms); - fclose(out); - } - - // Write the .h file - if (headerFilename.size() != 0) { - FILE* out = fopen(headerFilename.c_str(), "w"); - if (out == NULL) { - fprintf(stderr, "Unable to open file for write: %s\n", headerFilename.c_str()); - return 1; - } - errorCount = android::stats_log_api_gen::write_stats_log_header(out, atoms); - fclose(out); - } - - // Write the .java file - if (javaFilename.size() != 0) { - FILE* out = fopen(javaFilename.c_str(), "w"); - if (out == NULL) { - fprintf(stderr, "Unable to open file for write: %s\n", javaFilename.c_str()); - return 1; - } - errorCount = android::stats_log_api_gen::write_stats_log_java(out, atoms); - fclose(out); - } - - // Write the jni file - if (jniFilename.size() != 0) { - FILE* out = fopen(jniFilename.c_str(), "w"); - if (out == NULL) { - fprintf(stderr, "Unable to open file for write: %s\n", jniFilename.c_str()); - return 1; - } - errorCount = android::stats_log_api_gen::write_stats_log_jni(out, atoms); - fclose(out); - } - - return 0; -} - -} -} - -/** - * Main. - */ -int -main(int argc, char const*const* argv) -{ - GOOGLE_PROTOBUF_VERIFY_VERSION; - - return android::stats_log_api_gen::run(argc, argv); -} diff --git a/tools/stats_log_api_gen/test.proto b/tools/stats_log_api_gen/test.proto deleted file mode 100644 index 2311a1192c95..000000000000 --- a/tools/stats_log_api_gen/test.proto +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -syntax = "proto2"; - -import "frameworks/base/cmds/statsd/src/stats_events.proto"; - -package android.stats_log_api_gen; - -message IntAtom { - optional int32 field1 = 1; -} - -message AnotherIntAtom { - optional int32 field1 = 1; -} - -message OutOfOrderAtom { - optional int32 field2 = 2; - optional int32 field1 = 1; -} - -enum AnEnum { - VALUE0 = 0; - VALUE1 = 1; -} - -message AllTypesAtom { - optional android.os.statsd.WorkSource attribution = 1; - optional double double_field = 2; - optional float float_field = 3; - optional int64 int64_field = 4; - optional uint64 uint64_field = 5; - optional int32 int32_field = 6; - optional fixed64 fixed64_field = 7; - optional fixed32 fixed32_field = 8; - optional bool bool_field = 9; - optional string string_field = 10; - optional uint32 uint32_field = 11; - optional AnEnum enum_field = 12; - optional sfixed32 sfixed32_field = 13; - optional sfixed64 sfixed64_field = 14; - optional sint32 sint32_field = 15; - optional sint64 sint64_field = 16; -} - -message Event { - oneof event { - OutOfOrderAtom out_of_order_atom = 2; - IntAtom int_atom = 1; - AnotherIntAtom another_int_atom = 3; - AllTypesAtom all_types_atom = 4; - } -} - -message BadTypesAtom { - optional IntAtom bad_int_atom = 1; - optional bytes bad_bytes = 2; -} - -message BadTypesEvent { - oneof event { - BadTypesAtom bad_types_atom = 1; - } -} - -message BadSkippedFieldSingleAtom { - optional int32 field2 = 2; -} - -message BadSkippedFieldSingle { - oneof event { - BadSkippedFieldSingleAtom bad = 1; - } -} - -message BadSkippedFieldMultipleAtom { - optional int32 field1 = 1; - optional int32 field3 = 3; - optional int32 field5 = 5; -} - -message BadSkippedFieldMultiple { - oneof event { - BadSkippedFieldMultipleAtom bad = 1; - } -} - -message BadWorkSourcePositionAtom { - optional int32 field1 = 1; - optional android.os.statsd.WorkSource attribution = 2; -} - -message BadWorkSourcePosition { - oneof event { - BadWorkSourcePositionAtom bad = 1; - } -} - diff --git a/tools/stats_log_api_gen/test_collation.cpp b/tools/stats_log_api_gen/test_collation.cpp deleted file mode 100644 index 1bd2e3de332e..000000000000 --- a/tools/stats_log_api_gen/test_collation.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2017, 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 <gtest/gtest.h> - -#include "frameworks/base/tools/stats_log_api_gen/test.pb.h" -#include "Collation.h" - -#include <stdio.h> - -namespace android { -namespace stats_log_api_gen { - -using std::set; -using std::vector; - -/** - * Return whether the set contains a vector of the elements provided. - */ -static bool -set_contains_vector(const set<vector<java_type_t>>& s, int count, ...) -{ - va_list args; - vector<java_type_t> v; - - va_start(args, count); - for (int i=0; i<count; i++) { - v.push_back((java_type_t)va_arg(args, int)); - } - va_end(args); - - return s.find(v) != s.end(); -} - -/** - * Expect that the provided set contains the elements provided. - */ -#define EXPECT_SET_CONTAINS_SIGNATURE(s, ...) \ - do { \ - int count = sizeof((int[]){__VA_ARGS__})/sizeof(int); \ - EXPECT_TRUE(set_contains_vector(s, count, __VA_ARGS__)); \ - } while(0) - -/** - * Test a correct collation, with all the types. - */ -TEST(CollationTest, CollateStats) { - Atoms atoms; - int errorCount = collate_atoms(Event::descriptor(), &atoms); - - EXPECT_EQ(0, errorCount); - EXPECT_EQ(3ul, atoms.signatures.size()); - - // IntAtom, AnotherIntAtom - EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures, JAVA_TYPE_INT); - - // OutOfOrderAtom - EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures, JAVA_TYPE_INT, JAVA_TYPE_INT); - - // AllTypesAtom - EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures, - JAVA_TYPE_WORK_SOURCE, // WorkSource - JAVA_TYPE_DOUBLE, // double - JAVA_TYPE_FLOAT, // float - JAVA_TYPE_LONG, // int64 - JAVA_TYPE_LONG, // uint64 - JAVA_TYPE_INT, // int32 - JAVA_TYPE_LONG, // fixed64 - JAVA_TYPE_INT, // fixed32 - JAVA_TYPE_BOOLEAN, // bool - JAVA_TYPE_STRING, // string - JAVA_TYPE_INT, // uint32 - JAVA_TYPE_INT, // AnEnum - JAVA_TYPE_INT, // sfixed32 - JAVA_TYPE_LONG, // sfixed64 - JAVA_TYPE_INT, // sint32 - JAVA_TYPE_LONG // sint64 - ); - - set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - EXPECT_EQ(1, atom->code); - EXPECT_EQ("int_atom", atom->name); - EXPECT_EQ("IntAtom", atom->message); - atom++; - - EXPECT_EQ(2, atom->code); - EXPECT_EQ("out_of_order_atom", atom->name); - EXPECT_EQ("OutOfOrderAtom", atom->message); - atom++; - - EXPECT_EQ(3, atom->code); - EXPECT_EQ("another_int_atom", atom->name); - EXPECT_EQ("AnotherIntAtom", atom->message); - atom++; - - EXPECT_EQ(4, atom->code); - EXPECT_EQ("all_types_atom", atom->name); - EXPECT_EQ("AllTypesAtom", atom->message); - atom++; - - EXPECT_TRUE(atom == atoms.decls.end()); -} - -/** - * Test that event class that contains stuff other than the atoms is rejected. - */ -TEST(CollationTest, NonMessageTypeFails) { - Atoms atoms; - int errorCount = collate_atoms(IntAtom::descriptor(), &atoms); - - EXPECT_EQ(1, errorCount); -} - -/** - * Test that atoms that have non-primitve types are rejected. - */ -TEST(CollationTest, FailOnBadTypes) { - Atoms atoms; - int errorCount = collate_atoms(BadTypesEvent::descriptor(), &atoms); - - EXPECT_EQ(2, errorCount); -} - -/** - * Test that atoms that skip field numbers (in the first position) are rejected. - */ -TEST(CollationTest, FailOnSkippedFieldsSingle) { - Atoms atoms; - int errorCount = collate_atoms(BadSkippedFieldSingle::descriptor(), &atoms); - - EXPECT_EQ(1, errorCount); -} - -/** - * Test that atoms that skip field numbers (not in the first position, and multiple - * times) are rejected. - */ -TEST(CollationTest, FailOnSkippedFieldsMultiple) { - Atoms atoms; - int errorCount = collate_atoms(BadSkippedFieldMultiple::descriptor(), &atoms); - - EXPECT_EQ(2, errorCount); -} - -/** - * Test that atoms that have a WorkSource not in the first position are rejected. - */ -TEST(CollationTest, FailBadWorkSourcePosition) { - Atoms atoms; - int errorCount = collate_atoms(BadWorkSourcePosition::descriptor(), &atoms); - - EXPECT_EQ(1, errorCount); -} - - -} // namespace stats_log_api_gen -} // namespace android - |