New Japanese Era implementation in ojluni with a placeholder name
am: 02d0583d4f
Change-Id: I482b6c24e39a213c864dbbb99cf60754b69574c6
diff --git a/JavaLibrary.bp b/JavaLibrary.bp
index 2066c42..53d0a10 100644
--- a/JavaLibrary.bp
+++ b/JavaLibrary.bp
@@ -702,3 +702,14 @@
name: "timezone-host",
srcs: [":timezone_host_files"],
}
+
+// The source files that contain the UnsupportedAppUsage annotation and its dependencies.
+filegroup {
+ name: "unsupportedappusage_annotation_files",
+ srcs: [
+ "dalvik/src/main/java/dalvik/annotation/compat/UnsupportedAppUsage.java",
+ "dalvik/src/main/java/dalvik/system/VersionCodes.java",
+ "luni/src/main/java/libcore/api/CorePlatformApi.java",
+ "luni/src/main/java/libcore/api/IntraCoreApi.java",
+ ],
+}
\ No newline at end of file
diff --git a/expectations/Android.bp b/expectations/Android.bp
new file mode 100644
index 0000000..bf4a993
--- /dev/null
+++ b/expectations/Android.bp
@@ -0,0 +1,9 @@
+filegroup {
+ name: "libcore-expectations-knownfailures",
+ srcs: ["knownfailures.txt"],
+}
+
+filegroup {
+ name: "libcore-expectations-virtualdeviceknownfailures",
+ srcs: ["virtualdeviceknownfailures.txt"],
+}
diff --git a/luni/src/main/java/libcore/util/TimeZoneFinder.java b/luni/src/main/java/libcore/util/TimeZoneFinder.java
new file mode 100644
index 0000000..c98decd
--- /dev/null
+++ b/luni/src/main/java/libcore/util/TimeZoneFinder.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2017 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 libcore.util;
+
+import android.icu.util.TimeZone;
+
+import java.util.List;
+
+// Used by com.google.android.setupwizard.hiddenapi.reflection.TimeZoneFinderReflection
+// Used by org.robolectric.shadows.ShadowTimeZoneFinder
+// Used by org.robolectric.shadows.ShadowTimeZoneFinderTest
+/**
+ * A shim class over {@link libcore.timezone.TimeZoneFinder} which used to be in
+ * {@code libcore.util}. This class provides just enough API to keep robolectric and SUW
+ * (setup wizard) working util those have been updated to use replacement public SDK APIs or adjust
+ * to the new package. See http://b/119921242 and http://b/116544863.
+ * @hide
+ */
+@libcore.api.CorePlatformApi
+public final class TimeZoneFinder {
+
+ private static TimeZoneFinder instance;
+ private final libcore.timezone.TimeZoneFinder delegate;
+
+ private TimeZoneFinder(libcore.timezone.TimeZoneFinder delegate) {
+ this.delegate = delegate;
+ }
+
+ // Used by com.google.android.setupwizard.hiddenapi.reflection.TimeZoneFinderReflection
+ // Used by org.robolectric.shadows.ShadowTimeZoneFinderTest
+ /**
+ * Obtains an instance for use when resolving time zones. This method never returns
+ * {@code null}.
+ */
+ @libcore.api.CorePlatformApi
+ public static TimeZoneFinder getInstance() {
+ synchronized(TimeZoneFinder.class) {
+ if (instance == null) {
+ instance = new TimeZoneFinder(libcore.timezone.TimeZoneFinder.getInstance());
+ }
+ }
+ return instance;
+ }
+
+ // Used by org.robolectric.shadows.ShadowTimeZoneFinder
+ /** Used to create an instance using an in-memory XML String instead of a file. */
+ public static TimeZoneFinder createInstanceForTests(String xml) {
+ return new TimeZoneFinder(libcore.timezone.TimeZoneFinder.createInstanceForTests(xml));
+ }
+
+ // Used by com.google.android.setupwizard.hiddenapi.reflection.TimeZoneFinderReflection
+ // Used by org.robolectric.shadows.ShadowTimeZoneFinderTest
+ /**
+ * Returns an immutable list of frozen ICU time zones known to be used in the specified country.
+ * If the country code is not recognized or there is an error during lookup this can return
+ * null. The TimeZones returned will never contain {@link TimeZone#UNKNOWN_ZONE}. This method
+ * can return an empty list in a case when the underlying data files reference only unknown
+ * zone IDs.
+ */
+ @libcore.api.CorePlatformApi
+ public List<TimeZone> lookupTimeZonesByCountry(String countryIso) {
+ return delegate.lookupTimeZonesByCountry(countryIso);
+ }
+}
diff --git a/luni/src/test/java/libcore/java/io/ObjectStreamClassTest.java b/luni/src/test/java/libcore/java/io/ObjectStreamClassTest.java
index 612b7d8..8bee284 100644
--- a/luni/src/test/java/libcore/java/io/ObjectStreamClassTest.java
+++ b/luni/src/test/java/libcore/java/io/ObjectStreamClassTest.java
@@ -16,6 +16,7 @@
package libcore.java.io;
import java.io.ObjectStreamClass;
+import java.io.ObjectStreamClass.DefaultSUIDCompatibilityListener;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -31,6 +32,7 @@
import org.junit.runners.MethodSorters;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
@RunWith(JUnitParamsRunner.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@@ -99,8 +101,6 @@
// The default SUID for the InheritStaticInitializer should be affected by the b/29064453
// patch and so should differ between version <= 23 and version > 23.
{ InheritStaticInitializer.class, 4188245044387716731L, 992629205079295334L },
-
-
};
}
@@ -108,27 +108,46 @@
@Test
public void computeDefaultSUID_current(Class<?> clazz, long suid,
@SuppressWarnings("unused") long suid23) {
- checkSerialVersionUID(suid, clazz);
+ checkSerialVersionUID(suid, clazz, false);
}
@Parameters(method = "defaultSUIDs")
@Test
@TargetSdkVersion(23)
- public void computeDefaultSUID_targetSdkVersion_23(Class<?> clazz,
- @SuppressWarnings("unused") long suid, long suid23) {
- checkSerialVersionUID(suid23, clazz);
+ public void computeDefaultSUID_targetSdkVersion_23(Class<?> clazz, long suid, long suid23) {
+ // If the suid and suid23 hashes are different then a warning is expected to be logged.
+ boolean expectedWarning = suid23 != suid;
+ checkSerialVersionUID(suid23, clazz, expectedWarning);
}
- private static void checkSerialVersionUID(long expectedSUID, Class<?> clazz) {
- // Use reflection to access the private static computeDefaultSUID method.
+ private static void checkSerialVersionUID(
+ long expectedSUID, Class<?> clazz, boolean expectedWarning) {
+ // Use reflection to call the private static computeDefaultSUID method directly to avoid the
+ // caching performed by ObjectStreamClass.lookup(Class).
long defaultSUID;
+ DefaultSUIDCompatibilityListener savedListener
+ = ObjectStreamClass.suidCompatibilityListener;
try {
+ ObjectStreamClass.suidCompatibilityListener = (c, hash) -> {
+ // Delegate to the existing listener so that the warning is logged.
+ savedListener.warnDefaultSUIDTargetVersionDependent(clazz, hash);
+ if (expectedWarning) {
+ assertEquals(clazz, c);
+ assertEquals(expectedSUID, hash);
+ } else {
+ fail("Unexpected warning for " + c + " with defaultSUID " + hash);
+ }
+ };
+
Method computeDefaultSUIDMethod =
ObjectStreamClass.class.getDeclaredMethod("computeDefaultSUID", Class.class);
computeDefaultSUIDMethod.setAccessible(true);
+
defaultSUID = (Long) computeDefaultSUIDMethod.invoke(null, clazz);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
throw new IllegalStateException(e);
+ } finally {
+ ObjectStreamClass.suidCompatibilityListener = savedListener;
}
assertEquals(expectedSUID, defaultSUID);
}
diff --git a/luni/src/test/java/libcore/java/lang/StringTest.java b/luni/src/test/java/libcore/java/lang/StringTest.java
index 7320d9a..c440ebe 100644
--- a/luni/src/test/java/libcore/java/lang/StringTest.java
+++ b/luni/src/test/java/libcore/java/lang/StringTest.java
@@ -781,4 +781,18 @@
fail();
} catch (NullPointerException expected) {}
}
+
+ /**
+ * Check that String.format() does not throw when the default locale is invalid.
+ * http://b/129070579
+ */
+ public void testFormat_invalidLocale() {
+ Locale defaultLocale = Locale.getDefault();
+ try {
+ Locale.setDefault(new Locale("invalidLocale"));
+ String.format("%s", "");
+ } finally {
+ Locale.setDefault(defaultLocale);
+ }
+ }
}
diff --git a/luni/src/test/java/libcore/libcore/icu/LocaleDataTest.java b/luni/src/test/java/libcore/libcore/icu/LocaleDataTest.java
index f5be28b..607397d 100644
--- a/luni/src/test/java/libcore/libcore/icu/LocaleDataTest.java
+++ b/luni/src/test/java/libcore/libcore/icu/LocaleDataTest.java
@@ -138,4 +138,12 @@
LocaleData haw = LocaleData.get(new Locale("haw"));
assertFalse(haw.shortDateFormat.isEmpty());
}
+
+ /**
+ * Check that LocaleData.get() does not throw when the input locale is invalid.
+ * http://b/129070579
+ */
+ public void testInvalidLocale() {
+ LocaleData.get(new Locale("invalidLocale"));
+ }
}
diff --git a/luni/src/test/java/libcore/libcore/util/TimeZoneFinderTest.java b/luni/src/test/java/libcore/libcore/util/TimeZoneFinderTest.java
new file mode 100644
index 0000000..aa1565b
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/util/TimeZoneFinderTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2017 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 libcore.libcore.util;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import android.icu.util.TimeZone;
+
+import java.util.List;
+import libcore.util.TimeZoneFinder;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+public class TimeZoneFinderTest {
+
+ @Test
+ public void getInstance() throws Exception {
+ TimeZoneFinder finder1 = TimeZoneFinder.getInstance();
+ TimeZoneFinder finder2 = TimeZoneFinder.getInstance();
+ assertSame(finder1, finder2);
+ }
+
+ @Test
+ public void lookupTimeZonesByCountry() throws Exception {
+ TimeZoneFinder finder = TimeZoneFinder.createInstanceForTests(
+ "<timezones ianaversion=\"2017b\">\n"
+ + " <countryzones>\n"
+ + " <country code=\"gb\" default=\"Europe/London\" everutc=\"y\">\n"
+ + " <id>Europe/London</id>\n"
+ + " </country>\n"
+ + " </countryzones>\n"
+ + "</timezones>\n");
+
+ List<TimeZone> gbList = finder.lookupTimeZonesByCountry("gb");
+ assertEquals(1, gbList.size());
+ assertImmutableList(gbList);
+ assertImmutableTimeZone(gbList.get(0));
+
+ // Check country code normalization works too.
+ assertEquals(1, finder.lookupTimeZonesByCountry("GB").size());
+
+ assertNull(finder.lookupTimeZonesByCountry("unknown"));
+ }
+
+ private static void assertImmutableTimeZone(TimeZone timeZone) {
+ try {
+ timeZone.setRawOffset(1000);
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+
+ private static <X> void assertImmutableList(List<X> list) {
+ try {
+ list.add(null);
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+}
diff --git a/mmodules/core_platform_api/api/platform/current-api.txt b/mmodules/core_platform_api/api/platform/current-api.txt
index 225a28a..3686c20 100644
--- a/mmodules/core_platform_api/api/platform/current-api.txt
+++ b/mmodules/core_platform_api/api/platform/current-api.txt
@@ -800,10 +800,6 @@
package java.lang {
- public final class Byte extends java.lang.Number implements java.lang.Comparable<java.lang.Byte> {
- method public static String toHexString(byte, boolean);
- }
-
public final class Class<T> implements java.lang.reflect.AnnotatedElement java.lang.reflect.GenericDeclaration java.io.Serializable java.lang.reflect.Type {
method @dalvik.annotation.optimization.FastNative public java.lang.reflect.Field[] getDeclaredFieldsUnchecked(boolean);
method @dalvik.annotation.optimization.FastNative public java.lang.reflect.Method[] getDeclaredMethodsUnchecked(boolean);
@@ -1247,6 +1243,11 @@
method public static void sneakyThrow(Throwable);
}
+ public final class TimeZoneFinder {
+ method public static libcore.util.TimeZoneFinder getInstance();
+ method public java.util.List<android.icu.util.TimeZone> lookupTimeZonesByCountry(String);
+ }
+
public class XmlObjectFactory {
method public static org.xml.sax.XMLReader newXMLReader();
method public static org.xmlpull.v1.XmlPullParser newXmlPullParser();
diff --git a/non_openjdk_java_files.bp b/non_openjdk_java_files.bp
index 3e4083f..9d65f04 100644
--- a/non_openjdk_java_files.bp
+++ b/non_openjdk_java_files.bp
@@ -196,6 +196,7 @@
"luni/src/main/java/libcore/util/Nullable.java",
"luni/src/main/java/libcore/util/SneakyThrow.java",
"luni/src/main/java/libcore/util/XmlObjectFactory.java",
+ "luni/src/main/java/libcore/util/TimeZoneFinder.java",
"luni/src/main/java/libcore/util/ZoneInfo.java",
"dalvik/src/main/java/org/apache/harmony/dalvik/NativeTestTarget.java",
"dalvik/src/main/java/org/apache/harmony/dalvik/ddmc/Chunk.java",
diff --git a/ojluni/annotations/mmodule/java/lang/Byte.annotated.java b/ojluni/annotations/mmodule/java/lang/Byte.annotated.java
deleted file mode 100644
index 2d61598..0000000
--- a/ojluni/annotations/mmodule/java/lang/Byte.annotated.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package java.lang;
-
-
-@SuppressWarnings({"unchecked", "deprecation", "all"})
-public final class Byte extends java.lang.Number implements java.lang.Comparable<java.lang.Byte> {
-
-public Byte(byte value) { throw new RuntimeException("Stub!"); }
-
-public Byte(java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
-
-public static java.lang.String toString(byte b) { throw new RuntimeException("Stub!"); }
-
-public static java.lang.Byte valueOf(byte b) { throw new RuntimeException("Stub!"); }
-
-public static byte parseByte(java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
-
-public static byte parseByte(java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
-
-public static java.lang.Byte valueOf(java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
-
-public static java.lang.Byte valueOf(java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
-
-public static java.lang.Byte decode(java.lang.String nm) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
-
-public byte byteValue() { throw new RuntimeException("Stub!"); }
-
-public short shortValue() { throw new RuntimeException("Stub!"); }
-
-public int intValue() { throw new RuntimeException("Stub!"); }
-
-public long longValue() { throw new RuntimeException("Stub!"); }
-
-public float floatValue() { throw new RuntimeException("Stub!"); }
-
-public double doubleValue() { throw new RuntimeException("Stub!"); }
-
-public java.lang.String toString() { throw new RuntimeException("Stub!"); }
-
-public int hashCode() { throw new RuntimeException("Stub!"); }
-
-public static int hashCode(byte value) { throw new RuntimeException("Stub!"); }
-
-public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
-
-public int compareTo(java.lang.Byte anotherByte) { throw new RuntimeException("Stub!"); }
-
-public static int compare(byte x, byte y) { throw new RuntimeException("Stub!"); }
-
-public static int toUnsignedInt(byte x) { throw new RuntimeException("Stub!"); }
-
-public static long toUnsignedLong(byte x) { throw new RuntimeException("Stub!"); }
-
-@libcore.api.CorePlatformApi
-public static java.lang.String toHexString(byte b, boolean upperCase) { throw new RuntimeException("Stub!"); }
-
-public static final int BYTES = 1; // 0x1
-
-public static final byte MAX_VALUE = 127; // 0x7f
-
-public static final byte MIN_VALUE = -128; // 0xffffff80
-
-public static final int SIZE = 8; // 0x8
-
-public static final java.lang.Class<java.lang.Byte> TYPE;
-static { TYPE = null; }
-}
-
diff --git a/ojluni/src/main/java/java/io/ObjectStreamClass.java b/ojluni/src/main/java/java/io/ObjectStreamClass.java
index 7561aa8..10babed 100644
--- a/ojluni/src/main/java/java/io/ObjectStreamClass.java
+++ b/ojluni/src/main/java/java/io/ObjectStreamClass.java
@@ -1797,15 +1797,27 @@
}
}
- // Android-changed: Clinit serialization workaround b/29064453
+ // BEGIN Android-changed: Fix/log clinit serialization workaround b/29064453
// Prior to SDK 24 hasStaticInitializer() would return true if the superclass had a
// static initializer, that was contrary to the specification. In SDK 24 the default
// behavior was corrected but the old behavior was preserved for apps that targeted 23
// or below in order to maintain backwards compatibility.
+ //
+ // if (hasStaticInitializer(cl)) {
boolean inheritStaticInitializer =
(VMRuntime.getRuntime().getTargetSdkVersion()
<= MAX_SDK_TARGET_FOR_CLINIT_UIDGEN_WORKAROUND);
+ boolean warnIncompatibleSUIDChange = false;
if (hasStaticInitializer(cl, inheritStaticInitializer)) {
+ // If a static initializer was found but the current class does not have one then
+ // the class's default SUID will change if the app targets SDK > 24 so send a
+ // warning.
+ if (inheritStaticInitializer && !hasStaticInitializer(cl, false)) {
+ // Defer until hash has been calculated so the warning message can give precise
+ // instructions to the developer on how to fix the problems.
+ warnIncompatibleSUIDChange = true;
+ }
+ // END Android-changed: Fix/log clinit serialization workaround b/29064453
dout.writeUTF("<clinit>");
dout.writeInt(Modifier.STATIC);
dout.writeUTF("()V");
@@ -1870,6 +1882,14 @@
for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) {
hash = (hash << 8) | (hashBytes[i] & 0xFF);
}
+ // BEGIN Android-added: Fix/log clinit serialization workaround b/29064453
+ // ObjectStreamClass instances are cached per Class and caches its default
+ // serialVersionUID so it will only log one message per class per app process
+ // irrespective of the number of times the class is serialized.
+ if (warnIncompatibleSUIDChange) {
+ suidCompatibilityListener.warnDefaultSUIDTargetVersionDependent(cl, hash);
+ }
+ // END Android-added: Fix/log clinit serialization workaround b/29064453
return hash;
} catch (IOException ex) {
throw new InternalError(ex);
@@ -1878,8 +1898,38 @@
}
}
- // BEGIN Android-changed: Clinit serialization workaround b/29064453
- /** Max SDK target version for which we use buggy hasStaticIntializier implementation. */
+ // BEGIN Android-changed: Fix/log clinit serialization workaround b/29064453
+ /**
+ * Created for testing as there is no nice way to detect when a message is logged.
+ *
+ * @hide
+ */
+ public interface DefaultSUIDCompatibilityListener {
+ /**
+ * Called when a class being serialized/deserialized relies on the default SUID computation
+ * (because it has no explicit {@code serialVersionUID} field) where that computation is
+ * dependent on the app's targetSdkVersion.
+ *
+ * @param clazz the clazz for which the default SUID is being computed.
+ * @param hash the computed value.
+ */
+ void warnDefaultSUIDTargetVersionDependent(Class<?> clazz, long hash);
+ }
+
+ /**
+ * Public and mutable for testing purposes.
+ *
+ * @hide
+ */
+ public static DefaultSUIDCompatibilityListener suidCompatibilityListener =
+ (clazz, hash) -> {
+ System.logW("Class " + clazz.getCanonicalName() + " relies on its default SUID which"
+ + " is dependent on the app's targetSdkVersion. To avoid problems during upgrade"
+ + " add the following to class " + clazz.getCanonicalName() + "\n"
+ + " private static final long serialVersionUID = " + hash + "L;");
+ };
+
+ /** Max SDK target version for which we use buggy hasStaticInitializer implementation. */
static final int MAX_SDK_TARGET_FOR_CLINIT_UIDGEN_WORKAROUND = 23;
/**
@@ -1893,7 +1943,7 @@
*/
private native static boolean hasStaticInitializer(
Class<?> cl, boolean inheritStaticInitializer);
- // END Android-changed: Clinit serialization workaround b/29064453
+ // END Android-changed: Fix/log clinit serialization workaround b/29064453
/**
* Class for computing and caching field/constructor/method signatures
diff --git a/ojluni/src/main/java/java/lang/Byte.java b/ojluni/src/main/java/java/lang/Byte.java
index e53899c..deb4ecb 100644
--- a/ojluni/src/main/java/java/lang/Byte.java
+++ b/ojluni/src/main/java/java/lang/Byte.java
@@ -25,6 +25,8 @@
package java.lang;
+import libcore.util.HexEncoding;
+
/**
*
* The {@code Byte} class wraps a value of primitive type {@code byte}
@@ -523,24 +525,8 @@
* @hide
*/
public static String toHexString(byte b, boolean upperCase) {
- char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
- char[] buf = new char[2]; // We always want two digits.
- buf[0] = digits[(b >> 4) & 0xf];
- buf[1] = digits[b & 0xf];
- return new String(0, 2, buf);
+ // This method currently retained because it is marked @UnsupportedAppUsage.
+ return HexEncoding.encodeToString(b, upperCase);
}
- private static final char[] DIGITS = {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
- 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
- 'u', 'v', 'w', 'x', 'y', 'z'
- };
-
- private static final char[] UPPER_CASE_DIGITS = {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
- 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
- 'U', 'V', 'W', 'X', 'Y', 'Z'
- };
// END Android-added: toHexString() for internal use.
}