diff --git a/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java index 59755d364f0..88b8fa90cc6 100644 --- a/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java +++ b/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java @@ -24,6 +24,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.text.TextUtils; +import android.text.format.DateFormat; import android.text.format.DateUtils; import android.util.Log; @@ -47,7 +48,6 @@ import com.android.settingslib.core.lifecycle.events.OnResume; import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState; import com.android.settingslib.utils.StringUtil; -import java.time.Clock; import java.util.Arrays; import java.util.ArrayList; import java.util.Collections; @@ -88,6 +88,8 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll @VisibleForTesting long[] mBatteryHistoryKeys; @VisibleForTesting int mTrapezoidIndex = BatteryChartView.SELECTED_INDEX_INVALID; + private boolean mIs24HourFormat = false; + private final String mPreferenceKey; private final SettingsActivity mActivity; private final InstrumentedPreferenceFragment mFragment; @@ -110,6 +112,7 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll mActivity = activity; mFragment = fragment; mPreferenceKey = preferenceKey; + mIs24HourFormat = DateFormat.is24HourFormat(context); mNotAllowShowSummaryPackages = context.getResources() .getTextArray(R.array.allowlist_hide_summary_in_battery_usage); mNotAllowShowEntryPackages = context.getResources() @@ -144,6 +147,7 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll BatteryDiffEntry.clearCache(); Log.d(TAG, "clear icon and label cache since uiMode is changed"); } + mIs24HourFormat = DateFormat.is24HourFormat(mContext); mMetricsFeatureProvider.action(mPrefContext, SettingsEnums.OPEN_BATTERY_USAGE); } @@ -493,10 +497,10 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll return null; } final String fromHour = ConvertUtils.utcToLocalTimeHour( - mBatteryHistoryKeys[mTrapezoidIndex * 2]); + mBatteryHistoryKeys[mTrapezoidIndex * 2], mIs24HourFormat); final String toHour = ConvertUtils.utcToLocalTimeHour( - mBatteryHistoryKeys[(mTrapezoidIndex + 1) * 2]); - return String.format("%s-%s", fromHour, toHour); + mBatteryHistoryKeys[(mTrapezoidIndex + 1) * 2], mIs24HourFormat); + return String.format("%s - %s", fromHour, toHour); } @VisibleForTesting @@ -563,21 +567,9 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll if (mBatteryChartView == null || mBatteryHistoryKeys == null) { return; } - long latestTimestamp = + final long latestTimestamp = mBatteryHistoryKeys[mBatteryHistoryKeys.length - 1]; - // Uses the current time if we don't have history data. - if (latestTimestamp == 0) { - latestTimestamp = Clock.systemUTC().millis(); - } - // Generates timestamp label for chart graph (every 8 hours). - final long timeSlotOffset = DateUtils.HOUR_IN_MILLIS * 8; - final String[] timestampLabels = new String[4]; - for (int index = 0; index < timestampLabels.length; index++) { - timestampLabels[index] = - ConvertUtils.utcToLocalTimeHour( - latestTimestamp - (3 - index) * timeSlotOffset); - } - mBatteryChartView.setTimestamps(timestampLabels); + mBatteryChartView.setLatestTimestamp(latestTimestamp); } private static String utcToLocalTime(long[] timestamps) { diff --git a/src/com/android/settings/fuelgauge/BatteryChartView.java b/src/com/android/settings/fuelgauge/BatteryChartView.java index 1590a57818d..c6dab2250d9 100644 --- a/src/com/android/settings/fuelgauge/BatteryChartView.java +++ b/src/com/android/settings/fuelgauge/BatteryChartView.java @@ -25,6 +25,8 @@ import android.graphics.Paint; import android.graphics.Path; import android.graphics.Rect; import android.os.Handler; +import android.text.format.DateFormat; +import android.text.format.DateUtils; import android.util.AttributeSet; import android.util.Log; import android.view.HapticFeedbackConstants; @@ -40,6 +42,7 @@ import com.android.settings.R; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.Utils; +import java.time.Clock; import java.util.Arrays; import java.util.List; import java.util.Locale; @@ -74,6 +77,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick private boolean mIsSlotsClickabled; @VisibleForTesting int mSelectedIndex; + @VisibleForTesting String[] mTimestamps; // Colors for drawing the trapezoid shape and dividers. private int mTrapezoidColor; @@ -84,7 +88,6 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick private final Rect[] mPercentageBounds = new Rect[] {new Rect(), new Rect(), new Rect()}; // For drawing the timestamp information. - private String[] mTimestamps; private final Rect[] mTimestampsBounds = new Rect[] {new Rect(), new Rect(), new Rect(), new Rect()}; @@ -116,6 +119,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick setSelectedIndex(SELECTED_INDEX_ALL); setTrapezoidCount(DEFAULT_TRAPEZOID_COUNT); setClickable(false); + setLatestTimestamp(0); } /** Sets the total trapezoid count for drawing. */ @@ -182,12 +186,21 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick requestLayout(); } - /** Sets timestamps for drawing into x-axis information. */ - public void setTimestamps(String[] timestamps) { - mTimestamps = timestamps; - if (timestamps != null - && timestamps.length != DEFAULT_TIMESTAMP_COUNT) { - mTimestamps = null; + /** Sets the latest timestamp for drawing into x-axis information. */ + public void setLatestTimestamp(long latestTimestamp) { + if (latestTimestamp == 0) { + latestTimestamp = Clock.systemUTC().millis(); + } + if (mTimestamps == null) { + mTimestamps = new String[DEFAULT_TIMESTAMP_COUNT]; + } + final long timeSlotOffset = DateUtils.HOUR_IN_MILLIS * 8; + final boolean is24HourFormat = DateFormat.is24HourFormat(getContext()); + for (int index = 0; index < DEFAULT_TIMESTAMP_COUNT; index++) { + mTimestamps[index] = + ConvertUtils.utcToLocalTimeHour( + latestTimestamp - (3 - index) * timeSlotOffset, + is24HourFormat); } requestLayout(); } diff --git a/src/com/android/settings/fuelgauge/ConvertUtils.java b/src/com/android/settings/fuelgauge/ConvertUtils.java index e05247c3c40..df9374de6f1 100644 --- a/src/com/android/settings/fuelgauge/ConvertUtils.java +++ b/src/com/android/settings/fuelgauge/ConvertUtils.java @@ -71,6 +71,7 @@ public final class ConvertUtils { private static String sZoneId; private static String sZoneIdForHour; + private static boolean sIs24HourFormat; @VisibleForTesting static SimpleDateFormat sSimpleDateFormat; @@ -134,11 +135,15 @@ public final class ConvertUtils { } /** Converts UTC timestamp to local time hour data. */ - public static String utcToLocalTimeHour(long timestamp) { + public static String utcToLocalTimeHour(long timestamp, boolean is24HourFormat) { final String currentZoneId = TimeZone.getDefault().getID(); - if (!currentZoneId.equals(sZoneIdForHour) || sSimpleDateFormatForHour == null) { + if (!currentZoneId.equals(sZoneIdForHour) + || sIs24HourFormat != is24HourFormat + || sSimpleDateFormatForHour == null) { sZoneIdForHour = currentZoneId; - sSimpleDateFormatForHour = new SimpleDateFormat("h aa", Locale.ENGLISH); + sIs24HourFormat = is24HourFormat; + sSimpleDateFormatForHour = new SimpleDateFormat( + sIs24HourFormat ? "HH" : "h aa", Locale.ENGLISH); } return sSimpleDateFormatForHour.format(new Date(timestamp)) .toLowerCase(Locale.getDefault()); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartPreferenceControllerTest.java index 7cdd1c69c37..7caa32edf02 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartPreferenceControllerTest.java @@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyLong; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; @@ -604,7 +605,7 @@ public final class BatteryChartPreferenceControllerTest { mBatteryChartPreferenceController.setTimestampLabel(); verify(mBatteryChartPreferenceController.mBatteryChartView, never()) - .setTimestamps(any()); + .setLatestTimestamp(anyLong()); } @Test @@ -613,19 +614,11 @@ public final class BatteryChartPreferenceControllerTest { mBatteryChartPreferenceController.mBatteryChartView = spy(new BatteryChartView(mContext)); setUpBatteryHistoryKeys(); - // Generates the expected result. - final String[] expectedResults = new String[4]; - final long timeSlotOffset = DateUtils.HOUR_IN_MILLIS * 8; - for (int index = 0; index < expectedResults.length; index++) { - expectedResults[index] = - ConvertUtils.utcToLocalTimeHour( - 1619247636826L - (3 - index) * timeSlotOffset); - } mBatteryChartPreferenceController.setTimestampLabel(); verify(mBatteryChartPreferenceController.mBatteryChartView) - .setTimestamps(expectedResults); + .setLatestTimestamp(1619247636826L); } @Test @@ -638,7 +631,7 @@ public final class BatteryChartPreferenceControllerTest { mBatteryChartPreferenceController.setTimestampLabel(); verify(mBatteryChartPreferenceController.mBatteryChartView) - .setTimestamps(any()); + .setLatestTimestamp(anyLong()); } @Test @@ -709,7 +702,7 @@ public final class BatteryChartPreferenceControllerTest { private void setUpBatteryHistoryKeys() { mBatteryChartPreferenceController.mBatteryHistoryKeys = new long[] {1619196786769L, 0L, 1619247636826L}; - ConvertUtils.utcToLocalTimeHour(/*timestamp=*/ 0); + ConvertUtils.utcToLocalTimeHour(/*timestamp=*/ 0, /*is24HourFormat=*/ false); // Simulates the locale in GMT. ConvertUtils.sSimpleDateFormatForHour .setTimeZone(TimeZone.getTimeZone("GMT")); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartViewTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartViewTest.java index 3998a332630..3f94456f8e1 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartViewTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartViewTest.java @@ -41,6 +41,7 @@ import org.robolectric.RuntimeEnvironment; import java.util.Arrays; import java.util.ArrayList; +import java.util.TimeZone; @RunWith(RobolectricTestRunner.class) public final class BatteryChartViewTest { @@ -227,4 +228,20 @@ public final class BatteryChartViewTest { verify(mBatteryChartView.mHandler) .postDelayed(mBatteryChartView.mUpdateClickableStateRun, 500L); } + + @Test + public void testSetLatestTimestamp_generateExpectedTimestamps() { + final long timestamp = 1619196786769L; + ConvertUtils.sSimpleDateFormatForHour = null; + // Invokes the method first to create the SimpleDateFormat. + ConvertUtils.utcToLocalTimeHour(/*timestamp=*/ 0, /*is24HourFormat=*/ false); + ConvertUtils.sSimpleDateFormatForHour + .setTimeZone(TimeZone.getTimeZone("America/Los_Angeles")); + final String[] expectedTimestamps = + new String[] {"9 am", "5 pm", "1 am", "9 am"}; + + mBatteryChartView.setLatestTimestamp(timestamp); + + assertThat(mBatteryChartView.mTimestamps).isEqualTo(expectedTimestamps); + } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/ConvertUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/ConvertUtilsTest.java index 63a0b3d71d1..c9c5e465315 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/ConvertUtilsTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/ConvertUtilsTest.java @@ -316,28 +316,41 @@ public final class ConvertUtilsTest { @Test public void testUtcToLocalTime_returnExpectedResult() { - final long timestamp = 1619196786769L; - ConvertUtils.sSimpleDateFormat = null; - // Invokes the method first to create the SimpleDateFormat. - ConvertUtils.utcToLocalTime(/*timestamp=*/ 0); - ConvertUtils.sSimpleDateFormat - .setTimeZone(TimeZone.getTimeZone("America/Los_Angeles")); + final long timestamp = 1619196786769L; + ConvertUtils.sSimpleDateFormat = null; + // Invokes the method first to create the SimpleDateFormat. + ConvertUtils.utcToLocalTime(/*timestamp=*/ 0); + ConvertUtils.sSimpleDateFormat + .setTimeZone(TimeZone.getTimeZone("America/Los_Angeles")); - assertThat(ConvertUtils.utcToLocalTime(timestamp)) - .isEqualTo("Apr 23,2021 09:53:06"); + assertThat(ConvertUtils.utcToLocalTime(timestamp)) + .isEqualTo("Apr 23,2021 09:53:06"); } @Test - public void testUtcToLocalTmeHour_returnExpectedResult() { - final long timestamp = 1619196786769L; - ConvertUtils.sSimpleDateFormatForHour = null; - // Invokes the method first to create the SimpleDateFormat. - ConvertUtils.utcToLocalTimeHour(/*timestamp=*/ 0); - ConvertUtils.sSimpleDateFormatForHour - .setTimeZone(TimeZone.getTimeZone("America/Los_Angeles")); + public void testUtcToLocalTimeHour_12HourFormat_returnExpectedResult() { + final long timestamp = 1619196786769L; + ConvertUtils.sSimpleDateFormatForHour = null; + // Invokes the method first to create the SimpleDateFormat. + ConvertUtils.utcToLocalTimeHour(/*timestamp=*/ 0, /*is24HourFormat=*/ false); + ConvertUtils.sSimpleDateFormatForHour + .setTimeZone(TimeZone.getTimeZone("America/Los_Angeles")); - assertThat(ConvertUtils.utcToLocalTimeHour(timestamp)) - .isEqualTo("9 am"); + assertThat(ConvertUtils.utcToLocalTimeHour( + timestamp, /*is24HourFormat=*/ false)).isEqualTo("9 am"); + } + + @Test + public void testUtcToLocalTimeHour_24HourFormat_returnExpectedResult() { + final long timestamp = 1619196786769L; + ConvertUtils.sSimpleDateFormatForHour = null; + // Invokes the method first to create the SimpleDateFormat. + ConvertUtils.utcToLocalTimeHour(/*timestamp=*/ 0, /*is24HourFormat=*/ true); + ConvertUtils.sSimpleDateFormatForHour + .setTimeZone(TimeZone.getTimeZone("America/Los_Angeles")); + + assertThat(ConvertUtils.utcToLocalTimeHour( + timestamp, /*is24HourFormat=*/ true)).isEqualTo("09"); } private static BatteryHistEntry createBatteryHistEntry(