summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/os/BatteryUsageStatsQuery.java20
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/res/drawable-mdpi/border_ltr.9.pngbin0 -> 114 bytes
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/res/drawable-mdpi/border_tr.9.pngbin0 -> 108 bytes
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/res/drawable/power_other_24.xml10
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/res/drawable/screen_off_24.xml10
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/res/drawable/screen_on_24.xml10
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_entry_layout.xml158
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_layout.xml32
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_slices_layout.xml87
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_stats_viewer_layout.xml5
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/res/values/colors.xml1
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/res/values/styles.xml29
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java233
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java21
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java5
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java229
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/TrampolineActivity.java1
-rw-r--r--services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java18
18 files changed, 579 insertions, 290 deletions
diff --git a/core/java/android/os/BatteryUsageStatsQuery.java b/core/java/android/os/BatteryUsageStatsQuery.java
index 6d426128bd02..6e67578fadc8 100644
--- a/core/java/android/os/BatteryUsageStatsQuery.java
+++ b/core/java/android/os/BatteryUsageStatsQuery.java
@@ -24,6 +24,7 @@ import com.android.internal.os.MonotonicClock;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
/**
* Query parameters for the {@link BatteryStatsManager#getBatteryUsageStats()} call.
@@ -196,7 +197,24 @@ public final class BatteryUsageStatsQuery implements Parcelable {
return mAggregatedToTimestamp;
}
+ @Override
+ public String toString() {
+ return "BatteryUsageStatsQuery{"
+ + "mFlags=" + Integer.toHexString(mFlags)
+ + ", mUserIds=" + Arrays.toString(mUserIds)
+ + ", mMaxStatsAgeMs=" + mMaxStatsAgeMs
+ + ", mAggregatedFromTimestamp=" + mAggregatedFromTimestamp
+ + ", mAggregatedToTimestamp=" + mAggregatedToTimestamp
+ + ", mMonotonicStartTime=" + mMonotonicStartTime
+ + ", mMonotonicEndTime=" + mMonotonicEndTime
+ + ", mMinConsumedPowerThreshold=" + mMinConsumedPowerThreshold
+ + ", mPowerComponents=" + Arrays.toString(mPowerComponents)
+ + '}';
+ }
+
private BatteryUsageStatsQuery(Parcel in) {
+ mMonotonicStartTime = in.readLong();
+ mMonotonicEndTime = in.readLong();
mFlags = in.readInt();
mUserIds = new int[in.readInt()];
in.readIntArray(mUserIds);
@@ -209,6 +227,8 @@ public final class BatteryUsageStatsQuery implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
+ dest.writeLong(mMonotonicStartTime);
+ dest.writeLong(mMonotonicEndTime);
dest.writeInt(mFlags);
dest.writeInt(mUserIds.length);
dest.writeIntArray(mUserIds);
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/drawable-mdpi/border_ltr.9.png b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable-mdpi/border_ltr.9.png
new file mode 100644
index 000000000000..c7e937c6d77a
--- /dev/null
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable-mdpi/border_ltr.9.png
Binary files differ
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/drawable-mdpi/border_tr.9.png b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable-mdpi/border_tr.9.png
new file mode 100644
index 000000000000..a3cff989bad8
--- /dev/null
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable-mdpi/border_tr.9.png
Binary files differ
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/power_other_24.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/power_other_24.xml
new file mode 100644
index 000000000000..c9fb53ee78da
--- /dev/null
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/power_other_24.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M720,600L720,520L800,520Q817,520 828.5,531.5Q840,543 840,560Q840,577 828.5,588.5Q817,600 800,600L720,600ZM720,760L720,680L800,680Q817,680 828.5,691.5Q840,703 840,720Q840,737 828.5,748.5Q817,760 800,760L720,760ZM560,800Q527,800 503.5,776.5Q480,753 480,720L400,720L400,560L480,560Q480,527 503.5,503.5Q527,480 560,480L680,480L680,800L560,800ZM280,680Q214,680 167,633Q120,586 120,520Q120,454 167,407Q214,360 280,360L340,360Q365,360 382.5,342.5Q400,325 400,300Q400,275 382.5,257.5Q365,240 340,240L200,240Q183,240 171.5,228.5Q160,217 160,200Q160,183 171.5,171.5Q183,160 200,160L340,160Q398,160 439,201Q480,242 480,300Q480,358 439,399Q398,440 340,440L280,440Q247,440 223.5,463.5Q200,487 200,520Q200,553 223.5,576.5Q247,600 280,600L360,600L360,680L280,680Z" />
+</vector> \ No newline at end of file
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/screen_off_24.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/screen_off_24.xml
new file mode 100644
index 000000000000..ca9482503c92
--- /dev/null
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/screen_off_24.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M280,920Q247,920 223.5,896.5Q200,873 200,840L200,120Q200,87 223.5,63.5Q247,40 280,40L680,40Q713,40 736.5,63.5Q760,87 760,120L760,840Q760,873 736.5,896.5Q713,920 680,920L280,920ZM280,800L280,840Q280,840 280,840Q280,840 280,840L680,840Q680,840 680,840Q680,840 680,840L680,800L280,800ZM280,720L680,240L280,720ZM280,160L680,160L680,120Q680,120 680,120Q680,120 680,120L280,120Q280,120 280,120Q280,120 280,120L280,160ZM280,160L280,120Q280,120 280,120Q280,120 280,120L280,120Q280,120 280,120Q280,120 280,120L280,160ZM280,800L280,800L280,840Q280,840 280,840Q280,840 280,840L280,840Q280,840 280,840Q280,840 280,840L280,800Z" />
+</vector> \ No newline at end of file
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/screen_on_24.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/screen_on_24.xml
new file mode 100644
index 000000000000..48f990c3ba37
--- /dev/null
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/screen_on_24.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M280,920Q247,920 223.5,896.5Q200,873 200,840L200,120Q200,87 223.5,63.5Q247,40 280,40L680,40Q713,40 736.5,63.5Q760,87 760,120L760,840Q760,873 736.5,896.5Q713,920 680,920L280,920ZM280,800L280,840Q280,840 280,840Q280,840 280,840L680,840Q680,840 680,840Q680,840 680,840L680,800L280,800ZM280,720L680,720L680,240L280,240L280,720ZM280,160L680,160L680,120Q680,120 680,120Q680,120 680,120L280,120Q280,120 280,120Q280,120 280,120L280,160ZM280,160L280,120Q280,120 280,120Q280,120 280,120L280,120Q280,120 280,120Q280,120 280,120L280,160ZM280,800L280,800L280,840Q280,840 280,840Q280,840 280,840L280,840Q280,840 280,840Q280,840 280,840L280,800Z" />
+</vector> \ No newline at end of file
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_entry_layout.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_entry_layout.xml
index be0e135af23a..e1f46232488c 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_entry_layout.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_entry_layout.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,46 +13,127 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:minHeight="?android:attr/listPreferredItemHeightSmall"
- android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
- android:paddingTop="8dp"
- android:paddingBottom="8dp">
-
- <ImageView
- android:id="@+id/icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_marginEnd="8dp"
- android:paddingBottom="8dp"/>
-
- <TextView
- android:id="@+id/title"
- android:layout_width="0dp"
- android:layout_weight="1"
- android:layout_height="wrap_content"
- android:textAppearance="@style/TextAppearanceBody"/>
+ android:orientation="vertical">
- <TextView
- android:id="@+id/value1"
- android:layout_width="wrap_content"
+ <LinearLayout
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginStart="8dp"
- android:gravity="right"
- android:maxLines="1"
- android:textAppearance="@style/TextAppearanceBody"/>
-
- <TextView
- android:id="@+id/value2"
- android:layout_width="76dp"
+ android:minHeight="?android:attr/listPreferredItemHeightSmall"
+ android:orientation="horizontal"
+ android:paddingBottom="8dp"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingTop="8dp">
+
+ <ImageView
+ android:id="@+id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:layout_marginEnd="8dp"
+ android:paddingBottom="8dp" />
+
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:textAppearance="@style/TextAppearanceBody" />
+
+ <TextView
+ android:id="@+id/value1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="8dp"
+ android:gravity="right"
+ android:maxLines="1"
+ android:textAppearance="@style/TextAppearanceBody" />
+
+ <TextView
+ android:id="@+id/value2"
+ android:layout_width="76dp"
+ android:layout_height="wrap_content"
+ android:gravity="right"
+ android:maxLines="1"
+ android:textAppearance="@style/TextAppearanceBody" />
+ </LinearLayout>
+
+ <TableLayout
+ android:id="@+id/table"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:gravity="right"
- android:maxLines="1"
- android:textAppearance="@style/TextAppearanceBody"/>
+ android:layout_marginEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:layout_marginStart="50dp"
+ android:stretchColumns="1,2,3,4">
+
+ <TableRow android:background="#EEFFEE">
+ <LinearLayout
+ style="@style/TableCell.Start"
+ android:layout_width="65dp">
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="3dip"
+ android:text="State"
+ android:textStyle="bold" />
+ </LinearLayout>
+
+ <RelativeLayout style="@style/TableCell.Inner">
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerInParent="true"
+ android:src="@drawable/screen_on_24"
+ android:tint="@color/battery_consumer_slice_icon" />
+ </RelativeLayout>
+
+ <RelativeLayout style="@style/TableCell.Inner">
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerInParent="true"
+ android:src="@drawable/screen_off_24"
+ android:tint="@color/battery_consumer_slice_icon" />
+ </RelativeLayout>
+
+ <RelativeLayout style="@style/TableCell.Inner">
+ <ImageView
+ android:id="@+id/screen_on_24_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerInParent="true"
+ android:src="@drawable/screen_on_24"
+ android:tint="@color/battery_consumer_slice_icon" />
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@id/screen_on_24_icon"
+ android:src="@drawable/power_other_24"
+ android:tint="@color/battery_consumer_slice_icon" />
+ </RelativeLayout>
+
+ <RelativeLayout style="@style/TableCell.End">
+ <ImageView
+ android:id="@+id/screen_off_24_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerInParent="true"
+ android:src="@drawable/screen_off_24"
+ android:tint="@color/battery_consumer_slice_icon" />
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@id/screen_off_24_icon"
+ android:src="@drawable/power_other_24"
+ android:tint="@color/battery_consumer_slice_icon" />
+ </RelativeLayout>
+ </TableRow>
+
+ <View
+ android:layout_height="1dip"
+ android:background="#000000" />
+ </TableLayout>
</LinearLayout>
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_layout.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_layout.xml
index 987de6bcb4f4..b88425a57187 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_layout.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_layout.xml
@@ -14,16 +14,30 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/swipe_refresh"
- android:paddingTop="?attr/actionBarSize"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:fitsSystemWindows="true">
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/list_view"
+ <androidx.appcompat.widget.Toolbar
+ android:id="@+id/toolbar"
android:layout_width="match_parent"
- android:layout_height="match_parent"/>
+ android:layout_height="?attr/actionBarSize"
+ android:background="?attr/colorPrimary"
+ android:elevation="4dp"
+ android:theme="@style/ThemeOverlay.AppCompat.ActionBar" />
-</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
+ <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
+ android:id="@+id/swipe_refresh"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1">
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/list_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
+</LinearLayout>
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_slices_layout.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_slices_layout.xml
new file mode 100644
index 000000000000..642c0deac6f4
--- /dev/null
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_slices_layout.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ 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.
+ -->
+
+<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <LinearLayout style="@style/TableCell.Start">
+ <TextView
+ android:id="@+id/procState"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ </LinearLayout>
+
+ <LinearLayout
+ style="@style/TableCell.Inner"
+ android:orientation="vertical">
+ <TextView
+ android:id="@+id/power_b_on"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="right" />
+ <TextView
+ android:id="@+id/duration_b_on"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="right" />
+ </LinearLayout>
+
+ <LinearLayout
+ style="@style/TableCell.Inner"
+ android:orientation="vertical">
+ <TextView
+ android:id="@+id/power_b_off"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="right" />
+ <TextView
+ android:id="@+id/duration_b_off"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="right" />
+ </LinearLayout>
+
+ <LinearLayout
+ style="@style/TableCell.Inner"
+ android:orientation="vertical">
+ <TextView
+ android:id="@+id/power_c_on"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="right" />
+ <TextView
+ android:id="@+id/duration_c_on"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="right" />
+ </LinearLayout>
+
+ <LinearLayout
+ style="@style/TableCell.End"
+ android:orientation="vertical">
+ <TextView
+ android:id="@+id/power_c_off"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="right" />
+ <TextView
+ android:id="@+id/duration_c_off"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="right" />
+ </LinearLayout>
+</TableRow>
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_stats_viewer_layout.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_stats_viewer_layout.xml
index 2d276a51a1da..46d8f04f9eef 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_stats_viewer_layout.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_stats_viewer_layout.xml
@@ -17,13 +17,12 @@
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swipe_refresh"
- android:paddingTop="?attr/actionBarSize"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:fitsSystemWindows="true">
<LinearLayout
android:orientation="vertical"
- android:paddingTop="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="match_parent">
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/values/colors.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/values/colors.xml
index 6cc70bd1af61..1dc288af89b6 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/res/values/colors.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/values/colors.xml
@@ -18,4 +18,5 @@
<resources>
<color name="battery_consumer_bg_power_profile">#ffffff</color>
<color name="battery_consumer_bg_energy_consumption">#fff5eb</color>
+ <color name="battery_consumer_slice_icon">#aaaaaa</color>
</resources>
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/values/styles.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/values/styles.xml
index fa30b2c8dc6f..a298cc9f59e3 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/res/values/styles.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/values/styles.xml
@@ -17,11 +17,9 @@
-->
<resources>
- <style name="Theme" parent="Theme.MaterialComponents.Light">
+ <style name="Theme" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="colorPrimary">#34a853</item>
- <item name="android:windowActionBar">true</item>
- <item name="android:windowNoTitle">false</item>
- <item name="android:windowDrawsSystemBarBackgrounds">false</item>
+ <item name="toolbarStyle">@style/Widget.AppCompat.Toolbar</item>
</style>
<style name="LoadTestCardView" parent="Widget.MaterialComponents.CardView">
@@ -32,4 +30,25 @@
<item name="android:textColor">#000000</item>
<item name="android:textSize">18sp</item>
</style>
-</resources> \ No newline at end of file
+
+ <style name="TableCell">
+ <item name="android:layout_height">match_parent</item>
+ <item name="android:padding">4dp</item>
+ </style>
+
+ <style name="TableCell.Start" parent="TableCell">
+ <item name="android:background">@drawable/border_ltr</item>
+ </style>
+
+ <style name="TableCell.Inner" parent="TableCell">
+ <item name="android:background">@drawable/border_tr</item>
+ <item name="android:layout_width">0dp</item>
+ <item name="android:layout_weight">1</item>
+ </style>
+
+ <style name="TableCell.End" parent="TableCell">
+ <item name="android:background">@drawable/border_tr</item>
+ <item name="android:layout_width">0dp</item>
+ <item name="android:layout_weight">1</item>
+ </style>
+</resources>
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java
index f691a1b90934..35175a755e89 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java
@@ -31,22 +31,16 @@ public class BatteryConsumerData {
public static final String UID_BATTERY_CONSUMER_ID_PREFIX = "APP|";
public static final String AGGREGATE_BATTERY_CONSUMER_ID = "SYS|";
- enum EntryType {
- UID_TOTAL_POWER,
- UID_POWER_PROFILE,
- UID_POWER_PROFILE_PROCESS_STATE,
- UID_POWER_ENERGY_CONSUMPTION,
- UID_POWER_ENERGY_PROCESS_STATE,
- UID_POWER_CUSTOM,
- UID_DURATION,
+ public enum EntryType {
DEVICE_TOTAL_POWER,
- DEVICE_POWER_MODELED,
+ DEVICE_POWER,
DEVICE_POWER_ENERGY_CONSUMPTION,
DEVICE_POWER_CUSTOM,
DEVICE_DURATION,
+ UID,
}
- enum ConsumerType {
+ public enum ConsumerType {
UID_BATTERY_CONSUMER,
DEVICE_POWER_COMPONENT,
}
@@ -56,34 +50,38 @@ public class BatteryConsumerData {
public String title;
public double value1;
public double value2;
+ public List<Slice> slices;
+ }
+
+ public static class Slice {
+ public int powerState;
+ public int screenState;
+ public int processState;
+ public double powerMah;
+ public long durationMs;
}
private BatteryConsumerInfoHelper.BatteryConsumerInfo mBatteryConsumerInfo;
private final List<Entry> mEntries = new ArrayList<>();
public BatteryConsumerData(Context context,
- List<BatteryUsageStats> batteryUsageStatsList, String batteryConsumerId) {
+ BatteryUsageStats batteryUsageStats, String batteryConsumerId) {
switch (getConsumerType(batteryConsumerId)) {
case UID_BATTERY_CONSUMER:
- populateForUidBatteryConsumer(context, batteryUsageStatsList, batteryConsumerId);
+ populateForUidBatteryConsumer(context, batteryUsageStats, batteryConsumerId);
break;
case DEVICE_POWER_COMPONENT:
- populateForAggregateBatteryConsumer(context, batteryUsageStatsList);
+ populateForAggregateBatteryConsumer(context, batteryUsageStats);
break;
}
}
- private void populateForUidBatteryConsumer(
- Context context, List<BatteryUsageStats> batteryUsageStatsList,
+ private void populateForUidBatteryConsumer(Context context, BatteryUsageStats batteryUsageStats,
String batteryConsumerId) {
- BatteryUsageStats batteryUsageStats = batteryUsageStatsList.get(0);
- BatteryUsageStats modeledBatteryUsageStats = batteryUsageStatsList.get(1);
BatteryConsumer requestedBatteryConsumer = getRequestedBatteryConsumer(batteryUsageStats,
batteryConsumerId);
- BatteryConsumer requestedModeledBatteryConsumer = getRequestedBatteryConsumer(
- modeledBatteryUsageStats, batteryConsumerId);
- if (requestedBatteryConsumer == null || requestedModeledBatteryConsumer == null) {
+ if (requestedBatteryConsumer == null) {
mBatteryConsumerInfo = null;
return;
}
@@ -92,118 +90,95 @@ public class BatteryConsumerData {
batteryUsageStats, batteryConsumerId, context.getPackageManager());
double[] totalPowerByComponentMah = new double[BatteryConsumer.POWER_COMPONENT_COUNT];
- double[] totalModeledPowerByComponentMah =
- new double[BatteryConsumer.POWER_COMPONENT_COUNT];
long[] totalDurationByComponentMs = new long[BatteryConsumer.POWER_COMPONENT_COUNT];
- final int customComponentCount =
- requestedBatteryConsumer.getCustomPowerComponentCount();
+ final int customComponentCount = requestedBatteryConsumer.getCustomPowerComponentCount();
double[] totalCustomPowerByComponentMah = new double[customComponentCount];
computeTotalPower(batteryUsageStats, totalPowerByComponentMah);
- computeTotalPower(modeledBatteryUsageStats, totalModeledPowerByComponentMah);
computeTotalPowerForCustomComponent(batteryUsageStats, totalCustomPowerByComponentMah);
computeTotalDuration(batteryUsageStats, totalDurationByComponentMs);
- if (isPowerProfileModelsOnly(requestedBatteryConsumer)) {
- addEntry("Consumed", EntryType.UID_TOTAL_POWER,
- requestedBatteryConsumer.getConsumedPower(),
- batteryUsageStats.getAggregateBatteryConsumer(
- BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
- .getConsumedPower());
- } else {
- addEntry("Consumed (PowerStats)", EntryType.UID_TOTAL_POWER,
- requestedBatteryConsumer.getConsumedPower(),
- batteryUsageStats.getAggregateBatteryConsumer(
- BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
- .getConsumedPower());
- addEntry("Consumed (PowerProfile)", EntryType.UID_TOTAL_POWER,
- requestedModeledBatteryConsumer.getConsumedPower(),
- modeledBatteryUsageStats.getAggregateBatteryConsumer(
- BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
- .getConsumedPower());
+ Entry totalsEntry = addEntry("Consumed", EntryType.UID,
+ requestedBatteryConsumer.getConsumedPower(),
+ batteryUsageStats.getAggregateBatteryConsumer(
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
+ .getConsumedPower());
+ addSlices(totalsEntry, requestedBatteryConsumer, BatteryConsumer.POWER_COMPONENT_BASE);
+ for (Slice slice : totalsEntry.slices) {
+ slice.powerMah = requestedBatteryConsumer.getConsumedPower(
+ new BatteryConsumer.Dimensions(BatteryConsumer.POWER_COMPONENT_ANY,
+ slice.processState, slice.screenState, slice.powerState));
}
for (int component = 0; component < BatteryConsumer.POWER_COMPONENT_COUNT; component++) {
+ if (component == BatteryConsumer.POWER_COMPONENT_BASE) {
+ continue;
+ }
final String metricTitle = getPowerMetricTitle(component);
- final int powerModel = requestedBatteryConsumer.getPowerModel(component);
- if (powerModel == BatteryConsumer.POWER_MODEL_POWER_PROFILE
- || powerModel == BatteryConsumer.POWER_MODEL_UNDEFINED) {
- addEntry(metricTitle, EntryType.UID_POWER_PROFILE,
- requestedBatteryConsumer.getConsumedPower(component),
+ double consumedPower = requestedBatteryConsumer.getConsumedPower(component);
+ if (consumedPower != 0) {
+ Entry entry = addEntry(metricTitle, EntryType.UID, consumedPower,
totalPowerByComponentMah[component]);
- addProcessStateEntries(metricTitle, EntryType.UID_POWER_PROFILE_PROCESS_STATE,
- requestedBatteryConsumer, component);
- } else {
- addEntry(metricTitle + " (PowerStats)", EntryType.UID_POWER_ENERGY_CONSUMPTION,
- requestedBatteryConsumer.getConsumedPower(component),
- totalPowerByComponentMah[component]);
- addProcessStateEntries(metricTitle, EntryType.UID_POWER_ENERGY_PROCESS_STATE,
- requestedBatteryConsumer, component);
- addEntry(metricTitle + " (PowerProfile)", EntryType.UID_POWER_PROFILE,
- requestedModeledBatteryConsumer.getConsumedPower(component),
- totalModeledPowerByComponentMah[component]);
- addProcessStateEntries(metricTitle, EntryType.UID_POWER_PROFILE_PROCESS_STATE,
- requestedModeledBatteryConsumer, component);
+ addSlices(entry, requestedBatteryConsumer, component);
}
}
for (int component = 0; component < customComponentCount; component++) {
- final String name = requestedBatteryConsumer.getCustomPowerComponentName(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + component);
- addEntry(name + " (PowerStats)", EntryType.UID_POWER_CUSTOM,
- requestedBatteryConsumer.getConsumedPowerForCustomComponent(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + component),
- totalCustomPowerByComponentMah[component]
- );
- }
-
- for (int component = 0; component < BatteryConsumer.POWER_COMPONENT_COUNT; component++) {
- final String metricTitle = getTimeMetricTitle(component);
- addEntry(metricTitle, EntryType.UID_DURATION,
- requestedBatteryConsumer.getUsageDurationMillis(component),
- totalDurationByComponentMs[component]
- );
+ int componentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + component;
+ final String name = requestedBatteryConsumer.getCustomPowerComponentName(componentId);
+ double consumedPower = requestedBatteryConsumer.getConsumedPower(componentId);
+ if (consumedPower != 0) {
+ Entry entry = addEntry(name, EntryType.UID, consumedPower,
+ totalCustomPowerByComponentMah[component]);
+ addSlices(entry, requestedBatteryConsumer, componentId);
+ }
}
mBatteryConsumerInfo = BatteryConsumerInfoHelper.makeBatteryConsumerInfo(batteryUsageStats,
batteryConsumerId, context.getPackageManager());
}
- private void addProcessStateEntries(String metricTitle, EntryType entryType,
- BatteryConsumer batteryConsumer, int component) {
+ private void addSlices(Entry entry, BatteryConsumer batteryConsumer, int component) {
final BatteryConsumer.Key[] keys = batteryConsumer.getKeys(component);
if (keys == null || keys.length <= 1) {
return;
}
+ boolean hasProcStateData = false;
for (BatteryConsumer.Key key : keys) {
- String label;
- switch (key.processState) {
- case BatteryConsumer.PROCESS_STATE_FOREGROUND:
- label = "foreground";
- break;
- case BatteryConsumer.PROCESS_STATE_BACKGROUND:
- label = "background";
- break;
- case BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE:
- label = "FGS";
- break;
- case BatteryConsumer.PROCESS_STATE_CACHED:
- label = "cached";
- break;
- default:
- continue;
+ if (key.processState != BatteryConsumer.PROCESS_STATE_UNSPECIFIED) {
+ hasProcStateData = true;
+ break;
}
- addEntry(metricTitle + " \u2022 " + label, entryType,
- batteryConsumer.getConsumedPower(key), 0);
}
+
+ ArrayList<Slice> slices = new ArrayList<>();
+ for (BatteryConsumer.Key key : keys) {
+ if (hasProcStateData && key.processState == BatteryConsumer.PROCESS_STATE_UNSPECIFIED) {
+ continue;
+ }
+
+ double powerMah = batteryConsumer.getConsumedPower(key);
+ long durationMs = batteryConsumer.getUsageDurationMillis(key);
+
+ if (powerMah == 0 && durationMs == 0) {
+ continue;
+ }
+
+ Slice slice = new Slice();
+ slice.powerState = key.powerState;
+ slice.screenState = key.screenState;
+ slice.processState = key.processState;
+ slice.powerMah = powerMah;
+ slice.durationMs = durationMs;
+
+ slices.add(slice);
+ }
+ entry.slices = slices;
}
private void populateForAggregateBatteryConsumer(Context context,
- List<BatteryUsageStats> batteryUsageStatsList) {
- BatteryUsageStats batteryUsageStats = batteryUsageStatsList.get(0);
- BatteryUsageStats modeledBatteryUsageStats = batteryUsageStatsList.get(1);
-
+ BatteryUsageStats batteryUsageStats) {
final BatteryConsumer deviceBatteryConsumer =
batteryUsageStats.getAggregateBatteryConsumer(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
@@ -211,46 +186,18 @@ public class BatteryConsumerData {
batteryUsageStats.getAggregateBatteryConsumer(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS);
- BatteryConsumer modeledDeviceBatteryConsumer =
- modeledBatteryUsageStats.getAggregateBatteryConsumer(
- BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
- BatteryConsumer modeledAppsBatteryConsumer =
- modeledBatteryUsageStats.getAggregateBatteryConsumer(
- BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS);
-
- if (isPowerProfileModelsOnly(deviceBatteryConsumer)) {
- addEntry("Consumed", EntryType.DEVICE_TOTAL_POWER,
- deviceBatteryConsumer.getConsumedPower(),
- appsBatteryConsumer.getConsumedPower());
- } else {
- addEntry("Consumed (PowerStats)", EntryType.DEVICE_TOTAL_POWER,
- deviceBatteryConsumer.getConsumedPower(),
- appsBatteryConsumer.getConsumedPower());
- addEntry("Consumed (PowerProfile)", EntryType.DEVICE_TOTAL_POWER,
- modeledDeviceBatteryConsumer.getConsumedPower(),
- modeledAppsBatteryConsumer.getConsumedPower());
- }
+ addEntry("Consumed", EntryType.DEVICE_TOTAL_POWER,
+ deviceBatteryConsumer.getConsumedPower(),
+ appsBatteryConsumer.getConsumedPower());
mBatteryConsumerInfo = BatteryConsumerInfoHelper.makeBatteryConsumerInfo(batteryUsageStats,
AGGREGATE_BATTERY_CONSUMER_ID, context.getPackageManager());
-
for (int component = 0; component < BatteryConsumer.POWER_COMPONENT_COUNT; component++) {
final String metricTitle = getPowerMetricTitle(component);
- final int powerModel = deviceBatteryConsumer.getPowerModel(component);
- if (powerModel == BatteryConsumer.POWER_MODEL_POWER_PROFILE
- || powerModel == BatteryConsumer.POWER_MODEL_UNDEFINED) {
- addEntry(metricTitle, EntryType.DEVICE_POWER_MODELED,
- deviceBatteryConsumer.getConsumedPower(component),
- appsBatteryConsumer.getConsumedPower(component));
- } else {
- addEntry(metricTitle + " (PowerStats)", EntryType.DEVICE_POWER_ENERGY_CONSUMPTION,
- deviceBatteryConsumer.getConsumedPower(component),
- appsBatteryConsumer.getConsumedPower(component));
- addEntry(metricTitle + " (PowerProfile)", EntryType.DEVICE_POWER_MODELED,
- modeledDeviceBatteryConsumer.getConsumedPower(component),
- modeledAppsBatteryConsumer.getConsumedPower(component));
- }
+ addEntry(metricTitle, EntryType.DEVICE_POWER,
+ deviceBatteryConsumer.getConsumedPower(component),
+ appsBatteryConsumer.getConsumedPower(component));
}
final int customComponentCount =
@@ -258,10 +205,10 @@ public class BatteryConsumerData {
for (int component = 0; component < customComponentCount; component++) {
final String name = deviceBatteryConsumer.getCustomPowerComponentName(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + component);
- addEntry(name + " (PowerStats)", EntryType.DEVICE_POWER_CUSTOM,
- deviceBatteryConsumer.getConsumedPowerForCustomComponent(
+ addEntry(name, EntryType.DEVICE_POWER_CUSTOM,
+ deviceBatteryConsumer.getConsumedPower(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + component),
- appsBatteryConsumer.getConsumedPowerForCustomComponent(
+ appsBatteryConsumer.getConsumedPower(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + component));
}
@@ -272,17 +219,6 @@ public class BatteryConsumerData {
}
}
- private boolean isPowerProfileModelsOnly(BatteryConsumer batteryConsumer) {
- for (int component = 0; component < BatteryConsumer.POWER_COMPONENT_COUNT; component++) {
- final int powerModel = batteryConsumer.getPowerModel(component);
- if (powerModel != BatteryConsumer.POWER_MODEL_POWER_PROFILE
- && powerModel != BatteryConsumer.POWER_MODEL_UNDEFINED) {
- return false;
- }
- }
- return true;
- }
-
private BatteryConsumer getRequestedBatteryConsumer(BatteryUsageStats batteryUsageStats,
String batteryConsumerId) {
for (UidBatteryConsumer consumer : batteryUsageStats.getUidBatteryConsumers()) {
@@ -352,13 +288,14 @@ public class BatteryConsumerData {
}
}
- private void addEntry(String title, EntryType entryType, double value1, double value2) {
+ private Entry addEntry(String title, EntryType entryType, double value1, double value2) {
Entry entry = new Entry();
entry.title = title;
entry.entryType = entryType;
entry.value1 = value1;
entry.value2 = value2;
mEntries.add(entry);
+ return entry;
}
public BatteryConsumerInfoHelper.BatteryConsumerInfo getBatteryConsumerInfo() {
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java
index c6d71c3f573a..37d6b17a665c 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java
@@ -24,6 +24,8 @@ import android.os.UidBatteryConsumer;
import androidx.annotation.NonNull;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
import java.util.List;
class BatteryConsumerInfoHelper {
@@ -76,6 +78,8 @@ class BatteryConsumerInfoHelper {
String packageWithHighestDrain = uidBatteryConsumer.getPackageWithHighestDrain();
if (uid == Process.ROOT_UID) {
info.label = "<root>";
+ } else if (uid < Process.FIRST_APPLICATION_UID) {
+ info.label = makeSystemUidLabel(uid);
} else {
String[] packages = packageManager.getPackagesForUid(uid);
String primaryPackageName = null;
@@ -134,6 +138,23 @@ class BatteryConsumerInfoHelper {
return info;
}
+ private static CharSequence makeSystemUidLabel(int uid) {
+ for (Field field : Process.class.getDeclaredFields()) {
+ final int modifiers = field.getModifiers();
+ if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)
+ && field.getType().equals(int.class) && field.getName().endsWith("_UID")) {
+ try {
+ if (uid == field.getInt(null)) {
+ String label = field.getName();
+ return label.substring(0, label.lastIndexOf("_UID"));
+ }
+ } catch (IllegalAccessException ignored) {
+ }
+ }
+ }
+ return null;
+ }
+
private static BatteryConsumerInfo makeAggregateBatteryConsumerInfo(
BatteryUsageStats batteryUsageStats) {
BatteryConsumerInfo info = new BatteryConsumerInfo();
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java
index 4469168a77b4..3699690aca59 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java
@@ -30,8 +30,8 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
-import androidx.activity.ComponentActivity;
import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatActivity;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.LinearLayoutManager;
@@ -50,7 +50,7 @@ import java.util.Locale;
* Picker, showing a sorted lists of applications and other types of entities consuming power.
* Opens BatteryStatsViewerActivity upon item selection.
*/
-public class BatteryConsumerPickerActivity extends ComponentActivity {
+public class BatteryConsumerPickerActivity extends AppCompatActivity {
private static final String PREF_SELECTED_BATTERY_CONSUMER = "batteryConsumerId";
private static final int BATTERY_STATS_REFRESH_RATE_MILLIS = 60 * 1000;
private static final String FORCE_FRESH_STATS = "force_fresh_stats";
@@ -68,6 +68,7 @@ public class BatteryConsumerPickerActivity extends ComponentActivity {
super.onCreate(icicle);
setContentView(R.layout.battery_consumer_picker_layout);
+ setSupportActionBar(findViewById(R.id.toolbar));
mSwipeRefreshLayout = findViewById(R.id.swipe_refresh);
mSwipeRefreshLayout.setColorSchemeResources(android.R.color.holo_green_light);
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java
index e165c49ff55d..350213161b7b 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java
@@ -17,14 +17,18 @@
package com.android.frameworks.core.batterystatsviewer;
import android.content.Context;
+import android.os.BatteryConsumer;
import android.os.BatteryStatsManager;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
import android.os.Bundle;
+import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
+import android.widget.TableLayout;
+import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
@@ -40,6 +44,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.android.settingslib.utils.AsyncLoaderCompat;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
@@ -63,7 +68,16 @@ public class BatteryStatsViewerActivity extends ComponentActivity {
private SwipeRefreshLayout mSwipeRefreshLayout;
private View mCardView;
private View mEmptyView;
- private List<BatteryUsageStats> mBatteryUsageStats;
+ private BatteryUsageStats mBatteryUsageStats;
+
+ private static SparseArray<String> sProcStateNames = new SparseArray<>();
+ static {
+ sProcStateNames.put(BatteryConsumer.PROCESS_STATE_UNSPECIFIED, "-");
+ sProcStateNames.put(BatteryConsumer.PROCESS_STATE_FOREGROUND, "FG");
+ sProcStateNames.put(BatteryConsumer.PROCESS_STATE_BACKGROUND, "BG");
+ sProcStateNames.put(BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE, "FGS");
+ sProcStateNames.put(BatteryConsumer.PROCESS_STATE_CACHED, "Cached");
+ }
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -122,7 +136,7 @@ public class BatteryStatsViewerActivity extends ComponentActivity {
}
private static class BatteryUsageStatsLoader extends
- AsyncLoaderCompat<List<BatteryUsageStats>> {
+ AsyncLoaderCompat<BatteryUsageStats> {
private final BatteryStatsManager mBatteryStatsManager;
private final boolean mForceFreshStats;
@@ -133,51 +147,44 @@ public class BatteryStatsViewerActivity extends ComponentActivity {
}
@Override
- public List<BatteryUsageStats> loadInBackground() {
+ public BatteryUsageStats loadInBackground() {
final int maxStatsAgeMs = mForceFreshStats ? 0 : BATTERY_STATS_REFRESH_RATE_MILLIS;
final BatteryUsageStatsQuery queryDefault =
new BatteryUsageStatsQuery.Builder()
- .includePowerModels()
.includeProcessStateData()
+ .includeScreenStateData()
+ .includePowerStateData()
.setMaxStatsAgeMs(maxStatsAgeMs)
.build();
- final BatteryUsageStatsQuery queryPowerProfileModeledOnly =
- new BatteryUsageStatsQuery.Builder()
- .powerProfileModeledOnly()
- .includePowerModels()
- .includeProcessStateData()
- .setMaxStatsAgeMs(maxStatsAgeMs)
- .build();
- return mBatteryStatsManager.getBatteryUsageStats(
- List.of(queryDefault, queryPowerProfileModeledOnly));
+ return mBatteryStatsManager.getBatteryUsageStats(queryDefault);
}
@Override
- protected void onDiscardResult(List<BatteryUsageStats> result) {
+ protected void onDiscardResult(BatteryUsageStats result) {
}
}
private class BatteryUsageStatsLoaderCallbacks
- implements LoaderCallbacks<List<BatteryUsageStats>> {
+ implements LoaderCallbacks<BatteryUsageStats> {
@NonNull
@Override
- public Loader<List<BatteryUsageStats>> onCreateLoader(int id, Bundle args) {
+ public Loader<BatteryUsageStats> onCreateLoader(int id, Bundle args) {
return new BatteryUsageStatsLoader(BatteryStatsViewerActivity.this,
args.getBoolean(FORCE_FRESH_STATS));
}
@Override
- public void onLoadFinished(@NonNull Loader<List<BatteryUsageStats>> loader,
- List<BatteryUsageStats> batteryUsageStats) {
+ public void onLoadFinished(@NonNull Loader<BatteryUsageStats> loader,
+ BatteryUsageStats batteryUsageStats) {
onBatteryUsageStatsLoaded(batteryUsageStats);
}
@Override
- public void onLoaderReset(@NonNull Loader<List<BatteryUsageStats>> loader) {
+ public void onLoaderReset(@NonNull Loader<BatteryUsageStats> loader) {
}
}
- private void onBatteryUsageStatsLoaded(List<BatteryUsageStats> batteryUsageStats) {
+ private void onBatteryUsageStatsLoaded(BatteryUsageStats batteryUsageStats) {
mBatteryUsageStats = batteryUsageStats;
onBatteryStatsDataLoaded();
}
@@ -238,10 +245,21 @@ public class BatteryStatsViewerActivity extends ComponentActivity {
private static class BatteryStatsDataAdapter extends
RecyclerView.Adapter<BatteryStatsDataAdapter.ViewHolder> {
public static class ViewHolder extends RecyclerView.ViewHolder {
+ public static class SliceViewHolder {
+ public TableRow tableRow;
+ public int procState;
+ public int powerState;
+ public int screenState;
+ public TextView powerTextView;
+ public TextView durationTextView;
+ }
+
public ImageView iconImageView;
public TextView titleTextView;
public TextView value1TextView;
public TextView value2TextView;
+ public TableLayout table;
+ public List<SliceViewHolder> slices = new ArrayList<>();
ViewHolder(View itemView) {
super(itemView);
@@ -250,6 +268,40 @@ public class BatteryStatsViewerActivity extends ComponentActivity {
titleTextView = itemView.findViewById(R.id.title);
value1TextView = itemView.findViewById(R.id.value1);
value2TextView = itemView.findViewById(R.id.value2);
+ table = itemView.findViewById(R.id.table);
+
+ for (int i = 0; i < sProcStateNames.size(); i++) {
+ int procState = sProcStateNames.keyAt(i);
+ slices.add(createSliceViewHolder(procState,
+ BatteryConsumer.POWER_STATE_BATTERY,
+ BatteryConsumer.SCREEN_STATE_ON,
+ R.id.power_b_on, R.id.duration_b_on));
+ slices.add(createSliceViewHolder(procState,
+ BatteryConsumer.POWER_STATE_BATTERY,
+ BatteryConsumer.SCREEN_STATE_OTHER,
+ R.id.power_b_off, R.id.duration_b_off));
+ slices.add(createSliceViewHolder(procState,
+ BatteryConsumer.POWER_STATE_OTHER,
+ BatteryConsumer.SCREEN_STATE_ON,
+ R.id.power_c_on, R.id.duration_c_on));
+ slices.add(createSliceViewHolder(procState,
+ BatteryConsumer.POWER_STATE_OTHER,
+ BatteryConsumer.SCREEN_STATE_OTHER,
+ R.id.power_c_off, R.id.duration_c_off));
+ }
+ }
+
+ private SliceViewHolder createSliceViewHolder(int procState, int powerState,
+ int screenState, int powerTextViewResId, int durationTextViewResId) {
+ TableRow powerRow = table.findViewWithTag("procstate" + procState);
+ SliceViewHolder svh = new SliceViewHolder();
+ svh.tableRow = powerRow;
+ svh.procState = procState;
+ svh.powerState = powerState;
+ svh.screenState = screenState;
+ svh.powerTextView = powerRow.findViewById(powerTextViewResId);
+ svh.durationTextView = powerRow.findViewById(durationTextViewResId);
+ return svh;
}
}
@@ -269,62 +321,32 @@ public class BatteryStatsViewerActivity extends ComponentActivity {
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int position) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
- View itemView = layoutInflater.inflate(R.layout.battery_consumer_entry_layout, parent,
- false);
+ ViewGroup itemView = (ViewGroup) layoutInflater.inflate(
+ R.layout.battery_consumer_entry_layout, parent, false);
+ TableLayout table = itemView.findViewById(R.id.table);
+ int offset = 1; // Skip header
+ for (int i = 0; i < sProcStateNames.size(); i++) {
+ View powerRow = layoutInflater.inflate(R.layout.battery_consumer_slices_layout,
+ itemView, false);
+ ((TextView) powerRow.findViewById(R.id.procState))
+ .setText(sProcStateNames.valueAt(i));
+ powerRow.setTag("procstate" + sProcStateNames.keyAt(i));
+ table.addView(powerRow, offset++);
+ }
+
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
BatteryConsumerData.Entry entry = mEntries.get(position);
-
switch (entry.entryType) {
- case UID_TOTAL_POWER:
- setTitleIconAndBackground(viewHolder, entry.title,
- R.drawable.gm_sum_24, 0);
- setPowerText(viewHolder.value1TextView, entry.value1);
- setProportionText(viewHolder.value2TextView, entry);
- break;
- case UID_POWER_PROFILE:
- setTitleIconAndBackground(viewHolder, entry.title,
- R.drawable.gm_calculate_24,
- R.color.battery_consumer_bg_power_profile);
- setPowerText(viewHolder.value1TextView, entry.value1);
- setProportionText(viewHolder.value2TextView, entry);
- break;
- case UID_POWER_PROFILE_PROCESS_STATE:
- setTitleIconAndBackground(viewHolder, " " + entry.title,
- R.drawable.gm_calculate_24,
- R.color.battery_consumer_bg_power_profile);
- setPowerText(viewHolder.value1TextView, entry.value1);
- viewHolder.value2TextView.setVisibility(View.INVISIBLE);
- break;
- case UID_POWER_ENERGY_CONSUMPTION:
- setTitleIconAndBackground(viewHolder, entry.title,
- R.drawable.gm_energy_24,
- R.color.battery_consumer_bg_energy_consumption);
- setPowerText(viewHolder.value1TextView, entry.value1);
- setProportionText(viewHolder.value2TextView, entry);
- break;
- case UID_POWER_ENERGY_PROCESS_STATE:
- setTitleIconAndBackground(viewHolder, " " + entry.title,
- R.drawable.gm_energy_24,
- R.color.battery_consumer_bg_energy_consumption);
- setPowerText(viewHolder.value1TextView, entry.value1);
- viewHolder.value2TextView.setVisibility(View.INVISIBLE);
- break;
- case UID_POWER_CUSTOM:
+ case UID:
setTitleIconAndBackground(viewHolder, entry.title,
- R.drawable.gm_energy_24,
- R.color.battery_consumer_bg_energy_consumption);
+ R.drawable.gm_energy_24, 0);
setPowerText(viewHolder.value1TextView, entry.value1);
setProportionText(viewHolder.value2TextView, entry);
- break;
- case UID_DURATION:
- setTitleIconAndBackground(viewHolder, entry.title,
- R.drawable.gm_timer_24, 0);
- setDurationText(viewHolder.value1TextView, (long) entry.value1);
- setProportionText(viewHolder.value2TextView, entry);
+ bindSlices(viewHolder, entry);
break;
case DEVICE_TOTAL_POWER:
setTitleIconAndBackground(viewHolder, entry.title,
@@ -332,27 +354,13 @@ public class BatteryStatsViewerActivity extends ComponentActivity {
setPowerText(viewHolder.value1TextView, entry.value1);
setPowerText(viewHolder.value2TextView, entry.value2);
break;
- case DEVICE_POWER_MODELED:
+ case DEVICE_POWER:
setTitleIconAndBackground(viewHolder, entry.title,
R.drawable.gm_calculate_24,
R.color.battery_consumer_bg_power_profile);
setPowerText(viewHolder.value1TextView, entry.value1);
setPowerText(viewHolder.value2TextView, entry.value2);
break;
- case DEVICE_POWER_ENERGY_CONSUMPTION:
- setTitleIconAndBackground(viewHolder, entry.title,
- R.drawable.gm_energy_24,
- R.color.battery_consumer_bg_energy_consumption);
- setPowerText(viewHolder.value1TextView, entry.value1);
- setPowerText(viewHolder.value2TextView, entry.value2);
- break;
- case DEVICE_POWER_CUSTOM:
- setTitleIconAndBackground(viewHolder, entry.title,
- R.drawable.gm_energy_24,
- R.color.battery_consumer_bg_energy_consumption);
- setPowerText(viewHolder.value1TextView, entry.value1);
- setPowerText(viewHolder.value2TextView, entry.value2);
- break;
case DEVICE_DURATION:
setTitleIconAndBackground(viewHolder, entry.title,
R.drawable.gm_timer_24, 0);
@@ -362,6 +370,65 @@ public class BatteryStatsViewerActivity extends ComponentActivity {
}
}
+ private void bindSlices(ViewHolder viewHolder, BatteryConsumerData.Entry entry) {
+ if (entry.slices == null || entry.slices.isEmpty()) {
+ viewHolder.table.setVisibility(View.GONE);
+ return;
+ }
+ viewHolder.table.setVisibility(View.VISIBLE);
+
+ boolean[] procStateRowPopulated =
+ new boolean[BatteryConsumer.PROCESS_STATE_COUNT];
+ for (BatteryConsumerData.Slice s : entry.slices) {
+ if (s.powerMah != 0 || s.durationMs != 0) {
+ procStateRowPopulated[s.processState] = true;
+ }
+ }
+
+ for (ViewHolder.SliceViewHolder sliceViewHolder : viewHolder.slices) {
+ BatteryConsumerData.Slice slice = null;
+ for (BatteryConsumerData.Slice s : entry.slices) {
+ if (s.powerState == sliceViewHolder.powerState
+ && s.screenState == sliceViewHolder.screenState
+ && s.processState == sliceViewHolder.procState) {
+ slice = s;
+ break;
+ }
+ }
+ if (!procStateRowPopulated[sliceViewHolder.procState]) {
+ sliceViewHolder.tableRow.setVisibility(View.GONE);
+ } else {
+ sliceViewHolder.tableRow.setVisibility(View.VISIBLE);
+
+ if (slice != null && (slice.powerMah != 0 || slice.durationMs != 0)) {
+ sliceViewHolder.powerTextView.setText(
+ String.format(Locale.getDefault(), "%.1f", slice.powerMah));
+ } else {
+ sliceViewHolder.powerTextView.setText(null);
+ }
+
+ if (slice != null && slice.durationMs != 0) {
+ sliceViewHolder.durationTextView.setVisibility(View.VISIBLE);
+ String timeString;
+ if (slice.durationMs < MILLIS_IN_MINUTE) {
+ timeString = String.format(Locale.getDefault(), "%ds",
+ slice.durationMs / 1000);
+ } else if (slice.durationMs < 60 * MILLIS_IN_MINUTE) {
+ timeString = String.format(Locale.getDefault(), "%dm %ds",
+ slice.durationMs / MILLIS_IN_MINUTE,
+ (slice.durationMs % MILLIS_IN_MINUTE) / 1000);
+ } else {
+ timeString = String.format(Locale.getDefault(), "%dm",
+ slice.durationMs / MILLIS_IN_MINUTE);
+ }
+ sliceViewHolder.durationTextView.setText(timeString);
+ } else {
+ sliceViewHolder.durationTextView.setVisibility(View.GONE);
+ }
+ }
+ }
+ }
+
private void setTitleIconAndBackground(ViewHolder viewHolder, String title, int icon,
int background) {
viewHolder.titleTextView.setText(title);
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/TrampolineActivity.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/TrampolineActivity.java
index b01648838695..412169e7a905 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/TrampolineActivity.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/TrampolineActivity.java
@@ -42,5 +42,6 @@ public class TrampolineActivity extends Activity {
private void launchMainActivity() {
startActivity(new Intent(this, BatteryConsumerPickerActivity.class));
+ finish();
}
}
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 79c9ec56302b..63e8d9973237 100644
--- a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
+++ b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
@@ -26,6 +26,7 @@ import android.os.BatteryUsageStatsQuery;
import android.os.Handler;
import android.os.Process;
import android.util.Log;
+import android.util.LogWriter;
import android.util.Slog;
import android.util.SparseArray;
@@ -34,6 +35,7 @@ import com.android.internal.os.CpuScalingPolicies;
import com.android.internal.os.MonotonicClock;
import com.android.internal.os.PowerProfile;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -44,6 +46,8 @@ import java.util.List;
*/
public class BatteryUsageStatsProvider {
private static final String TAG = "BatteryUsageStatsProv";
+ private static final boolean DEBUG = false;
+
private final Context mContext;
private final PowerAttributor mPowerAttributor;
private final PowerStatsStore mPowerStatsStore;
@@ -262,17 +266,25 @@ public class BatteryUsageStatsProvider {
private BatteryUsageStats getBatteryUsageStats(BatteryStatsImpl stats,
BatteryUsageStatsQuery query, long currentTimeMs) {
+ BatteryUsageStats batteryUsageStats;
if ((query.getFlags()
& BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_ACCUMULATED) != 0) {
- return getAccumulatedBatteryUsageStats(stats, query, currentTimeMs);
+ batteryUsageStats = getAccumulatedBatteryUsageStats(stats, query, currentTimeMs);
} else if (query.getAggregatedToTimestamp() == 0) {
BatteryUsageStats.Builder builder = computeBatteryUsageStats(stats, query,
query.getMonotonicStartTime(),
query.getMonotonicEndTime(), currentTimeMs);
- return builder.build();
+ batteryUsageStats = builder.build();
} else {
- return getAggregatedBatteryUsageStats(stats, query);
+ batteryUsageStats = getAggregatedBatteryUsageStats(stats, query);
+ }
+ if (DEBUG) {
+ Slog.d(TAG, "query = " + query);
+ PrintWriter pw = new PrintWriter(new LogWriter(Log.DEBUG, TAG));
+ batteryUsageStats.dump(pw, "");
+ pw.flush();
}
+ return batteryUsageStats;
}
private BatteryUsageStats getAccumulatedBatteryUsageStats(BatteryStatsImpl stats,