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 import java.util.ArrayList; 23 import java.util.List; 24 25 /** Wrapper for reading & writing {@link List} instances from and to {@link Parcel} instances. */ 26 27 public class ParcelableList<E> implements Parcelable { 28 29 private static final int NULL_SIZE = -1; 30 31 private final Bundler bundler; 32 private final BundlerType type; 33 private final List<E> list; 34 35 /** 36 * Create a wrapper for a given list. 37 * 38 * <p>The passed in {@link Bundler} must be capable of bundling {@code F}. 39 */ of(Bundler bundler, BundlerType type, List<F> list)40 public static <F> ParcelableList<F> of(Bundler bundler, BundlerType type, List<F> list) { 41 return new ParcelableList<>(bundler, type, list); 42 } 43 get()44 public List<E> get() { 45 return list; 46 } 47 ParcelableList(Bundler bundler, BundlerType type, List<E> list)48 private ParcelableList(Bundler bundler, BundlerType type, List<E> list) { 49 if (bundler == null || type == null) { 50 throw new NullPointerException(); 51 } 52 this.bundler = bundler; 53 this.type = type; 54 this.list = list; 55 } 56 ParcelableList(Parcel in)57 private ParcelableList(Parcel in) { 58 bundler = in.readParcelable(Bundler.class.getClassLoader()); 59 int size = in.readInt(); 60 61 if (size == NULL_SIZE) { 62 type = null; 63 list = null; 64 return; 65 } 66 67 list = new ArrayList<>(); 68 type = (BundlerType) in.readParcelable(Bundler.class.getClassLoader()); 69 if (size > 0) { 70 BundlerType valueType = type.typeArguments().get(0); 71 for (int i = 0; i < size; i++) { 72 @SuppressWarnings("unchecked") 73 E value = (E) bundler.readFromParcel(in, valueType); 74 list.add(value); 75 } 76 } 77 } 78 79 @Override writeToParcel(Parcel dest, int flags)80 public void writeToParcel(Parcel dest, int flags) { 81 dest.writeParcelable(bundler, flags); 82 83 if (list == null) { 84 dest.writeInt(NULL_SIZE); 85 return; 86 } 87 88 dest.writeInt(list.size()); 89 dest.writeParcelable(type, flags); 90 if (!list.isEmpty()) { 91 BundlerType valueType = type.typeArguments().get(0); 92 93 for (E value : list) { 94 bundler.writeToParcel(dest, value, valueType, flags); 95 } 96 } 97 } 98 99 @Override describeContents()100 public int describeContents() { 101 return 0; 102 } 103 104 @SuppressWarnings("rawtypes") 105 public static final Creator<ParcelableList> CREATOR = 106 new Creator<ParcelableList>() { 107 @Override 108 public ParcelableList createFromParcel(Parcel in) { 109 return new ParcelableList(in); 110 } 111 112 @Override 113 public ParcelableList[] newArray(int size) { 114 return new ParcelableList[size]; 115 } 116 }; 117 } 118