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