1 package io.grpc.binder.internal; 2 3 import static com.google.common.base.Preconditions.checkState; 4 5 import android.os.Parcel; 6 import com.google.common.annotations.VisibleForTesting; 7 import java.io.Closeable; 8 import javax.annotation.Nullable; 9 10 /** 11 * Wraps a {@link Parcel} from the static {@link Parcel#obtain()} pool with methods that make it 12 * easy to eventually {@link Parcel#recycle()} it. 13 */ 14 class ParcelHolder implements Closeable { 15 16 @Nullable private Parcel parcel; 17 18 /** 19 * Creates a new instance that owns a {@link Parcel} newly obtained from Android's object pool. 20 */ obtain()21 public static ParcelHolder obtain() { 22 return new ParcelHolder(Parcel.obtain()); 23 } 24 25 /** Creates a new instance taking ownership of the specified {@code parcel}. */ ParcelHolder(Parcel parcel)26 public ParcelHolder(Parcel parcel) { 27 this.parcel = parcel; 28 } 29 30 /** 31 * Returns the wrapped {@link Parcel} if we still own it. 32 * 33 * @throws IllegalStateException if ownership has already been given up by {@link #release()} 34 */ get()35 public Parcel get() { 36 checkState(parcel != null, "get() after close()/release()"); 37 return parcel; 38 } 39 40 /** 41 * Returns the wrapped {@link Parcel} and releases ownership of it. 42 * 43 * @throws IllegalStateException if ownership has already been given up by {@link #release()} 44 */ release()45 public Parcel release() { 46 Parcel result = get(); 47 this.parcel = null; 48 return result; 49 } 50 51 /** 52 * Recycles the wrapped {@link Parcel} to Android's object pool, if we still own it. 53 * 54 * <p>Otherwise, this method has no effect. 55 */ 56 @Override close()57 public void close() { 58 if (parcel != null) { 59 parcel.recycle(); 60 parcel = null; 61 } 62 } 63 64 /** 65 * Returns true iff this container no longer owns a {@link Parcel}. 66 * 67 * <p>{@link #isEmpty()} is true after all call to {@link #close()} or {@link #release()}. 68 * 69 * <p>Typically only used for debugging or testing since Parcel-owning code should be calling 70 * {@link #close()} unconditionally. 71 */ 72 @VisibleForTesting isEmpty()73 public boolean isEmpty() { 74 return parcel == null; 75 } 76 } 77