Merge original AOSP chart into battery usage with runtime switchable

This patch is merged from ag/14111128 and seperate two different chart
design between isChratGraphEnabled() method, but we drop the options
menu in the both versions to align the new material next design.

Bug: 185187718
Bug: 185187591
Bug: 177406865
Test: make SettingsRoboTests
Test: make SettingsGoogleRoboTests
Change-Id: Ie88df6a94abf5d1652440fe35392b9f47c447537
This commit is contained in:
ykhung
2021-04-17 23:52:28 +08:00
committed by YUKAI HUNG
parent 434ce05cec
commit 33115020ba
4 changed files with 227 additions and 15 deletions

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2021 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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingStart="@dimen/preference_no_icon_padding_start"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:orientation="vertical">
<TextView
android:id="@+id/charge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:fontFamily="@*android:string/config_headlineFontFamily"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="36sp"
android:textColor="?android:attr/colorAccent" />
<com.android.settings.widget.UsageView
android:id="@+id/battery_usage"
android:layout_width="match_parent"
android:layout_height="141dp"
android:layout_marginBottom="16dp"
settings:sideLabels="@array/battery_labels"
android:colorAccent="?android:attr/colorAccent"
android:gravity="end"
settings:textColor="?android:attr/textColorSecondary" />
<TextView
android:id="@+id/bottom_summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>

View File

