Merge changes from topics "PersistableBundleUtils", "bytearray-utils", "integer-utils" am: e9226f999f am: 089a20034d am: 984f6a74ad
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1495099 Change-Id: I526b6098f46ee00ba17b2f3f5c0e679dc57190b5
This commit is contained in:
@@ -744,6 +744,7 @@ filegroup {
|
||||
"core/java/com/android/internal/util/IState.java",
|
||||
"core/java/com/android/internal/util/State.java",
|
||||
"core/java/com/android/internal/util/StateMachine.java",
|
||||
"services/core/java/com/android/server/vcn/util/PersistableBundleUtils.java",
|
||||
"telephony/java/android/telephony/Annotation.java",
|
||||
],
|
||||
}
|
||||
|
||||
@@ -0,0 +1,341 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.server.vcn.util;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.ParcelUuid;
|
||||
import android.os.PersistableBundle;
|
||||
|
||||
import com.android.internal.util.HexDump;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
/** @hide */
|
||||
public class PersistableBundleUtils {
|
||||
private static final String LIST_KEY_FORMAT = "LIST_ITEM_%d";
|
||||
private static final String COLLECTION_SIZE_KEY = "COLLECTION_LENGTH";
|
||||
private static final String MAP_KEY_FORMAT = "MAP_KEY_%d";
|
||||
private static final String MAP_VALUE_FORMAT = "MAP_VALUE_%d";
|
||||
|
||||
private static final String PARCEL_UUID_KEY = "PARCEL_UUID";
|
||||
private static final String BYTE_ARRAY_KEY = "BYTE_ARRAY_KEY";
|
||||
private static final String INTEGER_KEY = "INTEGER_KEY";
|
||||
|
||||
/**
|
||||
* Functional interface to convert an object of the specified type to a PersistableBundle.
|
||||
*
|
||||
* @param <T> the type of the source object
|
||||
*/
|
||||
public interface Serializer<T> {
|
||||
/**
|
||||
* Converts this object to a PersistableBundle.
|
||||
*
|
||||
* @return the PersistableBundle representation of this object
|
||||
*/
|
||||
PersistableBundle toPersistableBundle(T obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Functional interface used to create an object of the specified type from a PersistableBundle.
|
||||
*
|
||||
* @param <T> the type of the resultant object
|
||||
*/
|
||||
public interface Deserializer<T> {
|
||||
/**
|
||||
* Creates an instance of specified type from a PersistableBundle representation.
|
||||
*
|
||||
* @param in the PersistableBundle representation
|
||||
* @return an instance of the specified type
|
||||
*/
|
||||
T fromPersistableBundle(PersistableBundle in);
|
||||
}
|
||||
|
||||
/** Serializer to convert an integer to a PersistableBundle. */
|
||||
public static final Serializer<Integer> INTEGER_SERIALIZER =
|
||||
(i) -> {
|
||||
final PersistableBundle result = new PersistableBundle();
|
||||
result.putInt(INTEGER_KEY, i);
|
||||
return result;
|
||||
};
|
||||
|
||||
/** Deserializer to convert a PersistableBundle to an integer. */
|
||||
public static final Deserializer<Integer> INTEGER_DESERIALIZER =
|
||||
(bundle) -> {
|
||||
Objects.requireNonNull(bundle, "PersistableBundle is null");
|
||||
return bundle.getInt(INTEGER_KEY);
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts a ParcelUuid to a PersistableBundle.
|
||||
*
|
||||
* <p>To avoid key collisions, NO additional key/value pairs should be added to the returned
|
||||
* PersistableBundle object.
|
||||
*
|
||||
* @param uuid a ParcelUuid instance to persist
|
||||
* @return the PersistableBundle instance
|
||||
*/
|
||||
public static PersistableBundle fromParcelUuid(ParcelUuid uuid) {
|
||||
final PersistableBundle result = new PersistableBundle();
|
||||
|
||||
result.putString(PARCEL_UUID_KEY, uuid.toString());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts from a PersistableBundle to a ParcelUuid.
|
||||
*
|
||||
* @param bundle the PersistableBundle containing the ParcelUuid
|
||||
* @return the ParcelUuid instance
|
||||
*/
|
||||
public static ParcelUuid toParcelUuid(PersistableBundle bundle) {
|
||||
return ParcelUuid.fromString(bundle.getString(PARCEL_UUID_KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts from a list of Persistable objects to a single PersistableBundle.
|
||||
*
|
||||
* <p>To avoid key collisions, NO additional key/value pairs should be added to the returned
|
||||
* PersistableBundle object.
|
||||
*
|
||||
* @param <T> the type of the objects to convert to the PersistableBundle
|
||||
* @param in the list of objects to be serialized into a PersistableBundle
|
||||
* @param serializer an implementation of the {@link Serializer} functional interface that
|
||||
* converts an object of type T to a PersistableBundle
|
||||
*/
|
||||
@NonNull
|
||||
public static <T> PersistableBundle fromList(
|
||||
@NonNull List<T> in, @NonNull Serializer<T> serializer) {
|
||||
final PersistableBundle result = new PersistableBundle();
|
||||
|
||||
result.putInt(COLLECTION_SIZE_KEY, in.size());
|
||||
for (int i = 0; i < in.size(); i++) {
|
||||
final String key = String.format(LIST_KEY_FORMAT, i);
|
||||
result.putPersistableBundle(key, serializer.toPersistableBundle(in.get(i)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts from a PersistableBundle to a list of objects.
|
||||
*
|
||||
* @param <T> the type of the objects to convert from a PersistableBundle
|
||||
* @param in the PersistableBundle containing the persisted list
|
||||
* @param deserializer an implementation of the {@link Deserializer} functional interface that
|
||||
* builds the relevant type of objects.
|
||||
*/
|
||||
@NonNull
|
||||
public static <T> List<T> toList(
|
||||
@NonNull PersistableBundle in, @NonNull Deserializer<T> deserializer) {
|
||||
final int listLength = in.getInt(COLLECTION_SIZE_KEY);
|
||||
final ArrayList<T> result = new ArrayList<>(listLength);
|
||||
|
||||
for (int i = 0; i < listLength; i++) {
|
||||
final String key = String.format(LIST_KEY_FORMAT, i);
|
||||
final PersistableBundle item = in.getPersistableBundle(key);
|
||||
|
||||
result.add(deserializer.fromPersistableBundle(item));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// TODO: b/170513329 Delete #fromByteArray and #toByteArray once BaseBundle#putByteArray and
|
||||
// BaseBundle#getByteArray are exposed.
|
||||
|
||||
/**
|
||||
* Converts a byte array to a PersistableBundle.
|
||||
*
|
||||
* <p>To avoid key collisions, NO additional key/value pairs should be added to the returned
|
||||
* PersistableBundle object.
|
||||
*
|
||||
* @param array a byte array instance to persist
|
||||
* @return the PersistableBundle instance
|
||||
*/
|
||||
public static PersistableBundle fromByteArray(byte[] array) {
|
||||
final PersistableBundle result = new PersistableBundle();
|
||||
|
||||
result.putString(BYTE_ARRAY_KEY, HexDump.toHexString(array));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts from a PersistableBundle to a byte array.
|
||||
*
|
||||
* @param bundle the PersistableBundle containing the byte array
|
||||
* @return the byte array instance
|
||||
*/
|
||||
public static byte[] toByteArray(PersistableBundle bundle) {
|
||||
Objects.requireNonNull(bundle, "PersistableBundle is null");
|
||||
|
||||
String hex = bundle.getString(BYTE_ARRAY_KEY);
|
||||
if (hex == null || hex.length() % 2 != 0) {
|
||||
throw new IllegalArgumentException("PersistableBundle contains invalid byte array");
|
||||
}
|
||||
|
||||
return HexDump.hexStringToByteArray(hex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts from a Map of Persistable objects to a single PersistableBundle.
|
||||
*
|
||||
* <p>To avoid key collisions, NO additional key/value pairs should be added to the returned
|
||||
* PersistableBundle object.
|
||||
*
|
||||
* @param <K> the type of the map-key to convert to the PersistableBundle
|
||||
* @param <V> the type of the map-value to convert to the PersistableBundle
|
||||
* @param in the Map of objects implementing the {@link Persistable} interface
|
||||
* @param keySerializer an implementation of the {@link Serializer} functional interface that
|
||||
* converts a map-key of type T to a PersistableBundle
|
||||
* @param valueSerializer an implementation of the {@link Serializer} functional interface that
|
||||
* converts a map-value of type E to a PersistableBundle
|
||||
*/
|
||||
@NonNull
|
||||
public static <K, V> PersistableBundle fromMap(
|
||||
@NonNull Map<K, V> in,
|
||||
@NonNull Serializer<K> keySerializer,
|
||||
@NonNull Serializer<V> valueSerializer) {
|
||||
final PersistableBundle result = new PersistableBundle();
|
||||
|
||||
result.putInt(COLLECTION_SIZE_KEY, in.size());
|
||||
int i = 0;
|
||||
for (Entry<K, V> entry : in.entrySet()) {
|
||||
final String keyKey = String.format(MAP_KEY_FORMAT, i);
|
||||
final String valueKey = String.format(MAP_VALUE_FORMAT, i);
|
||||
result.putPersistableBundle(keyKey, keySerializer.toPersistableBundle(entry.getKey()));
|
||||
result.putPersistableBundle(
|
||||
valueKey, valueSerializer.toPersistableBundle(entry.getValue()));
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts from a PersistableBundle to a Map of objects.
|
||||
*
|
||||
* <p>In an attempt to preserve ordering, the returned map will be a LinkedHashMap. However, the
|
||||
* guarantees on the ordering can only ever be as strong as the map that was serialized in
|
||||
* {@link fromMap()}. If the initial map that was serialized had no ordering guarantees, the
|
||||
* deserialized map similarly may be of a non-deterministic order.
|
||||
*
|
||||
* @param <K> the type of the map-key to convert from a PersistableBundle
|
||||
* @param <V> the type of the map-value to convert from a PersistableBundle
|
||||
* @param in the PersistableBundle containing the persisted Map
|
||||
* @param keyDeserializer an implementation of the {@link Deserializer} functional interface
|
||||
* that builds the relevant type of map-key.
|
||||
* @param valueDeserializer an implementation of the {@link Deserializer} functional interface
|
||||
* that builds the relevant type of map-value.
|
||||
* @return An instance of the parsed map as a LinkedHashMap (in an attempt to preserve
|
||||
* ordering).
|
||||
*/
|
||||
@NonNull
|
||||
public static <K, V> LinkedHashMap<K, V> toMap(
|
||||
@NonNull PersistableBundle in,
|
||||
@NonNull Deserializer<K> keyDeserializer,
|
||||
@NonNull Deserializer<V> valueDeserializer) {
|
||||
final int mapSize = in.getInt(COLLECTION_SIZE_KEY);
|
||||
final LinkedHashMap<K, V> result = new LinkedHashMap<>(mapSize);
|
||||
|
||||
for (int i = 0; i < mapSize; i++) {
|
||||
final String keyKey = String.format(MAP_KEY_FORMAT, i);
|
||||
final String valueKey = String.format(MAP_VALUE_FORMAT, i);
|
||||
final PersistableBundle keyBundle = in.getPersistableBundle(keyKey);
|
||||
final PersistableBundle valueBundle = in.getPersistableBundle(valueKey);
|
||||
|
||||
final K key = keyDeserializer.fromPersistableBundle(keyBundle);
|
||||
final V value = valueDeserializer.fromPersistableBundle(valueBundle);
|
||||
result.put(key, value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures safe reading and writing of {@link PersistableBundle}s to and from disk.
|
||||
*
|
||||
* <p>This class will enforce exclusion between reads and writes using the standard semantics of
|
||||
* a ReadWriteLock. Specifically, concurrent readers ARE allowed, but reads/writes from/to the
|
||||
* file are mutually exclusive. In other words, for an unbounded number n, the acceptable states
|
||||
* are n readers, OR 1 writer (but not both).
|
||||
*/
|
||||
public static class LockingReadWriteHelper {
|
||||
private final ReadWriteLock mDiskLock = new ReentrantReadWriteLock();
|
||||
private final String mPath;
|
||||
|
||||
public LockingReadWriteHelper(@NonNull String path) {
|
||||
mPath = Objects.requireNonNull(path, "fileName was null");
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the {@link PersistableBundle} from the disk.
|
||||
*
|
||||
* @return the PersistableBundle, if the file existed, or null otherwise
|
||||
*/
|
||||
@Nullable
|
||||
public PersistableBundle readFromDisk() throws IOException {
|
||||
try {
|
||||
mDiskLock.readLock().lock();
|
||||
final File file = new File(mPath);
|
||||
if (!file.exists()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try (FileInputStream fis = new FileInputStream(file)) {
|
||||
return PersistableBundle.readFromStream(fis);
|
||||
}
|
||||
} finally {
|
||||
mDiskLock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a {@link PersistableBundle} to disk.
|
||||
*
|
||||
* @param bundle the {@link PersistableBundle} to write to disk
|
||||
*/
|
||||
public void writeToDisk(@NonNull PersistableBundle bundle) throws IOException {
|
||||
Objects.requireNonNull(bundle, "bundle was null");
|
||||
|
||||
try {
|
||||
mDiskLock.writeLock().lock();
|
||||
final File file = new File(mPath);
|
||||
if (!file.exists()) {
|
||||
file.getParentFile().mkdirs();
|
||||
}
|
||||
|
||||
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||
bundle.writeToStream(fos);
|
||||
}
|
||||
} finally {
|
||||
mDiskLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.server.vcn.util;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import android.os.PersistableBundle;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class PersistableBundleUtilsTest {
|
||||
private static final String TEST_KEY = "testKey";
|
||||
private static final String TEST_STRING_PREFIX = "testString";
|
||||
private static final int[] TEST_INT_ARRAY = new int[] {0, 1, 2, 3, 4};
|
||||
|
||||
private static final int NUM_COLLECTION_ENTRIES = 10;
|
||||
|
||||
private static class TestKey {
|
||||
private static final String TEST_INTEGER_KEY =
|
||||
"mTestInteger"; // Purposely colliding with keys of test class to ensure namespacing
|
||||
private final int mTestInteger;
|
||||
|
||||
TestKey(int testInteger) {
|
||||
mTestInteger = testInteger;
|
||||
}
|
||||
|
||||
TestKey(PersistableBundle in) {
|
||||
mTestInteger = in.getInt(TEST_INTEGER_KEY);
|
||||
}
|
||||
|
||||
public PersistableBundle toPersistableBundle() {
|
||||
final PersistableBundle result = new PersistableBundle();
|
||||
|
||||
result.putInt(TEST_INTEGER_KEY, mTestInteger);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mTestInteger);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof TestKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final TestKey other = (TestKey) o;
|
||||
return mTestInteger == other.mTestInteger;
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestClass {
|
||||
private static final String TEST_INTEGER_KEY = "mTestInteger";
|
||||
private final int mTestInteger;
|
||||
|
||||
private static final String TEST_INT_ARRAY_KEY = "mTestIntArray";
|
||||
private final int[] mTestIntArray;
|
||||
|
||||
private static final String TEST_STRING_KEY = "mTestString";
|
||||
private final String mTestString;
|
||||
|
||||
private static final String TEST_PERSISTABLE_BUNDLE_KEY = "mTestPersistableBundle";
|
||||
private final PersistableBundle mTestPersistableBundle;
|
||||
|
||||
TestClass(
|
||||
int testInteger,
|
||||
int[] testIntArray,
|
||||
String testString,
|
||||
PersistableBundle testPersistableBundle) {
|
||||
mTestInteger = testInteger;
|
||||
mTestIntArray = testIntArray;
|
||||
mTestString = testString;
|
||||
mTestPersistableBundle = testPersistableBundle;
|
||||
}
|
||||
|
||||
TestClass(PersistableBundle in) {
|
||||
mTestInteger = in.getInt(TEST_INTEGER_KEY);
|
||||
mTestIntArray = in.getIntArray(TEST_INT_ARRAY_KEY);
|
||||
mTestString = in.getString(TEST_STRING_KEY);
|
||||
mTestPersistableBundle = in.getPersistableBundle(TEST_PERSISTABLE_BUNDLE_KEY);
|
||||
}
|
||||
|
||||
public PersistableBundle toPersistableBundle() {
|
||||
final PersistableBundle result = new PersistableBundle();
|
||||
|
||||
result.putInt(TEST_INTEGER_KEY, mTestInteger);
|
||||
result.putIntArray(TEST_INT_ARRAY_KEY, mTestIntArray);
|
||||
result.putString(TEST_STRING_KEY, mTestString);
|
||||
result.putPersistableBundle(TEST_PERSISTABLE_BUNDLE_KEY, mTestPersistableBundle);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(
|
||||
mTestInteger,
|
||||
Arrays.hashCode(mTestIntArray),
|
||||
mTestString,
|
||||
mTestPersistableBundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof TestClass)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final TestClass other = (TestClass) o;
|
||||
|
||||
// TODO: Add a proper equals() to PersistableBundle. But in the meantime, force
|
||||
// TODO: unparcelling in order to allow test comparison.
|
||||
if (mTestPersistableBundle.size() != other.mTestPersistableBundle.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return mTestInteger == other.mTestInteger
|
||||
&& Arrays.equals(mTestIntArray, other.mTestIntArray)
|
||||
&& mTestString.equals(other.mTestString)
|
||||
&& mTestPersistableBundle.kindofEquals(other.mTestPersistableBundle);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListConversionLossless() throws Exception {
|
||||
final List<TestClass> sourceList = new ArrayList<>();
|
||||
for (int i = 0; i < NUM_COLLECTION_ENTRIES; i++) {
|
||||
final PersistableBundle innerBundle = new PersistableBundle();
|
||||
innerBundle.putInt(TEST_KEY, i);
|
||||
|
||||
sourceList.add(new TestClass(i, TEST_INT_ARRAY, TEST_STRING_PREFIX + i, innerBundle));
|
||||
}
|
||||
|
||||
final PersistableBundle bundled =
|
||||
PersistableBundleUtils.fromList(sourceList, TestClass::toPersistableBundle);
|
||||
final List<TestClass> resultList = PersistableBundleUtils.toList(bundled, TestClass::new);
|
||||
|
||||
assertEquals(sourceList, resultList);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMapConversionLossless() throws Exception {
|
||||
final LinkedHashMap<TestKey, TestClass> sourceMap = new LinkedHashMap<>();
|
||||
for (int i = 0; i < NUM_COLLECTION_ENTRIES; i++) {
|
||||
final TestKey key = new TestKey(i * i);
|
||||
|
||||
final PersistableBundle innerBundle = new PersistableBundle();
|
||||
innerBundle.putInt(TEST_KEY, i);
|
||||
final TestClass value =
|
||||
new TestClass(i, TEST_INT_ARRAY, TEST_STRING_PREFIX + i, innerBundle);
|
||||
|
||||
sourceMap.put(key, value);
|
||||
}
|
||||
|
||||
final PersistableBundle bundled =
|
||||
PersistableBundleUtils.fromMap(
|
||||
sourceMap, TestKey::toPersistableBundle, TestClass::toPersistableBundle);
|
||||
final LinkedHashMap<TestKey, TestClass> resultList =
|
||||
PersistableBundleUtils.toMap(bundled, TestKey::new, TestClass::new);
|
||||
|
||||
assertEquals(sourceMap, resultList);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testByteArrayConversionLossless() {
|
||||
final byte[] byteArray = "testByteArrayConversionLossless".getBytes();
|
||||
|
||||
PersistableBundle bundle = PersistableBundleUtils.fromByteArray(byteArray);
|
||||
byte[] result = PersistableBundleUtils.toByteArray(bundle);
|
||||
|
||||
assertArrayEquals(byteArray, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegerConversionLossless() throws Exception {
|
||||
final int testInt = 1;
|
||||
final PersistableBundle integerBundle =
|
||||
PersistableBundleUtils.INTEGER_SERIALIZER.toPersistableBundle(testInt);
|
||||
final int result =
|
||||
PersistableBundleUtils.INTEGER_DESERIALIZER.fromPersistableBundle(integerBundle);
|
||||
|
||||
assertEquals(testInt, result);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user