summaryrefslogtreecommitdiffstats
path: root/java/com/android/dialer/protos/ProtoParsers.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/dialer/protos/ProtoParsers.java')
-rw-r--r--java/com/android/dialer/protos/ProtoParsers.java125
1 files changed, 13 insertions, 112 deletions
diff --git a/java/com/android/dialer/protos/ProtoParsers.java b/java/com/android/dialer/protos/ProtoParsers.java
index b77c0699b..5a60799bc 100644
--- a/java/com/android/dialer/protos/ProtoParsers.java
+++ b/java/com/android/dialer/protos/ProtoParsers.java
@@ -18,13 +18,10 @@ package com.android.dialer.protos;
import android.content.Intent;
import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
+import android.support.annotation.NonNull;
import com.android.dialer.common.Assert;
-import com.google.protobuf.CodedOutputStream;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.MessageLite;
-import java.io.IOException;
/** Useful methods for using Protocol Buffers with Android. */
public final class ProtoParsers {
@@ -35,11 +32,8 @@ public final class ProtoParsers {
@SuppressWarnings("unchecked") // We want to eventually optimize away parser classes, so cast
public static <T extends MessageLite> T get(Bundle bundle, String key, T defaultInstance)
throws InvalidProtocolBufferException {
- // Class loaders are unique to each Class instance, so we need to specify how to decode
- // the information again, even though we set the class loaders when serializing the data.
- bundle.setClassLoader(ProtoParsers.class.getClassLoader());
- InternalDontUse parcelable = bundle.getParcelable(key);
- return (T) parcelable.getMessageUnsafe(defaultInstance.getDefaultInstanceForType());
+ byte[] bytes = bundle.getByteArray(key);
+ return (T) mergeFrom(bytes, defaultInstance.getDefaultInstanceForType());
}
/**
@@ -51,7 +45,7 @@ public final class ProtoParsers {
try {
return get(bundle, key, defaultInstance);
} catch (InvalidProtocolBufferException e) {
- throw new RuntimeException(e);
+ throw Assert.createIllegalStateFailException(e.toString());
}
}
@@ -68,121 +62,28 @@ public final class ProtoParsers {
* Stores a proto in a Bundle, for later retrieval by {@link #get(Bundle, String, MessageLite)} or
* {@link #getFromInstanceState(Bundle, String, MessageLite)}.
*/
- public static void put(Bundle bundle, String key, MessageLite message) {
- bundle.putParcelable(key, new InternalDontUse<>(null, message));
+ public static void put(
+ @NonNull Bundle bundle, @NonNull String key, @NonNull MessageLite message) {
+ Assert.checkState(message != null);
+ bundle.putByteArray(key, message.toByteArray());
}
/**
* Stores a proto in an Intent, for later retrieval by {@link #get(Bundle, String, MessageLite)}.
* Needs separate method because Intent has similar to but different API than Bundle.
*/
- public static void put(Intent intent, String key, MessageLite message) {
- intent.putExtra(key, new InternalDontUse<>(null, message));
- }
-
- /** Returns a {@linkplain Parcelable} representation of this protobuf message. */
- public static <T extends MessageLite> ParcelableProto<T> asParcelable(T message) {
- return new InternalDontUse<>(null, message);
- }
-
- /**
- * A protobuf message that can be stored in a {@link Parcel}.
- *
- * <p><b>Note:</b> This <code>Parcelable</code> can only be used in single app. Attempting to send
- * it to another app through an <code>Intent</code> will result in an exception due to Proguard
- * obfusation when the target application attempts to load the <code>ParcelableProto</code> class.
- */
- public interface ParcelableProto<T extends MessageLite> extends Parcelable {
- /**
- * @throws IllegalStateException if the parceled data does not correspond to the defaultInstance
- * type.
- */
- T getMessage(T defaultInstance);
- }
-
- /** Public because of Parcelable requirements. Do not use. */
- public static final class InternalDontUse<T extends MessageLite> implements ParcelableProto<T> {
- /* One of these two fields is always populated - since the bytes field never escapes this
- * object, there is no risk of concurrent modification by multiple threads, and volatile
- * is sufficient to be thread-safe. */
- private volatile byte[] bytes;
- private volatile T message;
-
- /**
- * Ideally, we would have type safety here. However, a static field {@link Creator} is required
- * by {@link Parcelable}. Static fields are inherently not type safe, since only 1 exists per
- * class (rather than 1 per type).
- */
- public static final Parcelable.Creator<InternalDontUse<?>> CREATOR =
- new Creator<InternalDontUse<?>>() {
- @Override
- public InternalDontUse<?> createFromParcel(Parcel parcel) {
- int serializedSize = parcel.readInt();
- byte[] array = new byte[serializedSize];
- parcel.readByteArray(array);
- return new InternalDontUse<>(array, null);
- }
-
- @Override
- public InternalDontUse<?>[] newArray(int i) {
- return new InternalDontUse[i];
- }
- };
-
- private InternalDontUse(byte[] bytes, T message) {
- Assert.checkArgument(bytes != null || message != null, "Must have a message or bytes");
- this.bytes = bytes;
- this.message = message;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel parcel, int i) {
- if (bytes == null) {
- final byte[] flatArray = new byte[message.getSerializedSize()];
- try {
- message.writeTo(CodedOutputStream.newInstance(flatArray));
- bytes = flatArray;
- } catch (IOException impossible) {
- throw new AssertionError(impossible);
- }
- }
- parcel.writeInt(bytes.length);
- parcel.writeByteArray(bytes);
- }
-
- @Override
- public T getMessage(T defaultInstance) {
- try {
- // The proto should never be invalid if it came from our application, so if it is, throw.
- return getMessageUnsafe(defaultInstance);
- } catch (InvalidProtocolBufferException e) {
- throw new IllegalStateException(e);
- }
- }
-
- @SuppressWarnings("unchecked") // We're being deserialized, so there's no real type safety
- T getMessageUnsafe(T defaultInstance) throws InvalidProtocolBufferException {
- // There's a risk that we'll double-parse the bytes, but that's OK, because it'll end up
- // as the same immutable object anyway.
- if (message == null) {
- message = (T) defaultInstance.toBuilder().mergeFrom(bytes).build();
- }
- return message;
- }
+ public static void put(@NonNull Intent intent, @NonNull String key, MessageLite message) {
+ Assert.checkState(message != null);
+ intent.putExtra(key, message.toByteArray());
}
/** Parses a proto, throwing parser errors as runtime exceptions. */
@SuppressWarnings("unchecked") // We want to eventually optimize away parser classes
- public static <T extends MessageLite> T mergeFrom(byte[] bytes, T defaultInstance) {
+ private static <T extends MessageLite> T mergeFrom(byte[] bytes, T defaultInstance) {
try {
return (T) defaultInstance.toBuilder().mergeFrom(bytes).build();
} catch (InvalidProtocolBufferException e) {
- throw new RuntimeException(e);
+ throw Assert.createIllegalStateFailException(e.toString());
}
}
}