Adds API for apps to push events to statsd.

This API allows app to construct custom metrics based on labels
chosen by the app developers. Also added some buttons to manually
test this functionality in the dogfood app.

Test: Verified that Android can be built and tested with custom app.
Bug: 69522276
Change-Id: Ifb7abea4c1d62fb435a9cb6f32df12bc2234d82f
This commit is contained in:
David Chen 2017-12-06 16:28:16 -08:00
parent b669be1dcc
commit 0a368b2c39
8 changed files with 136 additions and 2 deletions

View File

@ -624,7 +624,7 @@ genrule {
name: "framework-statslog-gen",
tools: ["stats-log-api-gen"],
cmd: "$(location stats-log-api-gen) --java $(out)",
out: ["android/util/StatsLog.java"],
out: ["android/util/StatsLogInternal.java"],
}
gensrcs {

View File

@ -44575,6 +44575,12 @@ package android.util {
field public static final int[] WILD_CARD;
}
public final class StatsLog {
method public static boolean logEvent(int);
method public static boolean logStart(int);
method public static boolean logStop(int);
}
public class StringBuilderPrinter implements android.util.Printer {
ctor public StringBuilderPrinter(java.lang.StringBuilder);
method public void println(java.lang.String);

View File

@ -79,6 +79,7 @@ message Atom {
IsolatedUidChanged isolated_uid_changed = 43;
PacketWakeupOccurred packet_wakeup_occurred = 44;
DropboxErrorChanged dropbox_error_changed = 45;
AppHook app_hook = 46;
// TODO: Reorder the numbering so that the most frequent occur events occur in the first 15.
}
@ -801,6 +802,29 @@ message DropboxErrorChanged {
optional int32 is_foreground = 7;
}
/*
* Allows other apps to push events into statsd.
* Logged from:
* frameworks/base/core/java/android/util/StatsLog.java
*/
message AppHook {
// The uid of the application that sent this custom atom.
optional int32 uid = 1;
// An arbitrary label chosen by the developer. For Android P, the label should be in [0, 16).
optional int32 label = 2;
// Allows applications to easily use a custom event as start/stop boundaries (ie, define custom
// predicates for the metrics).
enum State {
UNKNOWN = 0;
UNSPECIFIED = 1; // For events that are known to not represent START/STOP.
STOP = 2;
START = 3;
}
optional State state = 3;
}
/**
* Pulls bytes transferred via wifi (Sum of foreground and background usage).
*

View File

@ -111,6 +111,23 @@
android:text="@string/screen_off"/>
</LinearLayout>
<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/custom_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/custom_start" />
<Button
android:id="@+id/custom_stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/custom_stop" />
</LinearLayout>
<Button android:id="@+id/dump"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@ -47,6 +47,9 @@
<string name="screen_on">Screen On</string>
<string name="screen_off">Screen Off</string>
<string name="custom_start">App hook start</string>
<string name="custom_stop">App hook stop</string>
<string name="dump">DumpReport</string>
<string name="report_header">Report details</string>
</resources>

View File

@ -140,6 +140,20 @@ public class MainActivity extends Activity {
}
});
findViewById(R.id.custom_start).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
StatsLog.logStart(8);
}
});
findViewById(R.id.custom_stop).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
StatsLog.logStop(8);
}
});
mReportText = (TextView) findViewById(R.id.report_text);
findViewById(R.id.dump).setOnClickListener(new View.OnClickListener() {

View File

@ -0,0 +1,70 @@
/*
* 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.
*/
package android.util;
/**
* StatsLog provides an API for developers to send events to statsd. The events can be used to
* define custom metrics inside statsd. We will rate-limit how often the calls can be made inside
* statsd.
*/
public final class StatsLog extends StatsLogInternal {
private static final String TAG = "StatsManager";
private StatsLog() {}
/**
* Logs a start event.
*
* @param label developer-chosen label that is from [0, 16).
* @return True if the log request was sent to statsd.
*/
public static boolean logStart(int label) {
if (label >= 0 && label < 16) {
StatsLog.write(APP_HOOK, label, APP_HOOK__STATE__START);
return true;
}
return false;
}
/**
* Logs a stop event.
*
* @param label developer-chosen label that is from [0, 16).
* @return True if the log request was sent to statsd.
*/
public static boolean logStop(int label) {
if (label >= 0 && label < 16) {
StatsLog.write(APP_HOOK, label, APP_HOOK__STATE__STOP);
return true;
}
return false;
}
/**
* Logs an event that does not represent a start or stop boundary.
*
* @param label developer-chosen label that is from [0, 16).
* @return True if the log request was sent to statsd.
*/
public static boolean logEvent(int label) {
if (label >= 0 && label < 16) {
StatsLog.write(APP_HOOK, label, APP_HOOK__STATE__UNSPECIFIED);
return true;
}
return false;
}
}

View File

@ -247,7 +247,7 @@ write_stats_log_java(FILE* out, const Atoms& atoms)
fprintf(out, " * API For logging statistics events.\n");
fprintf(out, " * @hide\n");
fprintf(out, " */\n");
fprintf(out, "public final class StatsLog {\n");
fprintf(out, "public class StatsLogInternal {\n");
fprintf(out, " // Constants for atom codes.\n");
// Print constants for the atom codes.