Remove @CorePlatformApi LocaleData usage in frameworks

They can be replaced by the public API provided by ICU4J instead.
No extra layer of caching equivalent to the LocaleData cache is
added because ICU4J has caches instances, e.g. DateFormatSymbols,
etc.

Bug: 160606356
Test: atest FrameworksCoreTests:android.text.format
Change-Id: I07048e0e1a4835d2744b7fce6a5ed79a112e456b
This commit is contained in:
Victor Chang
2020-07-20 12:59:14 +01:00
parent c744bd5f64
commit 55a6efbfd9
9 changed files with 106 additions and 92 deletions

View File

@@ -26,8 +26,6 @@ import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.SpannedString;
import libcore.icu.LocaleData;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
@@ -287,8 +285,10 @@ public class DateFormat {
*/
@UnsupportedAppUsage
public static String getTimeFormatString(Context context, int userHandle) {
final LocaleData d = LocaleData.get(context.getResources().getConfiguration().locale);
return is24HourFormat(context, userHandle) ? d.timeFormat_Hm : d.timeFormat_hm;
DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(
context.getResources().getConfiguration().locale);
return is24HourFormat(context, userHandle) ? dtpg.getBestPattern("Hm")
: dtpg.getBestPattern("hm");
}
/**
@@ -475,7 +475,6 @@ public class DateFormat {
SpannableStringBuilder s = new SpannableStringBuilder(inFormat);
int count;
LocaleData localeData = LocaleData.get(Locale.getDefault());
DateFormatSymbols dfs = getIcuDateFormatSymbols(Locale.getDefault());
String[] amPm = dfs.getAmPmStrings();
@@ -506,7 +505,7 @@ public class DateFormat {
break;
case 'c':
case 'E':
replacement = getDayOfWeekString(localeData,
replacement = getDayOfWeekString(dfs,
inDate.get(Calendar.DAY_OF_WEEK), count, c);
break;
case 'K': // hour in am/pm (0-11)
@@ -534,8 +533,7 @@ public class DateFormat {
break;
case 'L':
case 'M':
replacement = getMonthString(localeData,
inDate.get(Calendar.MONTH), count, c);
replacement = getMonthString(dfs, inDate.get(Calendar.MONTH), count, c);
break;
case 'm':
replacement = zeroPad(inDate.get(Calendar.MINUTE), count);
@@ -568,25 +566,29 @@ public class DateFormat {
}
}
private static String getDayOfWeekString(LocaleData ld, int day, int count, int kind) {
private static String getDayOfWeekString(DateFormatSymbols dfs, int day, int count, int kind) {
boolean standalone = (kind == 'c');
int context = standalone ? DateFormatSymbols.STANDALONE : DateFormatSymbols.FORMAT;
final int width;
if (count == 5) {
return standalone ? ld.tinyStandAloneWeekdayNames[day] : ld.tinyWeekdayNames[day];
width = DateFormatSymbols.NARROW;
} else if (count == 4) {
return standalone ? ld.longStandAloneWeekdayNames[day] : ld.longWeekdayNames[day];
width = DateFormatSymbols.WIDE;
} else {
return standalone ? ld.shortStandAloneWeekdayNames[day] : ld.shortWeekdayNames[day];
width = DateFormatSymbols.ABBREVIATED;
}
return dfs.getWeekdays(context, width)[day];
}
private static String getMonthString(LocaleData ld, int month, int count, int kind) {
private static String getMonthString(DateFormatSymbols dfs, int month, int count, int kind) {
boolean standalone = (kind == 'L');
int monthContext = standalone ? DateFormatSymbols.STANDALONE : DateFormatSymbols.FORMAT;
if (count == 5) {
return standalone ? ld.tinyStandAloneMonthNames[month] : ld.tinyMonthNames[month];
return dfs.getMonths(monthContext, DateFormatSymbols.NARROW)[month];
} else if (count == 4) {
return standalone ? ld.longStandAloneMonthNames[month] : ld.longMonthNames[month];
return dfs.getMonths(monthContext, DateFormatSymbols.WIDE)[month];
} else if (count == 3) {
return standalone ? ld.shortStandAloneMonthNames[month] : ld.shortMonthNames[month];
return dfs.getMonths(monthContext, DateFormatSymbols.ABBREVIATED)[month];
} else {
// Calendar.JANUARY == 0, so add 1 to month.
return zeroPad(month+1, count);

View File

@@ -20,6 +20,7 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.icu.text.DateFormatSymbols;
import android.icu.text.MeasureFormat;
import android.icu.text.MeasureFormat.FormatWidth;
import android.icu.util.Measure;
@@ -27,8 +28,6 @@ import android.icu.util.MeasureUnit;
import com.android.internal.R;
import libcore.icu.LocaleData;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
@@ -200,17 +199,23 @@ public class DateUtils
*/
@Deprecated
public static String getDayOfWeekString(int dayOfWeek, int abbrev) {
LocaleData d = LocaleData.get(Locale.getDefault());
String[] names;
DateFormatSymbols dfs = DateFormatSymbols.getInstance();
final int width;
switch (abbrev) {
case LENGTH_LONG: names = d.longWeekdayNames; break;
case LENGTH_MEDIUM: names = d.shortWeekdayNames; break;
case LENGTH_SHORT: names = d.shortWeekdayNames; break; // TODO
case LENGTH_SHORTER: names = d.shortWeekdayNames; break; // TODO
case LENGTH_SHORTEST: names = d.tinyWeekdayNames; break;
default: names = d.shortWeekdayNames; break;
case LENGTH_LONG:
width = DateFormatSymbols.WIDE;
break;
case LENGTH_SHORTEST:
width = DateFormatSymbols.NARROW;
break;
case LENGTH_MEDIUM:
case LENGTH_SHORT: // TODO
case LENGTH_SHORTER: // TODO
default:
width = DateFormatSymbols.ABBREVIATED;
break;
}
return names[dayOfWeek];
return dfs.getWeekdays(DateFormatSymbols.FORMAT, width)[dayOfWeek];
}
/**
@@ -239,17 +244,23 @@ public class DateUtils
*/
@Deprecated
public static String getMonthString(int month, int abbrev) {
LocaleData d = LocaleData.get(Locale.getDefault());
String[] names;
DateFormatSymbols dfs = DateFormat.getIcuDateFormatSymbols(Locale.getDefault());
final int width;
switch (abbrev) {
case LENGTH_LONG: names = d.longMonthNames; break;
case LENGTH_MEDIUM: names = d.shortMonthNames; break;
case LENGTH_SHORT: names = d.shortMonthNames; break;
case LENGTH_SHORTER: names = d.shortMonthNames; break;
case LENGTH_SHORTEST: names = d.tinyMonthNames; break;
default: names = d.shortMonthNames; break;
case LENGTH_LONG:
width = DateFormatSymbols.WIDE;
break;
case LENGTH_SHORTEST:
width = DateFormatSymbols.NARROW;
break;
case LENGTH_MEDIUM:
case LENGTH_SHORT:
case LENGTH_SHORTER:
default:
width = DateFormatSymbols.ABBREVIATED;
break;
}
return names[month];
return dfs.getMonths(DateFormatSymbols.FORMAT, width)[month];
}
/**

View File

@@ -22,11 +22,10 @@ package android.text.format;
import android.content.res.Resources;
import android.icu.text.DateFormatSymbols;
import android.icu.text.DecimalFormatSymbols;
import com.android.i18n.timezone.ZoneInfoData;
import libcore.icu.LocaleData;
import java.nio.CharBuffer;
import java.time.Instant;
import java.time.LocalDateTime;
@@ -53,17 +52,17 @@ class TimeFormatter {
private static final int DAYSPERNYEAR = 365;
/**
* The Locale for which the cached LocaleData and formats have been loaded.
* The Locale for which the cached symbols and formats have been loaded.
*/
private static Locale sLocale;
private static DateFormatSymbols sDateFormatSymbols;
private static LocaleData sLocaleData;
private static DecimalFormatSymbols sDecimalFormatSymbols;
private static String sTimeOnlyFormat;
private static String sDateOnlyFormat;
private static String sDateTimeFormat;
private final DateFormatSymbols dateFormatSymbols;
private final LocaleData localeData;
private final DecimalFormatSymbols decimalFormatSymbols;
private final String dateTimeFormat;
private final String timeOnlyFormat;
private final String dateOnlyFormat;
@@ -78,7 +77,7 @@ class TimeFormatter {
if (sLocale == null || !(locale.equals(sLocale))) {
sLocale = locale;
sDateFormatSymbols = DateFormat.getIcuDateFormatSymbols(locale);
sLocaleData = LocaleData.get(locale);
sDecimalFormatSymbols = DecimalFormatSymbols.getInstance(locale);
Resources r = Resources.getSystem();
sTimeOnlyFormat = r.getString(com.android.internal.R.string.time_of_day);
@@ -87,10 +86,10 @@ class TimeFormatter {
}
this.dateFormatSymbols = sDateFormatSymbols;
this.decimalFormatSymbols = sDecimalFormatSymbols;
this.dateTimeFormat = sDateTimeFormat;
this.timeOnlyFormat = sTimeOnlyFormat;
this.dateOnlyFormat = sDateOnlyFormat;
localeData = sLocaleData;
}
}
@@ -172,12 +171,12 @@ class TimeFormatter {
}
private String localizeDigits(String s) {
if (localeData.zeroDigit == '0') {
if (decimalFormatSymbols.getZeroDigit() == '0') {
return s;
}
int length = s.length();
int offsetToLocalizedDigits = localeData.zeroDigit - '0';
int offsetToLocalizedDigits = decimalFormatSymbols.getZeroDigit() - '0';
StringBuilder result = new StringBuilder(length);
for (int i = 0; i < length; ++i) {
char ch = s.charAt(i);
@@ -220,35 +219,44 @@ class TimeFormatter {
char currentChar = formatBuffer.get(formatBuffer.position());
switch (currentChar) {
case 'A':
modifyAndAppend((wallTime.getWeekDay() < 0
|| wallTime.getWeekDay() >= DAYSPERWEEK)
? "?" : localeData.longWeekdayNames[wallTime.getWeekDay() + 1],
modifyAndAppend(
(wallTime.getWeekDay() < 0 || wallTime.getWeekDay() >= DAYSPERWEEK)
? "?"
: dateFormatSymbols.getWeekdays(DateFormatSymbols.FORMAT,
DateFormatSymbols.WIDE)[wallTime.getWeekDay() + 1],
modifier);
return false;
case 'a':
modifyAndAppend((wallTime.getWeekDay() < 0
|| wallTime.getWeekDay() >= DAYSPERWEEK)
? "?" : localeData.shortWeekdayNames[wallTime.getWeekDay() + 1],
modifyAndAppend(
(wallTime.getWeekDay() < 0 || wallTime.getWeekDay() >= DAYSPERWEEK)
? "?"
: dateFormatSymbols.getWeekdays(DateFormatSymbols.FORMAT,
DateFormatSymbols.ABBREVIATED)[wallTime.getWeekDay() + 1],
modifier);
return false;
case 'B':
if (modifier == '-') {
modifyAndAppend((wallTime.getMonth() < 0
|| wallTime.getMonth() >= MONSPERYEAR)
? "?"
: localeData.longStandAloneMonthNames[wallTime.getMonth()],
modifyAndAppend(
(wallTime.getMonth() < 0 || wallTime.getMonth() >= MONSPERYEAR)
? "?"
: dateFormatSymbols.getMonths(DateFormatSymbols.STANDALONE,
DateFormatSymbols.WIDE)[wallTime.getMonth()],
modifier);
} else {
modifyAndAppend((wallTime.getMonth() < 0
|| wallTime.getMonth() >= MONSPERYEAR)
? "?" : localeData.longMonthNames[wallTime.getMonth()],
modifyAndAppend(
(wallTime.getMonth() < 0 || wallTime.getMonth() >= MONSPERYEAR)
? "?"
: dateFormatSymbols.getMonths(DateFormatSymbols.FORMAT,
DateFormatSymbols.WIDE)[wallTime.getMonth()],
modifier);
}
return false;
case 'b':
case 'h':
modifyAndAppend((wallTime.getMonth() < 0 || wallTime.getMonth() >= MONSPERYEAR)
? "?" : localeData.shortMonthNames[wallTime.getMonth()],
? "?"
: dateFormatSymbols.getMonths(DateFormatSymbols.FORMAT,
DateFormatSymbols.ABBREVIATED)[wallTime.getMonth()],
modifier);
return false;
case 'C':

View File

@@ -38,8 +38,6 @@ import android.view.ViewGroup;
import com.android.internal.R;
import libcore.icu.LocaleData;
import java.util.Locale;
/**
@@ -264,7 +262,7 @@ class CalendarViewLegacyDelegate extends CalendarView.AbstractCalendarViewDelega
mShowWeekNumber = a.getBoolean(R.styleable.CalendarView_showWeekNumber,
DEFAULT_SHOW_WEEK_NUMBER);
mFirstDayOfWeek = a.getInt(R.styleable.CalendarView_firstDayOfWeek,
LocaleData.get(Locale.getDefault()).firstDayOfWeek);
Calendar.getInstance().getFirstDayOfWeek());
final String minDate = a.getString(R.styleable.CalendarView_minDate);
if (!CalendarView.parseDate(minDate, mMinDate)) {
CalendarView.parseDate(DEFAULT_MIN_DATE, mMinDate);

View File

@@ -33,10 +33,6 @@ import com.android.internal.R;
import com.android.internal.widget.ViewPager;
import com.android.internal.widget.ViewPager.OnPageChangeListener;
import libcore.icu.LocaleData;
import java.util.Locale;
class DayPickerView extends ViewGroup {
private static final int DEFAULT_LAYOUT = R.layout.day_picker_content_material;
private static final int DEFAULT_START_YEAR = 1900;
@@ -86,7 +82,7 @@ class DayPickerView extends ViewGroup {
attrs, a, defStyleAttr, defStyleRes);
final int firstDayOfWeek = a.getInt(R.styleable.CalendarView_firstDayOfWeek,
LocaleData.get(Locale.getDefault()).firstDayOfWeek);
Calendar.getInstance().getFirstDayOfWeek());
final String minDate = a.getString(R.styleable.CalendarView_minDate);
final String maxDate = a.getString(R.styleable.CalendarView_maxDate);

View File

@@ -34,6 +34,7 @@ import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.icu.text.DecimalFormatSymbols;
import android.os.Build;
import android.os.Bundle;
import android.text.InputFilter;
@@ -61,8 +62,6 @@ import android.view.inputmethod.InputMethodManager;
import com.android.internal.R;
import libcore.icu.LocaleData;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -209,7 +208,7 @@ public class NumberPicker extends LinearLayout {
}
private static char getZeroDigit(Locale locale) {
return LocaleData.get(locale).zeroDigit;
return DecimalFormatSymbols.getInstance(locale).getZeroDigit();
}
private java.util.Formatter createFormatter(Locale locale) {

View File

@@ -27,6 +27,7 @@ import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.icu.text.DateFormatSymbols;
import android.icu.text.DisplayContext;
import android.icu.text.SimpleDateFormat;
import android.icu.util.Calendar;
@@ -49,8 +50,6 @@ import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import com.android.internal.R;
import com.android.internal.widget.ExploreByTouchHelper;
import libcore.icu.LocaleData;
import java.text.NumberFormat;
import java.util.Locale;
@@ -193,7 +192,8 @@ class SimpleMonthView extends View {
private void updateDayOfWeekLabels() {
// Use tiny (e.g. single-character) weekday names from ICU. The indices
// for this list correspond to Calendar days, e.g. SUNDAY is index 1.
final String[] tinyWeekdayNames = LocaleData.get(mLocale).tinyWeekdayNames;
final String[] tinyWeekdayNames = DateFormatSymbols.getInstance(mLocale)
.getWeekdays(DateFormatSymbols.FORMAT, DateFormatSymbols.NARROW);
for (int i = 0; i < DAYS_IN_WEEK; i++) {
mDayOfWeekLabels[i] = tinyWeekdayNames[(mWeekStart + i - 1) % DAYS_IN_WEEK + 1];
}

View File

@@ -30,6 +30,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.TypedArray;
import android.database.ContentObserver;
import android.icu.text.DateTimePatternGenerator;
import android.net.Uri;
import android.os.Handler;
import android.os.SystemClock;
@@ -43,8 +44,6 @@ import android.view.inspector.InspectableProperty;
import com.android.internal.R;
import libcore.icu.LocaleData;
import java.util.Calendar;
import java.util.TimeZone;
@@ -259,14 +258,11 @@ public class TextClock extends TextView {
}
private void init() {
if (mFormat12 == null || mFormat24 == null) {
LocaleData ld = LocaleData.get(getContext().getResources().getConfiguration().locale);
if (mFormat12 == null) {
mFormat12 = ld.timeFormat_hm;
}
if (mFormat24 == null) {
mFormat24 = ld.timeFormat_Hm;
}
if (mFormat12 == null) {
mFormat12 = getBestDateTimePattern("hm");
}
if (mFormat24 == null) {
mFormat24 = getBestDateTimePattern("Hm");
}
createTime(mTimeZone);
@@ -508,13 +504,11 @@ public class TextClock extends TextView {
private void chooseFormat() {
final boolean format24Requested = is24HourModeEnabled();
LocaleData ld = LocaleData.get(getContext().getResources().getConfiguration().locale);
if (format24Requested) {
mFormat = abc(mFormat24, mFormat12, ld.timeFormat_Hm);
mFormat = abc(mFormat24, mFormat12, getBestDateTimePattern("Hm"));
mDescFormat = abc(mDescFormat24, mDescFormat12, mFormat);
} else {
mFormat = abc(mFormat12, mFormat24, ld.timeFormat_hm);
mFormat = abc(mFormat12, mFormat24, getBestDateTimePattern("hm"));
mDescFormat = abc(mDescFormat12, mDescFormat24, mFormat);
}
@@ -527,6 +521,12 @@ public class TextClock extends TextView {
}
}
private String getBestDateTimePattern(String skeleton) {
DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(
getContext().getResources().getConfiguration().locale);
return dtpg.getBestPattern(skeleton);
}
/**
* Returns a if not null, else return b if not null, else return c.
*/

View File

@@ -23,6 +23,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.icu.text.DateTimePatternGenerator;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
@@ -54,8 +55,6 @@ import com.android.systemui.statusbar.policy.ConfigurationController.Configurati
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
import libcore.icu.LocaleData;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
@@ -384,15 +383,16 @@ public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.C
private final CharSequence getSmallTime() {
Context context = getContext();
boolean is24 = DateFormat.is24HourFormat(context, mCurrentUserId);
LocaleData d = LocaleData.get(context.getResources().getConfiguration().locale);
DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(
context.getResources().getConfiguration().locale);
final char MAGIC1 = '\uEF00';
final char MAGIC2 = '\uEF01';
SimpleDateFormat sdf;
String format = mShowSeconds
? is24 ? d.timeFormat_Hms : d.timeFormat_hms
: is24 ? d.timeFormat_Hm : d.timeFormat_hm;
? is24 ? dtpg.getBestPattern("Hms") : dtpg.getBestPattern("hms")
: is24 ? dtpg.getBestPattern("Hm") : dtpg.getBestPattern("hm");
if (!format.equals(mClockFormatString)) {
mContentDescriptionFormat = new SimpleDateFormat(format);
/*