From efc4710b7fc9a49328e99f8a5c6d624c76176b8c Mon Sep 17 00:00:00 2001 From: Dmitry Dementyev Date: Thu, 11 Jul 2024 12:39:22 -0700 Subject: [PATCH 001/414] Update AccountManagerService checkKeyIntent. Block intents with "content" data scheme. Bug: 349780950 Test: manual Flag: EXEMPT bugfix (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:c1e79495a49bd4d3e380136fe4bca7ac1a9ed763) Merged-In: I8b23191d3d60036ca7ddf0ef7dcba6b38fb27b3c Change-Id: I8b23191d3d60036ca7ddf0ef7dcba6b38fb27b3c --- .../com/android/server/accounts/AccountManagerService.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index ac9ed0da95a54..6dc2dc2dc04a0 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -5048,6 +5048,9 @@ protected boolean checkKeyIntent(int authUid, Bundle bundle) { if (resolveInfo == null) { return false; } + if ("content".equals(intent.getScheme())) { + return false; + } ActivityInfo targetActivityInfo = resolveInfo.activityInfo; int targetUid = targetActivityInfo.applicationInfo.uid; PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class); From 22c6f644cb4d4ff6a717feb242a6c84ab17e65f9 Mon Sep 17 00:00:00 2001 From: Sumedh Sen Date: Wed, 17 Jul 2024 17:42:43 +0000 Subject: [PATCH 002/414] Check whether installerPackageName contains only valid characters Bug: 341256391 Bug: 307532206 Test: sts-tradefed run sts-dynamic-develop -m CtsSecurityTestCases -t android.security.cts.CVE_2024_0044 (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:c32cfc60ccf531470f6125b6019d8ab2452b3617) Merged-In: I74a172c617d6f5b13f0708092156b657b73b5891 Change-Id: I74a172c617d6f5b13f0708092156b657b73b5891 --- .../com/android/server/pm/PackageInstallerService.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index b93dcdc93a825..e15a1f1763c25 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -693,13 +693,18 @@ int createSessionInternal(SessionParams params, String installerPackageName, params.appLabel = TextUtils.trimToSize(params.appLabel, PackageItemInfo.MAX_SAFE_LABEL_LENGTH); - // Validate installer package name. + // Validate requested installer package name. if (params.installerPackageName != null && !isValidPackageName( params.installerPackageName)) { params.installerPackageName = null; } - var requestedInstallerPackageName = + // Validate installer package name. + if (installerPackageName != null && !isValidPackageName(installerPackageName)) { + installerPackageName = null; + } + + String requestedInstallerPackageName = params.installerPackageName != null ? params.installerPackageName : installerPackageName; From 9bbdeaecb728e563c87b610dae64f4d0cbd02bd3 Mon Sep 17 00:00:00 2001 From: Dmitry Dementyev Date: Mon, 22 Jul 2024 23:48:29 +0000 Subject: [PATCH 003/414] Prevent system service crash after SQL error in AccountManagerService. Catch broader exception instead of SQLiteCantOpenDatabaseException since current one ignores some errors during database update. Return empty list if error happened during getAccountsAsUser call used by SyncManager. Bug: 354764198 Test: manual Flag: EXEMPT bugfix (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:d248c61ef55b0874cd586d6812a9af29ad31e909) Merged-In: I0f3190e8b284230b5c955b9f43b09c4c291ea73a Change-Id: I0f3190e8b284230b5c955b9f43b09c4c291ea73a --- .../server/accounts/AccountManagerService.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index 6dc2dc2dc04a0..fb583acd7503c 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -72,6 +72,7 @@ import android.content.pm.UserInfo; import android.database.Cursor; import android.database.sqlite.SQLiteCantOpenDatabaseException; +import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteFullException; import android.database.sqlite.SQLiteStatement; import android.os.Binder; @@ -1457,8 +1458,8 @@ private void purgeOldGrants(UserAccounts accounts) { List uids; try { uids = accounts.accountsDb.findAllUidGrants(); - } catch (SQLiteCantOpenDatabaseException e) { - Log.w(TAG, "Could not delete grants for user = " + accounts.userId); + } catch (SQLiteException e) { + Log.w(TAG, "Could not delete grants for user = " + accounts.userId, e); return; } for (int uid : uids) { @@ -4460,6 +4461,9 @@ public Account[] getAccounts(int userId, String opPackageName) { opPackageName, visibleAccountTypes, false /* includeUserManagedNotVisible */); + } catch (SQLiteException e) { + Log.w(TAG, "Could not get accounts for user " + userId, e); + return new Account[]{}; } finally { restoreCallingIdentity(identityToken); } @@ -4535,7 +4539,7 @@ public Account[] getAccountsAsUser(String type, int userId, String opPackageName try { return getAccountsAsUserForPackage(type, userId, opPackageName /* callingPackage */, -1, opPackageName, false /* includeUserManagedNotVisible */); - } catch (SQLiteCantOpenDatabaseException e) { + } catch (SQLiteException e) { Log.e(TAG, "Could not get accounts for user " + userId, e); return new Account[]{}; } @@ -4545,7 +4549,7 @@ public Account[] getAccountsAsUser(String type, int userId, String opPackageName private Account[] getAccountsOrEmptyArray(String type, int userId, String opPackageName) { try { return getAccountsAsUser(type, userId, opPackageName); - } catch (SQLiteCantOpenDatabaseException e) { + } catch (SQLiteException e) { Log.w(TAG, "Could not get accounts for user " + userId, e); return new Account[]{}; } From 04d785f9bef9e47ce1282a57e1d18fcf28c60c8f Mon Sep 17 00:00:00 2001 From: Michael Wachenschwanz Date: Tue, 6 Aug 2024 21:14:42 +0000 Subject: [PATCH 004/414] Revert "Add power stats collector and processor for Camera and GNSS" This reverts commit 5be910088fa00a9d269cf927259ebff2517ff2f9. Reason for revert: b/356723894 (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:7b93613dbc30f0d2b718490047636696b5bb62c0) Merged-In: I9d127507fb50a0aad27af9dcf4e30785eb378594 Change-Id: I9d127507fb50a0aad27af9dcf4e30785eb378594 --- core/java/android/os/BatteryConsumer.java | 2 - core/java/android/os/BatteryStats.java | 3 +- .../server/am/BatteryStatsService.java | 40 +- .../server/power/stats/BatteryStatsImpl.java | 52 +-- .../stats/BatteryUsageStatsProvider.java | 8 +- .../stats/BinaryStatePowerStatsProcessor.java | 45 +-- .../stats/CameraPowerStatsCollector.java | 30 -- .../stats/CameraPowerStatsProcessor.java | 37 -- .../EnergyConsumerPowerStatsCollector.java | 150 ------- .../power/stats/GnssPowerStatsCollector.java | 30 -- .../power/stats/GnssPowerStatsLayout.java | 65 --- .../power/stats/GnssPowerStatsProcessor.java | 143 ------- .../power/stats/PowerStatsCollector.java | 11 +- .../power/stats/BatteryUsageStatsTest.java | 2 +- .../power/stats/CameraPowerStatsTest.java | 270 ------------- .../power/stats/GnssPowerStatsTest.java | 375 ------------------ 16 files changed, 38 insertions(+), 1225 deletions(-) delete mode 100644 services/core/java/com/android/server/power/stats/CameraPowerStatsCollector.java delete mode 100644 services/core/java/com/android/server/power/stats/CameraPowerStatsProcessor.java delete mode 100644 services/core/java/com/android/server/power/stats/EnergyConsumerPowerStatsCollector.java delete mode 100644 services/core/java/com/android/server/power/stats/GnssPowerStatsCollector.java delete mode 100644 services/core/java/com/android/server/power/stats/GnssPowerStatsLayout.java delete mode 100644 services/core/java/com/android/server/power/stats/GnssPowerStatsProcessor.java delete mode 100644 services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerStatsTest.java delete mode 100644 services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerStatsTest.java diff --git a/core/java/android/os/BatteryConsumer.java b/core/java/android/os/BatteryConsumer.java index 02f3a256aae30..7bdd53d002150 100644 --- a/core/java/android/os/BatteryConsumer.java +++ b/core/java/android/os/BatteryConsumer.java @@ -200,8 +200,6 @@ public abstract class BatteryConsumer { POWER_COMPONENT_AUDIO, POWER_COMPONENT_VIDEO, POWER_COMPONENT_FLASHLIGHT, - POWER_COMPONENT_CAMERA, - POWER_COMPONENT_GNSS, }; static final int COLUMN_INDEX_BATTERY_CONSUMER_TYPE = 0; diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 065b3d6c7a8aa..3e6223ab94004 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -1994,8 +1994,7 @@ public boolean isDeltaData() { // STATES2 bits that are used for Power Stats tracking public static final int IMPORTANT_FOR_POWER_STATS_STATES2 = - STATE2_VIDEO_ON_FLAG | STATE2_FLASHLIGHT_FLAG | STATE2_CAMERA_FLAG - | STATE2_GPS_SIGNAL_QUALITY_MASK; + STATE2_VIDEO_ON_FLAG | STATE2_FLASHLIGHT_FLAG | STATE2_CAMERA_FLAG; @UnsupportedAppUsage public int states2; diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 1ac37ad99ada1..29e0f7ae6f017 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -128,10 +128,8 @@ import com.android.server.power.stats.BatteryStatsImpl; import com.android.server.power.stats.BatteryUsageStatsProvider; import com.android.server.power.stats.BluetoothPowerStatsProcessor; -import com.android.server.power.stats.CameraPowerStatsProcessor; import com.android.server.power.stats.CpuPowerStatsProcessor; import com.android.server.power.stats.FlashlightPowerStatsProcessor; -import com.android.server.power.stats.GnssPowerStatsProcessor; import com.android.server.power.stats.MobileRadioPowerStatsProcessor; import com.android.server.power.stats.PhoneCallPowerStatsProcessor; import com.android.server.power.stats.PowerStatsAggregator; @@ -530,19 +528,10 @@ private AggregatedPowerStatsConfig createAggregatedPowerStatsConfig() { AggregatedPowerStatsConfig.STATE_SCREEN, AggregatedPowerStatsConfig.STATE_PROCESS_STATE) .setProcessor( - new AudioPowerStatsProcessor(mPowerProfile, mPowerStatsUidResolver)); + new AudioPowerStatsProcessor(mPowerProfile, + mPowerStatsUidResolver)); config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_VIDEO) - .trackDeviceStates( - AggregatedPowerStatsConfig.STATE_POWER, - AggregatedPowerStatsConfig.STATE_SCREEN) - .trackUidStates( - AggregatedPowerStatsConfig.STATE_POWER, - AggregatedPowerStatsConfig.STATE_SCREEN, - AggregatedPowerStatsConfig.STATE_PROCESS_STATE) - .setProcessor(new VideoPowerStatsProcessor(mPowerProfile, mPowerStatsUidResolver)); - - config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT) .trackDeviceStates( AggregatedPowerStatsConfig.STATE_POWER, AggregatedPowerStatsConfig.STATE_SCREEN) @@ -551,20 +540,10 @@ private AggregatedPowerStatsConfig createAggregatedPowerStatsConfig() { AggregatedPowerStatsConfig.STATE_SCREEN, AggregatedPowerStatsConfig.STATE_PROCESS_STATE) .setProcessor( - new FlashlightPowerStatsProcessor(mPowerProfile, mPowerStatsUidResolver)); + new VideoPowerStatsProcessor(mPowerProfile, + mPowerStatsUidResolver)); - config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_CAMERA) - .trackDeviceStates( - AggregatedPowerStatsConfig.STATE_POWER, - AggregatedPowerStatsConfig.STATE_SCREEN) - .trackUidStates( - AggregatedPowerStatsConfig.STATE_POWER, - AggregatedPowerStatsConfig.STATE_SCREEN, - AggregatedPowerStatsConfig.STATE_PROCESS_STATE) - .setProcessor( - new CameraPowerStatsProcessor(mPowerProfile, mPowerStatsUidResolver)); - - config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_GNSS) + config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT) .trackDeviceStates( AggregatedPowerStatsConfig.STATE_POWER, AggregatedPowerStatsConfig.STATE_SCREEN) @@ -573,7 +552,8 @@ private AggregatedPowerStatsConfig createAggregatedPowerStatsConfig() { AggregatedPowerStatsConfig.STATE_SCREEN, AggregatedPowerStatsConfig.STATE_PROCESS_STATE) .setProcessor( - new GnssPowerStatsProcessor(mPowerProfile, mPowerStatsUidResolver)); + new FlashlightPowerStatsProcessor(mPowerProfile, + mPowerStatsUidResolver)); return config; } @@ -659,12 +639,6 @@ public void systemServicesReady() { BatteryConsumer.POWER_COMPONENT_FLASHLIGHT, Flags.streamlinedMiscBatteryStats()); - mStats.setPowerStatsCollectorEnabled(BatteryConsumer.POWER_COMPONENT_CAMERA, - Flags.streamlinedMiscBatteryStats()); - mBatteryUsageStatsProvider.setPowerStatsExporterEnabled( - BatteryConsumer.POWER_COMPONENT_CAMERA, - Flags.streamlinedMiscBatteryStats()); - mWorker.systemServicesReady(); mStats.systemServicesReady(mContext); mCpuWakeupStats.systemServicesReady(); diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java index 322ed864fca6c..5bae5a42d484e 100644 --- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java +++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java @@ -298,8 +298,6 @@ public void logState(Printer pw, String prefix) { private final MobileRadioPowerStatsCollector mMobileRadioPowerStatsCollector; private final WifiPowerStatsCollector mWifiPowerStatsCollector; private final BluetoothPowerStatsCollector mBluetoothPowerStatsCollector; - private final CameraPowerStatsCollector mCameraPowerStatsCollector; - private final GnssPowerStatsCollector mGnssPowerStatsCollector; private final SparseBooleanArray mPowerStatsCollectorEnabled = new SparseBooleanArray(); private final WifiPowerStatsCollector.WifiStatsRetriever mWifiStatsRetriever = new WifiPowerStatsCollector.WifiStatsRetriever() { @@ -1965,7 +1963,7 @@ private void initKernelStatsReaders() { private class PowerStatsCollectorInjector implements CpuPowerStatsCollector.Injector, MobileRadioPowerStatsCollector.Injector, WifiPowerStatsCollector.Injector, - BluetoothPowerStatsCollector.Injector, EnergyConsumerPowerStatsCollector.Injector { + BluetoothPowerStatsCollector.Injector { private PackageManager mPackageManager; private PowerStatsCollector.ConsumedEnergyRetriever mConsumedEnergyRetriever; private NetworkStatsManager mNetworkStatsManager; @@ -5448,10 +5446,7 @@ private void noteStartGpsLocked(int uid, WorkChain workChain, final int mappedUid = mapUid(uid); if (mGpsNesting == 0) { mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, - HistoryItem.STATE_GPS_ON_FLAG, uid, "gnss"); - if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_GNSS)) { - mGnssPowerStatsCollector.schedule(); - } + HistoryItem.STATE_GPS_ON_FLAG); } mGpsNesting++; @@ -5470,14 +5465,11 @@ private void noteStopGpsLocked(int uid, WorkChain workChain, mGpsNesting--; if (mGpsNesting == 0) { mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, - HistoryItem.STATE_GPS_ON_FLAG, uid, "gnss"); + HistoryItem.STATE_GPS_ON_FLAG); mHistory.recordGpsSignalQualityEvent(elapsedRealtimeMs, uptimeMs, GPS_SIGNAL_QUALITY_NONE); stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs); mGpsSignalQualityBin = -1; - if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_GNSS)) { - mGnssPowerStatsCollector.schedule(); - } } mFrameworkStatsLogger.gpsScanStateChanged(mapIsolatedUid(uid), workChain, /* on */ false); @@ -6660,17 +6652,13 @@ public void noteCameraOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); if (mCameraOnNesting++ == 0) { mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, - HistoryItem.STATE2_CAMERA_FLAG, uid, "camera"); + HistoryItem.STATE2_CAMERA_FLAG); mCameraOnTimer.startRunningLocked(elapsedRealtimeMs); } getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) .noteCameraTurnedOnLocked(elapsedRealtimeMs); - if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CAMERA)) { - mCameraPowerStatsCollector.schedule(); - } else { - scheduleSyncExternalStatsLocked("camera-on", ExternalStatsSync.UPDATE_CAMERA); - } + scheduleSyncExternalStatsLocked("camera-on", ExternalStatsSync.UPDATE_CAMERA); } @GuardedBy("this") @@ -6681,17 +6669,13 @@ public void noteCameraOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) uid = mapUid(uid); if (--mCameraOnNesting == 0) { mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, - HistoryItem.STATE2_CAMERA_FLAG, uid, "camera"); + HistoryItem.STATE2_CAMERA_FLAG); mCameraOnTimer.stopRunningLocked(elapsedRealtimeMs); } getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) .noteCameraTurnedOffLocked(elapsedRealtimeMs); - if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CAMERA)) { - mCameraPowerStatsCollector.schedule(); - } else { - scheduleSyncExternalStatsLocked("camera-off", ExternalStatsSync.UPDATE_CAMERA); - } + scheduleSyncExternalStatsLocked("camera-off", ExternalStatsSync.UPDATE_CAMERA); } @GuardedBy("this") @@ -11297,12 +11281,6 @@ public BatteryStatsImpl(@NonNull BatteryStatsConfig config, @NonNull Clock clock mPowerStatsCollectorInjector); mBluetoothPowerStatsCollector.addConsumer(this::recordPowerStats); - mCameraPowerStatsCollector = new CameraPowerStatsCollector(mPowerStatsCollectorInjector); - mCameraPowerStatsCollector.addConsumer(this::recordPowerStats); - - mGnssPowerStatsCollector = new GnssPowerStatsCollector(mPowerStatsCollectorInjector); - mGnssPowerStatsCollector.addConsumer(this::recordPowerStats); - mStartCount++; initTimersAndCounters(); mOnBattery = mOnBatteryInternal = false; @@ -14725,14 +14703,6 @@ public void onSystemReady(Context context) { mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_BLUETOOTH)); mBluetoothPowerStatsCollector.schedule(); - mCameraPowerStatsCollector.setEnabled( - mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CAMERA)); - mCameraPowerStatsCollector.schedule(); - - mGnssPowerStatsCollector.setEnabled( - mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_GNSS)); - mGnssPowerStatsCollector.schedule(); - mSystemReady = true; } @@ -14751,10 +14721,6 @@ PowerStatsCollector getPowerStatsCollector( return mWifiPowerStatsCollector; case BatteryConsumer.POWER_COMPONENT_BLUETOOTH: return mBluetoothPowerStatsCollector; - case BatteryConsumer.POWER_COMPONENT_CAMERA: - return mCameraPowerStatsCollector; - case BatteryConsumer.POWER_COMPONENT_GNSS: - return mGnssPowerStatsCollector; } return null; } @@ -16292,8 +16258,6 @@ public void schedulePowerStatsSampleCollection() { mMobileRadioPowerStatsCollector.forceSchedule(); mWifiPowerStatsCollector.forceSchedule(); mBluetoothPowerStatsCollector.forceSchedule(); - mCameraPowerStatsCollector.forceSchedule(); - mGnssPowerStatsCollector.forceSchedule(); } /** @@ -16314,8 +16278,6 @@ public void dumpStatsSample(PrintWriter pw) { mMobileRadioPowerStatsCollector.collectAndDump(pw); mWifiPowerStatsCollector.collectAndDump(pw); mBluetoothPowerStatsCollector.collectAndDump(pw); - mCameraPowerStatsCollector.collectAndDump(pw); - mGnssPowerStatsCollector.collectAndDump(pw); } private final Runnable mWriteAsyncRunnable = () -> { diff --git a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java index ce0ee39d0a536..ba6e4a96ddc4b 100644 --- a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java +++ b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java @@ -95,12 +95,8 @@ private List getPowerCalculators() { } mPowerCalculators.add(new SensorPowerCalculator( mContext.getSystemService(SensorManager.class))); - if (!mPowerStatsExporterEnabled.get(BatteryConsumer.POWER_COMPONENT_GNSS)) { - mPowerCalculators.add(new GnssPowerCalculator(mPowerProfile)); - } - if (!mPowerStatsExporterEnabled.get(BatteryConsumer.POWER_COMPONENT_CAMERA)) { - mPowerCalculators.add(new CameraPowerCalculator(mPowerProfile)); - } + mPowerCalculators.add(new GnssPowerCalculator(mPowerProfile)); + mPowerCalculators.add(new CameraPowerCalculator(mPowerProfile)); if (!mPowerStatsExporterEnabled.get(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT)) { mPowerCalculators.add(new FlashlightPowerCalculator(mPowerProfile)); } diff --git a/services/core/java/com/android/server/power/stats/BinaryStatePowerStatsProcessor.java b/services/core/java/com/android/server/power/stats/BinaryStatePowerStatsProcessor.java index 599e63d129061..490bd5e77c7bd 100644 --- a/services/core/java/com/android/server/power/stats/BinaryStatePowerStatsProcessor.java +++ b/services/core/java/com/android/server/power/stats/BinaryStatePowerStatsProcessor.java @@ -51,7 +51,7 @@ abstract class BinaryStatePowerStatsProcessor extends PowerStatsProcessor { private long mLastUpdateTimestamp; private PowerStats.Descriptor mDescriptor; - private final BinaryStatePowerStatsLayout mStatsLayout; + private final BinaryStatePowerStatsLayout mStatsLayout = new BinaryStatePowerStatsLayout(); private PowerStats mPowerStats; private PowerEstimationPlan mPlan; private long[] mTmpDeviceStatsArray; @@ -59,17 +59,9 @@ abstract class BinaryStatePowerStatsProcessor extends PowerStatsProcessor { BinaryStatePowerStatsProcessor(int powerComponentId, PowerStatsUidResolver uidResolver, double averagePowerMilliAmp) { - this(powerComponentId, uidResolver, averagePowerMilliAmp, - new BinaryStatePowerStatsLayout()); - } - - BinaryStatePowerStatsProcessor(int powerComponentId, - PowerStatsUidResolver uidResolver, double averagePowerMilliAmp, - BinaryStatePowerStatsLayout statsLayout) { mPowerComponentId = powerComponentId; mUsageBasedPowerEstimator = new UsageBasedPowerEstimator(averagePowerMilliAmp); mUidResolver = uidResolver; - mStatsLayout = statsLayout; } protected abstract @BinaryState int getBinaryState(BatteryStats.HistoryItem item); @@ -115,7 +107,7 @@ void noteStateChange(PowerComponentAggregatedPowerStats stats, mInitiatingUid = mUidResolver.mapUid(item.eventTag.uid); } } else { - recordUsageDuration(mPowerStats, mInitiatingUid, item.time); + recordUsageDuration(item.time); mInitiatingUid = Process.INVALID_UID; if (!mEnergyConsumerSupported) { flushPowerStats(stats, item.time); @@ -125,16 +117,20 @@ void noteStateChange(PowerComponentAggregatedPowerStats stats, mLastState = state; } - protected void recordUsageDuration(PowerStats powerStats, int uid, long time) { + private void recordUsageDuration(long time) { + if (mLastState == STATE_OFF) { + return; + } + long durationMs = time - mLastStateTimestamp; mStatsLayout.setUsageDuration(mPowerStats.stats, mStatsLayout.getUsageDuration(mPowerStats.stats) + durationMs); - if (uid != Process.INVALID_UID) { - long[] uidStats = mPowerStats.uidStats.get(uid); + if (mInitiatingUid != Process.INVALID_UID) { + long[] uidStats = mPowerStats.uidStats.get(mInitiatingUid); if (uidStats == null) { uidStats = new long[mDescriptor.uidStatsArrayLength]; - mPowerStats.uidStats.put(uid, uidStats); + mPowerStats.uidStats.put(mInitiatingUid, uidStats); mStatsLayout.setUidUsageDuration(uidStats, durationMs); } else { mStatsLayout.setUsageDuration(mPowerStats.stats, @@ -147,11 +143,7 @@ protected void recordUsageDuration(PowerStats powerStats, int uid, long time) { void addPowerStats(PowerComponentAggregatedPowerStats stats, PowerStats powerStats, long timestampMs) { ensureInitialized(); - - if (mLastState == STATE_ON) { - recordUsageDuration(mPowerStats, mInitiatingUid, timestampMs); - } - + recordUsageDuration(timestampMs); long consumedEnergy = mStatsLayout.getConsumedEnergy(powerStats.stats, 0); if (consumedEnergy != BatteryStats.POWER_DATA_UNAVAILABLE) { mEnergyConsumerSupported = true; @@ -177,16 +169,14 @@ private static class Intermediates { @Override void finish(PowerComponentAggregatedPowerStats stats, long timestampMs) { - if (mLastState == STATE_ON) { - recordUsageDuration(mPowerStats, mInitiatingUid, timestampMs); - } + recordUsageDuration(timestampMs); flushPowerStats(stats, timestampMs); if (mPlan == null) { mPlan = new PowerEstimationPlan(stats.getConfig()); } - computeDevicePowerEstimates(stats, mPlan, mEnergyConsumerSupported); + computeDevicePowerEstimates(stats); combineDevicePowerEstimates(stats); List uids = new ArrayList<>(); @@ -196,10 +186,9 @@ void finish(PowerComponentAggregatedPowerStats stats, long timestampMs) { computeUidPowerEstimates(stats, uids); } - protected void computeDevicePowerEstimates(PowerComponentAggregatedPowerStats stats, - PowerEstimationPlan plan, boolean energyConsumerSupported) { - for (int i = plan.deviceStateEstimations.size() - 1; i >= 0; i--) { - DeviceStateEstimation estimation = plan.deviceStateEstimations.get(i); + private void computeDevicePowerEstimates(PowerComponentAggregatedPowerStats stats) { + for (int i = mPlan.deviceStateEstimations.size() - 1; i >= 0; i--) { + DeviceStateEstimation estimation = mPlan.deviceStateEstimations.get(i); if (!stats.getDeviceStats(mTmpDeviceStatsArray, estimation.stateValues)) { continue; } @@ -207,7 +196,7 @@ protected void computeDevicePowerEstimates(PowerComponentAggregatedPowerStats st long duration = mStatsLayout.getUsageDuration(mTmpDeviceStatsArray); if (duration > 0) { double power; - if (energyConsumerSupported) { + if (mEnergyConsumerSupported) { power = uCtoMah(mStatsLayout.getConsumedEnergy(mTmpDeviceStatsArray, 0)); } else { power = mUsageBasedPowerEstimator.calculatePower(duration); diff --git a/services/core/java/com/android/server/power/stats/CameraPowerStatsCollector.java b/services/core/java/com/android/server/power/stats/CameraPowerStatsCollector.java deleted file mode 100644 index 8705bd53a3b71..0000000000000 --- a/services/core/java/com/android/server/power/stats/CameraPowerStatsCollector.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.power.stats; - -import android.hardware.power.stats.EnergyConsumerType; -import android.os.BatteryConsumer; - -public class CameraPowerStatsCollector extends EnergyConsumerPowerStatsCollector { - - CameraPowerStatsCollector(Injector injector) { - super(injector, BatteryConsumer.POWER_COMPONENT_CAMERA, - BatteryConsumer.powerComponentIdToString(BatteryConsumer.POWER_COMPONENT_CAMERA), - EnergyConsumerType.CAMERA, /* energy consumer name */ null, - new BinaryStatePowerStatsLayout()); - } -} diff --git a/services/core/java/com/android/server/power/stats/CameraPowerStatsProcessor.java b/services/core/java/com/android/server/power/stats/CameraPowerStatsProcessor.java deleted file mode 100644 index 15c3eb8c00639..0000000000000 --- a/services/core/java/com/android/server/power/stats/CameraPowerStatsProcessor.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.power.stats; - -import android.os.BatteryConsumer; -import android.os.BatteryStats; - -import com.android.internal.os.PowerProfile; - -public class CameraPowerStatsProcessor extends BinaryStatePowerStatsProcessor { - public CameraPowerStatsProcessor(PowerProfile powerProfile, - PowerStatsUidResolver uidResolver) { - super(BatteryConsumer.POWER_COMPONENT_CAMERA, uidResolver, - powerProfile.getAveragePower(PowerProfile.POWER_CAMERA)); - } - - @Override - protected @BinaryState int getBinaryState(BatteryStats.HistoryItem item) { - return (item.states2 & BatteryStats.HistoryItem.STATE2_CAMERA_FLAG) != 0 - ? STATE_ON - : STATE_OFF; - } -} diff --git a/services/core/java/com/android/server/power/stats/EnergyConsumerPowerStatsCollector.java b/services/core/java/com/android/server/power/stats/EnergyConsumerPowerStatsCollector.java deleted file mode 100644 index 2021f85b0210e..0000000000000 --- a/services/core/java/com/android/server/power/stats/EnergyConsumerPowerStatsCollector.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.power.stats; - -import android.hardware.power.stats.EnergyConsumerType; -import android.os.Handler; -import android.os.PersistableBundle; -import android.util.Slog; - -import com.android.internal.os.Clock; -import com.android.internal.os.PowerStats; - -import java.util.function.IntSupplier; - -public class EnergyConsumerPowerStatsCollector extends PowerStatsCollector { - private static final String TAG = "CameraPowerStatsCollector"; - - private static final long CAMERA_ACTIVITY_REQUEST_TIMEOUT = 20000; - - private static final long ENERGY_UNSPECIFIED = -1; - - interface Injector { - Handler getHandler(); - Clock getClock(); - PowerStatsUidResolver getUidResolver(); - long getPowerStatsCollectionThrottlePeriod(String powerComponentName); - ConsumedEnergyRetriever getConsumedEnergyRetriever(); - IntSupplier getVoltageSupplier(); - } - - private final Injector mInjector; - private final int mPowerComponentId; - private final String mPowerComponentName; - private final int mEnergyConsumerType; - private final String mEnergyConsumerName; - - private final BinaryStatePowerStatsLayout mLayout; - private boolean mIsInitialized; - - private PowerStats mPowerStats; - private ConsumedEnergyRetriever mConsumedEnergyRetriever; - private IntSupplier mVoltageSupplier; - private int[] mEnergyConsumerIds = new int[0]; - private long mLastConsumedEnergyUws = ENERGY_UNSPECIFIED; - private int mLastVoltageMv; - private long mLastUpdateTimestamp; - private boolean mFirstCollection = true; - - EnergyConsumerPowerStatsCollector(Injector injector, int powerComponentId, - String powerComponentName, @EnergyConsumerType int energyConsumerType, - String energyConsumerName, BinaryStatePowerStatsLayout statsLayout) { - super(injector.getHandler(), - injector.getPowerStatsCollectionThrottlePeriod(powerComponentName), - injector.getUidResolver(), injector.getClock()); - mInjector = injector; - mPowerComponentId = powerComponentId; - mPowerComponentName = powerComponentName; - mEnergyConsumerType = energyConsumerType; - mEnergyConsumerName = energyConsumerName; - mLayout = statsLayout; - } - - private boolean ensureInitialized() { - if (mIsInitialized) { - return true; - } - - if (!isEnabled()) { - return false; - } - - mConsumedEnergyRetriever = mInjector.getConsumedEnergyRetriever(); - mVoltageSupplier = mInjector.getVoltageSupplier(); - mEnergyConsumerIds = mConsumedEnergyRetriever.getEnergyConsumerIds(mEnergyConsumerType, - mEnergyConsumerName); - - PersistableBundle extras = new PersistableBundle(); - mLayout.toExtras(extras); - PowerStats.Descriptor powerStatsDescriptor = new PowerStats.Descriptor( - mPowerComponentId, mPowerComponentName, mLayout.getDeviceStatsArrayLength(), - null, 0, mLayout.getUidStatsArrayLength(), - extras); - mPowerStats = new PowerStats(powerStatsDescriptor); - - mIsInitialized = true; - return true; - } - - @Override - protected PowerStats collectStats() { - if (!ensureInitialized()) { - return null; - } - - if (mEnergyConsumerIds.length == 0) { - return null; - } - - long consumedEnergy = 0; - int voltageMv = mVoltageSupplier.getAsInt(); - if (voltageMv <= 0) { - Slog.wtf(TAG, "Unexpected battery voltage (" + voltageMv - + " mV) when querying energy consumers"); - } else { - long[] energyUws = mConsumedEnergyRetriever.getConsumedEnergyUws(mEnergyConsumerIds); - if (energyUws != null) { - for (int i = energyUws.length - 1; i >= 0; i--) { - if (energyUws[i] != ENERGY_UNSPECIFIED) { - consumedEnergy += energyUws[i]; - } - } - } - } - - long energyDelta = mLastConsumedEnergyUws != ENERGY_UNSPECIFIED - ? consumedEnergy - mLastConsumedEnergyUws : 0; - mLastConsumedEnergyUws = consumedEnergy; - if (energyDelta < 0) { - // Likely, restart of powerstats HAL - energyDelta = 0; - } - - if (energyDelta == 0 && !mFirstCollection) { - return null; - } - - int averageVoltage = mLastVoltageMv != 0 ? (mLastVoltageMv + voltageMv) / 2 : voltageMv; - mLastVoltageMv = voltageMv; - mLayout.setConsumedEnergy(mPowerStats.stats, 0, uJtoUc(energyDelta, averageVoltage)); - long timestamp = mClock.elapsedRealtime(); - mPowerStats.durationMs = timestamp - mLastUpdateTimestamp; - mLastUpdateTimestamp = timestamp; - mFirstCollection = false; - return mPowerStats; - } -} diff --git a/services/core/java/com/android/server/power/stats/GnssPowerStatsCollector.java b/services/core/java/com/android/server/power/stats/GnssPowerStatsCollector.java deleted file mode 100644 index 168a8749b34c5..0000000000000 --- a/services/core/java/com/android/server/power/stats/GnssPowerStatsCollector.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.power.stats; - -import android.hardware.power.stats.EnergyConsumerType; -import android.os.BatteryConsumer; - -public class GnssPowerStatsCollector extends EnergyConsumerPowerStatsCollector { - - GnssPowerStatsCollector(Injector injector) { - super(injector, BatteryConsumer.POWER_COMPONENT_GNSS, - BatteryConsumer.powerComponentIdToString(BatteryConsumer.POWER_COMPONENT_GNSS), - EnergyConsumerType.GNSS, /* energy consumer name */ null, - new GnssPowerStatsLayout()); - } -} diff --git a/services/core/java/com/android/server/power/stats/GnssPowerStatsLayout.java b/services/core/java/com/android/server/power/stats/GnssPowerStatsLayout.java deleted file mode 100644 index 9a1317d2420c4..0000000000000 --- a/services/core/java/com/android/server/power/stats/GnssPowerStatsLayout.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.power.stats; - -import android.location.GnssSignalQuality; -import android.os.PersistableBundle; - -class GnssPowerStatsLayout extends BinaryStatePowerStatsLayout { - private static final String EXTRA_DEVICE_TIME_SIGNAL_LEVEL_POSITION = "dt-sig"; - private static final String EXTRA_UID_TIME_SIGNAL_LEVEL_POSITION = "ut-sig"; - - private int mDeviceSignalLevelTimePosition; - private int mUidSignalLevelTimePosition; - - GnssPowerStatsLayout() { - mDeviceSignalLevelTimePosition = addDeviceSection( - GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS, "level"); - mUidSignalLevelTimePosition = addUidSection( - GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS, "level"); - } - - @Override - public void fromExtras(PersistableBundle extras) { - super.fromExtras(extras); - mDeviceSignalLevelTimePosition = extras.getInt(EXTRA_DEVICE_TIME_SIGNAL_LEVEL_POSITION); - mUidSignalLevelTimePosition = extras.getInt(EXTRA_UID_TIME_SIGNAL_LEVEL_POSITION); - } - - @Override - public void toExtras(PersistableBundle extras) { - super.toExtras(extras); - extras.putInt(EXTRA_DEVICE_TIME_SIGNAL_LEVEL_POSITION, mDeviceSignalLevelTimePosition); - extras.putInt(EXTRA_UID_TIME_SIGNAL_LEVEL_POSITION, mUidSignalLevelTimePosition); - } - - public void setDeviceSignalLevelTime(long[] stats, int signalLevel, long durationMillis) { - stats[mDeviceSignalLevelTimePosition + signalLevel] = durationMillis; - } - - public long getDeviceSignalLevelTime(long[] stats, int signalLevel) { - return stats[mDeviceSignalLevelTimePosition + signalLevel]; - } - - public void setUidSignalLevelTime(long[] stats, int signalLevel, long durationMillis) { - stats[mUidSignalLevelTimePosition + signalLevel] = durationMillis; - } - - public long getUidSignalLevelTime(long[] stats, int signalLevel) { - return stats[mUidSignalLevelTimePosition + signalLevel]; - } -} diff --git a/services/core/java/com/android/server/power/stats/GnssPowerStatsProcessor.java b/services/core/java/com/android/server/power/stats/GnssPowerStatsProcessor.java deleted file mode 100644 index 572bde9b9266c..0000000000000 --- a/services/core/java/com/android/server/power/stats/GnssPowerStatsProcessor.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.power.stats; - -import android.location.GnssSignalQuality; -import android.os.BatteryConsumer; -import android.os.BatteryStats; -import android.os.Process; - -import com.android.internal.os.PowerProfile; -import com.android.internal.os.PowerStats; - -import java.util.Arrays; - -public class GnssPowerStatsProcessor extends BinaryStatePowerStatsProcessor { - private int mGnssSignalLevel = GnssSignalQuality.GNSS_SIGNAL_QUALITY_UNKNOWN; - private long mGnssSignalLevelTimestamp; - private final long[] mGnssSignalDurations = - new long[GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS]; - private static final GnssPowerStatsLayout sStatsLayout = new GnssPowerStatsLayout(); - private final UsageBasedPowerEstimator[] mSignalLevelEstimators = - new UsageBasedPowerEstimator[GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS]; - private final boolean mUseSignalLevelEstimators; - private long[] mTmpDeviceStatsArray; - - public GnssPowerStatsProcessor(PowerProfile powerProfile, PowerStatsUidResolver uidResolver) { - super(BatteryConsumer.POWER_COMPONENT_GNSS, uidResolver, - powerProfile.getAveragePower(PowerProfile.POWER_GPS_ON), - sStatsLayout); - - boolean useSignalLevelEstimators = false; - for (int level = 0; level < GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS; level++) { - double power = powerProfile.getAveragePower( - PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, level); - if (power != 0) { - useSignalLevelEstimators = true; - } - mSignalLevelEstimators[level] = new UsageBasedPowerEstimator(power); - } - mUseSignalLevelEstimators = useSignalLevelEstimators; - } - - @Override - protected @BinaryState int getBinaryState(BatteryStats.HistoryItem item) { - if ((item.states & BatteryStats.HistoryItem.STATE_GPS_ON_FLAG) == 0) { - mGnssSignalLevel = GnssSignalQuality.GNSS_SIGNAL_QUALITY_UNKNOWN; - return STATE_OFF; - } - - noteGnssSignalLevel(item); - return STATE_ON; - } - - private void noteGnssSignalLevel(BatteryStats.HistoryItem item) { - int signalLevel = (item.states2 & BatteryStats.HistoryItem.STATE2_GPS_SIGNAL_QUALITY_MASK) - >> BatteryStats.HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT; - if (signalLevel >= GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS) { - signalLevel = GnssSignalQuality.GNSS_SIGNAL_QUALITY_UNKNOWN; - } - if (signalLevel == mGnssSignalLevel) { - return; - } - - if (mGnssSignalLevel != GnssSignalQuality.GNSS_SIGNAL_QUALITY_UNKNOWN) { - mGnssSignalDurations[mGnssSignalLevel] += item.time - mGnssSignalLevelTimestamp; - } - mGnssSignalLevel = signalLevel; - mGnssSignalLevelTimestamp = item.time; - } - - @Override - protected void recordUsageDuration(PowerStats powerStats, int uid, long time) { - super.recordUsageDuration(powerStats, uid, time); - - if (mGnssSignalLevel != GnssSignalQuality.GNSS_SIGNAL_QUALITY_UNKNOWN) { - mGnssSignalDurations[mGnssSignalLevel] += time - mGnssSignalLevelTimestamp; - } else if (mUseSignalLevelEstimators) { - // Default GNSS signal quality to GOOD for the purposes of power attribution - mGnssSignalDurations[GnssSignalQuality.GNSS_SIGNAL_QUALITY_GOOD] += - time - mGnssSignalLevelTimestamp; - } - - for (int level = 0; level < GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS; level++) { - long duration = mGnssSignalDurations[level]; - sStatsLayout.setDeviceSignalLevelTime(powerStats.stats, level, duration); - if (uid != Process.INVALID_UID) { - long[] uidStats = powerStats.uidStats.get(uid); - if (uidStats == null) { - uidStats = new long[powerStats.descriptor.uidStatsArrayLength]; - powerStats.uidStats.put(uid, uidStats); - sStatsLayout.setUidSignalLevelTime(uidStats, level, duration); - } else { - sStatsLayout.setUidSignalLevelTime(uidStats, level, - sStatsLayout.getUidSignalLevelTime(uidStats, level) + duration); - } - } - } - - mGnssSignalLevelTimestamp = time; - Arrays.fill(mGnssSignalDurations, 0); - } - - protected void computeDevicePowerEstimates(PowerComponentAggregatedPowerStats stats, - PowerEstimationPlan plan, boolean energyConsumerSupported) { - if (!mUseSignalLevelEstimators || energyConsumerSupported) { - super.computeDevicePowerEstimates(stats, plan, energyConsumerSupported); - return; - } - - if (mTmpDeviceStatsArray == null) { - mTmpDeviceStatsArray = new long[stats.getPowerStatsDescriptor().statsArrayLength]; - } - - for (int i = plan.deviceStateEstimations.size() - 1; i >= 0; i--) { - DeviceStateEstimation estimation = plan.deviceStateEstimations.get(i); - if (!stats.getDeviceStats(mTmpDeviceStatsArray, estimation.stateValues)) { - continue; - } - - double power = 0; - for (int level = 0; level < GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS; level++) { - long duration = sStatsLayout.getDeviceSignalLevelTime(mTmpDeviceStatsArray, level); - power += mSignalLevelEstimators[level].calculatePower(duration); - } - sStatsLayout.setDevicePowerEstimate(mTmpDeviceStatsArray, power); - stats.setDeviceStats(estimation.stateValues, mTmpDeviceStatsArray); - } - } -} diff --git a/services/core/java/com/android/server/power/stats/PowerStatsCollector.java b/services/core/java/com/android/server/power/stats/PowerStatsCollector.java index d442c61ee9239..b82c0215013c3 100644 --- a/services/core/java/com/android/server/power/stats/PowerStatsCollector.java +++ b/services/core/java/com/android/server/power/stats/PowerStatsCollector.java @@ -231,14 +231,10 @@ protected static long uJtoUc(long deltaEnergyUj, int avgVoltageMv) { } interface ConsumedEnergyRetriever { - int[] getEnergyConsumerIds(@EnergyConsumerType int energyConsumerType, String name); + int[] getEnergyConsumerIds(@EnergyConsumerType int energyConsumerType); @Nullable long[] getConsumedEnergyUws(int[] energyConsumerIds); - - default int[] getEnergyConsumerIds(@EnergyConsumerType int energyConsumerType) { - return getEnergyConsumerIds(energyConsumerType, null); - } } static class ConsumedEnergyRetrieverImpl implements ConsumedEnergyRetriever { @@ -249,7 +245,7 @@ static class ConsumedEnergyRetrieverImpl implements ConsumedEnergyRetriever { } @Override - public int[] getEnergyConsumerIds(int energyConsumerType, String name) { + public int[] getEnergyConsumerIds(int energyConsumerType) { if (mPowerStatsInternal == null) { return new int[0]; } @@ -261,8 +257,7 @@ public int[] getEnergyConsumerIds(int energyConsumerType, String name) { List energyConsumers = new ArrayList<>(); for (EnergyConsumer energyConsumer : energyConsumerInfo) { - if (energyConsumer.type == energyConsumerType - && (name == null || name.equals(energyConsumer.name))) { + if (energyConsumer.type == energyConsumerType) { energyConsumers.add(energyConsumer); } } diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java index a3f0770ec8baf..976cc18127f09 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java @@ -91,7 +91,7 @@ public void testParcelability_smallNumberOfUids() { final Parcel parcel = Parcel.obtain(); parcel.writeParcelable(outBatteryUsageStats, 0); - assertThat(parcel.dataSize()).isLessThan(12000); + assertThat(parcel.dataSize()).isLessThan(10000); parcel.setDataPosition(0); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerStatsTest.java deleted file mode 100644 index 36deb08de8dea..0000000000000 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerStatsTest.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.power.stats; - -import static android.os.BatteryConsumer.PROCESS_STATE_BACKGROUND; -import static android.os.BatteryConsumer.PROCESS_STATE_CACHED; -import static android.os.BatteryConsumer.PROCESS_STATE_FOREGROUND; -import static android.os.BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE; - -import static com.android.server.power.stats.AggregatedPowerStatsConfig.POWER_STATE_OTHER; -import static com.android.server.power.stats.AggregatedPowerStatsConfig.SCREEN_STATE_ON; -import static com.android.server.power.stats.AggregatedPowerStatsConfig.SCREEN_STATE_OTHER; -import static com.android.server.power.stats.AggregatedPowerStatsConfig.STATE_POWER; -import static com.android.server.power.stats.AggregatedPowerStatsConfig.STATE_PROCESS_STATE; -import static com.android.server.power.stats.AggregatedPowerStatsConfig.STATE_SCREEN; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.when; - -import android.hardware.power.stats.EnergyConsumerType; -import android.os.BatteryConsumer; -import android.os.BatteryStats; -import android.os.Handler; -import android.os.Process; -import android.platform.test.ravenwood.RavenwoodRule; - -import com.android.internal.os.Clock; -import com.android.internal.os.MonotonicClock; -import com.android.internal.os.PowerProfile; -import com.android.internal.os.PowerStats; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.util.function.IntSupplier; - -public class CameraPowerStatsTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - - @Rule(order = 1) - public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() - .setAveragePower(PowerProfile.POWER_CAMERA, 100.0) - .initMeasuredEnergyStatsLocked(); - - private static final double PRECISION = 0.00001; - private static final int APP_UID1 = Process.FIRST_APPLICATION_UID + 42; - private static final int APP_UID2 = Process.FIRST_APPLICATION_UID + 101; - private static final int VOLTAGE_MV = 3500; - private static final int ENERGY_CONSUMER_ID = 777; - - private final PowerStatsUidResolver mUidResolver = new PowerStatsUidResolver(); - @Mock - private PowerStatsCollector.ConsumedEnergyRetriever mConsumedEnergyRetriever; - - EnergyConsumerPowerStatsCollector.Injector mInjector = - new EnergyConsumerPowerStatsCollector.Injector() { - @Override - public Handler getHandler() { - return mStatsRule.getHandler(); - } - - @Override - public Clock getClock() { - return mStatsRule.getMockClock(); - } - - @Override - public PowerStatsUidResolver getUidResolver() { - return mUidResolver; - } - - @Override - public long getPowerStatsCollectionThrottlePeriod(String powerComponentName) { - return 0; - } - - @Override - public PowerStatsCollector.ConsumedEnergyRetriever getConsumedEnergyRetriever() { - return mConsumedEnergyRetriever; - } - - @Override - public IntSupplier getVoltageSupplier() { - return () -> VOLTAGE_MV; - } - }; - - private MonotonicClock mMonotonicClock; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - mMonotonicClock = new MonotonicClock(0, mStatsRule.getMockClock()); - } - - @Test - public void energyConsumerModel() { - when(mConsumedEnergyRetriever.getEnergyConsumerIds(EnergyConsumerType.CAMERA, null)) - .thenReturn(new int[]{ENERGY_CONSUMER_ID}); - CameraPowerStatsProcessor processor = new CameraPowerStatsProcessor( - mStatsRule.getPowerProfile(), mUidResolver); - - PowerComponentAggregatedPowerStats stats = createAggregatedPowerStats(processor); - - CameraPowerStatsCollector collector = new CameraPowerStatsCollector(mInjector); - collector.addConsumer( - powerStats -> { - processor.addPowerStats(stats, powerStats, mMonotonicClock.monotonicTime()); - }); - collector.setEnabled(true); - - // Establish a baseline - when(mConsumedEnergyRetriever.getConsumedEnergyUws(new int[]{ENERGY_CONSUMER_ID})) - .thenReturn(new long[]{uCtoUj(10000)}); - collector.collectAndDeliverStats(); - - processor.noteStateChange(stats, buildHistoryItem(0, true, APP_UID1)); - - // Turn the screen off after 2.5 seconds - stats.setState(STATE_SCREEN, SCREEN_STATE_OTHER, 2500); - stats.setUidState(APP_UID1, STATE_PROCESS_STATE, PROCESS_STATE_BACKGROUND, 2500); - stats.setUidState(APP_UID1, STATE_PROCESS_STATE, PROCESS_STATE_FOREGROUND_SERVICE, 5000); - - processor.noteStateChange(stats, buildHistoryItem(6000, false, APP_UID1)); - - when(mConsumedEnergyRetriever.getConsumedEnergyUws(new int[]{ENERGY_CONSUMER_ID})) - .thenReturn(new long[]{uCtoUj(2_170_000)}); - collector.collectAndDeliverStats(); - - processor.noteStateChange(stats, buildHistoryItem(7000, true, APP_UID2)); - - mStatsRule.setTime(11_000, 11_000); - when(mConsumedEnergyRetriever.getConsumedEnergyUws(new int[]{ENERGY_CONSUMER_ID})) - .thenReturn(new long[]{uCtoUj(3_610_000)}); - collector.collectAndDeliverStats(); - - processor.finish(stats, 11_000); - - PowerStats.Descriptor descriptor = stats.getPowerStatsDescriptor(); - BinaryStatePowerStatsLayout statsLayout = new BinaryStatePowerStatsLayout(); - statsLayout.fromExtras(descriptor.extras); - - // Total estimated power = 3,600,000 uC = 1.0 mAh - // of which 3,000,000 is distributed: - // Screen-on - 2500/6000 * 2160000 = 900000 uC = 0.25 mAh - // Screen-off - 3500/6000 * 2160000 = 1260000 uC = 0.35 mAh - // and 600,000 was fully with screen off: - // Screen-off - 1440000 uC = 0.4 mAh - long[] deviceStats = new long[descriptor.statsArrayLength]; - stats.getDeviceStats(deviceStats, states(POWER_STATE_OTHER, SCREEN_STATE_ON)); - assertThat(statsLayout.getDevicePowerEstimate(deviceStats)) - .isWithin(PRECISION).of(0.25); - - stats.getDeviceStats(deviceStats, states(POWER_STATE_OTHER, SCREEN_STATE_OTHER)); - assertThat(statsLayout.getDevicePowerEstimate(deviceStats)) - .isWithin(PRECISION).of(0.35 + 0.4); - - // UID1 = - // 2,160,000 uC = 0.6 mAh - // split between three different states - // fg screen-on: 2500/6000 - // bg screen-off: 2500/6000 - // fgs screen-off: 1000/6000 - double expectedPower1 = 0.6; - long[] uidStats = new long[descriptor.uidStatsArrayLength]; - stats.getUidStats(uidStats, APP_UID1, - states(POWER_STATE_OTHER, SCREEN_STATE_ON, PROCESS_STATE_FOREGROUND)); - assertThat(statsLayout.getUidPowerEstimate(uidStats)) - .isWithin(PRECISION).of(expectedPower1 * 2500 / 6000); - - - stats.getUidStats(uidStats, APP_UID1, - states(POWER_STATE_OTHER, SCREEN_STATE_OTHER, PROCESS_STATE_BACKGROUND)); - assertThat(statsLayout.getUidPowerEstimate(uidStats)) - .isWithin(PRECISION).of(expectedPower1 * 2500 / 6000); - - stats.getUidStats(uidStats, APP_UID1, - states(POWER_STATE_OTHER, SCREEN_STATE_OTHER, PROCESS_STATE_FOREGROUND_SERVICE)); - assertThat(statsLayout.getUidPowerEstimate(uidStats)) - .isWithin(PRECISION).of(expectedPower1 * 1000 / 6000); - - // UID2 = - // 1440000 mA-ms = 0.4 mAh - // all in the same state - double expectedPower2 = 0.4; - stats.getUidStats(uidStats, APP_UID2, - states(POWER_STATE_OTHER, SCREEN_STATE_OTHER, PROCESS_STATE_CACHED)); - assertThat(statsLayout.getUidPowerEstimate(uidStats)) - .isWithin(PRECISION).of(expectedPower2); - - stats.getUidStats(uidStats, APP_UID2, - states(POWER_STATE_OTHER, SCREEN_STATE_ON, PROCESS_STATE_CACHED)); - assertThat(statsLayout.getUidPowerEstimate(uidStats)) - .isWithin(PRECISION).of(0); - } - - private BatteryStats.HistoryItem buildHistoryItem(int timestamp, boolean stateOn, - int uid) { - mStatsRule.setTime(timestamp, timestamp); - BatteryStats.HistoryItem historyItem = new BatteryStats.HistoryItem(); - historyItem.time = mMonotonicClock.monotonicTime(); - historyItem.states2 = stateOn ? BatteryStats.HistoryItem.STATE2_CAMERA_FLAG : 0; - if (stateOn) { - historyItem.eventCode = BatteryStats.HistoryItem.EVENT_STATE_CHANGE - | BatteryStats.HistoryItem.EVENT_FLAG_START; - } else { - historyItem.eventCode = BatteryStats.HistoryItem.EVENT_STATE_CHANGE - | BatteryStats.HistoryItem.EVENT_FLAG_FINISH; - } - historyItem.eventTag = historyItem.localEventTag; - historyItem.eventTag.uid = uid; - historyItem.eventTag.string = "camera"; - return historyItem; - } - - private int[] states(int... states) { - return states; - } - - private static PowerComponentAggregatedPowerStats createAggregatedPowerStats( - BinaryStatePowerStatsProcessor processor) { - AggregatedPowerStatsConfig config = new AggregatedPowerStatsConfig(); - config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_CAMERA) - .trackDeviceStates( - AggregatedPowerStatsConfig.STATE_POWER, - AggregatedPowerStatsConfig.STATE_SCREEN) - .trackUidStates( - AggregatedPowerStatsConfig.STATE_POWER, - AggregatedPowerStatsConfig.STATE_SCREEN, - AggregatedPowerStatsConfig.STATE_PROCESS_STATE) - .setProcessor(processor); - - AggregatedPowerStats aggregatedPowerStats = new AggregatedPowerStats(config); - PowerComponentAggregatedPowerStats powerComponentStats = - aggregatedPowerStats.getPowerComponentStats(BatteryConsumer.POWER_COMPONENT_CAMERA); - processor.start(powerComponentStats, 0); - - powerComponentStats.setState(STATE_POWER, POWER_STATE_OTHER, 0); - powerComponentStats.setState(STATE_SCREEN, SCREEN_STATE_ON, 0); - powerComponentStats.setUidState(APP_UID1, STATE_PROCESS_STATE, PROCESS_STATE_FOREGROUND, 0); - powerComponentStats.setUidState(APP_UID2, STATE_PROCESS_STATE, PROCESS_STATE_CACHED, 0); - - return powerComponentStats; - } - - private static long uCtoUj(long uc) { - return (long) (uc * (double) VOLTAGE_MV / 1000); - } -} diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerStatsTest.java deleted file mode 100644 index 8a391c6bb2ea3..0000000000000 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerStatsTest.java +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.power.stats; - -import static android.os.BatteryConsumer.PROCESS_STATE_BACKGROUND; -import static android.os.BatteryConsumer.PROCESS_STATE_CACHED; -import static android.os.BatteryConsumer.PROCESS_STATE_FOREGROUND; -import static android.os.BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE; - -import static com.android.server.power.stats.AggregatedPowerStatsConfig.POWER_STATE_OTHER; -import static com.android.server.power.stats.AggregatedPowerStatsConfig.SCREEN_STATE_ON; -import static com.android.server.power.stats.AggregatedPowerStatsConfig.SCREEN_STATE_OTHER; -import static com.android.server.power.stats.AggregatedPowerStatsConfig.STATE_POWER; -import static com.android.server.power.stats.AggregatedPowerStatsConfig.STATE_PROCESS_STATE; -import static com.android.server.power.stats.AggregatedPowerStatsConfig.STATE_SCREEN; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.when; - -import android.hardware.power.stats.EnergyConsumerType; -import android.location.GnssSignalQuality; -import android.os.BatteryConsumer; -import android.os.BatteryStats; -import android.os.Handler; -import android.os.Process; -import android.platform.test.ravenwood.RavenwoodRule; - -import com.android.internal.os.Clock; -import com.android.internal.os.MonotonicClock; -import com.android.internal.os.PowerProfile; -import com.android.internal.os.PowerStats; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.util.function.IntSupplier; - -public class GnssPowerStatsTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - - @Rule(order = 1) - public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() - .setAveragePower(PowerProfile.POWER_GPS_ON, 100.0) - .setAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, new double[]{1000, 100}) - .initMeasuredEnergyStatsLocked(); - - private static final double PRECISION = 0.00001; - private static final int APP_UID1 = Process.FIRST_APPLICATION_UID + 42; - private static final int APP_UID2 = Process.FIRST_APPLICATION_UID + 101; - private static final int VOLTAGE_MV = 3500; - private static final int ENERGY_CONSUMER_ID = 777; - - private final PowerStatsUidResolver mUidResolver = new PowerStatsUidResolver(); - @Mock - private PowerStatsCollector.ConsumedEnergyRetriever mConsumedEnergyRetriever; - - EnergyConsumerPowerStatsCollector.Injector mInjector = - new EnergyConsumerPowerStatsCollector.Injector() { - @Override - public Handler getHandler() { - return mStatsRule.getHandler(); - } - - @Override - public Clock getClock() { - return mStatsRule.getMockClock(); - } - - @Override - public PowerStatsUidResolver getUidResolver() { - return mUidResolver; - } - - @Override - public long getPowerStatsCollectionThrottlePeriod(String powerComponentName) { - return 0; - } - - @Override - public PowerStatsCollector.ConsumedEnergyRetriever getConsumedEnergyRetriever() { - return mConsumedEnergyRetriever; - } - - @Override - public IntSupplier getVoltageSupplier() { - return () -> VOLTAGE_MV; - } - }; - - private MonotonicClock mMonotonicClock; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - mMonotonicClock = new MonotonicClock(0, mStatsRule.getMockClock()); - } - - @Test - public void powerProfileModel() { - // ODPM unsupported - when(mConsumedEnergyRetriever.getEnergyConsumerIds(EnergyConsumerType.GNSS, null)) - .thenReturn(new int[0]); - GnssPowerStatsProcessor processor = new GnssPowerStatsProcessor( - mStatsRule.getPowerProfile(), mUidResolver); - - PowerComponentAggregatedPowerStats stats = createAggregatedPowerStats(processor); - - GnssPowerStatsCollector collector = new GnssPowerStatsCollector(mInjector); - collector.addConsumer( - powerStats -> { - processor.addPowerStats(stats, powerStats, mMonotonicClock.monotonicTime()); - }); - collector.setEnabled(true); - - // Establish a baseline - collector.collectAndDeliverStats(); - - processor.noteStateChange(stats, buildHistoryItem(0, true, APP_UID1)); - - // Turn the screen off after 2.5 seconds - stats.setState(STATE_SCREEN, SCREEN_STATE_OTHER, 2500); - stats.setUidState(APP_UID1, STATE_PROCESS_STATE, PROCESS_STATE_BACKGROUND, 2500); - stats.setUidState(APP_UID1, STATE_PROCESS_STATE, PROCESS_STATE_FOREGROUND_SERVICE, 5000); - - processor.noteStateChange(stats, buildHistoryItem(6000, false, APP_UID1)); - - collector.collectAndDeliverStats(); - - processor.noteStateChange(stats, buildHistoryItem(7000, true, APP_UID2)); - processor.noteStateChange(stats, buildHistoryItem(7000, - GnssSignalQuality.GNSS_SIGNAL_QUALITY_GOOD)); - processor.noteStateChange(stats, buildHistoryItem(8000, - GnssSignalQuality.GNSS_SIGNAL_QUALITY_POOR)); - mStatsRule.setTime(11_000, 11_000); - collector.collectAndDeliverStats(); - - processor.finish(stats, 11_000); - - PowerStats.Descriptor descriptor = stats.getPowerStatsDescriptor(); - BinaryStatePowerStatsLayout statsLayout = new BinaryStatePowerStatsLayout(); - statsLayout.fromExtras(descriptor.extras); - - // scr-on, GNSS-good: 2500 * 100 = 250000 mA-ms = 0.06944 mAh - // scr-off GNSS=good: 4500 * 100 = 0.12500 mAh - // scr-off GNSS=poor: 3000 * 1000 = 0.83333 mAh - // scr-off GNSS-on: 0.12500 + 0.83333 = 0.95833 mAh - long[] deviceStats = new long[descriptor.statsArrayLength]; - stats.getDeviceStats(deviceStats, states(POWER_STATE_OTHER, SCREEN_STATE_ON)); - assertThat(statsLayout.getDevicePowerEstimate(deviceStats)) - .isWithin(PRECISION).of(0.06944); - - stats.getDeviceStats(deviceStats, states(POWER_STATE_OTHER, SCREEN_STATE_OTHER)); - assertThat(statsLayout.getDevicePowerEstimate(deviceStats)) - .isWithin(PRECISION).of(0.12500 + 0.83333); - - // UID1 = - // scr-on FG: 2500 -> 0.06944 mAh - // scr-off BG: 2500/7500 * 0.95833 = 0.31944 mAh - // scr-off FGS: 1000/7500 * 0.95833 = 0.12777 mAh - long[] uidStats = new long[descriptor.uidStatsArrayLength]; - stats.getUidStats(uidStats, APP_UID1, - states(POWER_STATE_OTHER, SCREEN_STATE_ON, PROCESS_STATE_FOREGROUND)); - assertThat(statsLayout.getUidPowerEstimate(uidStats)) - .isWithin(PRECISION).of(0.06944); - - stats.getUidStats(uidStats, APP_UID1, - states(POWER_STATE_OTHER, SCREEN_STATE_OTHER, PROCESS_STATE_BACKGROUND)); - assertThat(statsLayout.getUidPowerEstimate(uidStats)) - .isWithin(PRECISION).of(0.31944); - - stats.getUidStats(uidStats, APP_UID1, - states(POWER_STATE_OTHER, SCREEN_STATE_OTHER, PROCESS_STATE_FOREGROUND_SERVICE)); - assertThat(statsLayout.getUidPowerEstimate(uidStats)) - .isWithin(PRECISION).of(0.12777); - - // UID2 = - // scr-off cached: 4000/7500 * 0.95833 = 0.51111 mAh - stats.getUidStats(uidStats, APP_UID2, - states(POWER_STATE_OTHER, SCREEN_STATE_OTHER, PROCESS_STATE_CACHED)); - assertThat(statsLayout.getUidPowerEstimate(uidStats)) - .isWithin(PRECISION).of(0.51111); - - stats.getUidStats(uidStats, APP_UID2, - states(POWER_STATE_OTHER, SCREEN_STATE_ON, PROCESS_STATE_CACHED)); - assertThat(statsLayout.getUidPowerEstimate(uidStats)) - .isWithin(PRECISION).of(0); - } - - @Test - public void energyConsumerModel() { - when(mConsumedEnergyRetriever.getEnergyConsumerIds(EnergyConsumerType.GNSS, null)) - .thenReturn(new int[]{ENERGY_CONSUMER_ID}); - GnssPowerStatsProcessor processor = new GnssPowerStatsProcessor( - mStatsRule.getPowerProfile(), mUidResolver); - - PowerComponentAggregatedPowerStats stats = createAggregatedPowerStats(processor); - - GnssPowerStatsCollector collector = new GnssPowerStatsCollector(mInjector); - collector.addConsumer( - powerStats -> { - processor.addPowerStats(stats, powerStats, mMonotonicClock.monotonicTime()); - }); - collector.setEnabled(true); - - // Establish a baseline - when(mConsumedEnergyRetriever.getConsumedEnergyUws(new int[]{ENERGY_CONSUMER_ID})) - .thenReturn(new long[]{uCtoUj(10000)}); - collector.collectAndDeliverStats(); - - processor.noteStateChange(stats, buildHistoryItem(0, true, APP_UID1)); - - // Turn the screen off after 2.5 seconds - stats.setState(STATE_SCREEN, SCREEN_STATE_OTHER, 2500); - stats.setUidState(APP_UID1, STATE_PROCESS_STATE, PROCESS_STATE_BACKGROUND, 2500); - stats.setUidState(APP_UID1, STATE_PROCESS_STATE, PROCESS_STATE_FOREGROUND_SERVICE, 5000); - - processor.noteStateChange(stats, buildHistoryItem(6000, false, APP_UID1)); - - when(mConsumedEnergyRetriever.getConsumedEnergyUws(new int[]{ENERGY_CONSUMER_ID})) - .thenReturn(new long[]{uCtoUj(2_170_000)}); - collector.collectAndDeliverStats(); - - processor.noteStateChange(stats, buildHistoryItem(7000, true, APP_UID2)); - processor.noteStateChange(stats, buildHistoryItem(7000, - GnssSignalQuality.GNSS_SIGNAL_QUALITY_GOOD)); - processor.noteStateChange(stats, buildHistoryItem(8000, - GnssSignalQuality.GNSS_SIGNAL_QUALITY_POOR)); - mStatsRule.setTime(11_000, 11_000); - when(mConsumedEnergyRetriever.getConsumedEnergyUws(new int[]{ENERGY_CONSUMER_ID})) - .thenReturn(new long[]{uCtoUj(3_610_000)}); - collector.collectAndDeliverStats(); - - processor.finish(stats, 11_000); - - PowerStats.Descriptor descriptor = stats.getPowerStatsDescriptor(); - BinaryStatePowerStatsLayout statsLayout = new BinaryStatePowerStatsLayout(); - statsLayout.fromExtras(descriptor.extras); - - // Total estimated power = 3,600,000 uC = 1.0 mAh - // of which 3,000,000 is distributed: - // Screen-on - 2500/6000 * 2160000 = 900000 uC = 0.25 mAh - // Screen-off - 3500/6000 * 2160000 = 1260000 uC = 0.35 mAh - // and 600,000 was fully with screen off: - // Screen-off - 1440000 uC = 0.4 mAh - long[] deviceStats = new long[descriptor.statsArrayLength]; - stats.getDeviceStats(deviceStats, states(POWER_STATE_OTHER, SCREEN_STATE_ON)); - assertThat(statsLayout.getDevicePowerEstimate(deviceStats)) - .isWithin(PRECISION).of(0.25); - - stats.getDeviceStats(deviceStats, states(POWER_STATE_OTHER, SCREEN_STATE_OTHER)); - assertThat(statsLayout.getDevicePowerEstimate(deviceStats)) - .isWithin(PRECISION).of(0.35 + 0.4); - - // UID1 = - // 2,160,000 uC = 0.6 mAh - // split between three different states - // fg screen-on: 2500/6000 - // bg screen-off: 2500/6000 - // fgs screen-off: 1000/6000 - double expectedPower1 = 0.6; - long[] uidStats = new long[descriptor.uidStatsArrayLength]; - stats.getUidStats(uidStats, APP_UID1, - states(POWER_STATE_OTHER, SCREEN_STATE_ON, PROCESS_STATE_FOREGROUND)); - assertThat(statsLayout.getUidPowerEstimate(uidStats)) - .isWithin(PRECISION).of(expectedPower1 * 2500 / 6000); - - stats.getUidStats(uidStats, APP_UID1, - states(POWER_STATE_OTHER, SCREEN_STATE_OTHER, PROCESS_STATE_BACKGROUND)); - assertThat(statsLayout.getUidPowerEstimate(uidStats)) - .isWithin(PRECISION).of(expectedPower1 * 2500 / 6000); - - stats.getUidStats(uidStats, APP_UID1, - states(POWER_STATE_OTHER, SCREEN_STATE_OTHER, PROCESS_STATE_FOREGROUND_SERVICE)); - assertThat(statsLayout.getUidPowerEstimate(uidStats)) - .isWithin(PRECISION).of(expectedPower1 * 1000 / 6000); - - // UID2 = - // 1440000 mA-ms = 0.4 mAh - // all in the same state - double expectedPower2 = 0.4; - stats.getUidStats(uidStats, APP_UID2, - states(POWER_STATE_OTHER, SCREEN_STATE_OTHER, PROCESS_STATE_CACHED)); - assertThat(statsLayout.getUidPowerEstimate(uidStats)) - .isWithin(PRECISION).of(expectedPower2); - - stats.getUidStats(uidStats, APP_UID2, - states(POWER_STATE_OTHER, SCREEN_STATE_ON, PROCESS_STATE_CACHED)); - assertThat(statsLayout.getUidPowerEstimate(uidStats)) - .isWithin(PRECISION).of(0); - } - - private BatteryStats.HistoryItem buildHistoryItem(int timestamp, boolean stateOn, - int uid) { - mStatsRule.setTime(timestamp, timestamp); - BatteryStats.HistoryItem historyItem = new BatteryStats.HistoryItem(); - historyItem.time = mMonotonicClock.monotonicTime(); - historyItem.states = stateOn ? BatteryStats.HistoryItem.STATE_GPS_ON_FLAG : 0; - if (stateOn) { - historyItem.eventCode = BatteryStats.HistoryItem.EVENT_STATE_CHANGE - | BatteryStats.HistoryItem.EVENT_FLAG_START; - } else { - historyItem.eventCode = BatteryStats.HistoryItem.EVENT_STATE_CHANGE - | BatteryStats.HistoryItem.EVENT_FLAG_FINISH; - } - historyItem.eventTag = historyItem.localEventTag; - historyItem.eventTag.uid = uid; - historyItem.eventTag.string = "gnss"; - return historyItem; - } - - private BatteryStats.HistoryItem buildHistoryItem(int timestamp, int signalLevel) { - mStatsRule.setTime(timestamp, timestamp); - BatteryStats.HistoryItem historyItem = new BatteryStats.HistoryItem(); - historyItem.time = mMonotonicClock.monotonicTime(); - historyItem.states = BatteryStats.HistoryItem.STATE_GPS_ON_FLAG; - historyItem.states2 = - signalLevel << BatteryStats.HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT; - return historyItem; - } - - private int[] states(int... states) { - return states; - } - - private static PowerComponentAggregatedPowerStats createAggregatedPowerStats( - BinaryStatePowerStatsProcessor processor) { - AggregatedPowerStatsConfig config = new AggregatedPowerStatsConfig(); - config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_GNSS) - .trackDeviceStates( - AggregatedPowerStatsConfig.STATE_POWER, - AggregatedPowerStatsConfig.STATE_SCREEN) - .trackUidStates( - AggregatedPowerStatsConfig.STATE_POWER, - AggregatedPowerStatsConfig.STATE_SCREEN, - AggregatedPowerStatsConfig.STATE_PROCESS_STATE) - .setProcessor(processor); - - AggregatedPowerStats aggregatedPowerStats = new AggregatedPowerStats(config); - PowerComponentAggregatedPowerStats powerComponentStats = - aggregatedPowerStats.getPowerComponentStats(BatteryConsumer.POWER_COMPONENT_GNSS); - processor.start(powerComponentStats, 0); - - powerComponentStats.setState(STATE_POWER, POWER_STATE_OTHER, 0); - powerComponentStats.setState(STATE_SCREEN, SCREEN_STATE_ON, 0); - powerComponentStats.setUidState(APP_UID1, STATE_PROCESS_STATE, PROCESS_STATE_FOREGROUND, 0); - powerComponentStats.setUidState(APP_UID2, STATE_PROCESS_STATE, PROCESS_STATE_CACHED, 0); - - return powerComponentStats; - } - - private static long uCtoUj(long uc) { - return (long) (uc * (double) VOLTAGE_MV / 1000); - } -} From e232c44ca3510746779a1a1a195515647993a126 Mon Sep 17 00:00:00 2001 From: Dmitry Dementyev Date: Wed, 24 Jul 2024 13:36:16 -0700 Subject: [PATCH 005/414] Ignore SQL exceptions in getAccountsAsUserForPackage and syncSharedAccounts. In rare cases API is called for removed user and crashes system server. Bug: 354148797 Test: manual Flag: EXEMPT bugfix (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:2403b49b56970221a7bfc31bd811a5cf9e094046) Merged-In: I9f1aef6f8e131ad1df11f68eda4c0db189b45b05 Change-Id: I9f1aef6f8e131ad1df11f68eda4c0db189b45b05 --- .../accounts/AccountManagerService.java | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index fb583acd7503c..1d07bcae3f354 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -4612,6 +4612,9 @@ private Account[] getAccountsAsUserForPackage( opPackageName, visibleAccountTypes, includeUserManagedNotVisible); + } catch (SQLiteException e) { + Log.w(TAG, "Could not get accounts for user " + userId, e); + return new Account[]{}; } finally { restoreCallingIdentity(identityToken); } @@ -4699,12 +4702,17 @@ private boolean removeSharedAccountAsUser(Account account, int userId, int calli public Account[] getSharedAccountsAsUser(int userId) { userId = handleIncomingUser(userId); - UserAccounts accounts = getUserAccounts(userId); - synchronized (accounts.dbLock) { - List accountList = accounts.accountsDb.getSharedAccounts(); - Account[] accountArray = new Account[accountList.size()]; - accountList.toArray(accountArray); - return accountArray; + try { + UserAccounts accounts = getUserAccounts(userId); + synchronized (accounts.dbLock) { + List accountList = accounts.accountsDb.getSharedAccounts(); + Account[] accountArray = new Account[accountList.size()]; + accountList.toArray(accountArray); + return accountArray; + } + } catch (SQLiteException e) { + Log.w(TAG, "Could not get shared accounts for user " + userId, e); + return new Account[]{}; } } From 6c841234e09a8afa50f3c25af915019e3e9badd3 Mon Sep 17 00:00:00 2001 From: Hao Dong Date: Mon, 29 Jul 2024 19:27:24 +0000 Subject: [PATCH 006/414] Log the warning if logo description exceeds char limit. 1. Remove the exception for logo description char limit and log a warning instead. 2. Truncate if the logo description exceeds 30 characters 3. Set title's top constraint on both logo icon and logo description for non-icon or non-description cases. Flag: android.hardware.biometrics.custom_biometric_prompt Bug: 355677518 Test: manual test on test app Test: atest BiometricPromptTest Test: atest BiometricPromptScreenshotTest (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:86e209599423f7a69f1466eadd71e94041164b4a) Merged-In: Icb07acd88138a7519f73d3df9ab323220d99dfe7 Change-Id: Icb07acd88138a7519f73d3df9ab323220d99dfe7 --- .../hardware/biometrics/BiometricPrompt.java | 15 +++++++------ .../biometrics/BiometricPromptTest.java | 15 +------------ .../biometric_prompt_two_pane_layout.xml | 22 ++++++++++++++----- packages/SystemUI/res/values/styles.xml | 5 ++--- .../ui/binder/BiometricViewBinder.kt | 9 +++++++- 5 files changed, 35 insertions(+), 31 deletions(-) diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java index 37a2df83cc003..5c6039489b6ba 100644 --- a/core/java/android/hardware/biometrics/BiometricPrompt.java +++ b/core/java/android/hardware/biometrics/BiometricPrompt.java @@ -240,18 +240,19 @@ public BiometricPrompt.Builder setLogoBitmap(@NonNull Bitmap logoBitmap) { * * @param logoDescription The logo description text that will be shown on the prompt. * @return This builder. - * @throws IllegalArgumentException If logo description is null or exceeds certain character - * limit. + * @throws IllegalArgumentException If logo description is null. */ @FlaggedApi(FLAG_CUSTOM_BIOMETRIC_PROMPT) @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED) @NonNull public BiometricPrompt.Builder setLogoDescription(@NonNull String logoDescription) { - if (logoDescription == null - || logoDescription.length() > MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER) { - throw new IllegalArgumentException( - "Logo description passed in can not be null or exceed " - + MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER + " character number."); + if (logoDescription == null || logoDescription.isEmpty()) { + throw new IllegalArgumentException("Logo description passed in can not be null"); + } + if (logoDescription.length() > MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER) { + Log.w(TAG, + "Logo description passed in exceeds" + MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER + + " character number and may be truncated."); } mPromptInfo.setLogoDescription(logoDescription); return this; diff --git a/core/tests/coretests/src/android/hardware/biometrics/BiometricPromptTest.java b/core/tests/coretests/src/android/hardware/biometrics/BiometricPromptTest.java index ca9154280a100..a3d0ec6236833 100644 --- a/core/tests/coretests/src/android/hardware/biometrics/BiometricPromptTest.java +++ b/core/tests/coretests/src/android/hardware/biometrics/BiometricPromptTest.java @@ -16,7 +16,6 @@ package android.hardware.biometrics; -import static android.hardware.biometrics.BiometricPrompt.MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER; import static android.hardware.biometrics.PromptContentViewWithMoreOptionsButton.MAX_DESCRIPTION_CHARACTER_NUMBER; import static android.hardware.biometrics.PromptVerticalListContentView.MAX_EACH_ITEM_CHARACTER_NUMBER; import static android.hardware.biometrics.PromptVerticalListContentView.MAX_ITEM_NUMBER; @@ -116,19 +115,7 @@ public void testLogoDescription_null() { () -> new BiometricPrompt.Builder(mContext).setLogoDescription(null) ); - assertThat(e).hasMessageThat().contains( - "Logo description passed in can not be null or exceed"); - } - - @Test - public void testLogoDescription_charLimit() { - IllegalArgumentException e = assertThrows(IllegalArgumentException.class, - () -> new BiometricPrompt.Builder(mContext).setLogoDescription( - generateRandomString(MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER + 1)) - ); - - assertThat(e).hasMessageThat().contains( - "Logo description passed in can not be null or exceed"); + assertThat(e).hasMessageThat().isEqualTo("Logo description passed in can not be null"); } @Test diff --git a/packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml b/packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml index c599f9e05b38b..18a1544a1d5d2 100644 --- a/packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml +++ b/packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml @@ -87,20 +87,21 @@ android:layout_height="match_parent"> android:id="@+id/logo_description" style="@style/TextAppearance.AuthCredential.LogoDescription" android:layout_width="0dp" - android:layout_height="wrap_content" + android:layout_height="@dimen/biometric_prompt_logo_size" + android:gravity="start|center_vertical" android:textAlignment="viewStart" - android:paddingStart="16dp" - app:layout_constraintBottom_toBottomOf="@+id/logo" + android:layout_marginStart="16dp" + app:layout_goneMarginStart="0dp" + app:layout_constraintBottom_toTopOf="@+id/title" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/logo" - app:layout_constraintTop_toTopOf="@+id/logo" /> + app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/logo" + app:layout_constraintTop_toBottomOf="@+id/logoBarrier" app:layout_constraintVertical_bias="0.0" app:layout_constraintVertical_chainStyle="packed" /> @@ -158,6 +159,15 @@ android:layout_height="match_parent"> app:layout_constraintTop_toBottomOf="@+id/subtitle" app:layout_constraintVertical_bias="0.0" /> + + @*android:string/config_bodyFontFamilyMedium - marquee @integer/biometric_dialog_text_gravity - 1 - true + 1 ?androidprv:attr/materialColorOnSurfaceVariant + end