Update copy for battery estimate related features

Many features are using the enhanced estimates but the copy for them
has gotten out of sync. This CL moves shared strings between Settings
and SysUI to SettingsLib and also updates features that use the
strings to have consistent behavior/text.

Test: Robotests
Bug: 65656091
Bug: 66909350
Bug: 67469159
Change-Id: Ie5ef1ed65429ca9805cff374f1439e5d61eb6591
This commit is contained in:
Salvador Martinez
2018-01-19 16:33:35 -08:00
parent d7557125c6
commit 408dc41228
18 changed files with 185 additions and 400 deletions

View File

@@ -5133,6 +5133,9 @@
<!-- Title for the battery management group [CHAR LIMIT=40] --> <!-- Title for the battery management group [CHAR LIMIT=40] -->
<string name ="battery_detail_manage_title">Manage battery usage</string> <string name ="battery_detail_manage_title">Manage battery usage</string>
<!-- Graph subtext displayed to user when enhanced battery estimate is being used [CHAR LIMIT=120] -->
<string name="advanced_battery_graph_subtext">Battery left estimate is based on your device usage</string>
<!-- Description for battery time left, i.e. 50min Estimated time left. [CHAR LIMIT=80]--> <!-- Description for battery time left, i.e. 50min Estimated time left. [CHAR LIMIT=80]-->
<string name="estimated_time_left">Estimated time left</string> <string name="estimated_time_left">Estimated time left</string>

View File

