Merge changes I6b2f5e01,Ice1b2a7b,Ib75f0162,I70b005a4,I8314a32b

* changes:
  Migrate pullBluetoothActivityInfo
  Migrate pullBluetoothBytesTransfer
  Migrate pullMobileBytesTransferBackground
  Migrate pullMobileBytesTransfer
  Migrate pullWifiBytesTransferBackground
This commit is contained in:
Jeffrey Huang
2020-01-14 04:08:41 +00:00
committed by Android (Google) Code Review
3 changed files with 235 additions and 238 deletions

View File

@@ -714,60 +714,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
}
}
private void addNetworkStats(
int tag, List<StatsLogEventWrapper> ret, NetworkStats stats, boolean withFGBG) {
int size = stats.size();
long elapsedNanos = SystemClock.elapsedRealtimeNanos();
long wallClockNanos = SystemClock.currentTimeMicro() * 1000L;
NetworkStats.Entry entry = new NetworkStats.Entry(); // For recycling
for (int j = 0; j < size; j++) {
stats.getValues(j, entry);
StatsLogEventWrapper e = new StatsLogEventWrapper(tag, elapsedNanos, wallClockNanos);
e.writeInt(entry.uid);
if (withFGBG) {
e.writeInt(entry.set);
}
e.writeLong(entry.rxBytes);
e.writeLong(entry.rxPackets);
e.writeLong(entry.txBytes);
e.writeLong(entry.txPackets);
ret.add(e);
}
}
/**
* Allows rollups per UID but keeping the set (foreground/background) slicing.
* Adapted from groupedByUid in frameworks/base/core/java/android/net/NetworkStats.java
*/
private NetworkStats rollupNetworkStatsByFGBG(NetworkStats stats) {
final NetworkStats ret = new NetworkStats(stats.getElapsedRealtime(), 1);
final NetworkStats.Entry entry = new NetworkStats.Entry();
entry.iface = NetworkStats.IFACE_ALL;
entry.tag = NetworkStats.TAG_NONE;
entry.metered = NetworkStats.METERED_ALL;
entry.roaming = NetworkStats.ROAMING_ALL;
int size = stats.size();
NetworkStats.Entry recycle = new NetworkStats.Entry(); // Used for retrieving values
for (int i = 0; i < size; i++) {
stats.getValues(i, recycle);
// Skip specific tags, since already counted in TAG_NONE
if (recycle.tag != NetworkStats.TAG_NONE) continue;
entry.set = recycle.set; // Allows slicing by background/foreground
entry.uid = recycle.uid;
entry.rxBytes = recycle.rxBytes;
entry.rxPackets = recycle.rxPackets;
entry.txBytes = recycle.txBytes;
entry.txPackets = recycle.txPackets;
// Operations purposefully omitted since we don't use them for statsd.
ret.combineValues(entry);
}
return ret;
}
/**
* Helper method to extract the Parcelable controller info from a
* SynchronousResultReceiver.
@@ -815,94 +761,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
}
}
private void pullWifiBytesTransferByFgBg(
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
long token = Binder.clearCallingIdentity();
try {
BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class);
String[] ifaces = bs.getWifiIfaces();
if (ifaces.length == 0) {
return;
}
if (mNetworkStatsService == null) {
Slog.e(TAG, "NetworkStats Service is not available!");
return;
}
NetworkStats stats = rollupNetworkStatsByFGBG(
mNetworkStatsService.getDetailedUidStats(ifaces));
addNetworkStats(tagId, pulledData, stats, true);
} catch (RemoteException e) {
Slog.e(TAG, "Pulling netstats for wifi bytes w/ fg/bg has error", e);
} finally {
Binder.restoreCallingIdentity(token);
}
}
private void pullMobileBytesTransfer(
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
long token = Binder.clearCallingIdentity();
try {
BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class);
String[] ifaces = bs.getMobileIfaces();
if (ifaces.length == 0) {
return;
}
if (mNetworkStatsService == null) {
Slog.e(TAG, "NetworkStats Service is not available!");
return;
}
// Combine all the metrics per Uid into one record.
NetworkStats stats = mNetworkStatsService.getDetailedUidStats(ifaces).groupedByUid();
addNetworkStats(tagId, pulledData, stats, false);
} catch (RemoteException e) {
Slog.e(TAG, "Pulling netstats for mobile bytes has error", e);
} finally {
Binder.restoreCallingIdentity(token);
}
}
private void pullBluetoothBytesTransfer(
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
BluetoothActivityEnergyInfo info = fetchBluetoothData();
if (info.getUidTraffic() != null) {
for (UidTraffic traffic : info.getUidTraffic()) {
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
wallClockNanos);
e.writeInt(traffic.getUid());
e.writeLong(traffic.getRxBytes());
e.writeLong(traffic.getTxBytes());
pulledData.add(e);
}
}
}
private void pullMobileBytesTransferByFgBg(
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
long token = Binder.clearCallingIdentity();
try {
BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class);
String[] ifaces = bs.getMobileIfaces();
if (ifaces.length == 0) {
return;
}
if (mNetworkStatsService == null) {
Slog.e(TAG, "NetworkStats Service is not available!");
return;
}
NetworkStats stats = rollupNetworkStatsByFGBG(
mNetworkStatsService.getDetailedUidStats(ifaces));
addNetworkStats(tagId, pulledData, stats, true);
} catch (RemoteException e) {
Slog.e(TAG, "Pulling netstats for mobile bytes w/ fg/bg has error", e);
} finally {
Binder.restoreCallingIdentity(token);
}
}
private void pullCpuTimePerFreq(
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
@@ -1052,33 +910,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
}
}
private void pullBluetoothActivityInfo(
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
BluetoothActivityEnergyInfo info = fetchBluetoothData();
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
e.writeLong(info.getTimeStamp());
e.writeInt(info.getBluetoothStackState());
e.writeLong(info.getControllerTxTimeMillis());
e.writeLong(info.getControllerRxTimeMillis());
e.writeLong(info.getControllerIdleTimeMillis());
e.writeLong(info.getControllerEnergyUsed());
pulledData.add(e);
}
private synchronized BluetoothActivityEnergyInfo fetchBluetoothData() {
final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) {
SynchronousResultReceiver bluetoothReceiver = new SynchronousResultReceiver(
"bluetooth");
adapter.requestControllerActivityEnergyInfo(bluetoothReceiver);
return awaitControllerInfo(bluetoothReceiver);
} else {
Slog.e(TAG, "Failed to get bluetooth adapter!");
return null;
}
}
private void pullSystemElapsedRealtime(
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
@@ -2291,26 +2122,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
long elapsedNanos = SystemClock.elapsedRealtimeNanos();
long wallClockNanos = SystemClock.currentTimeMicro() * 1000L;
switch (tagId) {
case StatsLog.MOBILE_BYTES_TRANSFER: {
pullMobileBytesTransfer(tagId, elapsedNanos, wallClockNanos, ret);
break;
}
case StatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG: {
pullWifiBytesTransferByFgBg(tagId, elapsedNanos, wallClockNanos, ret);
break;
}
case StatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG: {
pullMobileBytesTransferByFgBg(tagId, elapsedNanos, wallClockNanos, ret);
break;
}
case StatsLog.BLUETOOTH_BYTES_TRANSFER: {
pullBluetoothBytesTransfer(tagId, elapsedNanos, wallClockNanos, ret);
break;
}
case StatsLog.KERNEL_WAKELOCK: {
pullKernelWakelock(tagId, elapsedNanos, wallClockNanos, ret);
@@ -2352,11 +2163,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
break;
}
case StatsLog.BLUETOOTH_ACTIVITY_INFO: {
pullBluetoothActivityInfo(tagId, elapsedNanos, wallClockNanos, ret);
break;
}
case StatsLog.SYSTEM_UPTIME: {
pullSystemUpTime(tagId, elapsedNanos, wallClockNanos, ret);
break;

View File

@@ -60,27 +60,6 @@ const int64_t NO_ALARM_UPDATE = INT64_MAX;
std::map<PullerKey, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
// wifi_bytes_transfer_by_fg_bg
{{.atomTag = android::util::WIFI_BYTES_TRANSFER_BY_FG_BG},
{.additiveFields = {3, 4, 5, 6},
.puller = new StatsCompanionServicePuller(android::util::WIFI_BYTES_TRANSFER_BY_FG_BG)}},
// mobile_bytes_transfer
{{.atomTag = android::util::MOBILE_BYTES_TRANSFER},
{.additiveFields = {2, 3, 4, 5},
.puller = new StatsCompanionServicePuller(android::util::MOBILE_BYTES_TRANSFER)}},
// mobile_bytes_transfer_by_fg_bg
{{.atomTag = android::util::MOBILE_BYTES_TRANSFER_BY_FG_BG},
{.additiveFields = {3, 4, 5, 6},
.puller =
new StatsCompanionServicePuller(android::util::MOBILE_BYTES_TRANSFER_BY_FG_BG)}},
// bluetooth_bytes_transfer
{{.atomTag = android::util::BLUETOOTH_BYTES_TRANSFER},
{.additiveFields = {2, 3},
.puller = new StatsCompanionServicePuller(android::util::BLUETOOTH_BYTES_TRANSFER)}},
// kernel_wakelock
{{.atomTag = android::util::KERNEL_WAKELOCK},
{.puller = new StatsCompanionServicePuller(android::util::KERNEL_WAKELOCK)}},
@@ -132,10 +111,6 @@ std::map<PullerKey, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
{{.atomTag = android::util::MODEM_ACTIVITY_INFO},
{.puller = new StatsCompanionServicePuller(android::util::MODEM_ACTIVITY_INFO)}},
// bluetooth_activity_info
{{.atomTag = android::util::BLUETOOTH_ACTIVITY_INFO},
{.puller = new StatsCompanionServicePuller(android::util::BLUETOOTH_ACTIVITY_INFO)}},
// system_elapsed_realtime
{{.atomTag = android::util::SYSTEM_ELAPSED_REALTIME},
{.coolDownNs = NS_PER_SEC,

View File

@@ -186,6 +186,12 @@ public class StatsPullAtomService extends SystemService {
private static final String TAG = "StatsPullAtomService";
private static final boolean DEBUG = true;
private static final String RESULT_RECEIVER_CONTROLLER_KEY = "controller_activity";
/**
* How long to wait on an individual subsystem to return its stats.
*/
private static final long EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS = 2000;
private final Object mNetworkStatsLock = new Object();
@GuardedBy("mNetworkStatsLock")
private INetworkStatsService mNetworkStatsService;
@@ -327,11 +333,12 @@ public class StatsPullAtomService extends SystemService {
}
private void registerWifiBytesTransfer() {
int tagId = StatsLog.WIFI_BYTES_TRANSFER;
PullAtomMetadata metaData = PullAtomMetadata.newBuilder()
.setAdditiveFields(new int[] {2, 3, 4, 5}).build();
PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
.setAdditiveFields(new int[] {2, 3, 4, 5})
.build();
mStatsManager.registerPullAtomCallback(
tagId,
metaData,
metadata,
(atomTag, data) -> pullWifiBytesTransfer(atomTag, data),
Executors.newSingleThreadExecutor()
);
@@ -356,6 +363,7 @@ public class StatsPullAtomService extends SystemService {
addNetworkStats(atomTag, pulledData, stats, false);
} catch (RemoteException e) {
Slog.e(TAG, "Pulling netstats for wifi bytes has error", e);
return StatsManager.PULL_SKIP;
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -382,36 +390,224 @@ public class StatsPullAtomService extends SystemService {
}
}
private void registerWifiBytesTransferBackground() {
// No op.
/**
* Allows rollups per UID but keeping the set (foreground/background) slicing.
* Adapted from groupedByUid in frameworks/base/core/java/android/net/NetworkStats.java
*/
private NetworkStats rollupNetworkStatsByFGBG(NetworkStats stats) {
final NetworkStats ret = new NetworkStats(stats.getElapsedRealtime(), 1);
final NetworkStats.Entry entry = new NetworkStats.Entry();
entry.iface = NetworkStats.IFACE_ALL;
entry.tag = NetworkStats.TAG_NONE;
entry.metered = NetworkStats.METERED_ALL;
entry.roaming = NetworkStats.ROAMING_ALL;
int size = stats.size();
NetworkStats.Entry recycle = new NetworkStats.Entry(); // Used for retrieving values
for (int i = 0; i < size; i++) {
stats.getValues(i, recycle);
// Skip specific tags, since already counted in TAG_NONE
if (recycle.tag != NetworkStats.TAG_NONE) continue;
entry.set = recycle.set; // Allows slicing by background/foreground
entry.uid = recycle.uid;
entry.rxBytes = recycle.rxBytes;
entry.rxPackets = recycle.rxPackets;
entry.txBytes = recycle.txBytes;
entry.txPackets = recycle.txPackets;
// Operations purposefully omitted since we don't use them for statsd.
ret.combineValues(entry);
}
return ret;
}
private void pullWifiBytesTransferBackground() {
// No op.
private void registerWifiBytesTransferBackground() {
int tagId = StatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG;
PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
.setAdditiveFields(new int[] {3, 4, 5, 6})
.build();
mStatsManager.registerPullAtomCallback(
tagId,
metadata,
(atomTag, data) -> pullWifiBytesTransferBackground(atomTag, data),
Executors.newSingleThreadExecutor()
);
}
private int pullWifiBytesTransferBackground(int atomTag, List<StatsEvent> pulledData) {
INetworkStatsService networkStatsService = getINetworkStatsService();
if (networkStatsService == null) {
Slog.e(TAG, "NetworkStats Service is not available!");
return StatsManager.PULL_SKIP;
}
long token = Binder.clearCallingIdentity();
try {
BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class);
String[] ifaces = bs.getWifiIfaces();
if (ifaces.length == 0) {
return StatsManager.PULL_SKIP;
}
NetworkStats stats = rollupNetworkStatsByFGBG(
networkStatsService.getDetailedUidStats(ifaces));
addNetworkStats(atomTag, pulledData, stats, true);
} catch (RemoteException e) {
Slog.e(TAG, "Pulling netstats for wifi bytes w/ fg/bg has error", e);
return StatsManager.PULL_SKIP;
} finally {
Binder.restoreCallingIdentity(token);
}
return StatsManager.PULL_SUCCESS;
}
private void registerMobileBytesTransfer() {
// No op.
int tagId = StatsLog.MOBILE_BYTES_TRANSFER;
PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
.setAdditiveFields(new int[] {2, 3, 4, 5})
.build();
mStatsManager.registerPullAtomCallback(
tagId,
metadata,
(atomTag, data) -> pullMobileBytesTransfer(atomTag, data),
Executors.newSingleThreadExecutor()
);
}
private void pullMobileBytesTransfer() {
// No op.
private int pullMobileBytesTransfer(int atomTag, List<StatsEvent> pulledData) {
INetworkStatsService networkStatsService = getINetworkStatsService();
if (networkStatsService == null) {
Slog.e(TAG, "NetworkStats Service is not available!");
return StatsManager.PULL_SKIP;
}
long token = Binder.clearCallingIdentity();
try {
BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class);
String[] ifaces = bs.getMobileIfaces();
if (ifaces.length == 0) {
return StatsManager.PULL_SKIP;
}
// Combine all the metrics per Uid into one record.
NetworkStats stats = networkStatsService.getDetailedUidStats(ifaces).groupedByUid();
addNetworkStats(atomTag, pulledData, stats, false);
} catch (RemoteException e) {
Slog.e(TAG, "Pulling netstats for mobile bytes has error", e);
return StatsManager.PULL_SKIP;
} finally {
Binder.restoreCallingIdentity(token);
}
return StatsManager.PULL_SUCCESS;
}
private void registerMobileBytesTransferBackground() {
// No op.
int tagId = StatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG;
PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
.setAdditiveFields(new int[] {3, 4, 5, 6})
.build();
mStatsManager.registerPullAtomCallback(
tagId,
metadata,
(atomTag, data) -> pullMobileBytesTransferBackground(atomTag, data),
Executors.newSingleThreadExecutor()
);
}
private void pullMobileBytesTransferBackground() {
// No op.
private int pullMobileBytesTransferBackground(int atomTag, List<StatsEvent> pulledData) {
INetworkStatsService networkStatsService = getINetworkStatsService();
if (networkStatsService == null) {
Slog.e(TAG, "NetworkStats Service is not available!");
return StatsManager.PULL_SKIP;
}
long token = Binder.clearCallingIdentity();
try {
BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class);
String[] ifaces = bs.getMobileIfaces();
if (ifaces.length == 0) {
return StatsManager.PULL_SKIP;
}
NetworkStats stats = rollupNetworkStatsByFGBG(
networkStatsService.getDetailedUidStats(ifaces));
addNetworkStats(atomTag, pulledData, stats, true);
} catch (RemoteException e) {
Slog.e(TAG, "Pulling netstats for mobile bytes w/ fg/bg has error", e);
return StatsManager.PULL_SKIP;
} finally {
Binder.restoreCallingIdentity(token);
}
return StatsManager.PULL_SUCCESS;
}
private void registerBluetoothBytesTransfer() {
// No op.
int tagId = StatsLog.BLUETOOTH_BYTES_TRANSFER;
PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
.setAdditiveFields(new int[] {2, 3})
.build();
mStatsManager.registerPullAtomCallback(
tagId,
metadata,
(atomTag, data) -> pullBluetoothBytesTransfer(atomTag, data),
Executors.newSingleThreadExecutor()
);
}
private void pullBluetoothBytesTransfer() {
// No op.
/**
* Helper method to extract the Parcelable controller info from a
* SynchronousResultReceiver.
*/
private static <T extends Parcelable> T awaitControllerInfo(
@Nullable SynchronousResultReceiver receiver) {
if (receiver == null) {
return null;
}
try {
final SynchronousResultReceiver.Result result =
receiver.awaitResult(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS);
if (result.bundle != null) {
// This is the final destination for the Bundle.
result.bundle.setDefusable(true);
final T data = result.bundle.getParcelable(RESULT_RECEIVER_CONTROLLER_KEY);
if (data != null) {
return data;
}
}
Slog.e(TAG, "no controller energy info supplied for " + receiver.getName());
} catch (TimeoutException e) {
Slog.w(TAG, "timeout reading " + receiver.getName() + " stats");
}
return null;
}
private synchronized BluetoothActivityEnergyInfo fetchBluetoothData() {
// TODO: Investigate whether the synchronized keyword is needed.
final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) {
SynchronousResultReceiver bluetoothReceiver = new SynchronousResultReceiver(
"bluetooth");
adapter.requestControllerActivityEnergyInfo(bluetoothReceiver);
return awaitControllerInfo(bluetoothReceiver);
} else {
Slog.e(TAG, "Failed to get bluetooth adapter!");
return null;
}
}
private int pullBluetoothBytesTransfer(int atomTag, List<StatsEvent> pulledData) {
BluetoothActivityEnergyInfo info = fetchBluetoothData();
if (info == null || info.getUidTraffic() == null) {
return StatsManager.PULL_SKIP;
}
for (UidTraffic traffic : info.getUidTraffic()) {
StatsEvent e = StatsEvent.newBuilder()
.setAtomId(atomTag)
.writeInt(traffic.getUid())
.writeLong(traffic.getRxBytes())
.writeLong(traffic.getTxBytes())
.build();
pulledData.add(e);
}
return StatsManager.PULL_SUCCESS;
}
private void registerKernelWakelock() {
@@ -479,11 +675,31 @@ public class StatsPullAtomService extends SystemService {
}
private void registerBluetoothActivityInfo() {
// No op.
int tagId = StatsLog.BLUETOOTH_ACTIVITY_INFO;
mStatsManager.registerPullAtomCallback(
tagId,
/* metadata */ null,
(atomTag, data) -> pullBluetoothActivityInfo(atomTag, data),
Executors.newSingleThreadExecutor()
);
}
private void pullBluetoothActivityInfo() {
// No op.
private int pullBluetoothActivityInfo(int atomTag, List<StatsEvent> pulledData) {
BluetoothActivityEnergyInfo info = fetchBluetoothData();
if (info == null) {
return StatsManager.PULL_SKIP;
}
StatsEvent e = StatsEvent.newBuilder()
.setAtomId(atomTag)
.writeLong(info.getTimeStamp())
.writeInt(info.getBluetoothStackState())
.writeLong(info.getControllerTxTimeMillis())
.writeLong(info.getControllerRxTimeMillis())
.writeLong(info.getControllerIdleTimeMillis())
.writeLong(info.getControllerEnergyUsed())
.build();
pulledData.add(e);
return StatsManager.PULL_SUCCESS;
}
private void registerSystemElapsedRealtime() {