16a35dc83f18572097134c4864360743f02d4cd99Victor Chang/* 26a35dc83f18572097134c4864360743f02d4cd99Victor Chang * Copyright 2016, The Android Open Source Project 36a35dc83f18572097134c4864360743f02d4cd99Victor Chang * 46a35dc83f18572097134c4864360743f02d4cd99Victor Chang * Licensed under the Apache License, Version 2.0 (the "License"); 56a35dc83f18572097134c4864360743f02d4cd99Victor Chang * you may not use this file except in compliance with the License. 66a35dc83f18572097134c4864360743f02d4cd99Victor Chang * You may obtain a copy of the License at 76a35dc83f18572097134c4864360743f02d4cd99Victor Chang * 86a35dc83f18572097134c4864360743f02d4cd99Victor Chang * http://www.apache.org/licenses/LICENSE-2.0 96a35dc83f18572097134c4864360743f02d4cd99Victor Chang * 106a35dc83f18572097134c4864360743f02d4cd99Victor Chang * Unless required by applicable law or agreed to in writing, software 116a35dc83f18572097134c4864360743f02d4cd99Victor Chang * distributed under the License is distributed on an "AS IS" BASIS, 126a35dc83f18572097134c4864360743f02d4cd99Victor Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136a35dc83f18572097134c4864360743f02d4cd99Victor Chang * See the License for the specific language governing permissions and 146a35dc83f18572097134c4864360743f02d4cd99Victor Chang * limitations under the License. 156a35dc83f18572097134c4864360743f02d4cd99Victor Chang */ 166a35dc83f18572097134c4864360743f02d4cd99Victor Changpackage com.android.managedprovisioning.common; 176a35dc83f18572097134c4864360743f02d4cd99Victor Chang 186a35dc83f18572097134c4864360743f02d4cd99Victor Changimport android.os.Parcel; 196a35dc83f18572097134c4864360743f02d4cd99Victor Changimport android.os.Parcelable; 206a35dc83f18572097134c4864360743f02d4cd99Victor Changimport android.os.PersistableBundle; 2190f58ca887207a527c80d7e9ccea97e205c960d4Victor Changimport android.support.annotation.NonNull; 22a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Changimport android.text.TextUtils; 23a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Changimport java.util.ArrayList; 246a35dc83f18572097134c4864360743f02d4cd99Victor Changimport java.util.Arrays; 25a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Changimport java.util.Collections; 26a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Changimport java.util.List; 276a35dc83f18572097134c4864360743f02d4cd99Victor Changimport java.util.Objects; 286a35dc83f18572097134c4864360743f02d4cd99Victor Changimport java.util.Set; 296a35dc83f18572097134c4864360743f02d4cd99Victor Chang 30a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Changpublic abstract class PersistableBundlable implements Parcelable { 31a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang public abstract @NonNull PersistableBundle toPersistableBundle(); 326a35dc83f18572097134c4864360743f02d4cd99Victor Chang 33a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang public static PersistableBundle getPersistableBundleFromParcel(Parcel parcel) { 346a35dc83f18572097134c4864360743f02d4cd99Victor Chang return parcel.readParcelable(PersistableBundle.class.getClassLoader()); 356a35dc83f18572097134c4864360743f02d4cd99Victor Chang } 366a35dc83f18572097134c4864360743f02d4cd99Victor Chang 37a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang @Override 38a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang public boolean equals(Object object) { 39a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang return isPersistableBundlableEquals(this, object); 40a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang } 41a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang 42a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang @Override 43a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang public int hashCode() { 44a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang // Concatenated sorted keys should be good enough as a hash 45a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang List<String> keys = new ArrayList(toPersistableBundle().keySet()); 46059f6c435c561226b1e8c629396b55302aec3772Victor Chang Collections.sort(keys); 47a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang return TextUtils.join(",", keys).hashCode(); 48a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang } 49a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang 50a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang @Override 51a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang public int describeContents() { 52a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang return 0; 53a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang } 54a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang 55a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang @Override 56a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang public void writeToParcel(Parcel dest, int flags) { 57a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang dest.writeParcelable(toPersistableBundle(), flags); 58a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang } 59a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang 60a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang private static boolean isPersistableBundlableEquals(PersistableBundlable pb1, Object obj) { 616a35dc83f18572097134c4864360743f02d4cd99Victor Chang if (pb1 == obj) { 626a35dc83f18572097134c4864360743f02d4cd99Victor Chang return true; 636a35dc83f18572097134c4864360743f02d4cd99Victor Chang } 646a35dc83f18572097134c4864360743f02d4cd99Victor Chang if (obj == null || pb1.getClass() != obj.getClass()) { 656a35dc83f18572097134c4864360743f02d4cd99Victor Chang return false; 666a35dc83f18572097134c4864360743f02d4cd99Victor Chang } 676a35dc83f18572097134c4864360743f02d4cd99Victor Chang 686a35dc83f18572097134c4864360743f02d4cd99Victor Chang // obj has to be PersistableBundlable as it has the same class 696a35dc83f18572097134c4864360743f02d4cd99Victor Chang PersistableBundlable pb2 = (PersistableBundlable) obj; 706a35dc83f18572097134c4864360743f02d4cd99Victor Chang return isPersistableBundleEquals(pb1.toPersistableBundle(), pb2.toPersistableBundle()); 716a35dc83f18572097134c4864360743f02d4cd99Victor Chang } 726a35dc83f18572097134c4864360743f02d4cd99Victor Chang 736a35dc83f18572097134c4864360743f02d4cd99Victor Chang /** 746a35dc83f18572097134c4864360743f02d4cd99Victor Chang * Compares two {@link PersistableBundle} objects are equals. 756a35dc83f18572097134c4864360743f02d4cd99Victor Chang */ 76a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang private static boolean isPersistableBundleEquals(PersistableBundle obj1, PersistableBundle obj2) { 776a35dc83f18572097134c4864360743f02d4cd99Victor Chang if (obj1 == obj2) { 786a35dc83f18572097134c4864360743f02d4cd99Victor Chang return true; 796a35dc83f18572097134c4864360743f02d4cd99Victor Chang } 806a35dc83f18572097134c4864360743f02d4cd99Victor Chang if (obj1 == null || obj2 == null || obj1.size() != obj2.size()) { 816a35dc83f18572097134c4864360743f02d4cd99Victor Chang return false; 826a35dc83f18572097134c4864360743f02d4cd99Victor Chang } 836a35dc83f18572097134c4864360743f02d4cd99Victor Chang Set<String> keys = obj1.keySet(); 846a35dc83f18572097134c4864360743f02d4cd99Victor Chang for (String key : keys) { 856a35dc83f18572097134c4864360743f02d4cd99Victor Chang Object val1 = obj1.get(key); 866a35dc83f18572097134c4864360743f02d4cd99Victor Chang Object val2 = obj2.get(key); 876a35dc83f18572097134c4864360743f02d4cd99Victor Chang if (!isPersistableBundleSupportedValueEquals(val1, val2)) { 886a35dc83f18572097134c4864360743f02d4cd99Victor Chang return false; 896a35dc83f18572097134c4864360743f02d4cd99Victor Chang } 906a35dc83f18572097134c4864360743f02d4cd99Victor Chang } 916a35dc83f18572097134c4864360743f02d4cd99Victor Chang return true; 926a35dc83f18572097134c4864360743f02d4cd99Victor Chang } 936a35dc83f18572097134c4864360743f02d4cd99Victor Chang 946a35dc83f18572097134c4864360743f02d4cd99Victor Chang /** 956a35dc83f18572097134c4864360743f02d4cd99Victor Chang * Compares two values which type is supported by {@link PersistableBundle}. 966a35dc83f18572097134c4864360743f02d4cd99Victor Chang * 976a35dc83f18572097134c4864360743f02d4cd99Victor Chang * <p>If the type isn't supported. The equality is done by {@link Object#equals(Object)}. 986a35dc83f18572097134c4864360743f02d4cd99Victor Chang */ 99a6283e0106a8c3af0d5ed33bbb7a86d1b3661f81Victor Chang private static boolean isPersistableBundleSupportedValueEquals(Object val1, Object val2) { 1006a35dc83f18572097134c4864360743f02d4cd99Victor Chang if (val1 == val2) { 1016a35dc83f18572097134c4864360743f02d4cd99Victor Chang return true; 1026a35dc83f18572097134c4864360743f02d4cd99Victor Chang } else if (val1 == null || val2 == null || !val1.getClass().equals(val2.getClass())) { 1036a35dc83f18572097134c4864360743f02d4cd99Victor Chang return false; 1046a35dc83f18572097134c4864360743f02d4cd99Victor Chang } else if (val1 instanceof PersistableBundle) { 1056a35dc83f18572097134c4864360743f02d4cd99Victor Chang return isPersistableBundleEquals((PersistableBundle) val1, (PersistableBundle) val2); 1066a35dc83f18572097134c4864360743f02d4cd99Victor Chang } else if (val1 instanceof int[]) { 1076a35dc83f18572097134c4864360743f02d4cd99Victor Chang return Arrays.equals((int[]) val1, (int[]) val2); 1086a35dc83f18572097134c4864360743f02d4cd99Victor Chang } else if (val1 instanceof long[]) { 1096a35dc83f18572097134c4864360743f02d4cd99Victor Chang return Arrays.equals((long[]) val1, (long[]) val2); 1106a35dc83f18572097134c4864360743f02d4cd99Victor Chang } else if (val1 instanceof double[]) { 1116a35dc83f18572097134c4864360743f02d4cd99Victor Chang return Arrays.equals((double[]) val1, (double[]) val2); 1126a35dc83f18572097134c4864360743f02d4cd99Victor Chang } else if (val1 instanceof boolean[]) { 1136a35dc83f18572097134c4864360743f02d4cd99Victor Chang return Arrays.equals((boolean[]) val1, (boolean[]) val2); 1146a35dc83f18572097134c4864360743f02d4cd99Victor Chang } else if (val1 instanceof String[]) { 1156a35dc83f18572097134c4864360743f02d4cd99Victor Chang return Arrays.equals((String[]) val1, (String[]) val2); 1166a35dc83f18572097134c4864360743f02d4cd99Victor Chang } else { 1176a35dc83f18572097134c4864360743f02d4cd99Victor Chang return Objects.equals(val1, val2); 1186a35dc83f18572097134c4864360743f02d4cd99Victor Chang } 1196a35dc83f18572097134c4864360743f02d4cd99Victor Chang } 1206a35dc83f18572097134c4864360743f02d4cd99Victor Chang 1216a35dc83f18572097134c4864360743f02d4cd99Victor Chang} 122