Merge "Add support for pulling and pushing statsd atoms to CarService." into qt-qpr1-dev
diff --git a/car_product/sepolicy/private/carservice_app.te b/car_product/sepolicy/private/carservice_app.te
index bc1d74c..6e65a8f 100644
--- a/car_product/sepolicy/private/carservice_app.te
+++ b/car_product/sepolicy/private/carservice_app.te
@@ -12,6 +12,9 @@
# Allow Car Service to register/access itself with ServiceManager
add_service(carservice_app, carservice_service)
+# Allow Car Service to register its stats service with ServiceManager
+add_service(carservice_app, carstats_service)
+
allow carservice_app wifi_service:service_manager find;
# Allow Car Service to access certain system services.
diff --git a/car_product/sepolicy/private/service_contexts b/car_product/sepolicy/private/service_contexts
index 7ac544c..38d994c 100644
--- a/car_product/sepolicy/private/service_contexts
+++ b/car_product/sepolicy/private/service_contexts
@@ -1,2 +1,3 @@
car_service u:object_r:carservice_service:s0
+car_stats u:object_r:carstats_service:s0
com.android.car.procfsinspector u:object_r:procfsinspector_service:s0
diff --git a/car_product/sepolicy/private/statsd.te b/car_product/sepolicy/private/statsd.te
new file mode 100644
index 0000000..1a17418
--- /dev/null
+++ b/car_product/sepolicy/private/statsd.te
@@ -0,0 +1,2 @@
+# Allow statsd to pull atoms from car_stats service
+allow statsd carstats_service:service_manager find;
diff --git a/car_product/sepolicy/public/service.te b/car_product/sepolicy/public/service.te
index 87426f4..c6a2e30 100644
--- a/car_product/sepolicy/public/service.te
+++ b/car_product/sepolicy/public/service.te
@@ -1,2 +1,3 @@
type carservice_service, app_api_service, service_manager_type;
+type carstats_service, service_manager_type;
type procfsinspector_service, service_manager_type;
diff --git a/service/src/com/android/car/CarService.java b/service/src/com/android/car/CarService.java
index fdc4995..044c791 100644
--- a/service/src/com/android/car/CarService.java
+++ b/service/src/com/android/car/CarService.java
@@ -99,6 +99,7 @@
linkToDeath(mVehicle, mVehicleDeathRecipient);
ServiceManager.addService("car_service", mICarImpl);
+ ServiceManager.addService("car_stats", mICarImpl.getStatsService());
SystemProperties.set("boot.car_service_created", "1");
super.onCreate();
}
diff --git a/service/src/com/android/car/ICarImpl.java b/service/src/com/android/car/ICarImpl.java
index d98b780..d2fed46 100644
--- a/service/src/com/android/car/ICarImpl.java
+++ b/service/src/com/android/car/ICarImpl.java
@@ -386,6 +386,10 @@
}
}
+ CarStatsService getStatsService() {
+ return mCarStatsService;
+ }
+
public static void assertVehicleHalMockPermission(Context context) {
assertPermission(context, Car.PERMISSION_MOCK_VEHICLE_HAL);
}
diff --git a/service/src/com/android/car/stats/CarStatsService.java b/service/src/com/android/car/stats/CarStatsService.java
index db23355..64fbf1f 100644
--- a/service/src/com/android/car/stats/CarStatsService.java
+++ b/service/src/com/android/car/stats/CarStatsService.java
@@ -16,27 +16,36 @@
package com.android.car.stats;
+import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.os.StatsLogEventWrapper;
+import android.os.SystemClock;
import android.util.ArrayMap;
import android.util.Log;
+import android.util.StatsLog;
import com.android.car.stats.VmsClientLog.ConnectionState;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.car.ICarStatsService;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.function.Consumer;
import java.util.function.Function;
/**
- * Implements collection and dumpsys reporting of statistics in CSV format.
+ * Implementation of {@link ICarStatsService}, for reporting pulled atoms via statsd.
+ *
+ * Also implements collection and dumpsys reporting of atoms in CSV format.
*/
-public class CarStatsService {
+public class CarStatsService extends ICarStatsService.Stub {
private static final boolean DEBUG = false;
private static final String TAG = "CarStatsService";
private static final String VMS_CONNECTION_STATS_DUMPSYS_HEADER =
@@ -71,12 +80,14 @@
.thenComparingInt(VmsClientStats::getLayerChannel)
.thenComparingInt(VmsClientStats::getLayerVersion);
+ private final Context mContext;
private final PackageManager mPackageManager;
@GuardedBy("mVmsClientStats")
private final Map<Integer, VmsClientLog> mVmsClientStats = new ArrayMap<>();
public CarStatsService(Context context) {
+ mContext = context;
mPackageManager = context.getPackageManager();
}
@@ -97,9 +108,7 @@
}
}
- /**
- * Dumps metrics in CSV format.
- */
+ @Override
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
List<String> flags = Arrays.asList(args);
if (args.length == 0 || flags.contains("--vms-client")) {
@@ -107,6 +116,21 @@
}
}
+ @Override
+ public StatsLogEventWrapper[] pullData(int tagId) {
+ mContext.enforceCallingPermission(Manifest.permission.DUMP, null);
+ if (tagId != StatsLog.VMS_CLIENT_STATS) {
+ Log.w(TAG, "Unexpected tagId: " + tagId);
+ return null;
+ }
+
+ List<StatsLogEventWrapper> ret = new ArrayList<>();
+ long elapsedNanos = SystemClock.elapsedRealtimeNanos();
+ long wallClockNanos = SystemClock.currentTimeMicro() * 1000L;
+ pullVmsClientStats(tagId, elapsedNanos, wallClockNanos, ret);
+ return ret.toArray(new StatsLogEventWrapper[0]);
+ }
+
private void dumpVmsStats(PrintWriter writer) {
synchronized (mVmsClientStats) {
writer.println(VMS_CONNECTION_STATS_DUMPSYS_HEADER);
@@ -120,11 +144,38 @@
writer.println();
writer.println(VMS_CLIENT_STATS_DUMPSYS_HEADER);
+ dumpVmsClientStats(entry -> writer.println(
+ VMS_CLIENT_STATS_DUMPSYS_FORMAT.apply(entry)));
+ }
+ }
+
+ private void pullVmsClientStats(int tagId, long elapsedNanos, long wallClockNanos,
+ List<StatsLogEventWrapper> pulledData) {
+ dumpVmsClientStats((entry) -> {
+ StatsLogEventWrapper e =
+ new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
+ e.writeInt(entry.getUid());
+
+ e.writeInt(entry.getLayerType());
+ e.writeInt(entry.getLayerChannel());
+ e.writeInt(entry.getLayerVersion());
+
+ e.writeLong(entry.getTxBytes());
+ e.writeLong(entry.getTxPackets());
+ e.writeLong(entry.getRxBytes());
+ e.writeLong(entry.getRxPackets());
+ e.writeLong(entry.getDroppedBytes());
+ e.writeLong(entry.getDroppedPackets());
+ pulledData.add(e);
+ });
+ }
+
+ private void dumpVmsClientStats(Consumer<VmsClientStats> dumpFn) {
+ synchronized (mVmsClientStats) {
mVmsClientStats.values().stream()
.flatMap(log -> log.getLayerEntries().stream())
.sorted(VMS_CLIENT_STATS_ORDER)
- .forEachOrdered(entry -> writer.println(
- VMS_CLIENT_STATS_DUMPSYS_FORMAT.apply(entry)));
+ .forEachOrdered(dumpFn);
}
}
}
diff --git a/service/src/com/android/car/stats/VmsClientLog.java b/service/src/com/android/car/stats/VmsClientLog.java
index 506a5fc..0fa2198 100644
--- a/service/src/com/android/car/stats/VmsClientLog.java
+++ b/service/src/com/android/car/stats/VmsClientLog.java
@@ -19,6 +19,7 @@
import android.annotation.Nullable;
import android.car.vms.VmsLayer;
import android.util.ArrayMap;
+import android.util.StatsLog;
import com.android.internal.annotations.GuardedBy;
@@ -36,15 +37,20 @@
*/
public static class ConnectionState {
// Attempting to connect to the client
- public static final int CONNECTING = 0;
+ public static final int CONNECTING =
+ StatsLog.VMS_CLIENT_CONNECTION_STATE_CHANGED__STATE__CONNECTING;
// Client connection established
- public static final int CONNECTED = 1;
+ public static final int CONNECTED =
+ StatsLog.VMS_CLIENT_CONNECTION_STATE_CHANGED__STATE__CONNECTED;
// Client connection closed unexpectedly
- public static final int DISCONNECTED = 2;
+ public static final int DISCONNECTED =
+ StatsLog.VMS_CLIENT_CONNECTION_STATE_CHANGED__STATE__DISCONNECTED;
// Client connection closed by VMS
- public static final int TERMINATED = 3;
+ public static final int TERMINATED =
+ StatsLog.VMS_CLIENT_CONNECTION_STATE_CHANGED__STATE__TERMINATED;
// Error establishing the client connection
- public static final int CONNECTION_ERROR = 4;
+ public static final int CONNECTION_ERROR =
+ StatsLog.VMS_CLIENT_CONNECTION_STATE_CHANGED__STATE__CONNECTION_ERROR;
}
private final Object mLock = new Object();
@@ -77,6 +83,9 @@
* @param connectionState New connection state
*/
public void logConnectionState(int connectionState) {
+ StatsLog.write(StatsLog.VMS_CLIENT_CONNECTION_STATE_CHANGED,
+ mUid, mPackageName, connectionState);
+
AtomicLong counter;
synchronized (mLock) {
counter = mConnectionStateCounters.computeIfAbsent(connectionState,