Add BatteryMeterView in Settings

1. Show gauge icon at the top of battery main page instead of
battery usage graph.
2. Move the click action from battery usage graph to gauge icon.

Bug: 34387464
Test: RunSettingsRoboTest

Change-Id: Ib182619d6805b401cde03a50e2ae907cf4df7b94
This commit is contained in:
jackqdyulei
2017-02-02 11:25:15 -08:00
parent 3fca717d3b
commit 51967c0e6a
15 changed files with 366 additions and 38 deletions

View File

@@ -59,7 +59,6 @@ public class LayoutPreference extends Preference {
private void setView(View view) {
setLayoutResource(R.layout.layout_preference_frame);
setSelectable(false);
final ViewGroup allDetails = (ViewGroup) view.findViewById(R.id.all_details);
if (allDetails != null) {
Utils.forceCustomPadding(allDetails, true /* additive padding */);
@@ -70,6 +69,7 @@ public class LayoutPreference extends Preference {
@Override
public void onBindViewHolder(PreferenceViewHolder view) {
super.onBindViewHolder(view);
FrameLayout layout = (FrameLayout) view.itemView;
layout.removeAllViews();
ViewGroup parent = (ViewGroup) mRootView.getParent();

View File

@@ -37,6 +37,7 @@ import com.android.settingslib.graph.UsageView;
public class BatteryHistoryDetail extends SettingsPreferenceFragment {
public static final String EXTRA_STATS = "stats";
public static final String EXTRA_BROADCAST = "broadcast";
public static final String BATTERY_HISTORY_FILE = "tmp_bat_history.bin";
private BatteryStats mStats;
private Intent mBatteryBroadcast;

View File

@@ -33,43 +33,18 @@ import com.android.settingslib.graph.UsageView;
/**
* Custom preference for displaying power consumption as a bar and an icon on the left for the
* subsystem/app type.
*
*/
public class BatteryHistoryPreference extends Preference {
protected static final String BATTERY_HISTORY_FILE = "tmp_bat_history.bin";
private BatteryStatsHelper mHelper;
private BatteryInfo mBatteryInfo;
public BatteryHistoryPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setLayoutResource(R.layout.battery_usage_graph);
setSelectable(true);
}
@Override
public void performClick() {
// TODO(b/34890746): remove this since history graph is not clickable
final Context context = getContext();
final PowerUsageFeatureProvider featureProvider = FeatureFactory.getFactory(context)
.getPowerUsageFeatureProvider(context);
if (featureProvider.isAdvancedUiEnabled()) {
Utils.startWithFragment(getContext(), PowerUsageAdvanced.class.getName(), null,
null, 0, R.string.advanced_battery_title, null);
} else {
mHelper.storeStatsHistoryInFile(BATTERY_HISTORY_FILE);
Bundle args = new Bundle();
args.putString(BatteryHistoryDetail.EXTRA_STATS, BATTERY_HISTORY_FILE);
args.putParcelable(BatteryHistoryDetail.EXTRA_BROADCAST, mHelper.getBatteryBroadcast());
Utils.startWithFragment(getContext(), BatteryHistoryDetail.class.getName(), args,
null, 0, R.string.history_details_title, null);
}
setSelectable(false);
}
public void setStats(BatteryStatsHelper batteryStats) {
mHelper = batteryStats;
final long elapsedRealtimeUs = SystemClock.elapsedRealtime() * 1000;
mBatteryInfo = BatteryInfo.getBatteryInfo(getContext(), batteryStats.getBatteryBroadcast(),
batteryStats.getStats(), elapsedRealtimeUs);

View File

@@ -0,0 +1,86 @@
/*
* Copyright (C) 2017 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 android.annotation.Nullable;
import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.support.annotation.VisibleForTesting;
import android.util.AttributeSet;
import android.widget.ImageView;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settingslib.graph.BatteryMeterDrawableBase;
public class BatteryMeterView extends ImageView {
private BatteryMeterDrawable mDrawable;
public BatteryMeterView(Context context) {
this(context, null, 0);
}
public BatteryMeterView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public BatteryMeterView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
final int frameColor = context.getColor(R.color.batterymeter_frame_color);
final int tintColor = Utils.getColorAttr(context, android.R.attr.colorAccent);
mDrawable = new BatteryMeterDrawable(context, frameColor);
mDrawable.setColorFilter(new PorterDuffColorFilter(tintColor, PorterDuff.Mode.SRC_IN));
mDrawable.setShowPercent(true);
setImageDrawable(mDrawable);
}
public void setBatteryInfo(int level) {
mDrawable.setBatteryLevel(level);
}
@VisibleForTesting
void setBatteryDrawable(BatteryMeterDrawable drawable) {
mDrawable = drawable;
}
public static class BatteryMeterDrawable extends BatteryMeterDrawableBase {
private final int mIntrinsicWidth;
private final int mIntrinsicHeight;
public BatteryMeterDrawable(Context context, int frameColor) {
super(context, frameColor);
mIntrinsicWidth = context.getResources()
.getDimensionPixelSize(R.dimen.battery_meter_width);
mIntrinsicHeight = context.getResources()
.getDimensionPixelSize(R.dimen.battery_meter_height);
}
@Override
public int getIntrinsicWidth() {
return mIntrinsicWidth;
}
@Override
public int getIntrinsicHeight() {
return mIntrinsicHeight;
}
}
}

View File

@@ -72,7 +72,7 @@ public abstract class PowerUsageBase extends DashboardFragment {
@Override
public void onResume() {
super.onResume();
BatteryStatsHelper.dropFile(getActivity(), BatteryHistoryPreference.BATTERY_HISTORY_FILE);
BatteryStatsHelper.dropFile(getActivity(), BatteryHistoryDetail.BATTERY_HISTORY_FILE);
updateBatteryStatus(getActivity().registerReceiver(mBatteryInfoReceiver,
new IntentFilter(Intent.ACTION_BATTERY_CHANGED)));
if (mHandler.hasMessages(MSG_REFRESH_STATS)) {

View File

@@ -38,7 +38,9 @@ import android.util.TypedValue;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatterySipper.DrainType;
@@ -47,6 +49,7 @@ import com.android.settings.R;
import com.android.settings.Settings.HighPowerApplicationsActivity;
import com.android.settings.SettingsActivity;
import com.android.settings.Utils;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.applications.ManageApplications;
import com.android.settings.core.PreferenceController;
import com.android.settings.dashboard.SummaryLoader;
@@ -75,7 +78,7 @@ public class PowerUsageSummary extends PowerUsageBase {
static final String TAG = "PowerUsageSummary";
private static final String KEY_APP_LIST = "app_list";
private static final String KEY_BATTERY_HISTORY = "battery_history";
private static final String KEY_BATTERY_HEADER = "battery_header";
private static final int MENU_STATS_TYPE = Menu.FIRST;
private static final int MENU_HIGH_POWER_APPS = Menu.FIRST + 3;
@@ -83,7 +86,7 @@ public class PowerUsageSummary extends PowerUsageBase {
static final int MENU_ADDITIONAL_BATTERY_INFO = Menu.FIRST + 4;
private static final int MENU_HELP = Menu.FIRST + 5;
private BatteryHistoryPreference mHistPref;
private LayoutPreference mBatteryLayoutPref;
private PreferenceGroup mAppListGroup;
private int mStatsType = BatteryStats.STATS_SINCE_CHARGED;
@@ -98,7 +101,7 @@ public class PowerUsageSummary extends PowerUsageBase {
super.onCreate(icicle);
setAnimationAllowed(true);
mHistPref = (BatteryHistoryPreference) findPreference(KEY_BATTERY_HISTORY);
mBatteryLayoutPref = (LayoutPreference) findPreference(KEY_BATTERY_HEADER);
mAppListGroup = (PreferenceGroup) findPreference(KEY_APP_LIST);
}
@@ -130,7 +133,10 @@ public class PowerUsageSummary extends PowerUsageBase {
@Override
public boolean onPreferenceTreeClick(Preference preference) {
if (!(preference instanceof PowerGaugePreference)) {
if (KEY_BATTERY_HEADER.equals(preference.getKey())) {
performBatteryHeaderClick();
return true;
} else if (!(preference instanceof PowerGaugePreference)) {
return super.onPreferenceTreeClick(preference);
}
PowerGaugePreference pgp = (PowerGaugePreference) preference;
@@ -224,6 +230,26 @@ public class PowerUsageSummary extends PowerUsageBase {
}
}
private void performBatteryHeaderClick() {
final Context context = getContext();
final PowerUsageFeatureProvider featureProvider = FeatureFactory.getFactory(context)
.getPowerUsageFeatureProvider(context);
if (featureProvider.isAdvancedUiEnabled()) {
Utils.startWithFragment(getContext(), PowerUsageAdvanced.class.getName(), null,
null, 0, R.string.advanced_battery_title, null);
} else {
mStatsHelper.storeStatsHistoryInFile(BatteryHistoryDetail.BATTERY_HISTORY_FILE);
Bundle args = new Bundle(2);
args.putString(BatteryHistoryDetail.EXTRA_STATS,
BatteryHistoryDetail.BATTERY_HISTORY_FILE);
args.putParcelable(BatteryHistoryDetail.EXTRA_BROADCAST,
mStatsHelper.getBatteryBroadcast());
Utils.startWithFragment(getContext(), BatteryHistoryDetail.class.getName(), args,
null, 0, R.string.history_details_title, null);
}
}
private static boolean isSharedGid(int uid) {
return UserHandle.getAppIdFromSharedAppGid(uid) > 0;
}
@@ -325,7 +351,14 @@ public class PowerUsageSummary extends PowerUsageBase {
protected void refreshStats() {
super.refreshStats();
updatePreference(mHistPref);
BatteryInfo.getBatteryInfo(getContext(), new BatteryInfo.Callback() {
@Override
public void onBatteryInfoLoaded(BatteryInfo info) {
updateHeaderPreference(info);
}
});
cacheRemoveAllPrefs(mAppListGroup);
mAppListGroup.setOrderingAsAdded(false);
boolean addedSome = false;
@@ -436,6 +469,27 @@ public class PowerUsageSummary extends PowerUsageBase {
BatteryEntry.startRequestQueue();
}
@VisibleForTesting
void updateHeaderPreference(BatteryInfo info) {
final BatteryMeterView batteryView = (BatteryMeterView) mBatteryLayoutPref
.findViewById(R.id.battery_header_icon);
final TextView timeText = (TextView) mBatteryLayoutPref.findViewById(R.id.time);
final TextView summary1 = (TextView) mBatteryLayoutPref.findViewById(R.id.summary1);
final TextView summary2 = (TextView) mBatteryLayoutPref.findViewById(R.id.summary2);
final int visible = info.mBatteryLevel != 100 ? View.VISIBLE : View.INVISIBLE;
if (info.remainingTimeUs != 0) {
timeText.setText(Utils.formatElapsedTime(getContext(),
info.remainingTimeUs / 1000, false));
} else {
timeText.setText(info.remainingLabel != null ?
info.remainingLabel : info.batteryPercentString);
}
summary1.setVisibility(visible);
summary2.setVisibility(visible);
batteryView.setBatteryInfo(info.mBatteryLevel);
}
@VisibleForTesting
void setUsageSummary(Preference preference, String usedTimePrefix, long usageTimeMs) {
// Only show summary when usage time is longer than one minute
@@ -482,6 +536,11 @@ public class PowerUsageSummary extends PowerUsageBase {
return 0;
}
@VisibleForTesting
void setBatteryLayoutPreference(LayoutPreference layoutPreference) {
mBatteryLayoutPref = layoutPreference;
}
private static List<BatterySipper> getFakeStats() {
ArrayList<BatterySipper> stats = new ArrayList<>();
float use = 5;