@@ -52,11 +52,8 @@ import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintManager;
import android.icu.text.MeasureFormat;
import android.icu.text.RelativeDateTimeFormatter; import android.icu.text.RelativeDateTimeFormatter;
import android.icu.text.RelativeDateTimeFormatter.RelativeUnit; import android.icu.text.RelativeDateTimeFormatter.RelativeUnit;
import android.icu.util.Measure;
import android.icu.util.MeasureUnit;
import android.icu.util.ULocale; import android.icu.util.ULocale;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.LinkProperties; import android.net.LinkProperties;
@@ -88,8 +85,6 @@ import android.support.v7.preference.PreferenceScreen;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.text.Spannable; import android.text.Spannable;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.format.DateUtils; import android.text.format.DateUtils;
import android.text.style.TtsSpan; import android.text.style.TtsSpan;
@@ -112,6 +107,7 @@ import com.android.settings.wrapper.DevicePolicyManagerWrapper;
import com.android.settings.wrapper.FingerprintManagerWrapper; import com.android.settings.wrapper.FingerprintManagerWrapper;
import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
import com.android.settingslib.utils.StringUtil;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
@@ -138,10 +134,6 @@ public final class Utils extends com.android.settingslib.Utils {
private static final String SETTINGS_PACKAGE_NAME = "com.android.settings"; private static final String SETTINGS_PACKAGE_NAME = "com.android.settings";
private static final int SECONDS_PER_MINUTE = 60;
private static final int SECONDS_PER_HOUR = 60 * 60;
private static final int SECONDS_PER_DAY = 24 * 60 * 60;
public static final String OS_PKG = "os"; public static final String OS_PKG = "os";
/** /**
@@ -771,113 +763,6 @@ public final class Utils extends com.android.settingslib.Utils {
return tm.getSimCount() > 1; return tm.getSimCount() > 1;
} }
/**
* Returns elapsed time for the given millis, in the following format:
* 2d 5h 40m 29s
* @param context the application context
* @param millis the elapsed time in milli seconds
* @param withSeconds include seconds?
* @return the formatted elapsed time
*/
public static CharSequence formatElapsedTime(Context context, double millis,
boolean withSeconds) {
SpannableStringBuilder sb = new SpannableStringBuilder();
int seconds = (int) Math.floor(millis / 1000);
if (!withSeconds) {
// Round up.
seconds += 30;
}
int days = 0, hours = 0, minutes = 0;
if (seconds >= SECONDS_PER_DAY) {
days = seconds / SECONDS_PER_DAY;
seconds -= days * SECONDS_PER_DAY;
}
if (seconds >= SECONDS_PER_HOUR) {
hours = seconds / SECONDS_PER_HOUR;
seconds -= hours * SECONDS_PER_HOUR;
}
if (seconds >= SECONDS_PER_MINUTE) {
minutes = seconds / SECONDS_PER_MINUTE;
seconds -= minutes * SECONDS_PER_MINUTE;
}
final ArrayList<Measure> measureList = new ArrayList(4);
if (days > 0) {
measureList.add(new Measure(days, MeasureUnit.DAY));
}
if (hours > 0) {
measureList.add(new Measure(hours, MeasureUnit.HOUR));
}
if (minutes > 0) {
measureList.add(new Measure(minutes, MeasureUnit.MINUTE));
}
if (withSeconds && seconds > 0) {
measureList.add(new Measure(seconds, MeasureUnit.SECOND));
}
if (measureList.size() == 0) {
// Everything addable was zero, so nothing was added. We add a zero.
measureList.add(new Measure(0, withSeconds ? MeasureUnit.SECOND : MeasureUnit.MINUTE));
}
final Measure[] measureArray = measureList.toArray(new Measure[measureList.size()]);
final Locale locale = context.getResources().getConfiguration().locale;
final MeasureFormat measureFormat = MeasureFormat.getInstance(
locale, MeasureFormat.FormatWidth.NARROW);
sb.append(measureFormat.formatMeasures(measureArray));
if (measureArray.length == 1 && MeasureUnit.MINUTE.equals(measureArray[0].getUnit())) {
// Add ttsSpan if it only have minute value, because it will be read as "meters"
final TtsSpan ttsSpan = new TtsSpan.MeasureBuilder().setNumber(minutes)
.setUnit("minute").build();
sb.setSpan(ttsSpan, 0, sb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
return sb;
}
/**
* Returns relative time for the given millis in the past, in a short format such as "2 days
* ago", "5 hr. ago", "40 min. ago", or "29 sec. ago".
*
* <p>The unit is chosen to have good information value while only using one unit. So 27 hours
* and 50 minutes would be formatted as "28 hr. ago", while 50 hours would be formatted as
* "2 days ago".
*
* @param context the application context
* @param millis the elapsed time in milli seconds
* @param withSeconds include seconds?
* @return the formatted elapsed time
*/
public static CharSequence formatRelativeTime(Context context, double millis,
boolean withSeconds) {
final int seconds = (int) Math.floor(millis / 1000);
final RelativeUnit unit;
final int value;
if (withSeconds && seconds < 2 * SECONDS_PER_MINUTE) {
unit = RelativeUnit.SECONDS;
value = seconds;
} else if (seconds < 2 * SECONDS_PER_HOUR) {
unit = RelativeUnit.MINUTES;
value = (seconds + SECONDS_PER_MINUTE / 2) / SECONDS_PER_MINUTE;
} else if (seconds < 2 * SECONDS_PER_DAY) {
unit = RelativeUnit.HOURS;
value = (seconds + SECONDS_PER_HOUR / 2) / SECONDS_PER_HOUR;
} else {
unit = RelativeUnit.DAYS;
value = (seconds + SECONDS_PER_DAY / 2) / SECONDS_PER_DAY;
}
final Locale locale = context.getResources().getConfiguration().locale;
final RelativeDateTimeFormatter formatter = RelativeDateTimeFormatter.getInstance(
ULocale.forLocale(locale),
null /* default NumberFormat */,
RelativeDateTimeFormatter.Style.SHORT,
android.icu.text.DisplayContext.CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE);
return formatter.format(value, RelativeDateTimeFormatter.Direction.LAST, unit);
}
/** /**
* Queries for the UserInfo of a user. Returns null if the user doesn't exist (was removed). * Queries for the UserInfo of a user. Returns null if the user doesn't exist (was removed).
* @param userManager Instance of UserManager * @param userManager Instance of UserManager

View File

@@ -38,13 +38,13 @@ import android.util.IconDrawableFactory;
import android.util.Log; import android.util.Log;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.applications.appinfo.AppInfoDashboardFragment; import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.widget.AppPreference; import com.android.settings.widget.AppPreference;
import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.utils.StringUtil;
import com.android.settingslib.wrapper.PackageManagerWrapper; import com.android.settingslib.wrapper.PackageManagerWrapper;
import java.util.ArrayList; import java.util.ArrayList;
@@ -239,7 +239,7 @@ public class RecentAppsPreferenceController extends AbstractPreferenceController
pref.setKey(pkgName); pref.setKey(pkgName);
pref.setTitle(appEntry.label); pref.setTitle(appEntry.label);
pref.setIcon(mIconDrawableFactory.getBadgedIcon(appEntry.info)); pref.setIcon(mIconDrawableFactory.getBadgedIcon(appEntry.info));
pref.setSummary(Utils.formatRelativeTime(mContext, pref.setSummary(StringUtil.formatRelativeTime(mContext,
System.currentTimeMillis() - stat.getLastTimeUsed(), false)); System.currentTimeMillis() - stat.getLastTimeUsed(), false));
pref.setOrder(i); pref.setOrder(i);
pref.setOnPreferenceClickListener(preference -> { pref.setOnPreferenceClickListener(preference -> {

View File

@@ -58,6 +58,7 @@ import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.utils.StringUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -284,10 +285,10 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
final int powerMah = bundle.getInt(EXTRA_POWER_USAGE_AMOUNT); final int powerMah = bundle.getInt(EXTRA_POWER_USAGE_AMOUNT);
mForegroundPreference.setSummary( mForegroundPreference.setSummary(
TextUtils.expandTemplate(getText(R.string.battery_used_for), TextUtils.expandTemplate(getText(R.string.battery_used_for),
Utils.formatElapsedTime(context, foregroundTimeMs, false))); StringUtil.formatElapsedTime(context, foregroundTimeMs, false)));
mBackgroundPreference.setSummary( mBackgroundPreference.setSummary(
TextUtils.expandTemplate(getText(R.string.battery_active_for), TextUtils.expandTemplate(getText(R.string.battery_active_for),
Utils.formatElapsedTime(context, backgroundTimeMs, false))); StringUtil.formatElapsedTime(context, backgroundTimeMs, false)));
mPowerUsagePreference.setSummary( mPowerUsagePreference.setSummary(
getString(R.string.battery_detail_power_percentage, usagePercent, powerMah)); getString(R.string.battery_detail_power_percentage, usagePercent, powerMah));
} }

View File

@@ -18,7 +18,6 @@
package com.android.settings.fuelgauge; package com.android.settings.fuelgauge;
import android.app.Activity; import android.app.Activity;
import android.app.Fragment;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.BatteryStats; import android.os.BatteryStats;
@@ -31,7 +30,6 @@ import android.support.annotation.VisibleForTesting;
import android.support.v14.preference.PreferenceFragment; import android.support.v14.preference.PreferenceFragment;
import android.support.v7.preference.Preference; import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceGroup; import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceManager;
import android.support.v7.preference.PreferenceScreen; import android.support.v7.preference.PreferenceScreen;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.format.DateUtils; import android.text.format.DateUtils;
@@ -48,16 +46,14 @@ import com.android.settings.R;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.core.FeatureFlags; import com.android.settings.core.FeatureFlags;
import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.Utils;
import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.fuelgauge.anomaly.Anomaly;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnDestroy; import com.android.settingslib.core.lifecycle.events.OnDestroy;
import com.android.settingslib.core.lifecycle.events.OnPause; import com.android.settingslib.core.lifecycle.events.OnPause;
import com.android.settingslib.utils.StringUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -362,8 +358,8 @@ public class BatteryAppListPreferenceController extends AbstractPreferenceContro
// Only show summary when usage time is longer than one minute // Only show summary when usage time is longer than one minute
final long usageTimeMs = sipper.usageTimeMs; final long usageTimeMs = sipper.usageTimeMs;
if (usageTimeMs >= DateUtils.MINUTE_IN_MILLIS) { if (usageTimeMs >= DateUtils.MINUTE_IN_MILLIS) {
final CharSequence timeSequence = Utils.formatElapsedTime(mContext, usageTimeMs, final CharSequence timeSequence =
false); StringUtil.formatElapsedTime(mContext, usageTimeMs, false);
preference.setSummary( preference.setSummary(
(sipper.drainType != DrainType.APP || mBatteryUtils.shouldHideSipper(sipper)) (sipper.drainType != DrainType.APP || mBatteryUtils.shouldHideSipper(sipper))
? timeSequence ? timeSequence

View File

@@ -25,7 +25,6 @@ import android.os.BatteryStats.HistoryItem;
import android.os.Bundle; import android.os.Bundle;
import android.os.SystemClock; import android.os.SystemClock;
import android.support.annotation.WorkerThread; import android.support.annotation.WorkerThread;
import android.text.TextUtils;
import android.text.format.Formatter; import android.text.format.Formatter;
import android.util.SparseIntArray; import android.util.SparseIntArray;
@@ -34,8 +33,14 @@ import com.android.settings.Utils;
import com.android.settings.graph.UsageView; import com.android.settings.graph.UsageView;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.R; import com.android.settingslib.R;
import com.android.settingslib.utils.PowerUtil;
import com.android.settingslib.utils.StringUtil;
import java.util.concurrent.TimeUnit;
public class BatteryInfo { public class BatteryInfo {
private static final long SEVEN_MINUTES_MICROS = TimeUnit.MINUTES.toMicros(7);
private static final long FIFTEEN_MINUTES_MICROS = TimeUnit.MINUTES.toMicros(15);
private static final long ONE_DAY_MICROS = TimeUnit.DAYS.toMicros(1);
public CharSequence chargeLabel; public CharSequence chargeLabel;
public CharSequence remainingLabel; public CharSequence remainingLabel;
@@ -100,7 +105,7 @@ public class BatteryInfo {
if (lastTime >= 0) { if (lastTime >= 0) {
points.put(lastTime, lastLevel); points.put(lastTime, lastLevel);
points.put((int) (timePeriod + points.put((int) (timePeriod +
BatteryUtils.convertUsToMs(remainingTimeUs)), PowerUtil.convertUsToMs(remainingTimeUs)),
mCharging ? 100 : 0); mCharging ? 100 : 0);
} }
} }
@@ -160,7 +165,7 @@ public class BatteryInfo {
PowerUsageFeatureProvider provider = PowerUsageFeatureProvider provider =
FeatureFactory.getFactory(context).getPowerUsageFeatureProvider(context); FeatureFactory.getFactory(context).getPowerUsageFeatureProvider(context);
final long elapsedRealtimeUs = final long elapsedRealtimeUs =
BatteryUtils.convertMsToUs(SystemClock.elapsedRealtime()); PowerUtil.convertMsToUs(SystemClock.elapsedRealtime());
Intent batteryBroadcast = context.registerReceiver(null, Intent batteryBroadcast = context.registerReceiver(null,
new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
@@ -176,7 +181,7 @@ public class BatteryInfo {
.logRuntime(LOG_TAG, "time for enhanced BatteryInfo", startTime); .logRuntime(LOG_TAG, "time for enhanced BatteryInfo", startTime);
return BatteryInfo.getBatteryInfo(context, batteryBroadcast, stats, return BatteryInfo.getBatteryInfo(context, batteryBroadcast, stats,
elapsedRealtimeUs, shortString, elapsedRealtimeUs, shortString,
BatteryUtils.convertMsToUs(estimate.estimateMillis), PowerUtil.convertMsToUs(estimate.estimateMillis),
estimate.isBasedOnUsage); estimate.isBasedOnUsage);
} }
} }
@@ -217,40 +222,29 @@ public class BatteryInfo {
info.statusLabel = Utils.getBatteryStatus(resources, batteryBroadcast); info.statusLabel = Utils.getBatteryStatus(resources, batteryBroadcast);
if (!info.mCharging) { if (!info.mCharging) {
if (drainTimeUs > 0) { updateBatteryInfoDischarging(context, shortString, drainTimeUs, basedOnUsage, info);
info.remainingTimeUs = drainTimeUs;
CharSequence timeString = Utils.formatElapsedTime(context,
BatteryUtils.convertUsToMs(drainTimeUs), false /* withSeconds */);
info.remainingLabel = TextUtils.expandTemplate(context.getText(shortString ?
R.string.power_remaining_duration_only_short :
(basedOnUsage ?
R.string.power_remaining_duration_only_enhanced :
R.string.power_remaining_duration_only)), timeString);
info.chargeLabel = TextUtils.expandTemplate(context.getText(
shortString ?
R.string.power_discharging_duration_short :
basedOnUsage ?
R.string.power_discharging_duration_enhanced :
R.string.power_discharging_duration),
info.batteryPercentString, timeString);
} else { } else {
info.remainingLabel = null; updateBatteryInfoCharging(context, batteryBroadcast, stats, elapsedRealtimeUs, info);
info.chargeLabel = info.batteryPercentString;
} }
} else { BatteryUtils.logRuntime(LOG_TAG, "time for getBatteryInfo", startTime);
return info;
}
private static void updateBatteryInfoCharging(Context context, Intent batteryBroadcast,
BatteryStats stats, long elapsedRealtimeUs, BatteryInfo info) {
final Resources resources = context.getResources();
final long chargeTime = stats.computeChargeTimeRemaining(elapsedRealtimeUs); final long chargeTime = stats.computeChargeTimeRemaining(elapsedRealtimeUs);
final int status = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_STATUS, final int status = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_STATUS,
BatteryManager.BATTERY_STATUS_UNKNOWN); BatteryManager.BATTERY_STATUS_UNKNOWN);
info.discharging = false; info.discharging = false;
if (chargeTime > 0 && status != BatteryManager.BATTERY_STATUS_FULL) { if (chargeTime > 0 && status != BatteryManager.BATTERY_STATUS_FULL) {
info.remainingTimeUs = chargeTime; info.remainingTimeUs = chargeTime;
CharSequence timeString = Utils.formatElapsedTime(context, CharSequence timeString = StringUtil.formatElapsedTime(context,
BatteryUtils.convertUsToMs(chargeTime), false /* withSeconds */); PowerUtil.convertUsToMs(info.remainingTimeUs), false /* withSeconds */);
int resId = R.string.power_charging_duration; int resId = R.string.power_charging_duration;
info.remainingLabel = TextUtils.expandTemplate(context.getText( info.remainingLabel = context.getString(
R.string.power_remaining_charging_duration_only), timeString); R.string.power_remaining_charging_duration_only, timeString);
info.chargeLabel = TextUtils.expandTemplate(context.getText(resId), info.chargeLabel = context.getString(resId, info.batteryPercentString, timeString);
info.batteryPercentString, timeString);
} else { } else {
final String chargeStatusLabel = resources.getString( final String chargeStatusLabel = resources.getString(
R.string.battery_info_status_charging_lower); R.string.battery_info_status_charging_lower);
@@ -260,8 +254,27 @@ public class BatteryInfo {
chargeStatusLabel); chargeStatusLabel);
} }
} }
BatteryUtils.logRuntime(LOG_TAG, "time for getBatteryInfo", startTime);
return info; private static void updateBatteryInfoDischarging(Context context, boolean shortString,
long drainTimeUs, boolean basedOnUsage, BatteryInfo info) {
if (drainTimeUs > 0) {
info.remainingTimeUs = drainTimeUs;
info.remainingLabel = PowerUtil.getBatteryRemainingStringFormatted(
context,
PowerUtil.convertUsToMs(drainTimeUs),
null /* percentageString */,
basedOnUsage && !shortString
);
info.chargeLabel = PowerUtil.getBatteryRemainingStringFormatted(
context,
PowerUtil.convertUsToMs(drainTimeUs),
info.batteryPercentString,
basedOnUsage && !shortString
);
} else {
info.remainingLabel = null;
info.chargeLabel = info.batteryPercentString;
}
} }
public interface BatteryDataParser { public interface BatteryDataParser {

View File

@@ -43,6 +43,7 @@ import com.android.settings.R;
import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.fuelgauge.anomaly.Anomaly;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.utils.PowerUtil;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.Collections; import java.util.Collections;
@@ -68,19 +69,18 @@ public class BatteryUtils {
int BACKGROUND = 2; int BACKGROUND = 2;
int ALL = 3; int ALL = 3;
} }
private static final String TAG = "BatteryUtils"; private static final String TAG = "BatteryUtils";
private static final int MIN_POWER_THRESHOLD_MILLI_AMP = 5; private static final int MIN_POWER_THRESHOLD_MILLI_AMP = 5;
private static final int SECONDS_IN_HOUR = 60 * 60; private static final int SECONDS_IN_HOUR = 60 * 60;
private static BatteryUtils sInstance; private static BatteryUtils sInstance;
private PackageManager mPackageManager; private PackageManager mPackageManager;
private AppOpsManager mAppOpsManager; private AppOpsManager mAppOpsManager;
private Context mContext; private Context mContext;
@VisibleForTesting @VisibleForTesting
PowerUsageFeatureProvider mPowerUsageFeatureProvider; PowerUsageFeatureProvider mPowerUsageFeatureProvider;
public static BatteryUtils getInstance(Context context) { public static BatteryUtils getInstance(Context context) {
if (sInstance == null || sInstance.isDataCorrupted()) { if (sInstance == null || sInstance.isDataCorrupted()) {
sInstance = new BatteryUtils(context); sInstance = new BatteryUtils(context);
@@ -131,29 +131,30 @@ public class BatteryUtils {
// Return the min value of STATE_TOP time and foreground activity time, since both of these // Return the min value of STATE_TOP time and foreground activity time, since both of these
// time have some errors // time have some errors
return convertUsToMs( return PowerUtil.convertUsToMs(
Math.min(timeUs, getForegroundActivityTotalTimeUs(uid, rawRealTimeUs))); Math.min(timeUs, getForegroundActivityTotalTimeUs(uid, rawRealTimeUs)));
} }
private long getScreenUsageTimeMs(BatteryStats.Uid uid, int which) { private long getScreenUsageTimeMs(BatteryStats.Uid uid, int which) {
final long rawRealTimeUs = convertMsToUs(SystemClock.elapsedRealtime()); final long rawRealTimeUs = PowerUtil.convertMsToUs(SystemClock.elapsedRealtime());
return getScreenUsageTimeMs(uid, which, rawRealTimeUs); return getScreenUsageTimeMs(uid, which, rawRealTimeUs);
} }
private long getProcessBackgroundTimeMs(BatteryStats.Uid uid, int which) { private long getProcessBackgroundTimeMs(BatteryStats.Uid uid, int which) {
final long rawRealTimeUs = convertMsToUs(SystemClock.elapsedRealtime()); final long rawRealTimeUs = PowerUtil.convertMsToUs(SystemClock.elapsedRealtime());
final long timeUs = uid.getProcessStateTime( final long timeUs = uid.getProcessStateTime(
BatteryStats.Uid.PROCESS_STATE_BACKGROUND, rawRealTimeUs, which); BatteryStats.Uid.PROCESS_STATE_BACKGROUND, rawRealTimeUs, which);
Log.v(TAG, "package: " + mPackageManager.getNameForUid(uid.getUid())); Log.v(TAG, "package: " + mPackageManager.getNameForUid(uid.getUid()));
Log.v(TAG, "background time(us): " + timeUs); Log.v(TAG, "background time(us): " + timeUs);
return convertUsToMs(timeUs); return PowerUtil.convertUsToMs(timeUs);
} }
private long getProcessForegroundTimeMs(BatteryStats.Uid uid, int which) { private long getProcessForegroundTimeMs(BatteryStats.Uid uid, int which) {
final long rawRealTimeUs = convertMsToUs(SystemClock.elapsedRealtime()); final long rawRealTimeUs = PowerUtil.convertMsToUs(SystemClock.elapsedRealtime());
return getScreenUsageTimeMs(uid, which, rawRealTimeUs) return getScreenUsageTimeMs(uid, which, rawRealTimeUs)
+ convertUsToMs(getForegroundServiceTotalTimeUs(uid, rawRealTimeUs)); + PowerUtil.convertUsToMs(
getForegroundServiceTotalTimeUs(uid, rawRealTimeUs));
} }
/** /**
@@ -267,9 +268,10 @@ public class BatteryUtils {
*/ */
public long calculateRunningTimeBasedOnStatsType(BatteryStatsHelper batteryStatsHelper, public long calculateRunningTimeBasedOnStatsType(BatteryStatsHelper batteryStatsHelper,
int statsType) { int statsType) {
final long elapsedRealtimeUs = convertMsToUs(SystemClock.elapsedRealtime()); final long elapsedRealtimeUs = PowerUtil.convertMsToUs(
SystemClock.elapsedRealtime());
// Return the battery time (millisecond) on status mStatsType // Return the battery time (millisecond) on status mStatsType
return convertUsToMs( return PowerUtil.convertUsToMs(
batteryStatsHelper.getStats().computeBatteryRealtime(elapsedRealtimeUs, statsType)); batteryStatsHelper.getStats().computeBatteryRealtime(elapsedRealtimeUs, statsType));
} }
@@ -390,25 +392,15 @@ public class BatteryUtils {
} }
} }
public static long convertUsToMs(long timeUs) {
return timeUs / 1000;
}
public static long convertMsToUs(long timeMs) {
return timeMs * 1000;
}
public void setForceAppStandby(int uid, String packageName, public void setForceAppStandby(int uid, String packageName,
int mode) { int mode) {
final boolean isPreOApp = isLegacyApp(packageName); final boolean isPreOApp = isLegacyApp(packageName);
if (isPreOApp) { if (isPreOApp) {
// Control whether app could run in the background if it is pre O app // Control whether app could run in the background if it is pre O app
mAppOpsManager.setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName, mAppOpsManager.setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName, mode);
mode);
} }
// Control whether app could run jobs in the background // Control whether app could run jobs in the background
mAppOpsManager.setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName, mAppOpsManager.setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName, mode);
mode);
} }
public void initBatteryStatsHelper(BatteryStatsHelper statsHelper, Bundle bundle, public void initBatteryStatsHelper(BatteryStatsHelper statsHelper, Bundle bundle,
@@ -425,7 +417,8 @@ public class BatteryUtils {
// Stuff we always need to get BatteryInfo // Stuff we always need to get BatteryInfo
final Intent batteryBroadcast = mContext.registerReceiver(null, final Intent batteryBroadcast = mContext.registerReceiver(null,
new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
final long elapsedRealtimeUs = BatteryUtils.convertMsToUs(SystemClock.elapsedRealtime()); final long elapsedRealtimeUs = PowerUtil.convertMsToUs(
SystemClock.elapsedRealtime());
BatteryInfo batteryInfo; BatteryInfo batteryInfo;
// 0 means we are discharging, anything else means charging // 0 means we are discharging, anything else means charging
@@ -443,7 +436,7 @@ public class BatteryUtils {
if (estimate != null) { if (estimate != null) {
batteryInfo = BatteryInfo.getBatteryInfo(mContext, batteryBroadcast, stats, batteryInfo = BatteryInfo.getBatteryInfo(mContext, batteryBroadcast, stats,
elapsedRealtimeUs, false /* shortString */, elapsedRealtimeUs, false /* shortString */,
BatteryUtils.convertMsToUs(estimate.estimateMillis), PowerUtil.convertMsToUs(estimate.estimateMillis),
estimate.isBasedOnUsage); estimate.isBasedOnUsage);
} else { } else {
batteryInfo = BatteryInfo.getBatteryInfo(mContext, batteryBroadcast, stats, batteryInfo = BatteryInfo.getBatteryInfo(mContext, batteryBroadcast, stats,

View File

@@ -22,6 +22,7 @@ import android.os.BatteryStats;
import android.os.SystemClock; import android.os.SystemClock;
import com.android.internal.os.BatteryStatsHelper; import com.android.internal.os.BatteryStatsHelper;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.utils.PowerUtil;
import com.android.settingslib.utils.AsyncLoader; import com.android.settingslib.utils.AsyncLoader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -46,7 +47,8 @@ public class DebugEstimatesLoader extends AsyncLoader<List<BatteryInfo>> {
FeatureFactory.getFactory(context).getPowerUsageFeatureProvider(context); FeatureFactory.getFactory(context).getPowerUsageFeatureProvider(context);
// get stuff we'll need for both BatteryInfo // get stuff we'll need for both BatteryInfo
final long elapsedRealtimeUs = BatteryUtils.convertMsToUs(SystemClock.elapsedRealtime()); final long elapsedRealtimeUs = PowerUtil.convertMsToUs(
SystemClock.elapsedRealtime());
Intent batteryBroadcast = getContext().registerReceiver(null, Intent batteryBroadcast = getContext().registerReceiver(null,
new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
BatteryStats stats = mStatsHelper.getStats(); BatteryStats stats = mStatsHelper.getStats();
@@ -60,7 +62,7 @@ public class DebugEstimatesLoader extends AsyncLoader<List<BatteryInfo>> {
} }
BatteryInfo newInfo = BatteryInfo.getBatteryInfo(getContext(), batteryBroadcast, stats, BatteryInfo newInfo = BatteryInfo.getBatteryInfo(getContext(), batteryBroadcast, stats,
elapsedRealtimeUs, false, elapsedRealtimeUs, false,
BatteryUtils.convertMsToUs(estimate.estimateMillis), PowerUtil.convertMsToUs(estimate.estimateMillis),
estimate.isBasedOnUsage); estimate.isBasedOnUsage);
List<BatteryInfo> infos = new ArrayList<>(); List<BatteryInfo> infos = new ArrayList<>();

View File

@@ -47,6 +47,7 @@ import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.utils.StringUtil;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList; import java.util.ArrayList;
@@ -318,7 +319,7 @@ public class PowerUsageAdvanced extends PowerUsageBase {
return; return;
} }
if (usageData.usageList.size() <= 1) { if (usageData.usageList.size() <= 1) {
CharSequence timeSequence = Utils.formatElapsedTime(getContext(), CharSequence timeSequence = StringUtil.formatElapsedTime(getContext(),
usageData.totalUsageTimeMs, false); usageData.totalUsageTimeMs, false);
usageData.summary = usageData.usageType == UsageType.IDLE ? timeSequence usageData.summary = usageData.usageType == UsageType.IDLE ? timeSequence
: TextUtils.expandTemplate(getText(R.string.battery_used_for), timeSequence); : TextUtils.expandTemplate(getText(R.string.battery_used_for), timeSequence);

View File

@@ -37,10 +37,7 @@ import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener; import android.view.View.OnLongClickListener;
import android.widget.TextView; import android.widget.TextView;
import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatterySipper.DrainType;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Settings.HighPowerApplicationsActivity; import com.android.settings.Settings.HighPowerApplicationsActivity;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
@@ -48,10 +45,7 @@ import com.android.settings.Utils;
import com.android.settings.applications.LayoutPreference; import com.android.settings.applications.LayoutPreference;
import com.android.settings.applications.manageapplications.ManageApplications; import com.android.settings.applications.manageapplications.ManageApplications;
import com.android.settings.dashboard.SummaryLoader; import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.display.AmbientDisplayPreferenceController;
import com.android.settings.display.AutoBrightnessPreferenceController;
import com.android.settings.display.BatteryPercentagePreferenceController; import com.android.settings.display.BatteryPercentagePreferenceController;
import com.android.settings.display.TimeoutPreferenceController;
import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.fuelgauge.anomaly.Anomaly;
import com.android.settings.fuelgauge.anomaly.AnomalyDetectionPolicy; import com.android.settings.fuelgauge.anomaly.AnomalyDetectionPolicy;
import com.android.settings.fuelgauge.batterytip.BatteryTipLoader; import com.android.settings.fuelgauge.batterytip.BatteryTipLoader;
@@ -63,6 +57,8 @@ import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.utils.PowerUtil;
import com.android.settingslib.utils.StringUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@@ -164,12 +160,12 @@ public class PowerUsageSummary extends PowerUsageBase implements OnLongClickList
// be unplugged for a period of time before being willing ot make an estimate. // be unplugged for a period of time before being willing ot make an estimate.
summary1.setText(mPowerFeatureProvider.getOldEstimateDebugString( summary1.setText(mPowerFeatureProvider.getOldEstimateDebugString(
Formatter.formatShortElapsedTime(getContext(), Formatter.formatShortElapsedTime(getContext(),
BatteryUtils.convertUsToMs(oldInfo.remainingTimeUs)))); PowerUtil.convertUsToMs(oldInfo.remainingTimeUs))));
// for this one we can just set the string directly // for this one we can just set the string directly
summary2.setText(mPowerFeatureProvider.getEnhancedEstimateDebugString( summary2.setText(mPowerFeatureProvider.getEnhancedEstimateDebugString(
Formatter.formatShortElapsedTime(getContext(), Formatter.formatShortElapsedTime(getContext(),
BatteryUtils.convertUsToMs(newInfo.remainingTimeUs)))); PowerUtil.convertUsToMs(newInfo.remainingTimeUs))));
batteryView.setBatteryLevel(oldInfo.batteryLevel); batteryView.setBatteryLevel(oldInfo.batteryLevel);
batteryView.setCharging(!oldInfo.discharging); batteryView.setCharging(!oldInfo.discharging);
@@ -314,10 +310,10 @@ public class PowerUsageSummary extends PowerUsageBase implements OnLongClickList
final long lastFullChargeTime = mBatteryUtils.calculateLastFullChargeTime(mStatsHelper, final long lastFullChargeTime = mBatteryUtils.calculateLastFullChargeTime(mStatsHelper,
System.currentTimeMillis()); System.currentTimeMillis());
updateLastFullChargePreference(lastFullChargeTime); updateLastFullChargePreference(lastFullChargeTime);
mScreenUsagePref.setSubtitle(Utils.formatElapsedTime(getContext(), mScreenUsagePref.setSubtitle(StringUtil.formatElapsedTime(getContext(),
mBatteryUtils.calculateScreenUsageTime(mStatsHelper), false)); mBatteryUtils.calculateScreenUsageTime(mStatsHelper), false));
final CharSequence timeSequence = Utils.formatRelativeTime(context, lastFullChargeTime, final CharSequence timeSequence = StringUtil.formatRelativeTime(context, lastFullChargeTime,
false); false);
mBatteryAppListPreferenceController.refreshAppListGroup(mStatsHelper, mBatteryAppListPreferenceController.refreshAppListGroup(mStatsHelper,
false /* showAllApps */, timeSequence); false /* showAllApps */, timeSequence);
@@ -340,7 +336,7 @@ public class PowerUsageSummary extends PowerUsageBase implements OnLongClickList
@VisibleForTesting @VisibleForTesting
void updateLastFullChargePreference(long timeMs) { void updateLastFullChargePreference(long timeMs) {
final CharSequence timeSequence = Utils.formatRelativeTime(getContext(), timeMs, false); final CharSequence timeSequence = StringUtil.formatRelativeTime(getContext(), timeMs, false);
mLastFullChargePref.setSubtitle(timeSequence); mLastFullChargePref.setSubtitle(timeSequence);
} }

View File

@@ -69,6 +69,8 @@ import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.utils.PowerUtil;
import com.android.settingslib.utils.StringUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -210,12 +212,12 @@ public class PowerUsageSummaryLegacy extends PowerUsageBase implements
// be unplugged for a period of time before being willing ot make an estimate. // be unplugged for a period of time before being willing ot make an estimate.
summary1.setText(mPowerFeatureProvider.getOldEstimateDebugString( summary1.setText(mPowerFeatureProvider.getOldEstimateDebugString(
Formatter.formatShortElapsedTime(getContext(), Formatter.formatShortElapsedTime(getContext(),
BatteryUtils.convertUsToMs(oldInfo.remainingTimeUs)))); PowerUtil.convertUsToMs(oldInfo.remainingTimeUs))));
// for this one we can just set the string directly // for this one we can just set the string directly
summary2.setText(mPowerFeatureProvider.getEnhancedEstimateDebugString( summary2.setText(mPowerFeatureProvider.getEnhancedEstimateDebugString(
Formatter.formatShortElapsedTime(getContext(), Formatter.formatShortElapsedTime(getContext(),
BatteryUtils.convertUsToMs(newInfo.remainingTimeUs)))); PowerUtil.convertUsToMs(newInfo.remainingTimeUs))));
batteryView.setBatteryLevel(oldInfo.batteryLevel); batteryView.setBatteryLevel(oldInfo.batteryLevel);
batteryView.setCharging(!oldInfo.discharging); batteryView.setCharging(!oldInfo.discharging);
@@ -524,7 +526,7 @@ public class PowerUsageSummaryLegacy extends PowerUsageBase implements
updateScreenPreference(); updateScreenPreference();
updateLastFullChargePreference(lastFullChargeTime); updateLastFullChargePreference(lastFullChargeTime);
final CharSequence timeSequence = Utils.formatRelativeTime(context, lastFullChargeTime, final CharSequence timeSequence = StringUtil.formatRelativeTime(context, lastFullChargeTime,
false); false);
final int resId = mShowAllApps ? R.string.power_usage_list_summary_device final int resId = mShowAllApps ? R.string.power_usage_list_summary_device
: R.string.power_usage_list_summary; : R.string.power_usage_list_summary;
@@ -653,12 +655,13 @@ public class PowerUsageSummaryLegacy extends PowerUsageBase implements
mStatsHelper.getUsageList(), DrainType.SCREEN); mStatsHelper.getUsageList(), DrainType.SCREEN);
final long usageTimeMs = sipper != null ? sipper.usageTimeMs : 0; final long usageTimeMs = sipper != null ? sipper.usageTimeMs : 0;
mScreenUsagePref.setSubtitle(Utils.formatElapsedTime(getContext(), usageTimeMs, false)); mScreenUsagePref.setSubtitle(
StringUtil.formatElapsedTime(getContext(), usageTimeMs, false));
} }
@VisibleForTesting @VisibleForTesting
void updateLastFullChargePreference(long timeMs) { void updateLastFullChargePreference(long timeMs) {
final CharSequence timeSequence = Utils.formatRelativeTime(getContext(), timeMs, false); final CharSequence timeSequence = StringUtil.formatRelativeTime(getContext(), timeMs, false);
mLastFullChargePref.setSubtitle(timeSequence); mLastFullChargePref.setSubtitle(timeSequence);
} }
@@ -685,8 +688,8 @@ public class PowerUsageSummaryLegacy extends PowerUsageBase implements
// Only show summary when usage time is longer than one minute // Only show summary when usage time is longer than one minute
final long usageTimeMs = sipper.usageTimeMs; final long usageTimeMs = sipper.usageTimeMs;
if (usageTimeMs >= DateUtils.MINUTE_IN_MILLIS) { if (usageTimeMs >= DateUtils.MINUTE_IN_MILLIS) {
final CharSequence timeSequence = Utils.formatElapsedTime(getContext(), usageTimeMs, final CharSequence timeSequence =
false); StringUtil.formatElapsedTime(getContext(), usageTimeMs, false);
preference.setSummary( preference.setSummary(
(sipper.drainType != DrainType.APP || mBatteryUtils.shouldHideSipper(sipper)) (sipper.drainType != DrainType.APP || mBatteryUtils.shouldHideSipper(sipper))
? timeSequence ? timeSequence

View File

@@ -36,6 +36,7 @@ import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
import com.android.settings.fuelgauge.batterytip.tips.HighUsageTip; import com.android.settings.fuelgauge.batterytip.tips.HighUsageTip;
import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip; import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip; import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip;
import com.android.settingslib.utils.StringUtil;
import java.util.List; import java.util.List;
@@ -83,7 +84,8 @@ public class BatteryTipDialogFragment extends InstrumentedDialogFragment impleme
return new AlertDialog.Builder(context) return new AlertDialog.Builder(context)
.setMessage(getString(R.string.battery_tip_dialog_message, .setMessage(getString(R.string.battery_tip_dialog_message,
Utils.formatElapsedTime(context, highUsageTip.getScreenTimeMs(), StringUtil.formatElapsedTime(
context, highUsageTip.getScreenTimeMs(),
false /* withSeconds */))) false /* withSeconds */)))
.setView(view) .setView(view)
.setPositiveButton(android.R.string.ok, null) .setPositiveButton(android.R.string.ok, null)

View File

@@ -30,6 +30,7 @@ import android.widget.TextView;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils; import com.android.settings.Utils;
import com.android.settingslib.utils.StringUtil;
import java.util.List; import java.util.List;
/** /**
@@ -78,7 +79,7 @@ public class HighUsageAdapter extends RecyclerView.Adapter<HighUsageAdapter.View
UserHandle.myUserId())); UserHandle.myUserId()));
holder.appName.setText(Utils.getApplicationLabel(mContext, app.packageName)); holder.appName.setText(Utils.getApplicationLabel(mContext, app.packageName));
if (app.screenOnTimeMs != 0) { if (app.screenOnTimeMs != 0) {
holder.appTime.setText(Utils.formatElapsedTime(mContext, app.screenOnTimeMs, false)); holder.appTime.setText(StringUtil.formatElapsedTime(mContext, app.screenOnTimeMs, false));
} }
} }

View File

@@ -22,9 +22,9 @@ import android.os.Parcelable;
import android.support.annotation.VisibleForTesting; import android.support.annotation.VisibleForTesting;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.fuelgauge.batterytip.AppInfo; import com.android.settings.fuelgauge.batterytip.AppInfo;
import com.android.settingslib.utils.StringUtil;
import java.util.List; import java.util.List;
/** /**
@@ -65,7 +65,7 @@ public class HighUsageTip extends BatteryTip {
@Override @Override
public CharSequence getSummary(Context context) { public CharSequence getSummary(Context context) {
return context.getString(R.string.battery_tip_high_usage_summary, return context.getString(R.string.battery_tip_high_usage_summary,
Utils.formatElapsedTime(context, mScreenTimeMs, false)); StringUtil.formatElapsedTime(context, mScreenTimeMs, false));
} }
@Override @Override

View File

@@ -46,6 +46,7 @@ import com.android.settings.widget.MasterSwitchPreference;
import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.utils.StringUtil;
import com.android.settingslib.wrapper.PackageManagerWrapper; import com.android.settingslib.wrapper.PackageManagerWrapper;
import java.util.ArrayList; import java.util.ArrayList;
@@ -229,7 +230,7 @@ public class RecentNotifyingAppsPreferenceController extends AbstractPreferenceC
pref.setKey(pkgName); pref.setKey(pkgName);
pref.setTitle(appEntry.label); pref.setTitle(appEntry.label);
pref.setIcon(mIconDrawableFactory.getBadgedIcon(appEntry.info)); pref.setIcon(mIconDrawableFactory.getBadgedIcon(appEntry.info));
pref.setSummary(Utils.formatRelativeTime(mContext, pref.setSummary(StringUtil.formatRelativeTime(mContext,
System.currentTimeMillis() - app.getLastNotified(), false)); System.currentTimeMillis() - app.getLastNotified(), false));
pref.setOrder(i); pref.setOrder(i);
Bundle args = new Bundle(); Bundle args = new Bundle();

View File

@@ -1,3 +1,19 @@
/*
* Copyright (C) 2018 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; package com.android.settings;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
@@ -25,9 +41,7 @@ import android.os.UserManager;
import android.os.storage.DiskInfo; import android.os.storage.DiskInfo;
import android.os.storage.StorageManager; import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo; import android.os.storage.VolumeInfo;
import android.text.SpannableStringBuilder;
import android.text.format.DateUtils; import android.text.format.DateUtils;
import android.text.style.TtsSpan;
import android.util.IconDrawableFactory; import android.util.IconDrawableFactory;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
@@ -35,6 +49,7 @@ import android.widget.TextView;
import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.wrapper.DevicePolicyManagerWrapper; import com.android.settings.wrapper.DevicePolicyManagerWrapper;
import com.android.settingslib.utils.StringUtil;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@@ -109,175 +124,6 @@ public class UtilsTest {
assertThat(Utils.getWifiIpAddresses(mContext)).isNull(); assertThat(Utils.getWifiIpAddresses(mContext)).isNull();
} }
@Test
public void testFormatElapsedTime_WithSeconds_ShowSeconds() {
final double testMillis = 5 * DateUtils.MINUTE_IN_MILLIS + 30 * DateUtils.SECOND_IN_MILLIS;
final String expectedTime = "5m 30s";
assertThat(Utils.formatElapsedTime(mContext, testMillis, true).toString()).isEqualTo(
expectedTime);
}
@Test
public void testFormatElapsedTime_NoSeconds_DoNotShowSeconds() {
final double testMillis = 5 * DateUtils.MINUTE_IN_MILLIS + 30 * DateUtils.SECOND_IN_MILLIS;
final String expectedTime = "6m";
assertThat(Utils.formatElapsedTime(mContext, testMillis, false).toString()).isEqualTo(
expectedTime);
}
@Test
public void testFormatElapsedTime_TimeMoreThanOneDay_ShowCorrectly() {
final double testMillis = 2 * DateUtils.DAY_IN_MILLIS
+ 4 * DateUtils.HOUR_IN_MILLIS + 15 * DateUtils.MINUTE_IN_MILLIS;
final String expectedTime = "2d 4h 15m";
assertThat(Utils.formatElapsedTime(mContext, testMillis, false).toString()).isEqualTo(
expectedTime);
}
@Test
public void testFormatElapsedTime_ZeroFieldsInTheMiddleDontShow() {
final double testMillis = 2 * DateUtils.DAY_IN_MILLIS + 15 * DateUtils.MINUTE_IN_MILLIS;
final String expectedTime = "2d 15m";
assertThat(Utils.formatElapsedTime(mContext, testMillis, false).toString()).isEqualTo(
expectedTime);
}
@Test
public void testFormatElapsedTime_FormatZero_WithSeconds() {
final double testMillis = 0;
final String expectedTime = "0s";
assertThat(Utils.formatElapsedTime(mContext, testMillis, true).toString()).isEqualTo(
expectedTime);
}
@Test
public void testFormatElapsedTime_FormatZero_NoSeconds() {
final double testMillis = 0;
final String expectedTime = "0m";
assertThat(Utils.formatElapsedTime(mContext, testMillis, false).toString()).isEqualTo(
expectedTime);
}
@Test
public void testFormatElapsedTime_onlyContainsMinute_hasTtsSpan() {
final double testMillis = 15 * DateUtils.MINUTE_IN_MILLIS;
final CharSequence charSequence = Utils.formatElapsedTime(mContext, testMillis, false);
assertThat(charSequence).isInstanceOf(SpannableStringBuilder.class);
final SpannableStringBuilder expectedString = (SpannableStringBuilder) charSequence;
final TtsSpan[] ttsSpans = expectedString.getSpans(0, expectedString.length(),
TtsSpan.class);
assertThat(ttsSpans).asList().hasSize(1);
assertThat(ttsSpans[0].getType()).isEqualTo(TtsSpan.TYPE_MEASURE);
}
@Test
public void testFormatRelativeTime_WithSeconds_ShowSeconds() {
final double testMillis = 40 * DateUtils.SECOND_IN_MILLIS;
final String expectedTime = "40 sec. ago";
assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo(
expectedTime);
}
@Test
public void testFormatRelativeTime_NoSeconds_DoNotShowSeconds() {
final double testMillis = 40 * DateUtils.SECOND_IN_MILLIS;
final String expectedTime = "1 min. ago";
assertThat(Utils.formatRelativeTime(mContext, testMillis, false).toString()).isEqualTo(
expectedTime);
}
@Test
public void testFormatRelativeTime_LessThanTwoMinutes_withSeconds() {
final double testMillis = 119 * DateUtils.SECOND_IN_MILLIS;
final String expectedTime = "119 sec. ago";
assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo(
expectedTime);
}
@Test
public void testFormatRelativeTime_LessThanTwoMinutes_NoSeconds() {
final double testMillis = 119 * DateUtils.SECOND_IN_MILLIS;
final String expectedTime = "2 min. ago";
assertThat(Utils.formatRelativeTime(mContext, testMillis, false).toString()).isEqualTo(
expectedTime);
}
@Test
public void testFormatRelativeTime_TwoMinutes_withSeconds() {
final double testMillis = 2 * DateUtils.MINUTE_IN_MILLIS;
final String expectedTime = "2 min. ago";
assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo(
expectedTime);
}
@Test
public void testFormatRelativeTime_LessThanTwoHours_withSeconds() {
final double testMillis = 119 * DateUtils.MINUTE_IN_MILLIS;
final String expectedTime = "119 min. ago";
assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo(
expectedTime);
}
@Test
public void testFormatRelativeTime_TwoHours_withSeconds() {
final double testMillis = 2 * DateUtils.HOUR_IN_MILLIS;
final String expectedTime = "2 hr. ago";
assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo(
expectedTime);
}
@Test
public void testFormatRelativeTime_LessThanTwoDays_withSeconds() {
final double testMillis = 47 * DateUtils.HOUR_IN_MILLIS;
final String expectedTime = "47 hr. ago";
assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo(
expectedTime);
}
@Test
public void testFormatRelativeTime_TwoDays_withSeconds() {
final double testMillis = 2 * DateUtils.DAY_IN_MILLIS;
final String expectedTime = "2 days ago";
assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo(
expectedTime);
}
@Test
public void testFormatRelativeTime_FormatZero_WithSeconds() {
final double testMillis = 0;
final String expectedTime = "0 sec. ago";
assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo(
expectedTime);
}
@Test
public void testFormatRelativeTime_FormatZero_NoSeconds() {
final double testMillis = 0;
final String expectedTime = "0 min. ago";
assertThat(Utils.formatRelativeTime(mContext, testMillis, false).toString()).isEqualTo(
expectedTime);
}
@Test @Test
public void testInitializeVolumeDoesntBreakOnNullVolume() { public void testInitializeVolumeDoesntBreakOnNullVolume() {
VolumeInfo info = new VolumeInfo("id", 0, new DiskInfo("id", 0), ""); VolumeInfo info = new VolumeInfo("id", 0, new DiskInfo("id", 0), "");

View File

@@ -43,6 +43,9 @@ import com.android.settings.testutils.BatteryTestUtils;
import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.R;
import com.android.settingslib.utils.PowerUtil;
import java.time.Duration;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@@ -72,6 +75,8 @@ public class BatteryInfoTest {
public static final long TEST_CHARGE_TIME_REMAINING = TimeUnit.MINUTES.toMicros(1); public static final long TEST_CHARGE_TIME_REMAINING = TimeUnit.MINUTES.toMicros(1);
public static final String TEST_CHARGE_TIME_REMAINING_STRINGIFIED = public static final String TEST_CHARGE_TIME_REMAINING_STRINGIFIED =
"1m left until fully charged"; "1m left until fully charged";
public static final String TEST_BATTERY_LEVEL_10 = "10%";
public static final String FIFTEEN_MIN_FORMATTED = "15m";
private Intent mDisChargingBatteryBroadcast; private Intent mDisChargingBatteryBroadcast;
private Intent mChargingBatteryBroadcast; private Intent mChargingBatteryBroadcast;
private Context mContext; private Context mContext;
@@ -134,13 +139,15 @@ public class BatteryInfoTest {
} }
@Test @Test
public void testGetBatteryInfo_basedOnUsageTrue_usesCorrectString() { public void testGetBatteryInfo_basedOnUsageTrueMoreThanFifteenMinutes_usesCorrectString() {
BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast, BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
mBatteryStats, SystemClock.elapsedRealtime() * 1000, false /* shortString */, mBatteryStats, SystemClock.elapsedRealtime() * 1000, false /* shortString */,
1000, true /* basedOnUsage */); PowerUtil.convertMsToUs(Duration.ofHours(4).toMillis()),
true /* basedOnUsage */);
BatteryInfo info2 = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast, BatteryInfo info2 = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
mBatteryStats, SystemClock.elapsedRealtime() * 1000, true /* shortString */, mBatteryStats, SystemClock.elapsedRealtime() * 1000, true /* shortString */,
1000, true /* basedOnUsage */); PowerUtil.convertMsToUs(Duration.ofHours(4).toMillis()),
true /* basedOnUsage */);
// We only add special mention for the long string // We only add special mention for the long string
assertThat(info.remainingLabel.toString()).contains(ENHANCED_STRING_SUFFIX); assertThat(info.remainingLabel.toString()).contains(ENHANCED_STRING_SUFFIX);
@@ -148,6 +155,41 @@ public class BatteryInfoTest {
assertThat(info2.remainingLabel.toString()).doesNotContain(ENHANCED_STRING_SUFFIX); assertThat(info2.remainingLabel.toString()).doesNotContain(ENHANCED_STRING_SUFFIX);
} }
@Test
public void testGetBatteryInfo_basedOnUsageTrueLessThanSevenMinutes_usesCorrectString() {
BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
mBatteryStats, SystemClock.elapsedRealtime() * 1000, false /* shortString */,
PowerUtil.convertMsToUs(Duration.ofMinutes(7).toMillis()),
true /* basedOnUsage */);
BatteryInfo info2 = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
mBatteryStats, SystemClock.elapsedRealtime() * 1000, true /* shortString */,
PowerUtil.convertMsToUs(Duration.ofMinutes(7).toMillis()),
true /* basedOnUsage */);
// These should be identical in either case
assertThat(info.remainingLabel.toString()).isEqualTo(
mContext.getString(R.string.power_remaining_duration_only_shutdown_imminent));
assertThat(info2.remainingLabel.toString()).isEqualTo(
mContext.getString(R.string.power_remaining_duration_only_shutdown_imminent));
}
@Test
public void testGetBatteryInfo_basedOnUsageTrueBetweenSevenAndFifteenMinutes_usesCorrectString() {
BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
mBatteryStats, SystemClock.elapsedRealtime() * 1000, false /* shortString */,
PowerUtil.convertMsToUs(Duration.ofMinutes(10).toMillis()),
true /* basedOnUsage */);
// Check that strings are showing less than 15 minutes remaining regardless of exact time.
assertThat(info.chargeLabel.toString()).isEqualTo(
mContext.getString(R.string.power_remaining_less_than_duration,
TEST_BATTERY_LEVEL_10, FIFTEEN_MIN_FORMATTED));
assertThat(info.remainingLabel.toString()).isEqualTo(
mContext.getString(R.string.power_remaining_less_than_duration_only,
FIFTEEN_MIN_FORMATTED));
}
@Test @Test
public void testGetBatteryInfo_basedOnUsageFalse_usesDefaultString() { public void testGetBatteryInfo_basedOnUsageFalse_usesDefaultString() {
BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast, BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,

View File

@@ -55,7 +55,6 @@ import com.android.internal.os.BatteryStatsImpl;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.TestConfig; import com.android.settings.TestConfig;
import com.android.settings.Utils;
import com.android.settings.applications.LayoutPreference; import com.android.settings.applications.LayoutPreference;
import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.fuelgauge.anomaly.Anomaly;
import com.android.settings.fuelgauge.anomaly.AnomalyDetectionPolicy; import com.android.settings.fuelgauge.anomaly.AnomalyDetectionPolicy;
@@ -65,6 +64,7 @@ import com.android.settings.testutils.XmlTestUtils;
import com.android.settings.testutils.shadow.SettingsShadowResources; import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.utils.StringUtil;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
@@ -367,8 +367,8 @@ public class PowerUsageSummaryLegacyTest {
public void testUpdateScreenPreference_showCorrectSummary() { public void testUpdateScreenPreference_showCorrectSummary() {
doReturn(mScreenBatterySipper).when(mFragment).findBatterySipperByType(any(), any()); doReturn(mScreenBatterySipper).when(mFragment).findBatterySipperByType(any(), any());
doReturn(mRealContext).when(mFragment).getContext(); doReturn(mRealContext).when(mFragment).getContext();
final CharSequence expectedSummary = Utils.formatElapsedTime(mRealContext, USAGE_TIME_MS, final CharSequence expectedSummary =
false); StringUtil.formatElapsedTime(mRealContext, USAGE_TIME_MS, false);
mFragment.updateScreenPreference(); mFragment.updateScreenPreference();