Merge changes Ib321743b,I9d58a4b8,I6501109a,I0ce870a3,I5107aa47
* changes: Migrate pullBinderStats Migrate pullTemperature and pullCooldownDevice Migrate ionHeapSize Migrate ProcessMemory pullers Fix crash when pulling certain atoms
This commit is contained in:
committed by
Android (Google) Code Review
commit
1507e3b1bf
@@ -24,11 +24,11 @@ import static android.os.storage.VolumeInfo.TYPE_PRIVATE;
|
||||
import static android.os.storage.VolumeInfo.TYPE_PUBLIC;
|
||||
|
||||
import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
|
||||
import static com.android.server.stats.IonMemoryUtil.readProcessSystemIonHeapSizesFromDebugfs;
|
||||
import static com.android.server.stats.IonMemoryUtil.readSystemIonHeapSizeFromDebugfs;
|
||||
import static com.android.server.stats.ProcfsMemoryUtil.forEachPid;
|
||||
import static com.android.server.stats.ProcfsMemoryUtil.readCmdlineFromProcfs;
|
||||
import static com.android.server.stats.ProcfsMemoryUtil.readMemorySnapshotFromProcfs;
|
||||
import static com.android.server.stats.pull.IonMemoryUtil.readProcessSystemIonHeapSizesFromDebugfs;
|
||||
import static com.android.server.stats.pull.IonMemoryUtil.readSystemIonHeapSizeFromDebugfs;
|
||||
import static com.android.server.stats.pull.ProcfsMemoryUtil.forEachPid;
|
||||
import static com.android.server.stats.pull.ProcfsMemoryUtil.readCmdlineFromProcfs;
|
||||
import static com.android.server.stats.pull.ProcfsMemoryUtil.readMemorySnapshotFromProcfs;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
@@ -135,8 +135,8 @@ import com.android.server.SystemServiceManager;
|
||||
import com.android.server.am.MemoryStatUtil.MemoryStat;
|
||||
import com.android.server.notification.NotificationManagerService;
|
||||
import com.android.server.role.RoleManagerInternal;
|
||||
import com.android.server.stats.IonMemoryUtil.IonAllocations;
|
||||
import com.android.server.stats.ProcfsMemoryUtil.MemorySnapshot;
|
||||
import com.android.server.stats.pull.IonMemoryUtil.IonAllocations;
|
||||
import com.android.server.stats.pull.ProcfsMemoryUtil.MemorySnapshot;
|
||||
import com.android.server.storage.DiskStatsFileLogger;
|
||||
import com.android.server.storage.DiskStatsLoggingService;
|
||||
|
||||
@@ -722,207 +722,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
|
||||
pulledData.add(e);
|
||||
}
|
||||
|
||||
private void pullProcessMemoryState(
|
||||
int tagId, long elapsedNanos, long wallClockNanos,
|
||||
List<StatsLogEventWrapper> pulledData) {
|
||||
List<ProcessMemoryState> processMemoryStates =
|
||||
LocalServices.getService(
|
||||
ActivityManagerInternal.class).getMemoryStateForProcesses();
|
||||
for (ProcessMemoryState processMemoryState : processMemoryStates) {
|
||||
final MemoryStat memoryStat = readMemoryStatFromFilesystem(processMemoryState.uid,
|
||||
processMemoryState.pid);
|
||||
if (memoryStat == null) {
|
||||
continue;
|
||||
}
|
||||
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
|
||||
e.writeInt(processMemoryState.uid);
|
||||
e.writeString(processMemoryState.processName);
|
||||
e.writeInt(processMemoryState.oomScore);
|
||||
e.writeLong(memoryStat.pgfault);
|
||||
e.writeLong(memoryStat.pgmajfault);
|
||||
e.writeLong(memoryStat.rssInBytes);
|
||||
e.writeLong(memoryStat.cacheInBytes);
|
||||
e.writeLong(memoryStat.swapInBytes);
|
||||
e.writeLong(-1); // unused
|
||||
e.writeLong(-1); // unused
|
||||
e.writeInt(-1); // unsed
|
||||
pulledData.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void pullProcessMemoryHighWaterMark(
|
||||
int tagId, long elapsedNanos, long wallClockNanos,
|
||||
List<StatsLogEventWrapper> pulledData) {
|
||||
List<ProcessMemoryState> managedProcessList =
|
||||
LocalServices.getService(
|
||||
ActivityManagerInternal.class).getMemoryStateForProcesses();
|
||||
for (ProcessMemoryState managedProcess : managedProcessList) {
|
||||
final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(managedProcess.pid);
|
||||
if (snapshot == null) {
|
||||
continue;
|
||||
}
|
||||
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
|
||||
e.writeInt(managedProcess.uid);
|
||||
e.writeString(managedProcess.processName);
|
||||
// RSS high-water mark in bytes.
|
||||
e.writeLong((long) snapshot.rssHighWaterMarkInKilobytes * 1024L);
|
||||
e.writeInt(snapshot.rssHighWaterMarkInKilobytes);
|
||||
pulledData.add(e);
|
||||
}
|
||||
forEachPid((pid, cmdLine) -> {
|
||||
if (!MEMORY_INTERESTING_NATIVE_PROCESSES.contains(cmdLine)) {
|
||||
return;
|
||||
}
|
||||
final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(pid);
|
||||
if (snapshot == null) {
|
||||
return;
|
||||
}
|
||||
// Sometimes we get here a process that is not included in the whitelist. It comes
|
||||
// from forking the zygote for an app. We can ignore that sample because this process
|
||||
// is collected by ProcessMemoryState.
|
||||
if (isAppUid(snapshot.uid)) {
|
||||
return;
|
||||
}
|
||||
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
|
||||
e.writeInt(snapshot.uid);
|
||||
e.writeString(cmdLine);
|
||||
// RSS high-water mark in bytes.
|
||||
e.writeLong((long) snapshot.rssHighWaterMarkInKilobytes * 1024L);
|
||||
e.writeInt(snapshot.rssHighWaterMarkInKilobytes);
|
||||
pulledData.add(e);
|
||||
});
|
||||
// Invoke rss_hwm_reset binary to reset RSS HWM counters for all processes.
|
||||
SystemProperties.set("sys.rss_hwm_reset.on", "1");
|
||||
}
|
||||
|
||||
private void pullProcessMemorySnapshot(
|
||||
int tagId, long elapsedNanos, long wallClockNanos,
|
||||
List<StatsLogEventWrapper> pulledData) {
|
||||
List<ProcessMemoryState> managedProcessList =
|
||||
LocalServices.getService(
|
||||
ActivityManagerInternal.class).getMemoryStateForProcesses();
|
||||
for (ProcessMemoryState managedProcess : managedProcessList) {
|
||||
final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(managedProcess.pid);
|
||||
if (snapshot == null) {
|
||||
continue;
|
||||
}
|
||||
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
|
||||
e.writeInt(managedProcess.uid);
|
||||
e.writeString(managedProcess.processName);
|
||||
e.writeInt(managedProcess.pid);
|
||||
e.writeInt(managedProcess.oomScore);
|
||||
e.writeInt(snapshot.rssInKilobytes);
|
||||
e.writeInt(snapshot.anonRssInKilobytes);
|
||||
e.writeInt(snapshot.swapInKilobytes);
|
||||
e.writeInt(snapshot.anonRssInKilobytes + snapshot.swapInKilobytes);
|
||||
pulledData.add(e);
|
||||
}
|
||||
forEachPid((pid, cmdLine) -> {
|
||||
if (!MEMORY_INTERESTING_NATIVE_PROCESSES.contains(cmdLine)) {
|
||||
return;
|
||||
}
|
||||
final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(pid);
|
||||
if (snapshot == null) {
|
||||
return;
|
||||
}
|
||||
// Sometimes we get here a process that is not included in the whitelist. It comes
|
||||
// from forking the zygote for an app. We can ignore that sample because this process
|
||||
// is collected by ProcessMemoryState.
|
||||
if (isAppUid(snapshot.uid)) {
|
||||
return;
|
||||
}
|
||||
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
|
||||
e.writeInt(snapshot.uid);
|
||||
e.writeString(cmdLine);
|
||||
e.writeInt(pid);
|
||||
e.writeInt(-1001); // Placeholder for native processes, OOM_SCORE_ADJ_MIN - 1.
|
||||
e.writeInt(snapshot.rssInKilobytes);
|
||||
e.writeInt(snapshot.anonRssInKilobytes);
|
||||
e.writeInt(snapshot.swapInKilobytes);
|
||||
e.writeInt(snapshot.anonRssInKilobytes + snapshot.swapInKilobytes);
|
||||
pulledData.add(e);
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean isAppUid(int uid) {
|
||||
return uid >= MIN_APP_UID;
|
||||
}
|
||||
|
||||
private void pullSystemIonHeapSize(
|
||||
int tagId, long elapsedNanos, long wallClockNanos,
|
||||
List<StatsLogEventWrapper> pulledData) {
|
||||
final long systemIonHeapSizeInBytes = readSystemIonHeapSizeFromDebugfs();
|
||||
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
|
||||
e.writeLong(systemIonHeapSizeInBytes);
|
||||
pulledData.add(e);
|
||||
}
|
||||
|
||||
private void pullProcessSystemIonHeapSize(
|
||||
int tagId, long elapsedNanos, long wallClockNanos,
|
||||
List<StatsLogEventWrapper> pulledData) {
|
||||
List<IonAllocations> result = readProcessSystemIonHeapSizesFromDebugfs();
|
||||
for (IonAllocations allocations : result) {
|
||||
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
|
||||
e.writeInt(getUidForPid(allocations.pid));
|
||||
e.writeString(readCmdlineFromProcfs(allocations.pid));
|
||||
e.writeInt((int) (allocations.totalSizeInBytes / 1024));
|
||||
e.writeInt(allocations.count);
|
||||
e.writeInt((int) (allocations.maxSizeInBytes / 1024));
|
||||
pulledData.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void pullBinderCallsStats(
|
||||
int tagId, long elapsedNanos, long wallClockNanos,
|
||||
List<StatsLogEventWrapper> pulledData) {
|
||||
BinderCallsStatsService.Internal binderStats =
|
||||
LocalServices.getService(BinderCallsStatsService.Internal.class);
|
||||
if (binderStats == null) {
|
||||
throw new IllegalStateException("binderStats is null");
|
||||
}
|
||||
|
||||
List<ExportedCallStat> callStats = binderStats.getExportedCallStats();
|
||||
binderStats.reset();
|
||||
for (ExportedCallStat callStat : callStats) {
|
||||
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
|
||||
e.writeInt(callStat.workSourceUid);
|
||||
e.writeString(callStat.className);
|
||||
e.writeString(callStat.methodName);
|
||||
e.writeLong(callStat.callCount);
|
||||
e.writeLong(callStat.exceptionCount);
|
||||
e.writeLong(callStat.latencyMicros);
|
||||
e.writeLong(callStat.maxLatencyMicros);
|
||||
e.writeLong(callStat.cpuTimeMicros);
|
||||
e.writeLong(callStat.maxCpuTimeMicros);
|
||||
e.writeLong(callStat.maxReplySizeBytes);
|
||||
e.writeLong(callStat.maxRequestSizeBytes);
|
||||
e.writeLong(callStat.recordedCallCount);
|
||||
e.writeInt(callStat.screenInteractive ? 1 : 0);
|
||||
e.writeInt(callStat.callingUid);
|
||||
pulledData.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void pullBinderCallsStatsExceptions(
|
||||
int tagId, long elapsedNanos, long wallClockNanos,
|
||||
List<StatsLogEventWrapper> pulledData) {
|
||||
BinderCallsStatsService.Internal binderStats =
|
||||
LocalServices.getService(BinderCallsStatsService.Internal.class);
|
||||
if (binderStats == null) {
|
||||
throw new IllegalStateException("binderStats is null");
|
||||
}
|
||||
|
||||
ArrayMap<String, Integer> exceptionStats = binderStats.getExportedExceptionStats();
|
||||
// TODO: decouple binder calls exceptions with the rest of the binder calls data so that we
|
||||
// can reset the exception stats.
|
||||
for (Entry<String, Integer> entry : exceptionStats.entrySet()) {
|
||||
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
|
||||
e.writeString(entry.getKey());
|
||||
e.writeInt(entry.getValue());
|
||||
pulledData.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void pullLooperStats(int tagId, long elapsedNanos, long wallClockNanos,
|
||||
List<StatsLogEventWrapper> pulledData) {
|
||||
LooperStats looperStats = LocalServices.getService(LooperStats.class);
|
||||
@@ -1397,49 +1196,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private void pullTemperature(int tagId, long elapsedNanos, long wallClockNanos,
|
||||
List<StatsLogEventWrapper> pulledData) {
|
||||
long callingToken = Binder.clearCallingIdentity();
|
||||
try {
|
||||
List<Temperature> temperatures = sThermalService.getCurrentTemperatures();
|
||||
for (Temperature temp : temperatures) {
|
||||
StatsLogEventWrapper e =
|
||||
new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
|
||||
e.writeInt(temp.getType());
|
||||
e.writeString(temp.getName());
|
||||
e.writeInt((int) (temp.getValue() * 10));
|
||||
e.writeInt(temp.getStatus());
|
||||
pulledData.add(e);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
// Should not happen.
|
||||
Slog.e(TAG, "Disconnected from thermal service. Cannot pull temperatures.");
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(callingToken);
|
||||
}
|
||||
}
|
||||
|
||||
private void pullCoolingDevices(int tagId, long elapsedNanos, long wallClockNanos,
|
||||
List<StatsLogEventWrapper> pulledData) {
|
||||
long callingToken = Binder.clearCallingIdentity();
|
||||
try {
|
||||
List<CoolingDevice> devices = sThermalService.getCurrentCoolingDevices();
|
||||
for (CoolingDevice device : devices) {
|
||||
StatsLogEventWrapper e =
|
||||
new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
|
||||
e.writeInt(device.getType());
|
||||
e.writeString(device.getName());
|
||||
e.writeInt((int) (device.getValue()));
|
||||
pulledData.add(e);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
// Should not happen.
|
||||
Slog.e(TAG, "Disconnected from thermal service. Cannot pull temperatures.");
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(callingToken);
|
||||
}
|
||||
}
|
||||
|
||||
private void pullDebugElapsedClock(int tagId,
|
||||
long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData) {
|
||||
final long elapsedMillis = SystemClock.elapsedRealtime();
|
||||
@@ -1823,41 +1579,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
|
||||
break;
|
||||
}
|
||||
|
||||
case StatsLog.PROCESS_MEMORY_STATE: {
|
||||
pullProcessMemoryState(tagId, elapsedNanos, wallClockNanos, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
case StatsLog.PROCESS_MEMORY_HIGH_WATER_MARK: {
|
||||
pullProcessMemoryHighWaterMark(tagId, elapsedNanos, wallClockNanos, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
case StatsLog.PROCESS_MEMORY_SNAPSHOT: {
|
||||
pullProcessMemorySnapshot(tagId, elapsedNanos, wallClockNanos, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
case StatsLog.SYSTEM_ION_HEAP_SIZE: {
|
||||
pullSystemIonHeapSize(tagId, elapsedNanos, wallClockNanos, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
case StatsLog.PROCESS_SYSTEM_ION_HEAP_SIZE: {
|
||||
pullProcessSystemIonHeapSize(tagId, elapsedNanos, wallClockNanos, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
case StatsLog.BINDER_CALLS: {
|
||||
pullBinderCallsStats(tagId, elapsedNanos, wallClockNanos, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
case StatsLog.BINDER_CALLS_EXCEPTIONS: {
|
||||
pullBinderCallsStatsExceptions(tagId, elapsedNanos, wallClockNanos, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
case StatsLog.LOOPER_STATS: {
|
||||
pullLooperStats(tagId, elapsedNanos, wallClockNanos, ret);
|
||||
break;
|
||||
@@ -1920,16 +1641,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
|
||||
break;
|
||||
}
|
||||
|
||||
case StatsLog.TEMPERATURE: {
|
||||
pullTemperature(tagId, elapsedNanos, wallClockNanos, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
case StatsLog.COOLING_DEVICE: {
|
||||
pullCoolingDevices(tagId, elapsedNanos, wallClockNanos, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
case StatsLog.DEBUG_ELAPSED_CLOCK: {
|
||||
pullDebugElapsedClock(tagId, elapsedNanos, wallClockNanos, ret);
|
||||
break;
|
||||
|
||||
39
cmds/statsd/src/external/StatsPullerManager.cpp
vendored
39
cmds/statsd/src/external/StatsPullerManager.cpp
vendored
@@ -95,45 +95,6 @@ std::map<PullerKey, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
|
||||
{{.atomTag = android::util::BATTERY_CYCLE_COUNT},
|
||||
{.puller = new ResourceHealthManagerPuller(android::util::BATTERY_CYCLE_COUNT)}},
|
||||
|
||||
// process_memory_state
|
||||
{{.atomTag = android::util::PROCESS_MEMORY_STATE},
|
||||
{.additiveFields = {4, 5, 6, 7, 8},
|
||||
.puller = new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}},
|
||||
|
||||
// process_memory_high_water_mark
|
||||
{{.atomTag = android::util::PROCESS_MEMORY_HIGH_WATER_MARK},
|
||||
{.puller =
|
||||
new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_HIGH_WATER_MARK)}},
|
||||
|
||||
// process_memory_snapshot
|
||||
{{.atomTag = android::util::PROCESS_MEMORY_SNAPSHOT},
|
||||
{.puller = new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_SNAPSHOT)}},
|
||||
|
||||
// system_ion_heap_size
|
||||
{{.atomTag = android::util::SYSTEM_ION_HEAP_SIZE},
|
||||
{.puller = new StatsCompanionServicePuller(android::util::SYSTEM_ION_HEAP_SIZE)}},
|
||||
|
||||
// process_system_ion_heap_size
|
||||
{{.atomTag = android::util::PROCESS_SYSTEM_ION_HEAP_SIZE},
|
||||
{.puller = new StatsCompanionServicePuller(android::util::PROCESS_SYSTEM_ION_HEAP_SIZE)}},
|
||||
|
||||
// temperature
|
||||
{{.atomTag = android::util::TEMPERATURE},
|
||||
{.puller = new StatsCompanionServicePuller(android::util::TEMPERATURE)}},
|
||||
|
||||
// cooling_device
|
||||
{{.atomTag = android::util::COOLING_DEVICE},
|
||||
{.puller = new StatsCompanionServicePuller(android::util::COOLING_DEVICE)}},
|
||||
|
||||
// binder_calls
|
||||
{{.atomTag = android::util::BINDER_CALLS},
|
||||
{.additiveFields = {4, 5, 6, 8, 12},
|
||||
.puller = new StatsCompanionServicePuller(android::util::BINDER_CALLS)}},
|
||||
|
||||
// binder_calls_exceptions
|
||||
{{.atomTag = android::util::BINDER_CALLS_EXCEPTIONS},
|
||||
{.puller = new StatsCompanionServicePuller(android::util::BINDER_CALLS_EXCEPTIONS)}},
|
||||
|
||||
// looper_stats
|
||||
{{.atomTag = android::util::LOOPER_STATS},
|
||||
{.additiveFields = {5, 6, 7, 8, 9},
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.server.stats;
|
||||
package com.android.server.stats.pull;
|
||||
|
||||
import android.os.FileUtils;
|
||||
import android.util.Slog;
|
||||
@@ -30,8 +30,11 @@ import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** Utility methods for reading ion memory stats. */
|
||||
final class IonMemoryUtil {
|
||||
/**
|
||||
* Utility methods for reading ion memory stats.
|
||||
* TODO: Consider making package private after puller migration
|
||||
*/
|
||||
public final class IonMemoryUtil {
|
||||
private static final String TAG = "IonMemoryUtil";
|
||||
|
||||
/** Path to debugfs file for the system ion heap. */
|
||||
@@ -50,7 +53,7 @@ final class IonMemoryUtil {
|
||||
* Returns value of the total size in bytes of the system ion heap from
|
||||
* /sys/kernel/debug/ion/heaps/system.
|
||||
*/
|
||||
static long readSystemIonHeapSizeFromDebugfs() {
|
||||
public static long readSystemIonHeapSizeFromDebugfs() {
|
||||
return parseIonHeapSizeFromDebugfs(readFile(DEBUG_SYSTEM_ION_HEAP_FILE));
|
||||
}
|
||||
|
||||
@@ -78,7 +81,7 @@ final class IonMemoryUtil {
|
||||
* Returns values of allocation sizes in bytes on the system ion heap from
|
||||
* /sys/kernel/debug/ion/heaps/system.
|
||||
*/
|
||||
static List<IonAllocations> readProcessSystemIonHeapSizesFromDebugfs() {
|
||||
public static List<IonAllocations> readProcessSystemIonHeapSizesFromDebugfs() {
|
||||
return parseProcessIonHeapSizesFromDebugfs(readFile(DEBUG_SYSTEM_ION_HEAP_FILE));
|
||||
}
|
||||
|
||||
@@ -130,7 +133,7 @@ final class IonMemoryUtil {
|
||||
}
|
||||
|
||||
/** Summary information about process ion allocations. */
|
||||
static final class IonAllocations {
|
||||
public static final class IonAllocations {
|
||||
/** PID these allocations belong to. */
|
||||
public int pid;
|
||||
/** Size of all individual allocations added together. */
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.server.stats;
|
||||
package com.android.server.stats.pull;
|
||||
|
||||
import static android.os.Process.PROC_OUT_STRING;
|
||||
|
||||
@@ -22,7 +22,7 @@ import android.os.Process;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
final class ProcfsMemoryUtil {
|
||||
public final class ProcfsMemoryUtil {
|
||||
private static final int[] CMDLINE_OUT = new int[] { PROC_OUT_STRING };
|
||||
private static final String[] STATUS_KEYS = new String[] {
|
||||
"Uid:",
|
||||
@@ -39,7 +39,7 @@ final class ProcfsMemoryUtil {
|
||||
* VmSwap fields in /proc/pid/status in kilobytes or null if not available.
|
||||
*/
|
||||
@Nullable
|
||||
static MemorySnapshot readMemorySnapshotFromProcfs(int pid) {
|
||||
public static MemorySnapshot readMemorySnapshotFromProcfs(int pid) {
|
||||
long[] output = new long[STATUS_KEYS.length];
|
||||
output[0] = -1;
|
||||
Process.readProcLines("/proc/" + pid + "/status", STATUS_KEYS, output);
|
||||
@@ -63,7 +63,7 @@ final class ProcfsMemoryUtil {
|
||||
* Returns content of /proc/pid/cmdline (e.g. /system/bin/statsd) or an empty string
|
||||
* if the file is not available.
|
||||
*/
|
||||
static String readCmdlineFromProcfs(int pid) {
|
||||
public static String readCmdlineFromProcfs(int pid) {
|
||||
String[] cmdline = new String[1];
|
||||
if (!Process.readProcFile("/proc/" + pid + "/cmdline", CMDLINE_OUT, cmdline, null, null)) {
|
||||
return "";
|
||||
@@ -71,7 +71,7 @@ final class ProcfsMemoryUtil {
|
||||
return cmdline[0];
|
||||
}
|
||||
|
||||
static void forEachPid(BiConsumer<Integer, String> func) {
|
||||
public static void forEachPid(BiConsumer<Integer, String> func) {
|
||||
int[] pids = new int[1024];
|
||||
pids = Process.getPids("/proc", pids);
|
||||
for (int pid : pids) {
|
||||
@@ -86,7 +86,7 @@ final class ProcfsMemoryUtil {
|
||||
}
|
||||
}
|
||||
|
||||
static final class MemorySnapshot {
|
||||
public static final class MemorySnapshot {
|
||||
public int uid;
|
||||
public int rssHighWaterMarkInKilobytes;
|
||||
public int rssInKilobytes;
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.stats;
|
||||
package com.android.server.stats.pull;
|
||||
|
||||
import static android.app.AppOpsManager.OP_FLAGS_ALL_TRUSTED;
|
||||
import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
|
||||
@@ -26,11 +26,11 @@ import static android.os.storage.VolumeInfo.TYPE_PRIVATE;
|
||||
import static android.os.storage.VolumeInfo.TYPE_PUBLIC;
|
||||
|
||||
import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
|
||||
import static com.android.server.stats.IonMemoryUtil.readProcessSystemIonHeapSizesFromDebugfs;
|
||||
import static com.android.server.stats.IonMemoryUtil.readSystemIonHeapSizeFromDebugfs;
|
||||
import static com.android.server.stats.ProcfsMemoryUtil.forEachPid;
|
||||
import static com.android.server.stats.ProcfsMemoryUtil.readCmdlineFromProcfs;
|
||||
import static com.android.server.stats.ProcfsMemoryUtil.readMemorySnapshotFromProcfs;
|
||||
import static com.android.server.stats.pull.IonMemoryUtil.readProcessSystemIonHeapSizesFromDebugfs;
|
||||
import static com.android.server.stats.pull.IonMemoryUtil.readSystemIonHeapSizeFromDebugfs;
|
||||
import static com.android.server.stats.pull.ProcfsMemoryUtil.forEachPid;
|
||||
import static com.android.server.stats.pull.ProcfsMemoryUtil.readCmdlineFromProcfs;
|
||||
import static com.android.server.stats.pull.ProcfsMemoryUtil.readMemorySnapshotFromProcfs;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
@@ -142,8 +142,8 @@ import com.android.server.SystemServiceManager;
|
||||
import com.android.server.am.MemoryStatUtil.MemoryStat;
|
||||
import com.android.server.notification.NotificationManagerService;
|
||||
import com.android.server.role.RoleManagerInternal;
|
||||
import com.android.server.stats.IonMemoryUtil.IonAllocations;
|
||||
import com.android.server.stats.ProcfsMemoryUtil.MemorySnapshot;
|
||||
import com.android.server.stats.pull.IonMemoryUtil.IonAllocations;
|
||||
import com.android.server.stats.pull.ProcfsMemoryUtil.MemorySnapshot;
|
||||
import com.android.server.storage.DiskStatsFileLogger;
|
||||
import com.android.server.storage.DiskStatsLoggingService;
|
||||
|
||||
@@ -270,8 +270,8 @@ public class StatsPullAtomService extends SystemService {
|
||||
registerProcessSystemIonHeapSize();
|
||||
registerTemperature();
|
||||
registerCoolingDevice();
|
||||
registerBinderCalls();
|
||||
registerBinderCallsExceptions();
|
||||
registerBinderCallsStats();
|
||||
registerBinderCallsStatsExceptions();
|
||||
registerLooperStats();
|
||||
registerDiskStats();
|
||||
registerDirectoryUsage();
|
||||
@@ -1004,35 +1004,227 @@ public class StatsPullAtomService extends SystemService {
|
||||
}
|
||||
|
||||
private void registerProcessMemoryState() {
|
||||
// No op.
|
||||
int tagId = StatsLog.PROCESS_MEMORY_STATE;
|
||||
PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
|
||||
.setAdditiveFields(new int[] {4, 5, 6, 7, 8})
|
||||
.build();
|
||||
mStatsManager.registerPullAtomCallback(
|
||||
tagId,
|
||||
metadata,
|
||||
(atomTag, data) -> pullProcessMemoryState(atomTag, data),
|
||||
BackgroundThread.getExecutor()
|
||||
);
|
||||
}
|
||||
|
||||
private void pullProcessMemoryState() {
|
||||
// No op.
|
||||
private int pullProcessMemoryState(int atomTag, List<StatsEvent> pulledData) {
|
||||
List<ProcessMemoryState> processMemoryStates =
|
||||
LocalServices.getService(ActivityManagerInternal.class)
|
||||
.getMemoryStateForProcesses();
|
||||
for (ProcessMemoryState processMemoryState : processMemoryStates) {
|
||||
final MemoryStat memoryStat = readMemoryStatFromFilesystem(processMemoryState.uid,
|
||||
processMemoryState.pid);
|
||||
if (memoryStat == null) {
|
||||
continue;
|
||||
}
|
||||
StatsEvent e = StatsEvent.newBuilder()
|
||||
.setAtomId(atomTag)
|
||||
.writeInt(processMemoryState.uid)
|
||||
.writeString(processMemoryState.processName)
|
||||
.writeInt(processMemoryState.oomScore)
|
||||
.writeLong(memoryStat.pgfault)
|
||||
.writeLong(memoryStat.pgmajfault)
|
||||
.writeLong(memoryStat.rssInBytes)
|
||||
.writeLong(memoryStat.cacheInBytes)
|
||||
.writeLong(memoryStat.swapInBytes)
|
||||
.writeLong(-1) // unused
|
||||
.writeLong(-1) // unused
|
||||
.writeInt(-1) // unused
|
||||
.build();
|
||||
pulledData.add(e);
|
||||
}
|
||||
return StatsManager.PULL_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Which native processes to snapshot memory for.
|
||||
*
|
||||
* <p>Processes are matched by their cmdline in procfs. Example: cat /proc/pid/cmdline returns
|
||||
* /system/bin/statsd for the stats daemon.
|
||||
*/
|
||||
private static final Set<String> MEMORY_INTERESTING_NATIVE_PROCESSES = Sets.newHashSet(
|
||||
"/system/bin/statsd", // Stats daemon.
|
||||
"/system/bin/surfaceflinger",
|
||||
"/system/bin/apexd", // APEX daemon.
|
||||
"/system/bin/audioserver",
|
||||
"/system/bin/cameraserver",
|
||||
"/system/bin/drmserver",
|
||||
"/system/bin/healthd",
|
||||
"/system/bin/incidentd",
|
||||
"/system/bin/installd",
|
||||
"/system/bin/lmkd", // Low memory killer daemon.
|
||||
"/system/bin/logd",
|
||||
"media.codec",
|
||||
"media.extractor",
|
||||
"media.metrics",
|
||||
"/system/bin/mediadrmserver",
|
||||
"/system/bin/mediaserver",
|
||||
"/system/bin/performanced",
|
||||
"/system/bin/tombstoned",
|
||||
"/system/bin/traced", // Perfetto.
|
||||
"/system/bin/traced_probes", // Perfetto.
|
||||
"webview_zygote",
|
||||
"zygote",
|
||||
"zygote64");
|
||||
|
||||
/**
|
||||
* Lowest available uid for apps.
|
||||
*
|
||||
* <p>Used to quickly discard memory snapshots of the zygote forks from native process
|
||||
* measurements.
|
||||
*/
|
||||
private static final int MIN_APP_UID = 10_000;
|
||||
|
||||
private static boolean isAppUid(int uid) {
|
||||
return uid >= MIN_APP_UID;
|
||||
}
|
||||
|
||||
private void registerProcessMemoryHighWaterMark() {
|
||||
// No op.
|
||||
int tagId = StatsLog.PROCESS_MEMORY_HIGH_WATER_MARK;
|
||||
mStatsManager.registerPullAtomCallback(
|
||||
tagId,
|
||||
null, // use default PullAtomMetadata values
|
||||
(atomTag, data) -> pullProcessMemoryHighWaterMark(atomTag, data),
|
||||
BackgroundThread.getExecutor()
|
||||
);
|
||||
}
|
||||
|
||||
private void pullProcessMemoryHighWaterMark() {
|
||||
// No op.
|
||||
private int pullProcessMemoryHighWaterMark(int atomTag, List<StatsEvent> pulledData) {
|
||||
List<ProcessMemoryState> managedProcessList =
|
||||
LocalServices.getService(ActivityManagerInternal.class)
|
||||
.getMemoryStateForProcesses();
|
||||
for (ProcessMemoryState managedProcess : managedProcessList) {
|
||||
final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(managedProcess.pid);
|
||||
if (snapshot == null) {
|
||||
continue;
|
||||
}
|
||||
StatsEvent e = StatsEvent.newBuilder()
|
||||
.setAtomId(atomTag)
|
||||
.writeInt(managedProcess.uid)
|
||||
.writeString(managedProcess.processName)
|
||||
// RSS high-water mark in bytes.
|
||||
.writeLong(snapshot.rssHighWaterMarkInKilobytes * 1024L)
|
||||
.writeInt(snapshot.rssHighWaterMarkInKilobytes)
|
||||
.build();
|
||||
pulledData.add(e);
|
||||
}
|
||||
forEachPid((pid, cmdLine) -> {
|
||||
if (!MEMORY_INTERESTING_NATIVE_PROCESSES.contains(cmdLine)) {
|
||||
return;
|
||||
}
|
||||
final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(pid);
|
||||
if (snapshot == null) {
|
||||
return;
|
||||
}
|
||||
// Sometimes we get here a process that is not included in the whitelist. It comes
|
||||
// from forking the zygote for an app. We can ignore that sample because this process
|
||||
// is collected by ProcessMemoryState.
|
||||
if (isAppUid(snapshot.uid)) {
|
||||
return;
|
||||
}
|
||||
StatsEvent e = StatsEvent.newBuilder()
|
||||
.setAtomId(atomTag)
|
||||
.writeInt(snapshot.uid)
|
||||
.writeString(cmdLine)
|
||||
// RSS high-water mark in bytes.
|
||||
.writeLong(snapshot.rssHighWaterMarkInKilobytes * 1024L)
|
||||
.writeInt(snapshot.rssHighWaterMarkInKilobytes)
|
||||
.build();
|
||||
pulledData.add(e);
|
||||
});
|
||||
// Invoke rss_hwm_reset binary to reset RSS HWM counters for all processes.
|
||||
SystemProperties.set("sys.rss_hwm_reset.on", "1");
|
||||
return StatsManager.PULL_SUCCESS;
|
||||
}
|
||||
|
||||
private void registerProcessMemorySnapshot() {
|
||||
// No op.
|
||||
int tagId = StatsLog.PROCESS_MEMORY_SNAPSHOT;
|
||||
mStatsManager.registerPullAtomCallback(
|
||||
tagId,
|
||||
null, // use default PullAtomMetadata values
|
||||
(atomTag, data) -> pullProcessMemorySnapshot(atomTag, data),
|
||||
BackgroundThread.getExecutor()
|
||||
);
|
||||
}
|
||||
|
||||
private void pullProcessMemorySnapshot() {
|
||||
// No op.
|
||||
private int pullProcessMemorySnapshot(int atomTag, List<StatsEvent> pulledData) {
|
||||
List<ProcessMemoryState> managedProcessList =
|
||||
LocalServices.getService(ActivityManagerInternal.class)
|
||||
.getMemoryStateForProcesses();
|
||||
for (ProcessMemoryState managedProcess : managedProcessList) {
|
||||
final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(managedProcess.pid);
|
||||
if (snapshot == null) {
|
||||
continue;
|
||||
}
|
||||
StatsEvent e = StatsEvent.newBuilder()
|
||||
.writeInt(managedProcess.uid)
|
||||
.writeString(managedProcess.processName)
|
||||
.writeInt(managedProcess.pid)
|
||||
.writeInt(managedProcess.oomScore)
|
||||
.writeInt(snapshot.rssInKilobytes)
|
||||
.writeInt(snapshot.anonRssInKilobytes)
|
||||
.writeInt(snapshot.swapInKilobytes)
|
||||
.writeInt(snapshot.anonRssInKilobytes + snapshot.swapInKilobytes)
|
||||
.build();
|
||||
pulledData.add(e);
|
||||
}
|
||||
forEachPid((pid, cmdLine) -> {
|
||||
if (!MEMORY_INTERESTING_NATIVE_PROCESSES.contains(cmdLine)) {
|
||||
return;
|
||||
}
|
||||
final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(pid);
|
||||
if (snapshot == null) {
|
||||
return;
|
||||
}
|
||||
// Sometimes we get here a process that is not included in the whitelist. It comes
|
||||
// from forking the zygote for an app. We can ignore that sample because this process
|
||||
// is collected by ProcessMemoryState.
|
||||
if (isAppUid(snapshot.uid)) {
|
||||
return;
|
||||
}
|
||||
StatsEvent e = StatsEvent.newBuilder()
|
||||
.setAtomId(atomTag)
|
||||
.writeInt(snapshot.uid)
|
||||
.writeString(cmdLine)
|
||||
.writeInt(pid)
|
||||
.writeInt(-1001) // Placeholder for native processes, OOM_SCORE_ADJ_MIN - 1.
|
||||
.writeInt(snapshot.rssInKilobytes)
|
||||
.writeInt(snapshot.anonRssInKilobytes)
|
||||
.writeInt(snapshot.swapInKilobytes)
|
||||
.writeInt(snapshot.anonRssInKilobytes + snapshot.swapInKilobytes)
|
||||
.build();
|
||||
pulledData.add(e);
|
||||
});
|
||||
return StatsManager.PULL_SUCCESS;
|
||||
}
|
||||
|
||||
private void registerSystemIonHeapSize() {
|
||||
// No op.
|
||||
int tagId = StatsLog.SYSTEM_ION_HEAP_SIZE;
|
||||
mStatsManager.registerPullAtomCallback(
|
||||
tagId,
|
||||
null, // use default PullAtomMetadata values
|
||||
(atomTag, data) -> pullSystemIonHeapSize(atomTag, data),
|
||||
BackgroundThread.getExecutor()
|
||||
);
|
||||
}
|
||||
|
||||
private void pullSystemIonHeapSize() {
|
||||
// No op.
|
||||
private int pullSystemIonHeapSize(int atomTag, List<StatsEvent> pulledData) {
|
||||
final long systemIonHeapSizeInBytes = readSystemIonHeapSizeFromDebugfs();
|
||||
StatsEvent e = StatsEvent.newBuilder()
|
||||
.setAtomId(atomTag)
|
||||
.writeLong(systemIonHeapSizeInBytes)
|
||||
.build();
|
||||
pulledData.add(e);
|
||||
return StatsManager.PULL_SUCCESS;
|
||||
}
|
||||
|
||||
private void registerIonHeapSize() {
|
||||
@@ -1056,43 +1248,182 @@ public class StatsPullAtomService extends SystemService {
|
||||
}
|
||||
|
||||
private void registerProcessSystemIonHeapSize() {
|
||||
// No op.
|
||||
int tagId = StatsLog.PROCESS_SYSTEM_ION_HEAP_SIZE;
|
||||
mStatsManager.registerPullAtomCallback(
|
||||
tagId,
|
||||
null, // use default PullAtomMetadata values
|
||||
(atomTag, data) -> pullProcessSystemIonHeapSize(atomTag, data),
|
||||
BackgroundThread.getExecutor()
|
||||
);
|
||||
}
|
||||
|
||||
private void pullProcessSystemIonHeapSize() {
|
||||
// No op.
|
||||
private int pullProcessSystemIonHeapSize(int atomTag, List<StatsEvent> pulledData) {
|
||||
List<IonAllocations> result = readProcessSystemIonHeapSizesFromDebugfs();
|
||||
for (IonAllocations allocations : result) {
|
||||
StatsEvent e = StatsEvent.newBuilder()
|
||||
.setAtomId(atomTag)
|
||||
.writeInt(getUidForPid(allocations.pid))
|
||||
.writeString(readCmdlineFromProcfs(allocations.pid))
|
||||
.writeInt((int) (allocations.totalSizeInBytes / 1024))
|
||||
.writeInt(allocations.count)
|
||||
.writeInt((int) (allocations.maxSizeInBytes / 1024))
|
||||
.build();
|
||||
pulledData.add(e);
|
||||
}
|
||||
return StatsManager.PULL_SUCCESS;
|
||||
}
|
||||
|
||||
private void registerTemperature() {
|
||||
// No op.
|
||||
int tagId = StatsLog.TEMPERATURE;
|
||||
mStatsManager.registerPullAtomCallback(
|
||||
tagId,
|
||||
null, // use default PullAtomMetadata values
|
||||
(atomTag, data) -> pullTemperature(atomTag, data),
|
||||
BackgroundThread.getExecutor()
|
||||
);
|
||||
}
|
||||
|
||||
private void pullTemperature() {
|
||||
// No op.
|
||||
private int pullTemperature(int atomTag, List<StatsEvent> pulledData) {
|
||||
IThermalService thermalService = getIThermalService();
|
||||
if (thermalService == null) {
|
||||
return StatsManager.PULL_SKIP;
|
||||
}
|
||||
final long callingToken = Binder.clearCallingIdentity();
|
||||
try {
|
||||
List<Temperature> temperatures = thermalService.getCurrentTemperatures();
|
||||
for (Temperature temp : temperatures) {
|
||||
StatsEvent e = StatsEvent.newBuilder()
|
||||
.setAtomId(atomTag)
|
||||
.writeInt(temp.getType())
|
||||
.writeString(temp.getName())
|
||||
.writeInt((int) (temp.getValue() * 10))
|
||||
.writeInt(temp.getStatus())
|
||||
.build();
|
||||
pulledData.add(e);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
// Should not happen.
|
||||
Slog.e(TAG, "Disconnected from thermal service. Cannot pull temperatures.");
|
||||
return StatsManager.PULL_SKIP;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(callingToken);
|
||||
}
|
||||
return StatsManager.PULL_SUCCESS;
|
||||
}
|
||||
|
||||
private void registerCoolingDevice() {
|
||||
// No op.
|
||||
int tagId = StatsLog.COOLING_DEVICE;
|
||||
mStatsManager.registerPullAtomCallback(
|
||||
tagId,
|
||||
null, // use default PullAtomMetadata values
|
||||
(atomTag, data) -> pullCooldownDevice(atomTag, data),
|
||||
BackgroundThread.getExecutor()
|
||||
);
|
||||
}
|
||||
|
||||
private void pullCooldownDevice() {
|
||||
// No op.
|
||||
private int pullCooldownDevice(int atomTag, List<StatsEvent> pulledData) {
|
||||
IThermalService thermalService = getIThermalService();
|
||||
if (thermalService == null) {
|
||||
return StatsManager.PULL_SKIP;
|
||||
}
|
||||
final long callingToken = Binder.clearCallingIdentity();
|
||||
try {
|
||||
List<CoolingDevice> devices = thermalService.getCurrentCoolingDevices();
|
||||
for (CoolingDevice device : devices) {
|
||||
StatsEvent e = StatsEvent.newBuilder()
|
||||
.setAtomId(atomTag)
|
||||
.writeInt(device.getType())
|
||||
.writeString(device.getName())
|
||||
.writeInt((int) (device.getValue()))
|
||||
.build();
|
||||
pulledData.add(e);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
// Should not happen.
|
||||
Slog.e(TAG, "Disconnected from thermal service. Cannot pull temperatures.");
|
||||
return StatsManager.PULL_SKIP;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(callingToken);
|
||||
}
|
||||
return StatsManager.PULL_SUCCESS;
|
||||
}
|
||||
|
||||
private void registerBinderCalls() {
|
||||
// No op.
|
||||
private void registerBinderCallsStats() {
|
||||
int tagId = StatsLog.BINDER_CALLS;
|
||||
PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
|
||||
.setAdditiveFields(new int[] {4, 5, 6, 8, 12})
|
||||
.build();
|
||||
mStatsManager.registerPullAtomCallback(
|
||||
tagId,
|
||||
metadata,
|
||||
(atomTag, data) -> pullBinderCallsStats(atomTag, data),
|
||||
BackgroundThread.getExecutor()
|
||||
);
|
||||
}
|
||||
|
||||
private void pullBinderCalls() {
|
||||
// No op.
|
||||
private int pullBinderCallsStats(int atomTag, List<StatsEvent> pulledData) {
|
||||
BinderCallsStatsService.Internal binderStats =
|
||||
LocalServices.getService(BinderCallsStatsService.Internal.class);
|
||||
if (binderStats == null) {
|
||||
Slog.e(TAG, "failed to get binderStats");
|
||||
return StatsManager.PULL_SKIP;
|
||||
}
|
||||
|
||||
List<ExportedCallStat> callStats = binderStats.getExportedCallStats();
|
||||
binderStats.reset();
|
||||
for (ExportedCallStat callStat : callStats) {
|
||||
StatsEvent e = StatsEvent.newBuilder()
|
||||
.setAtomId(atomTag)
|
||||
.writeInt(callStat.workSourceUid)
|
||||
.writeString(callStat.className)
|
||||
.writeString(callStat.methodName)
|
||||
.writeLong(callStat.callCount)
|
||||
.writeLong(callStat.exceptionCount)
|
||||
.writeLong(callStat.latencyMicros)
|
||||
.writeLong(callStat.maxLatencyMicros)
|
||||
.writeLong(callStat.cpuTimeMicros)
|
||||
.writeLong(callStat.maxCpuTimeMicros)
|
||||
.writeLong(callStat.maxReplySizeBytes)
|
||||
.writeLong(callStat.maxRequestSizeBytes)
|
||||
.writeLong(callStat.recordedCallCount)
|
||||
.writeInt(callStat.screenInteractive ? 1 : 0)
|
||||
.writeInt(callStat.callingUid)
|
||||
.build();
|
||||
pulledData.add(e);
|
||||
}
|
||||
return StatsManager.PULL_SUCCESS;
|
||||
}
|
||||
|
||||
private void registerBinderCallsExceptions() {
|
||||
// No op.
|
||||
private void registerBinderCallsStatsExceptions() {
|
||||
int tagId = StatsLog.BINDER_CALLS_EXCEPTIONS;
|
||||
mStatsManager.registerPullAtomCallback(
|
||||
tagId,
|
||||
null, // use default PullAtomMetadata values
|
||||
(atomTag, data) -> pullBinderCallsStatsExceptions(atomTag, data),
|
||||
BackgroundThread.getExecutor()
|
||||
);
|
||||
}
|
||||
|
||||
private void pullBinderCallsExceptions() {
|
||||
// No op.
|
||||
private int pullBinderCallsStatsExceptions(int atomTag, List<StatsEvent> pulledData) {
|
||||
BinderCallsStatsService.Internal binderStats =
|
||||
LocalServices.getService(BinderCallsStatsService.Internal.class);
|
||||
if (binderStats == null) {
|
||||
Slog.e(TAG, "failed to get binderStats");
|
||||
return StatsManager.PULL_SKIP;
|
||||
}
|
||||
|
||||
ArrayMap<String, Integer> exceptionStats = binderStats.getExportedExceptionStats();
|
||||
// TODO: decouple binder calls exceptions with the rest of the binder calls data so that we
|
||||
// can reset the exception stats.
|
||||
for (Map.Entry<String, Integer> entry : exceptionStats.entrySet()) {
|
||||
StatsEvent e = StatsEvent.newBuilder()
|
||||
.setAtomId(atomTag)
|
||||
.writeString(entry.getKey())
|
||||
.writeInt(entry.getValue())
|
||||
.build();
|
||||
pulledData.add(e);
|
||||
}
|
||||
return StatsManager.PULL_SUCCESS;
|
||||
}
|
||||
|
||||
private void registerLooperStats() {
|
||||
@@ -218,7 +218,7 @@ public final class SystemServer {
|
||||
private static final String STATS_COMPANION_LIFECYCLE_CLASS =
|
||||
"com.android.server.stats.StatsCompanion$Lifecycle";
|
||||
private static final String STATS_PULL_ATOM_SERVICE_CLASS =
|
||||
"com.android.server.stats.StatsPullAtomService";
|
||||
"com.android.server.stats.pull.StatsPullAtomService";
|
||||
private static final String USB_SERVICE_CLASS =
|
||||
"com.android.server.usb.UsbService$Lifecycle";
|
||||
private static final String MIDI_SERVICE_CLASS =
|
||||
|
||||
@@ -13,16 +13,16 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.server.stats;
|
||||
package com.android.server.stats.pull;
|
||||
|
||||
import static com.android.server.stats.IonMemoryUtil.parseIonHeapSizeFromDebugfs;
|
||||
import static com.android.server.stats.IonMemoryUtil.parseProcessIonHeapSizesFromDebugfs;
|
||||
import static com.android.server.stats.pull.IonMemoryUtil.parseIonHeapSizeFromDebugfs;
|
||||
import static com.android.server.stats.pull.IonMemoryUtil.parseProcessIonHeapSizesFromDebugfs;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.server.stats.IonMemoryUtil.IonAllocations;
|
||||
import com.android.server.stats.pull.IonMemoryUtil.IonAllocations;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
Reference in New Issue
Block a user