@@ -21,6 +21,7 @@ import android.os.BatteryUsageStats;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
@@ -29,6 +30,7 @@ import androidx.preference.PreferenceViewHolder;
import com.android.settings.R;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.UsageView;
/**
* Custom preference for displaying the battery level as chart graph.
@@ -36,24 +38,45 @@ import com.android.settings.overlay.FeatureFactory;
public class BatteryHistoryPreference extends Preference {
private static final String TAG = "BatteryHistoryPreference";
@VisibleForTesting
BatteryInfo mBatteryInfo;
@VisibleForTesting boolean mHideSummary;
@VisibleForTesting BatteryInfo mBatteryInfo;
private boolean mIsChartGraphEnabled;
private TextView mSummaryView;
private CharSequence mSummaryContent;
private BatteryChartView mBatteryChartView;
private BatteryChartPreferenceController mChartPreferenceController;
public BatteryHistoryPreference(Context context, AttributeSet attrs) {
super(context, attrs);
final boolean isChartGraphEnabled =
mIsChartGraphEnabled =
FeatureFactory.getFactory(context).getPowerUsageFeatureProvider(context)
.isChartGraphEnabled(context);
Log.i(TAG, "isChartGraphEnabled: " + isChartGraphEnabled);
if (isChartGraphEnabled) {
setLayoutResource(R.layout.battery_chart_graph);
}
Log.i(TAG, "isChartGraphEnabled: " + mIsChartGraphEnabled);
setLayoutResource(
mIsChartGraphEnabled
? R.layout.battery_chart_graph
: R.layout.battery_usage_graph);
setSelectable(false);
}
public void setBottomSummary(CharSequence text) {
mSummaryContent = text;
if (mSummaryView != null) {
mSummaryView.setVisibility(View.VISIBLE);
mSummaryView.setText(mSummaryContent);
}
mHideSummary = false;
}
public void hideBottomSummary() {
if (mSummaryView != null) {
mSummaryView.setVisibility(View.GONE);
}
mHideSummary = true;
}
void setBatteryUsageStats(@NonNull BatteryUsageStats batteryUsageStats) {
BatteryInfo.getBatteryInfo(getContext(), info -> {
mBatteryInfo = info;
@@ -75,9 +98,24 @@ public class BatteryHistoryPreference extends Preference {
if (mBatteryInfo == null) {
return;
}
mBatteryChartView = (BatteryChartView) view.findViewById(R.id.battery_chart);
if (mChartPreferenceController != null) {
mChartPreferenceController.setBatteryChartView(mBatteryChartView);
if (mIsChartGraphEnabled) {
mBatteryChartView = (BatteryChartView) view.findViewById(R.id.battery_chart);
if (mChartPreferenceController != null) {
mChartPreferenceController.setBatteryChartView(mBatteryChartView);
}
} else {
final TextView chargeView = (TextView) view.findViewById(R.id.charge);
chargeView.setText(mBatteryInfo.batteryPercentString);
mSummaryView = (TextView) view.findViewById(R.id.bottom_summary);
if (mSummaryContent != null) {
mSummaryView.setText(mSummaryContent);
}
if (mHideSummary) {
mSummaryView.setVisibility(View.GONE);
}
final UsageView usageView = (UsageView) view.findViewById(R.id.battery_usage);
usageView.findViewById(R.id.label_group).setAlpha(.7f);
mBatteryInfo.bindHistory(usageView);
}
BatteryUtils.logRuntime(TAG, "onBindViewHolder", startTime);
}

View File

@@ -17,6 +17,8 @@ import static com.android.settings.fuelgauge.BatteryBroadcastReceiver.BatteryUpd
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Bundle;
import android.provider.SearchIndexableResource;
@@ -63,13 +65,14 @@ public class PowerUsageAdvanced extends PowerUsageBase {
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
refreshFeatureFlag(getContext());
final Context context = getContext();
refreshFeatureFlag(context);
mHistPref = (BatteryHistoryPreference) findPreference(KEY_BATTERY_GRAPH);
// Removes chart graph preference if the chart design is disabled.
if (!mIsChartGraphEnabled) {
removePreference(KEY_BATTERY_GRAPH);
if (mIsChartGraphEnabled) {
setBatteryChartPreferenceController();
} else {
updateHistPrefSummary(context);
}
setBatteryChartPreferenceController();
}
@Override
@@ -128,6 +131,7 @@ public class PowerUsageAdvanced extends PowerUsageBase {
}
updatePreference(mHistPref);
if (mBatteryAppListPreferenceController != null && mBatteryUsageStats != null) {
updateHistPrefSummary(context);
mBatteryAppListPreferenceController.refreshAppListGroup(
mBatteryUsageStats, /* showAllApps */true);
}
@@ -149,6 +153,18 @@ public class PowerUsageAdvanced extends PowerUsageBase {
}
}
private void updateHistPrefSummary(Context context) {
final Intent batteryIntent =
context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
final boolean plugged = batteryIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) != 0;
if (mPowerUsageFeatureProvider.isEnhancedBatteryPredictionEnabled(context) && !plugged) {
mHistPref.setBottomSummary(
mPowerUsageFeatureProvider.getAdvancedUsageScreenInfoString());
} else {
mHistPref.hideBottomSummary();
}
}
private void refreshFeatureFlag(Context context) {
if (mPowerUsageFeatureProvider == null) {
mPowerUsageFeatureProvider = FeatureFactory.getFactory(context)

View File

@@ -0,0 +1,105 @@
/*
* Copyright (C) 2021 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.settings.fuelgauge;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import androidx.preference.PreferenceViewHolder;
import com.android.settings.R;
import com.android.settings.widget.UsageView;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class BatteryHistoryPreferenceTest {
private static final String TEST_STRING = "test";
@Mock
private PreferenceViewHolder mViewHolder;
@Mock
private BatteryInfo mBatteryInfo;
@Mock
private TextView mTextView;
@Mock
private UsageView mUsageView;
@Mock
private View mLabelView;
private BatteryHistoryPreference mBatteryHistoryPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
final Context context = RuntimeEnvironment.application;
final View itemView =
LayoutInflater.from(context).inflate(R.layout.battery_usage_graph, null);
mBatteryHistoryPreference = new BatteryHistoryPreference(context, null);
mBatteryHistoryPreference.mBatteryInfo = mBatteryInfo;
mViewHolder = spy(PreferenceViewHolder.createInstanceForTests(itemView));
when(mViewHolder.findViewById(R.id.battery_usage)).thenReturn(mUsageView);
when(mViewHolder.findViewById(R.id.charge)).thenReturn(mTextView);
when(mUsageView.findViewById(anyInt())).thenReturn(mLabelView);
}
@Test
public void testOnBindViewHolder_updateBatteryUsage() {
mBatteryHistoryPreference.onBindViewHolder(mViewHolder);
verify(mViewHolder).findViewById(R.id.battery_usage);
verify(mTextView).setText(nullable(String.class));
verify(mBatteryInfo).bindHistory(mUsageView);
}
@Test
public void testSetBottomSummary_updatesBottomSummaryTextIfSet() {
mBatteryHistoryPreference.setBottomSummary(TEST_STRING);
mBatteryHistoryPreference.onBindViewHolder(mViewHolder);
TextView view = (TextView) mViewHolder.findViewById(R.id.bottom_summary);
assertThat(view.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(view.getText()).isEqualTo(TEST_STRING);
assertThat(mBatteryHistoryPreference.mHideSummary).isFalse();
}
@Test
public void testSetBottomSummary_leavesBottomSummaryTextBlankIfNotSet() {
mBatteryHistoryPreference.hideBottomSummary();
mBatteryHistoryPreference.onBindViewHolder(mViewHolder);
TextView view = (TextView) mViewHolder.findViewById(R.id.bottom_summary);
assertThat(view.getVisibility()).isEqualTo(View.GONE);
assertThat(view.getText()).isEqualTo("");
assertThat(mBatteryHistoryPreference.mHideSummary).isTrue();
}
}