Align system time 12-24 hour format in the time slot information

align the time format configuration in the Settings -> System ->
Date/Time to show 12- or 24- hour format in the usage time slot

screenshot: https://screenshot.googleplex.com/3w2SFvBLpC5oHBs
screenshot: https://screenshot.googleplex.com/86uCq6R4PKEg9RD
screenshot: https://screenshot.googleplex.com/3easrEFMQdZEjGP
screenshot: https://screenshot.googleplex.com/7dPWVJNTbSShFPa

Bug: 187783891
Test: make SettingsRoboTests
Change-Id: I9af0a69bd7c67562526bd5ee74a657635068ef44
This commit is contained in:
ykhung
2021-05-18 14:01:23 +08:00
committed by YUKAI HUNG
parent db6c7211e4
commit 1ea5208fa8
6 changed files with 90 additions and 57 deletions

View File

@@ -24,6 +24,7 @@ import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.format.DateFormat;
import android.text.format.DateUtils; import android.text.format.DateUtils;
import android.util.Log; 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.core.lifecycle.events.OnSaveInstanceState;
import com.android.settingslib.utils.StringUtil; import com.android.settingslib.utils.StringUtil;
import java.time.Clock;
import java.util.Arrays; import java.util.Arrays;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@@ -88,6 +88,8 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
@VisibleForTesting long[] mBatteryHistoryKeys; @VisibleForTesting long[] mBatteryHistoryKeys;
@VisibleForTesting int mTrapezoidIndex = BatteryChartView.SELECTED_INDEX_INVALID; @VisibleForTesting int mTrapezoidIndex = BatteryChartView.SELECTED_INDEX_INVALID;
private boolean mIs24HourFormat = false;
private final String mPreferenceKey; private final String mPreferenceKey;
private final SettingsActivity mActivity; private final SettingsActivity mActivity;
private final InstrumentedPreferenceFragment mFragment; private final InstrumentedPreferenceFragment mFragment;
@@ -110,6 +112,7 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
mActivity = activity; mActivity = activity;
mFragment = fragment; mFragment = fragment;
mPreferenceKey = preferenceKey; mPreferenceKey = preferenceKey;
mIs24HourFormat = DateFormat.is24HourFormat(context);
mNotAllowShowSummaryPackages = context.getResources() mNotAllowShowSummaryPackages = context.getResources()
.getTextArray(R.array.allowlist_hide_summary_in_battery_usage); .getTextArray(R.array.allowlist_hide_summary_in_battery_usage);
mNotAllowShowEntryPackages = context.getResources() mNotAllowShowEntryPackages = context.getResources()
@@ -144,6 +147,7 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
BatteryDiffEntry.clearCache(); BatteryDiffEntry.clearCache();
Log.d(TAG, "clear icon and label cache since uiMode is changed"); Log.d(TAG, "clear icon and label cache since uiMode is changed");
} }
mIs24HourFormat = DateFormat.is24HourFormat(mContext);
mMetricsFeatureProvider.action(mPrefContext, SettingsEnums.OPEN_BATTERY_USAGE); mMetricsFeatureProvider.action(mPrefContext, SettingsEnums.OPEN_BATTERY_USAGE);
} }
@@ -493,10 +497,10 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
return null; return null;
} }
final String fromHour = ConvertUtils.utcToLocalTimeHour( final String fromHour = ConvertUtils.utcToLocalTimeHour(
mBatteryHistoryKeys[mTrapezoidIndex * 2]); mBatteryHistoryKeys[mTrapezoidIndex * 2], mIs24HourFormat);
final String toHour = ConvertUtils.utcToLocalTimeHour( final String toHour = ConvertUtils.utcToLocalTimeHour(
mBatteryHistoryKeys[(mTrapezoidIndex + 1) * 2]); mBatteryHistoryKeys[(mTrapezoidIndex + 1) * 2], mIs24HourFormat);
return String.format("%s-%s", fromHour, toHour); return String.format("%s - %s", fromHour, toHour);
} }
@VisibleForTesting @VisibleForTesting
@@ -563,21 +567,9 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
if (mBatteryChartView == null || mBatteryHistoryKeys == null) { if (mBatteryChartView == null || mBatteryHistoryKeys == null) {
return; return;
} }
long latestTimestamp = final long latestTimestamp =
mBatteryHistoryKeys[mBatteryHistoryKeys.length - 1]; mBatteryHistoryKeys[mBatteryHistoryKeys.length - 1];
// Uses the current time if we don't have history data. mBatteryChartView.setLatestTimestamp(latestTimestamp);
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);
} }
private static String utcToLocalTime(long[] timestamps) { private static String utcToLocalTime(long[] timestamps) {

View File

@@ -25,6 +25,8 @@ import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.Handler; import android.os.Handler;
import android.text.format.DateFormat;
import android.text.format.DateUtils;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
import android.view.HapticFeedbackConstants; import android.view.HapticFeedbackConstants;
@@ -40,6 +42,7 @@ import com.android.settings.R;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.Utils; import com.android.settingslib.Utils;
import java.time.Clock;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@@ -74,6 +77,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
private boolean mIsSlotsClickabled; private boolean mIsSlotsClickabled;
@VisibleForTesting int mSelectedIndex; @VisibleForTesting int mSelectedIndex;
@VisibleForTesting String[] mTimestamps;
// Colors for drawing the trapezoid shape and dividers. // Colors for drawing the trapezoid shape and dividers.
private int mTrapezoidColor; private int mTrapezoidColor;
@@ -84,7 +88,6 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
private final Rect[] mPercentageBounds = private final Rect[] mPercentageBounds =
new Rect[] {new Rect(), new Rect(), new Rect()}; new Rect[] {new Rect(), new Rect(), new Rect()};
// For drawing the timestamp information. // For drawing the timestamp information.
private String[] mTimestamps;
private final Rect[] mTimestampsBounds = private final Rect[] mTimestampsBounds =
new Rect[] {new Rect(), new Rect(), new Rect(), new Rect()}; 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); setSelectedIndex(SELECTED_INDEX_ALL);
setTrapezoidCount(DEFAULT_TRAPEZOID_COUNT); setTrapezoidCount(DEFAULT_TRAPEZOID_COUNT);
setClickable(false); setClickable(false);
setLatestTimestamp(0);
} }
/** Sets the total trapezoid count for drawing. */ /** Sets the total trapezoid count for drawing. */
@@ -182,12 +186,21 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
requestLayout(); requestLayout();
} }
/** Sets timestamps for drawing into x-axis information. */ /** Sets the latest timestamp for drawing into x-axis information. */
public void setTimestamps(String[] timestamps) { public void setLatestTimestamp(long latestTimestamp) {
mTimestamps = timestamps; if (latestTimestamp == 0) {
if (timestamps != null latestTimestamp = Clock.systemUTC().millis();
&& timestamps.length != DEFAULT_TIMESTAMP_COUNT) { }
mTimestamps = null; 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(); requestLayout();
} }

View File

@@ -71,6 +71,7 @@ public final class ConvertUtils {
private static String sZoneId; private static String sZoneId;
private static String sZoneIdForHour; private static String sZoneIdForHour;
private static boolean sIs24HourFormat;
@VisibleForTesting @VisibleForTesting
static SimpleDateFormat sSimpleDateFormat; static SimpleDateFormat sSimpleDateFormat;
@@ -134,11 +135,15 @@ public final class ConvertUtils {
} }
/** Converts UTC timestamp to local time hour data. */ /** 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(); final String currentZoneId = TimeZone.getDefault().getID();
if (!currentZoneId.equals(sZoneIdForHour) || sSimpleDateFormatForHour == null) { if (!currentZoneId.equals(sZoneIdForHour)
|| sIs24HourFormat != is24HourFormat
|| sSimpleDateFormatForHour == null) {
sZoneIdForHour = currentZoneId; 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)) return sSimpleDateFormatForHour.format(new Date(timestamp))
.toLowerCase(Locale.getDefault()); .toLowerCase(Locale.getDefault());

View File

@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
@@ -604,7 +605,7 @@ public final class BatteryChartPreferenceControllerTest {
mBatteryChartPreferenceController.setTimestampLabel(); mBatteryChartPreferenceController.setTimestampLabel();
verify(mBatteryChartPreferenceController.mBatteryChartView, never()) verify(mBatteryChartPreferenceController.mBatteryChartView, never())
.setTimestamps(any()); .setLatestTimestamp(anyLong());
} }
@Test @Test
@@ -613,19 +614,11 @@ public final class BatteryChartPreferenceControllerTest {
mBatteryChartPreferenceController.mBatteryChartView = mBatteryChartPreferenceController.mBatteryChartView =
spy(new BatteryChartView(mContext)); spy(new BatteryChartView(mContext));
setUpBatteryHistoryKeys(); 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(); mBatteryChartPreferenceController.setTimestampLabel();
verify(mBatteryChartPreferenceController.mBatteryChartView) verify(mBatteryChartPreferenceController.mBatteryChartView)
.setTimestamps(expectedResults); .setLatestTimestamp(1619247636826L);
} }
@Test @Test
@@ -638,7 +631,7 @@ public final class BatteryChartPreferenceControllerTest {
mBatteryChartPreferenceController.setTimestampLabel(); mBatteryChartPreferenceController.setTimestampLabel();
verify(mBatteryChartPreferenceController.mBatteryChartView) verify(mBatteryChartPreferenceController.mBatteryChartView)
.setTimestamps(any()); .setLatestTimestamp(anyLong());
} }
@Test @Test
@@ -709,7 +702,7 @@ public final class BatteryChartPreferenceControllerTest {
private void setUpBatteryHistoryKeys() { private void setUpBatteryHistoryKeys() {
mBatteryChartPreferenceController.mBatteryHistoryKeys = mBatteryChartPreferenceController.mBatteryHistoryKeys =
new long[] {1619196786769L, 0L, 1619247636826L}; new long[] {1619196786769L, 0L, 1619247636826L};
ConvertUtils.utcToLocalTimeHour(/*timestamp=*/ 0); ConvertUtils.utcToLocalTimeHour(/*timestamp=*/ 0, /*is24HourFormat=*/ false);
// Simulates the locale in GMT. // Simulates the locale in GMT.
ConvertUtils.sSimpleDateFormatForHour ConvertUtils.sSimpleDateFormatForHour
.setTimeZone(TimeZone.getTimeZone("GMT")); .setTimeZone(TimeZone.getTimeZone("GMT"));

