1 /* 2 * Copyright 2021 Google LLC 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * https://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.google.android.enterprise.connectedapps.parcelablewrappers; 17 18 import android.os.Parcel; 19 import android.os.Parcelable; 20 import com.google.android.enterprise.connectedapps.internal.Bundler; 21 import com.google.android.enterprise.connectedapps.internal.BundlerType; 22 23 /** Wrapper for reading & writing arrays from and to {@link Parcel} instances. */ 24 public class ParcelableArray<E> implements Parcelable { 25 26 private static final int NULL_SIZE = -1; 27 28 private final Bundler bundler; 29 private final BundlerType type; 30 private final E[] array; 31 32 /** 33 * Create a wrapper for a given array. 34 * 35 * <p>The passed in {@link Bundler} must be capable of bundling {@code F}. 36 */ of(Bundler bundler, BundlerType type, F[] array)37 public static <F> ParcelableArray<F> of(Bundler bundler, BundlerType type, F[] array) { 38 return new ParcelableArray<>(bundler, type, array); 39 } 40 get()41 public E[] get() { 42 return array; 43 } 44 ParcelableArray(Bundler bundler, BundlerType type, E[] array)45 private ParcelableArray(Bundler bundler, BundlerType type, E[] array) { 46 if (bundler == null || type == null) { 47 throw new NullPointerException(); 48 } 49 this.bundler = bundler; 50 this.type = type; 51 this.array = array; 52 } 53 ParcelableArray(Parcel in)54 private ParcelableArray(Parcel in) { 55 bundler = in.readParcelable(Bundler.class.getClassLoader()); 56 int size = in.readInt(); 57 58 if (size == NULL_SIZE) { 59 type = null; 60 array = null; 61 return; 62 } 63 64 type = in.readParcelable(Bundler.class.getClassLoader()); 65 BundlerType valueType = type.typeArguments().get(0); 66 67 @SuppressWarnings("unchecked") 68 E[] a = (E[]) bundler.createArray(valueType, size); 69 array = a; 70 71 if (size > 0) { 72 for (int i = 0; i < size; i++) { 73 @SuppressWarnings("unchecked") 74 E value = (E) bundler.readFromParcel(in, valueType); 75 array[i] = value; 76 } 77 } 78 } 79 80 @Override writeToParcel(Parcel dest, int flags)81 public void writeToParcel(Parcel dest, int flags) { 82 dest.writeParcelable(bundler, flags); 83 84 if (array == null) { 85 dest.writeInt(NULL_SIZE); 86 return; 87 } 88 89 dest.writeInt(array.length); 90 dest.writeParcelable(type, flags); 91 if (array.length > 0) { 92 BundlerType valueType = type.typeArguments().get(0); 93 94 for (E value : array) { 95 bundler.writeToParcel(dest, value, valueType, flags); 96 } 97 } 98 } 99 100 @Override describeContents()101 public int describeContents() { 102 return 0; 103 } 104 105 @SuppressWarnings("rawtypes") 106 public static final Creator<ParcelableArray> CREATOR = 107 new Creator<ParcelableArray>() { 108 @Override 109 public ParcelableArray createFromParcel(Parcel in) { 110 return new ParcelableArray(in); 111 } 112 113 @Override 114 public ParcelableArray[] newArray(int size) { 115 return new ParcelableArray[size]; 116 } 117 }; 118 } 119