Migrate pullBatteryLevel

Bug: 145565890
Test: adb shell cmd stats pull-source 10043
Test: atest HostAtomTests#testBatteryLevel
Test: atest HostAtomTests#testBatteryLevelChangedAtom
Change-Id: I91d3a6291f368061c76116c039f9185a9f56de2c
This commit is contained in:
Jeffrey Huang
2020-01-27 17:33:13 -08:00
parent 55b30b35dd
commit 9a3c1b6e1b
5 changed files with 66 additions and 22 deletions

View File

@@ -436,7 +436,7 @@ message Atom {
DeviceCalculatedPowerBlameOther device_calculated_power_blame_other =
10041 [(module) = "framework"];
ProcessMemoryHighWaterMark process_memory_high_water_mark = 10042 [(module) = "framework"];
BatteryLevel battery_level = 10043;
BatteryLevel battery_level = 10043 [(module) = "framework"];
BuildInformation build_information = 10044 [(module) = "framework"];
BatteryCycleCount battery_cycle_count = 10045;
DebugElapsedClock debug_elapsed_clock = 10046 [(module) = "framework"];

View File

@@ -91,12 +91,6 @@ bool ResourceHealthManagerPuller::PullInternal(vector<shared_ptr<LogEvent>>* dat
ptr->write(v.legacy.batteryVoltage);
ptr->init();
data->push_back(ptr);
} else if (mTagId == android::util::BATTERY_LEVEL) {
auto ptr = make_shared<LogEvent>(android::util::BATTERY_LEVEL, wallClockTimestampNs,
elapsedTimestampNs);
ptr->write(v.legacy.batteryLevel);
ptr->init();
data->push_back(ptr);
} else if (mTagId == android::util::BATTERY_CYCLE_COUNT) {
auto ptr = make_shared<LogEvent>(android::util::BATTERY_CYCLE_COUNT,
wallClockTimestampNs, elapsedTimestampNs);

View File

@@ -74,10 +74,6 @@ StatsPullerManager::StatsPullerManager()
{{.atomTag = android::util::BATTERY_VOLTAGE},
new ResourceHealthManagerPuller(android::util::BATTERY_VOLTAGE)},
// battery_level
{{.atomTag = android::util::BATTERY_LEVEL},
new ResourceHealthManagerPuller(android::util::BATTERY_LEVEL)},
// battery_cycle_count
{{.atomTag = android::util::BATTERY_CYCLE_COUNT},
new ResourceHealthManagerPuller(android::util::BATTERY_CYCLE_COUNT)},

View File

@@ -18,6 +18,7 @@ package com.android.server;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.content.ContentResolver;
@@ -1318,8 +1319,7 @@ public final class BatteryService extends SystemService {
*
* @hide Should only be used internally.
*/
@VisibleForTesting
static final class HealthServiceWrapper {
public static final class HealthServiceWrapper {
private static final String TAG = "HealthServiceWrapper";
public static final String INSTANCE_HEALTHD = "backup";
public static final String INSTANCE_VENDOR = "default";
@@ -1341,20 +1341,28 @@ public final class BatteryService extends SystemService {
* init should be called after constructor. For testing purposes, init is not called by
* constructor.
*/
HealthServiceWrapper() {
public HealthServiceWrapper() {
}
IHealth getLastService() {
public IHealth getLastService() {
return mLastService.get();
}
/**
* See {@link #init(Callback, IServiceManagerSupplier, IHealthSupplier)}
*/
public void init() throws RemoteException, NoSuchElementException {
init(/* callback= */null, new HealthServiceWrapper.IServiceManagerSupplier() {},
new HealthServiceWrapper.IHealthSupplier() {});
}
/**
* Start monitoring registration of new IHealth services. Only instances that are in
* {@code sAllInstances} and in device / framework manifest are used. This function should
* only be called once.
*
* mCallback.onRegistration() is called synchronously (aka in init thread) before
* this method returns.
* this method returns if callback is not null.
*
* @throws RemoteException transaction error when talking to IServiceManager
* @throws NoSuchElementException if one of the following cases:
@@ -1362,18 +1370,17 @@ public final class BatteryService extends SystemService {
* - none of {@code sAllInstances} are in manifests (i.e. not
* available on this device), or none of these instances are available to current
* process.
* @throws NullPointerException when callback is null or supplier is null
* @throws NullPointerException when supplier is null
*/
void init(Callback callback,
void init(@Nullable Callback callback,
IServiceManagerSupplier managerSupplier,
IHealthSupplier healthSupplier)
throws RemoteException, NoSuchElementException, NullPointerException {
if (callback == null || managerSupplier == null || healthSupplier == null)
if (managerSupplier == null || healthSupplier == null) {
throw new NullPointerException();
}
IServiceManager manager;
mCallback = callback;
mHealthSupplier = healthSupplier;
// Initialize mLastService and call callback for the first time (in init thread)
@@ -1399,7 +1406,11 @@ public final class BatteryService extends SystemService {
"No IHealth service instance among %s is available. Perhaps no permission?",
sAllInstances.toString()));
}
mCallback.onRegistration(null, newService, mInstanceName);
if (callback != null) {
mCallback = callback;
mCallback.onRegistration(null, newService, mInstanceName);
}
// Register for future service registrations
traceBegin("HealthInitRegisterNotification");

View File

@@ -54,6 +54,7 @@ import android.content.pm.UserInfo;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.health.V2_0.IHealth;
import android.net.ConnectivityManager;
import android.net.INetworkStatsService;
import android.net.Network;
@@ -119,6 +120,7 @@ import com.android.internal.os.PowerProfile;
import com.android.internal.os.ProcessCpuTracker;
import com.android.internal.os.StoragedUidIoStatsReader;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.BatteryService;
import com.android.server.BinderCallsStatsService;
import com.android.server.LocalServices;
import com.android.server.SystemService;
@@ -239,6 +241,8 @@ public class StatsPullAtomService extends SystemService {
private File mBaseDir;
private BatteryService.HealthServiceWrapper mHealthService;
@Nullable
private KernelCpuThreadReaderDiff mKernelCpuThreadReader;
@@ -373,6 +377,8 @@ public class StatsPullAtomService extends SystemService {
return pullNotificationRemoteViews(atomTag, data);
case FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED:
return pullDangerousPermissionState(atomTag, data);
case FrameworkStatsLog.BATTERY_LEVEL:
return pullBatteryLevel(atomTag, data);
default:
throw new UnsupportedOperationException("Unknown tagId=" + atomTag);
}
@@ -438,6 +444,14 @@ public class StatsPullAtomService extends SystemService {
// Used by PROC_STATS and PROC_STATS_PKG_PROC atoms
mBaseDir.mkdirs();
// Initialize HealthService
mHealthService = new BatteryService.HealthServiceWrapper();
try {
mHealthService.init();
} catch (RemoteException e) {
Slog.e(TAG, "failed to initialize healthHalWrapper");
}
}
void registerEventListeners() {
@@ -519,6 +533,7 @@ public class StatsPullAtomService extends SystemService {
registerNotificationRemoteViews();
registerDangerousPermissionState();
registerDangerousPermissionStateSampled();
registerBatteryLevel();
}
private INetworkStatsService getINetworkStatsService() {
@@ -2961,6 +2976,34 @@ public class StatsPullAtomService extends SystemService {
);
}
private void registerBatteryLevel() {
int tagId = FrameworkStatsLog.BATTERY_LEVEL;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
BackgroundThread.getExecutor(),
mStatsCallbackImpl
);
}
int pullBatteryLevel(int atomTag, List<StatsEvent> pulledData) {
IHealth healthService = mHealthService.getLastService();
if (healthService == null) {
return StatsManager.PULL_SKIP;
}
try {
healthService.getHealthInfo((result, value) -> {
StatsEvent e = StatsEvent.newBuilder()
.setAtomId(atomTag)
.writeInt(value.legacy.batteryLevel)
.build();
pulledData.add(e);
});
} catch (RemoteException e) {
return StatsManager.PULL_SKIP;
}
return StatsManager.PULL_SUCCESS;
}
// Thermal event received from vendor thermal management subsystem
private static final class ThermalEventListener extends IThermalEventListener.Stub {