View File

@@ -41,6 +41,7 @@ import org.robolectric.RuntimeEnvironment;
import java.util.Arrays; import java.util.Arrays;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.TimeZone;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
public final class BatteryChartViewTest { public final class BatteryChartViewTest {
@@ -227,4 +228,20 @@ public final class BatteryChartViewTest {
verify(mBatteryChartView.mHandler) verify(mBatteryChartView.mHandler)
.postDelayed(mBatteryChartView.mUpdateClickableStateRun, 500L); .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);
}
} }

View File

@@ -316,28 +316,41 @@ public final class ConvertUtilsTest {
@Test @Test
public void testUtcToLocalTime_returnExpectedResult() { public void testUtcToLocalTime_returnExpectedResult() {
final long timestamp = 1619196786769L; final long timestamp = 1619196786769L;
ConvertUtils.sSimpleDateFormat = null; ConvertUtils.sSimpleDateFormat = null;
// Invokes the method first to create the SimpleDateFormat. // Invokes the method first to create the SimpleDateFormat.
ConvertUtils.utcToLocalTime(/*timestamp=*/ 0); ConvertUtils.utcToLocalTime(/*timestamp=*/ 0);
ConvertUtils.sSimpleDateFormat ConvertUtils.sSimpleDateFormat
.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles")); .setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
assertThat(ConvertUtils.utcToLocalTime(timestamp)) assertThat(ConvertUtils.utcToLocalTime(timestamp))
.isEqualTo("Apr 23,2021 09:53:06"); .isEqualTo("Apr 23,2021 09:53:06");
} }
@Test @Test
public void testUtcToLocalTmeHour_returnExpectedResult() { public void testUtcToLocalTimeHour_12HourFormat_returnExpectedResult() {
final long timestamp = 1619196786769L; final long timestamp = 1619196786769L;
ConvertUtils.sSimpleDateFormatForHour = null; ConvertUtils.sSimpleDateFormatForHour = null;
// Invokes the method first to create the SimpleDateFormat. // Invokes the method first to create the SimpleDateFormat.
ConvertUtils.utcToLocalTimeHour(/*timestamp=*/ 0); ConvertUtils.utcToLocalTimeHour(/*timestamp=*/ 0, /*is24HourFormat=*/ false);
ConvertUtils.sSimpleDateFormatForHour ConvertUtils.sSimpleDateFormatForHour
.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles")); .setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
assertThat(ConvertUtils.utcToLocalTimeHour(timestamp)) assertThat(ConvertUtils.utcToLocalTimeHour(
.isEqualTo("9 am"); 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( private static BatteryHistEntry createBatteryHistEntry(