From abdd568bcf5045cf20228645cf9b0069cfcb3f1b Mon Sep 17 00:00:00 2001 From: Michael Wachenschwanz Date: Wed, 5 Jan 2022 17:14:07 -0800 Subject: [PATCH] Move PowerStatsLogger off of the main thread. Logging data from the PowerStatshal can take a significantly long time. Moving the PowerStatsLogger to the PowerStatsService thread to avoid choking other system services. Fixes: 212652242 Test: atest PowerStatsServicetest Change-Id: I990d38ae8c51741b8cdc41bf60938e19342f8ef4 --- .../server/powerstats/PowerStatsLogger.java | 5 ++- .../server/powerstats/PowerStatsService.java | 35 +++++++++++++------ .../powerstats/PowerStatsServiceTest.java | 7 ++-- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/services/core/java/com/android/server/powerstats/PowerStatsLogger.java b/services/core/java/com/android/server/powerstats/PowerStatsLogger.java index ef0079e0c01fc..ca675973b2fdd 100644 --- a/services/core/java/com/android/server/powerstats/PowerStatsLogger.java +++ b/services/core/java/com/android/server/powerstats/PowerStatsLogger.java @@ -35,7 +35,6 @@ import android.util.proto.ProtoInputStream; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.VisibleForTesting; - import com.android.server.powerstats.PowerStatsHALWrapper.IPowerStatsHALWrapper; import com.android.server.powerstats.ProtoStreamUtils.ChannelUtils; import com.android.server.powerstats.ProtoStreamUtils.EnergyConsumerResultUtils; @@ -313,12 +312,12 @@ public final class PowerStatsLogger extends Handler { return mStartWallTime; } - public PowerStatsLogger(Context context, File dataStoragePath, + public PowerStatsLogger(Context context, Looper looper, File dataStoragePath, String meterFilename, String meterCacheFilename, String modelFilename, String modelCacheFilename, String residencyFilename, String residencyCacheFilename, IPowerStatsHALWrapper powerStatsHALWrapper) { - super(Looper.getMainLooper()); + super(looper); mStartWallTime = currentTimeMillis() - SystemClock.elapsedRealtime(); if (DEBUG) Slog.d(TAG, "mStartWallTime: " + mStartWallTime); mPowerStatsHALWrapper = powerStatsHALWrapper; diff --git a/services/core/java/com/android/server/powerstats/PowerStatsService.java b/services/core/java/com/android/server/powerstats/PowerStatsService.java index bb52c1dc1a298..9953ca8f9b65e 100644 --- a/services/core/java/com/android/server/powerstats/PowerStatsService.java +++ b/services/core/java/com/android/server/powerstats/PowerStatsService.java @@ -28,6 +28,7 @@ import android.os.Binder; import android.os.Environment; import android.os.Handler; import android.os.HandlerThread; +import android.os.Looper; import android.os.UserHandle; import android.power.PowerStatsInternal; import android.util.Slog; @@ -79,6 +80,9 @@ public class PowerStatsService extends SystemService { private StatsPullAtomCallbackImpl mPullAtomCallback; @Nullable private PowerStatsInternal mPowerStatsInternal; + @Nullable + @GuardedBy("this") + private Looper mLooper; @VisibleForTesting static class Injector { @@ -127,12 +131,12 @@ public class PowerStatsService extends SystemService { } } - PowerStatsLogger createPowerStatsLogger(Context context, File dataStoragePath, - String meterFilename, String meterCacheFilename, + PowerStatsLogger createPowerStatsLogger(Context context, Looper looper, + File dataStoragePath, String meterFilename, String meterCacheFilename, String modelFilename, String modelCacheFilename, String residencyFilename, String residencyCacheFilename, IPowerStatsHALWrapper powerStatsHALWrapper) { - return new PowerStatsLogger(context, dataStoragePath, + return new PowerStatsLogger(context, looper, dataStoragePath, meterFilename, meterCacheFilename, modelFilename, modelCacheFilename, residencyFilename, residencyCacheFilename, @@ -229,11 +233,11 @@ public class PowerStatsService extends SystemService { mDataStoragePath = mInjector.createDataStoragePath(); // Only start logger and triggers if initialization is successful. - mPowerStatsLogger = mInjector.createPowerStatsLogger(mContext, mDataStoragePath, - mInjector.createMeterFilename(), mInjector.createMeterCacheFilename(), - mInjector.createModelFilename(), mInjector.createModelCacheFilename(), - mInjector.createResidencyFilename(), mInjector.createResidencyCacheFilename(), - getPowerStatsHal()); + mPowerStatsLogger = mInjector.createPowerStatsLogger(mContext, getLooper(), + mDataStoragePath, mInjector.createMeterFilename(), + mInjector.createMeterCacheFilename(), mInjector.createModelFilename(), + mInjector.createModelCacheFilename(), mInjector.createResidencyFilename(), + mInjector.createResidencyCacheFilename(), getPowerStatsHal()); mBatteryTrigger = mInjector.createBatteryTrigger(mContext, mPowerStatsLogger); mTimerTrigger = mInjector.createTimerTrigger(mContext, mPowerStatsLogger); } else { @@ -245,6 +249,17 @@ public class PowerStatsService extends SystemService { return mInjector.getPowerStatsHALWrapperImpl(); } + private Looper getLooper() { + synchronized (this) { + if (mLooper == null) { + HandlerThread thread = new HandlerThread(TAG); + thread.start(); + return thread.getLooper(); + } + return mLooper; + } + } + public PowerStatsService(Context context) { this(context, new Injector()); } @@ -260,9 +275,7 @@ public class PowerStatsService extends SystemService { private final Handler mHandler; LocalService() { - HandlerThread thread = new HandlerThread(TAG); - thread.start(); - mHandler = new Handler(thread.getLooper()); + mHandler = new Handler(getLooper()); } diff --git a/services/tests/servicestests/src/com/android/server/powerstats/PowerStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/powerstats/PowerStatsServiceTest.java index 26b34fdd4e043..304fe5a1c9c3e 100644 --- a/services/tests/servicestests/src/com/android/server/powerstats/PowerStatsServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/powerstats/PowerStatsServiceTest.java @@ -30,6 +30,7 @@ import android.hardware.power.stats.PowerEntity; import android.hardware.power.stats.State; import android.hardware.power.stats.StateResidency; import android.hardware.power.stats.StateResidencyResult; +import android.os.Looper; import androidx.test.InstrumentationRegistry; @@ -145,12 +146,12 @@ public class PowerStatsServiceTest { } @Override - PowerStatsLogger createPowerStatsLogger(Context context, File dataStoragePath, - String meterFilename, String meterCacheFilename, + PowerStatsLogger createPowerStatsLogger(Context context, Looper looper, + File dataStoragePath, String meterFilename, String meterCacheFilename, String modelFilename, String modelCacheFilename, String residencyFilename, String residencyCacheFilename, IPowerStatsHALWrapper powerStatsHALWrapper) { - mPowerStatsLogger = new PowerStatsLogger(context, dataStoragePath, + mPowerStatsLogger = new PowerStatsLogger(context, looper, dataStoragePath, meterFilename, meterCacheFilename, modelFilename, modelCacheFilename, residencyFilename, residencyCacheFilename,