Fix and update battery detail page

Bug: 27205329
Change-Id: Ie984348d59c1b15bec7283a94a94489f78cacb79
This commit is contained in:
Jason Monk
2016-02-23 12:45:20 -05:00
parent 60df76b169
commit d1ea8a05b0
9 changed files with 523 additions and 9 deletions

View File

@@ -0,0 +1,75 @@
/*
* Copyright (C) 2016 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.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.SparseIntArray;
import android.view.View;
public class BatteryActiveView extends View {
private final Paint mPaint = new Paint();
private BatteryActiveProvider mProvider;
public BatteryActiveView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public void setProvider(BatteryActiveProvider provider) {
mProvider = provider;
if (getWidth() != 0) {
postInvalidate();
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (getWidth() != 0) {
postInvalidate();
}
}
@Override
protected void onDraw(Canvas canvas) {
if (mProvider == null) {
return;
}
SparseIntArray array = mProvider.getColorArray();
float period = mProvider.getPeriod();
for (int i = 0; i < array.size() - 1; i++) {
drawColor(canvas, array.keyAt(i), array.keyAt(i + 1), array.valueAt(i), period);
}
}
private void drawColor(Canvas canvas, int start, int end, int color, float period) {
if (color == 0) {
return;
}
mPaint.setColor(color);
canvas.drawRect(start / period * getWidth(), 0, end / period * getWidth(), getHeight(),
mPaint);
}
public interface BatteryActiveProvider {
boolean hasData();
long getPeriod();
SparseIntArray getColorArray();
}
}

View File

@@ -0,0 +1,101 @@
/*
* Copyright (C) 2016 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.os.BatteryStats.HistoryItem;
import android.telephony.ServiceState;
import android.util.SparseIntArray;
import com.android.settings.Utils;
import com.android.settings.fuelgauge.BatteryActiveView.BatteryActiveProvider;
import com.android.settingslib.BatteryInfo;
public class BatteryCellParser implements BatteryInfo.BatteryDataParser, BatteryActiveProvider {
private final SparseIntArray mData = new SparseIntArray();
private int mLastValue;
private long mLength;
private long mLastTime;
protected int getValue(HistoryItem rec) {
int bin;
if (((rec.states & HistoryItem.STATE_PHONE_STATE_MASK)
>> HistoryItem.STATE_PHONE_STATE_SHIFT)
== ServiceState.STATE_POWER_OFF) {
bin = 0;
} else if ((rec.states & HistoryItem.STATE_PHONE_SCANNING_FLAG) != 0) {
bin = 1;
} else {
bin = (rec.states & HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK)
>> HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT;
bin += 2;
}
return bin;
}
@Override
public void onParsingStarted(long startTime, long endTime) {
mLength = endTime - startTime;
}
@Override
public void onDataPoint(long time, HistoryItem record) {
int value = getValue(record);
if (value != mLastValue) {
mData.put((int) time, value);
mLastValue = value;
}
mLastTime = time;
}
@Override
public void onDataGap() {
if (mLastValue != 0) {
mData.put((int) mLastTime, 0);
mLastValue = 0;
}
}
@Override
public void onParsingDone() {
if (mLastValue != 0) {
mData.put((int) mLastTime, 0);
mLastValue = 0;
}
}
@Override
public long getPeriod() {
return mLength;
}
@Override
public boolean hasData() {
return mData.size() > 1;
}
@Override
public SparseIntArray getColorArray() {
SparseIntArray ret = new SparseIntArray();
for (int i = 0; i < mData.size(); i++) {
ret.put(mData.keyAt(i), getColor(mData.valueAt(i)));
}
return ret;
}
private int getColor(int i) {
return Utils.BADNESS_COLORS[i];
}
}

View File

@@ -0,0 +1,100 @@
/*
* Copyright (C) 2016 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.os.BatteryStats.HistoryItem;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import com.android.settings.fuelgauge.BatteryActiveView.BatteryActiveProvider;
import com.android.settingslib.BatteryInfo;
public class BatteryFlagParser implements BatteryInfo.BatteryDataParser, BatteryActiveProvider {
private final SparseBooleanArray mData = new SparseBooleanArray();
private final int mFlag;
private final boolean mState2;
private final int mAccentColor;
private boolean mLastSet;
private long mLength;
private long mLastTime;
public BatteryFlagParser(int accent, boolean state2, int flag) {
mAccentColor = accent;
mFlag = flag;
mState2 = state2;
}
protected boolean isSet(HistoryItem record) {
return ((mState2 ? record.states2 : record.states) & mFlag) != 0;
}
@Override
public void onParsingStarted(long startTime, long endTime) {
mLength = endTime - startTime;
}
@Override
public void onDataPoint(long time, HistoryItem record) {
boolean isSet = isSet(record);
if (isSet != mLastSet) {
mData.put((int) time, isSet);
mLastSet = isSet;
}
mLastTime = time;
}
@Override
public void onDataGap() {
if (mLastSet) {
mData.put((int) mLastTime, false);
mLastSet = false;
}
}
@Override
public void onParsingDone() {
if (mLastSet) {
mData.put((int) mLastTime, false);
mLastSet = false;
}
}
@Override
public long getPeriod() {
return mLength;
}
@Override
public boolean hasData() {
return mData.size() > 1;
}
@Override
public SparseIntArray getColorArray() {
SparseIntArray ret = new SparseIntArray();
for (int i = 0; i < mData.size(); i++) {
ret.put(mData.keyAt(i), getColor(mData.valueAt(i)));
}
return ret;
}
private int getColor(boolean b) {
if (b) {
return mAccentColor;
}
return 0;
}
}

View File

@@ -18,15 +18,21 @@ package com.android.settings.fuelgauge;
import android.content.Intent;
import android.os.BatteryStats;
import android.os.BatteryStats.HistoryItem;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.internal.os.BatteryStatsHelper;
import com.android.settings.InstrumentedFragment;
import com.android.settings.R;
import com.android.settings.fuelgauge.BatteryActiveView.BatteryActiveProvider;
import com.android.settingslib.BatteryInfo;
import com.android.settingslib.graph.UsageView;
public class BatteryHistoryDetail extends InstrumentedFragment {
public static final String EXTRA_STATS = "stats";
@@ -35,21 +41,80 @@ public class BatteryHistoryDetail extends InstrumentedFragment {
private BatteryStats mStats;
private Intent mBatteryBroadcast;
private BatteryFlagParser mChargingParser;
private BatteryFlagParser mScreenOn;
private BatteryFlagParser mGpsParser;
private BatteryFlagParser mFlashlightParser;
private BatteryFlagParser mCameraParser;
private BatteryWifiParser mWifiParser;
private BatteryFlagParser mCpuParser;
private BatteryCellParser mPhoneParser;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
String histFile = getArguments().getString(EXTRA_STATS);
mStats = BatteryStatsHelper.statsFromFile(getActivity(), histFile);
mBatteryBroadcast = getArguments().getParcelable(EXTRA_BROADCAST);
TypedValue value = new TypedValue();
getContext().getTheme().resolveAttribute(android.R.attr.colorAccent, value, true);
int accentColor = getContext().getColor(value.resourceId);
mChargingParser = new BatteryFlagParser(accentColor, false,
HistoryItem.STATE_BATTERY_PLUGGED_FLAG);
mScreenOn = new BatteryFlagParser(accentColor, false,
HistoryItem.STATE_SCREEN_ON_FLAG);
mGpsParser = new BatteryFlagParser(accentColor, false,
HistoryItem.STATE_GPS_ON_FLAG);
mFlashlightParser = new BatteryFlagParser(accentColor, true,
HistoryItem.STATE2_FLASHLIGHT_FLAG);
mCameraParser = new BatteryFlagParser(accentColor, true,
HistoryItem.STATE2_CAMERA_FLAG);
mWifiParser = new BatteryWifiParser(accentColor);
mCpuParser = new BatteryFlagParser(accentColor, false,
HistoryItem.STATE_CPU_RUNNING_FLAG);
mPhoneParser = new BatteryCellParser();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.battery_history_chart, null);
BatteryHistoryChart chart = (BatteryHistoryChart)view.findViewById(
R.id.battery_history_chart);
chart.setStats(mStats, mBatteryBroadcast);
return view;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.battery_history_detail, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
updateEverything();
}
private void updateEverything() {
BatteryInfo info = BatteryInfo.getBatteryInfo(getContext(), mBatteryBroadcast, mStats,
SystemClock.elapsedRealtime() * 1000);
final View view = getView();
info.bindHistory((UsageView) view.findViewById(R.id.battery_usage), mChargingParser,
mScreenOn, mGpsParser, mFlashlightParser, mCameraParser, mWifiParser, mCpuParser,
mPhoneParser);
((TextView) view.findViewById(R.id.charge)).setText(info.batteryPercentString);
((TextView) view.findViewById(R.id.estimation)).setText(info.remainingLabel);
bindData(mChargingParser, R.string.battery_stats_charging_label, R.id.charging_group);
bindData(mScreenOn, R.string.battery_stats_screen_on_label, R.id.screen_on_group);
bindData(mGpsParser, R.string.battery_stats_gps_on_label, R.id.gps_group);
bindData(mFlashlightParser, R.string.battery_stats_flashlight_on_label,
R.id.flashlight_group);
bindData(mCameraParser, R.string.battery_stats_camera_on_label, R.id.camera_group);
bindData(mWifiParser, R.string.battery_stats_wifi_running_label, R.id.wifi_group);
bindData(mCpuParser, R.string.battery_stats_wake_lock_label, R.id.cpu_group);
bindData(mPhoneParser, R.string.battery_stats_phone_signal_label, R.id.cell_network_group);
}
private void bindData(BatteryActiveProvider provider, int label, int groupId) {
View group = getView().findViewById(groupId);
group.setVisibility(provider.hasData() ? View.VISIBLE : View.GONE);
((TextView) group.findViewById(android.R.id.title)).setText(label);
((BatteryActiveView) group.findViewById(R.id.battery_active)).setProvider(provider);
}
@Override

View File

@@ -44,10 +44,11 @@ public class BatteryHistoryPreference extends Preference {
public BatteryHistoryPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setLayoutResource(R.layout.battery_usage_graph);
setSelectable(true);
}
@Override
protected void onClick() {
public void performClick() {
mHelper.storeStatsHistoryInFile(BATTERY_HISTORY_FILE);
Bundle args = new Bundle();
args.putString(BatteryHistoryDetail.EXTRA_STATS, BATTERY_HISTORY_FILE);
@@ -66,9 +67,11 @@ public class BatteryHistoryPreference extends Preference {
@Override
public void onBindViewHolder(PreferenceViewHolder view) {
super.onBindViewHolder(view);
if (mBatteryInfo == null) {
return;
}
view.itemView.setClickable(true);
view.setDividerAllowedAbove(true);
((TextView) view.findViewById(R.id.charge)).setText(mBatteryInfo.batteryPercentString);
((TextView) view.findViewById(R.id.estimation)).setText(mBatteryInfo.remainingLabel);

View File

@@ -0,0 +1,40 @@
/*
* Copyright (C) 2016 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.os.BatteryStats;
import android.os.BatteryStats.HistoryItem;
public class BatteryWifiParser extends BatteryFlagParser {
public BatteryWifiParser(int accentColor) {
super(accentColor, false, 0);
}
@Override
protected boolean isSet(HistoryItem record) {
switch ((record.states2 & HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK)
>> HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT) {
case BatteryStats.WIFI_SUPPL_STATE_DISCONNECTED:
case BatteryStats.WIFI_SUPPL_STATE_DORMANT:
case BatteryStats.WIFI_SUPPL_STATE_INACTIVE:
case BatteryStats.WIFI_SUPPL_STATE_INTERFACE_DISABLED:
case BatteryStats.WIFI_SUPPL_STATE_INVALID:
case BatteryStats.WIFI_SUPPL_STATE_UNINITIALIZED:
return false;
}
return true;
}
}

View File

@@ -116,7 +116,7 @@ public class PowerUsageSummary extends PowerUsageBase {
@Override
public boolean onPreferenceTreeClick(Preference preference) {
if (!(preference instanceof PowerGaugePreference)) {
return false;
return super.onPreferenceTreeClick(preference);
}
PowerGaugePreference pgp = (PowerGaugePreference) preference;
BatteryEntry entry = pgp.getInfo();