• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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