Merge "[RESTRICT AUTOMERGE][CarTelemetryService] Add memory metrics test to kitchen sink" into sc-v2-dev
diff --git a/service/src/com/android/car/telemetry/publisher/StatsPublisher.java b/service/src/com/android/car/telemetry/publisher/StatsPublisher.java
index 1005b03..00481fe 100644
--- a/service/src/com/android/car/telemetry/publisher/StatsPublisher.java
+++ b/service/src/com/android/car/telemetry/publisher/StatsPublisher.java
@@ -41,6 +41,7 @@
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.Duration;
@@ -149,6 +150,8 @@
private PersistableBundle loadBundle() {
try (FileInputStream fileInputStream = new FileInputStream(mSavedStatsConfigsFile)) {
return PersistableBundle.readFromStream(fileInputStream);
+ } catch (FileNotFoundException e) {
+ return new PersistableBundle();
} catch (IOException e) {
// TODO(b/199947533): handle failure
Slog.e(CarLog.TAG_TELEMETRY,
@@ -159,6 +162,10 @@
/** Writes the PersistableBundle containing stats config keys and versions to disk. */
private void saveBundle() {
+ if (mSavedStatsConfigs.size() == 0) {
+ mSavedStatsConfigsFile.delete();
+ return;
+ }
try (FileOutputStream fileOutputStream = new FileOutputStream(mSavedStatsConfigsFile)) {
mSavedStatsConfigs.writeToStream(fileOutputStream);
} catch (IOException e) {
@@ -175,13 +182,14 @@
Preconditions.checkArgument(
publisherParam.getPublisherCase() == PublisherCase.STATS,
"Subscribers only with StatsPublisher are supported by this class.");
-
synchronized (mLock) {
long configKey = addStatsConfigLocked(subscriber);
mConfigKeyToSubscribers.put(configKey, subscriber);
}
if (!mIsPullingReports.getAndSet(true)) {
+ Slog.d(CarLog.TAG_TELEMETRY, "Stats report will be pulled in "
+ + PULL_REPORTS_PERIOD.toMinutes() + " minutes.");
mTelemetryHandler.postDelayed(mPullReportsPeriodically, PULL_REPORTS_PERIOD.toMillis());
}
}
@@ -246,6 +254,8 @@
}
if (mIsPullingReports.get()) {
+ Slog.d(CarLog.TAG_TELEMETRY, "Stats report will be pulled in "
+ + PULL_REPORTS_PERIOD.toMinutes() + " minutes.");
mTelemetryHandler.postDelayed(mPullReportsPeriodically, PULL_REPORTS_PERIOD.toMillis());
}
}
diff --git a/tests/EmbeddedKitchenSinkApp/res/layout/car_telemetry_test.xml b/tests/EmbeddedKitchenSinkApp/res/layout/car_telemetry_test.xml
index 2576b7d..3110d82 100644
--- a/tests/EmbeddedKitchenSinkApp/res/layout/car_telemetry_test.xml
+++ b/tests/EmbeddedKitchenSinkApp/res/layout/car_telemetry_test.xml
@@ -39,6 +39,29 @@
android:layout_height="wrap_content"
android:text="@string/get_on_gear_change"/>
</LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/on_process_memory_state_layout"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+ <Button
+ android:id="@+id/send_on_process_memory_config"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/send_process_memory_state_config"/>
+ <Button
+ android:id="@+id/remove_on_process_memory_config"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/remove_process_memory_state_config"/>
+ <Button
+ android:id="@+id/get_on_process_memory_report"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/get_report_process_memory_state_config"/>
+ </LinearLayout>
+
<TextView
android:id="@+id/output_textview"
android:layout_width="wrap_content"
diff --git a/tests/EmbeddedKitchenSinkApp/res/values/strings.xml b/tests/EmbeddedKitchenSinkApp/res/values/strings.xml
index d43e715..77e3989 100644
--- a/tests/EmbeddedKitchenSinkApp/res/values/strings.xml
+++ b/tests/EmbeddedKitchenSinkApp/res/values/strings.xml
@@ -385,5 +385,8 @@
<!-- CarTelemetryService Test -->
<string name="send_on_gear_change" translatable="false">Send MetricsConfig on_gear_change</string>
<string name="remove_on_gear_change" translatable="false">Remove MetricsConfig on_gear_change</string>
- <string name="get_on_gear_change" translatable="false">Get on_gear_change Report</string>
+ <string name="get_on_gear_change" translatable="false">Get Report on_gear_change</string>
+ <string name="send_process_memory_state_config" translatable="false">Send MetricsConfig process_memory</string>
+ <string name="remove_process_memory_state_config" translatable="false">Remove MetricsConfig process_memory</string>
+ <string name="get_report_process_memory_state_config" translatable="false">Get Report process_memory</string>
</resources>
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/telemetry/CarTelemetryTestFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/telemetry/CarTelemetryTestFragment.java
index 13392b4..5a76abc 100644
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/telemetry/CarTelemetryTestFragment.java
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/telemetry/CarTelemetryTestFragment.java
@@ -16,6 +16,8 @@
package com.google.android.car.kitchensink.telemetry;
+import static com.android.car.telemetry.TelemetryProto.StatsPublisher.SystemMetric.PROCESS_MEMORY_STATE;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.car.telemetry.CarTelemetryManager;
@@ -35,6 +37,7 @@
import com.google.android.car.kitchensink.KitchenSinkActivity;
import com.google.android.car.kitchensink.R;
+import com.google.protobuf.InvalidProtocolBufferException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -42,6 +45,8 @@
import java.util.concurrent.Executors;
public class CarTelemetryTestFragment extends Fragment {
+
+ /** Hello World test from vehicle property publisher by injecting gear change. */
private static final String LUA_SCRIPT_ON_GEAR_CHANGE =
"function onGearChange(published_data, state)\n"
+ " result = {data = \"Hello World!\"}\n"
@@ -55,23 +60,69 @@
.setReadRate(0f)
.build()
).build();
- private static final TelemetryProto.Subscriber VEHICLE_PROPERTY_SUBSCRIBER =
- TelemetryProto.Subscriber.newBuilder()
- .setHandler("onGearChange")
- .setPublisher(VEHICLE_PROPERTY_PUBLISHER)
- .setPriority(0)
- .build();
private static final TelemetryProto.MetricsConfig METRICS_CONFIG_ON_GEAR_CHANGE_V1 =
TelemetryProto.MetricsConfig.newBuilder()
.setName("my_metrics_config")
.setVersion(1)
.setScript(LUA_SCRIPT_ON_GEAR_CHANGE)
- .addSubscribers(VEHICLE_PROPERTY_SUBSCRIBER)
+ .addSubscribers(
+ TelemetryProto.Subscriber.newBuilder()
+ .setHandler("onGearChange")
+ .setPublisher(VEHICLE_PROPERTY_PUBLISHER)
+ .setPriority(100)) // low priority
.build();
- private static final MetricsConfigKey KEY_V1 = new MetricsConfigKey(
+ private static final MetricsConfigKey ON_GEAR_CHANGE_KEY_V1 = new MetricsConfigKey(
METRICS_CONFIG_ON_GEAR_CHANGE_V1.getName(),
METRICS_CONFIG_ON_GEAR_CHANGE_V1.getVersion());
+ /** Memory metrics test. */
+ private static final String LUA_SCRIPT_ON_PROCESS_MEMORY_STATE = new StringBuilder()
+ .append("function calculateAverage(tbl)\n")
+ .append(" sum = 0\n")
+ .append(" size = 0\n")
+ .append(" for _, value in ipairs(tbl) do\n")
+ .append(" sum = sum + value\n")
+ .append(" size = size + 1\n")
+ .append(" end\n")
+ .append(" return sum/size\n")
+ .append("end\n")
+ .append("function onProcessMemory(published_data, state)\n")
+ .append(" result = {}\n")
+ .append(" result.page_fault_avg = calculateAverage(published_data.page_fault)\n")
+ .append(" result.major_page_fault_avg = calculateAverage("
+ + "published_data.page_major_fault)\n")
+ .append(" result.oom_adj_score_avg = calculateAverage("
+ + "published_data.oom_adj_score)\n")
+ .append(" result.rss_in_bytes_avg = calculateAverage(published_data.rss_in_bytes)\n")
+ .append(" result.swap_in_bytes_avg = calculateAverage("
+ + "published_data.swap_in_bytes)\n")
+ .append(" result.cache_in_bytes_avg = calculateAverage("
+ + "published_data.cache_in_bytes)\n")
+ .append(" on_script_finished(result)\n")
+ .append("end\n")
+ .toString();
+
+ private static final TelemetryProto.Publisher PROCESS_MEMORY_PUBLISHER =
+ TelemetryProto.Publisher.newBuilder()
+ .setStats(
+ TelemetryProto.StatsPublisher.newBuilder()
+ .setSystemMetric(PROCESS_MEMORY_STATE)
+ ).build();
+ private static final TelemetryProto.MetricsConfig METRICS_CONFIG_PROCESS_MEMORY_V1 =
+ TelemetryProto.MetricsConfig.newBuilder()
+ .setName("process_memory_metrics_config")
+ .setVersion(1)
+ .setScript(LUA_SCRIPT_ON_PROCESS_MEMORY_STATE)
+ .addSubscribers(
+ TelemetryProto.Subscriber.newBuilder()
+ .setHandler("onProcessMemory")
+ .setPublisher(PROCESS_MEMORY_PUBLISHER)
+ .setPriority(0)) // high priority
+ .build();
+ private static final MetricsConfigKey PROCESS_MEMORY_KEY_V1 = new MetricsConfigKey(
+ METRICS_CONFIG_PROCESS_MEMORY_V1.getName(),
+ METRICS_CONFIG_PROCESS_MEMORY_V1.getVersion());
+
private final Executor mExecutor = Executors.newSingleThreadExecutor();
private CarTelemetryManager mCarTelemetryManager;
@@ -105,6 +156,15 @@
removeGearConfigBtn.setOnClickListener(this::onRemoveGearChangeConfigBtnClick);
getGearReportBtn.setOnClickListener(this::onGetGearChangeReportBtnClick);
+ mOutputTextView = view.findViewById(R.id.output_textview);
+ Button sendProcessMemConfigBtn = view.findViewById(R.id.send_on_process_memory_config);
+ Button getProcessMemReportBtn = view.findViewById(R.id.get_on_process_memory_report);
+ Button removeProcessMemConfigBtn = view.findViewById(R.id.remove_on_process_memory_config);
+
+ sendProcessMemConfigBtn.setOnClickListener(this::onSendProcessMemoryConfigBtnClick);
+ removeProcessMemConfigBtn.setOnClickListener(this::onRemoveProcessMemoryConfigBtnClick);
+ getProcessMemReportBtn.setOnClickListener(this::onGetProcessMemoryReportBtnClick);
+
return view;
}
@@ -114,19 +174,36 @@
private void onSendGearChangeConfigBtnClick(View view) {
showOutput("Sending MetricsConfig that listen for gear change...");
- mCarTelemetryManager.addMetricsConfig(KEY_V1,
+ mCarTelemetryManager.addMetricsConfig(ON_GEAR_CHANGE_KEY_V1,
METRICS_CONFIG_ON_GEAR_CHANGE_V1.toByteArray());
}
private void onRemoveGearChangeConfigBtnClick(View view) {
showOutput("Removing MetricsConfig that listens for gear change...");
- mCarTelemetryManager.removeMetricsConfig(KEY_V1);
+ mCarTelemetryManager.removeMetricsConfig(ON_GEAR_CHANGE_KEY_V1);
}
private void onGetGearChangeReportBtnClick(View view) {
showOutput("Fetching report... If nothing shows up after a few seconds, "
+ "then no result exists");
- mCarTelemetryManager.sendFinishedReports(KEY_V1);
+ mCarTelemetryManager.sendFinishedReports(ON_GEAR_CHANGE_KEY_V1);
+ }
+
+ private void onSendProcessMemoryConfigBtnClick(View view) {
+ showOutput("Sending MetricsConfig that listen for process memory state...");
+ mCarTelemetryManager.addMetricsConfig(PROCESS_MEMORY_KEY_V1,
+ METRICS_CONFIG_PROCESS_MEMORY_V1.toByteArray());
+ }
+
+ private void onRemoveProcessMemoryConfigBtnClick(View view) {
+ showOutput("Removing MetricsConfig that listens for process memory state...");
+ mCarTelemetryManager.removeMetricsConfig(PROCESS_MEMORY_KEY_V1);
+ }
+
+ private void onGetProcessMemoryReportBtnClick(View view) {
+ showOutput("Fetching report for process memory state... If nothing shows up after "
+ + "a few seconds, then no result exists");
+ mCarTelemetryManager.sendFinishedReports(PROCESS_MEMORY_KEY_V1);
}
@Override
@@ -155,6 +232,14 @@
@Override
public void onError(@NonNull MetricsConfigKey key, @NonNull byte[] error) {
+ try {
+ TelemetryProto.TelemetryError telemetryError =
+ TelemetryProto.TelemetryError.parseFrom(error);
+ showOutput("Error is " + telemetryError);
+ } catch (InvalidProtocolBufferException e) {
+ showOutput("Unable to parse error result for MetricsConfig " + key.getName()
+ + ". " + e.getMessage());
+ }
}
@Override