1 /* 2 * Copyright (C) 2023 The Android Open Source Project 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 * http://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 17 package android.devicepolicy.cts.utils; 18 19 import static com.google.common.truth.Truth.assertWithMessage; 20 21 import static org.junit.Assert.fail; 22 23 import android.os.Bundle; 24 import android.os.Parcelable; 25 import android.util.ArraySet; 26 import android.util.Log; 27 28 import java.util.Arrays; 29 import java.util.List; 30 import java.util.Set; 31 32 /** 33 * Utility class for {@link Bundle} related operations. 34 */ 35 public final class BundleUtils { 36 37 private static final String TAG = BundleUtils.class.getSimpleName(); 38 39 private static final String[] TEST_STRINGS = new String[]{ 40 "<bad/>", 41 ">worse!\"£$%^&*()'<", 42 "<JSON>\"{ \\\"One\\\": { \\\"OneOne\\\": \\\"11\\\", \\\"" 43 + "OneTwo\\\": \\\"12\\\" }, \\\"Two\\\": \\\"2\\\" } <JSON/>\"" 44 }; 45 BundleUtils()46 private BundleUtils() {} 47 48 /** 49 * Returns a {@link Bundle} that is uniquely identified by the provided {@code id}, see 50 * {@link #assertEqualToBundle(String, Bundle)}. 51 */ 52 // Should be consistent with assertEqualToBundle createBundle(String id)53 public static Bundle createBundle(String id) { 54 Bundle result = new Bundle(); 55 // Tests for 6 allowed types: Integer, Boolean, String, String[], Bundle and Parcelable[] 56 // Also test for string escaping handling 57 result.putBoolean("boolean_0", false); 58 result.putBoolean("boolean_1", true); 59 result.putInt("integer", 0xfffff); 60 // If a null is stored, "" will be read back 61 result.putString("empty", ""); 62 result.putString("string", id); 63 result.putStringArray("string[]", TEST_STRINGS); 64 65 // Adding a bundle, which contain 2 nested restrictions - bundle_string and bundle_int 66 Bundle bundle = new Bundle(); 67 bundle.putString("bundle_string", "bundle_string"); 68 bundle.putInt("bundle_int", 1); 69 result.putBundle("bundle", bundle); 70 71 // Adding an array of 2 bundles 72 Bundle[] bundleArray = new Bundle[2]; 73 bundleArray[0] = new Bundle(); 74 bundleArray[0].putString("bundle_array_string", "bundle_array_string"); 75 // Put bundle inside bundle 76 bundleArray[0].putBundle("bundle_array_bundle", bundle); 77 bundleArray[1] = new Bundle(); 78 bundleArray[1].putString("bundle_array_string2", "bundle_array_string2"); 79 result.putParcelableArray("bundle_array", bundleArray); 80 return result; 81 } 82 83 /** 84 * Returns {@code true} if the provided {@code bundle} matches a bundle created using 85 * {@link #createBundle(String)} with the provided {@code id}. 86 */ 87 // Should be consistent with createBundle assertEqualToBundle(String id, Bundle bundle)88 public static void assertEqualToBundle(String id, Bundle bundle) { 89 assertWithMessage("bundle0 size") 90 .that(bundle.size()).isEqualTo(8); 91 assertBooleanKey(bundle, "boolean_0", false); 92 assertBooleanKey(bundle, "boolean_1", true); 93 assertIntKey(bundle, "integer", 0xfffff); 94 assertStringKey(bundle, "empty", ""); 95 assertStringKey(bundle, "string", id); 96 assertStringsKey(bundle, "string[]", TEST_STRINGS); 97 98 Bundle childBundle = bundle.getBundle("bundle"); 99 assertStringKey(childBundle, "bundle_string", "bundle_string"); 100 assertIntKey(childBundle, "bundle_int", 1); 101 102 Parcelable[] bundleArray = bundle.getParcelableArray("bundle_array"); 103 assertWithMessage("size of bundle_array").that(bundleArray).hasLength(2); 104 105 // Verifying bundle_array[0] 106 Bundle bundle1 = (Bundle) bundleArray[0]; 107 assertStringKey(bundle1, "bundle_array_string", "bundle_array_string"); 108 109 Bundle bundle1ChildBundle = getBundleKey(bundle1, "bundle_array_bundle"); 110 111 assertWithMessage("bundle_array_bundle") 112 .that(bundle1ChildBundle).isNotNull(); 113 assertStringKey(bundle1ChildBundle, "bundle_string", "bundle_string"); 114 assertIntKey(bundle1ChildBundle, "bundle_int", 1); 115 116 // Verifying bundle_array[1] 117 Bundle bundle2 = (Bundle) bundleArray[1]; 118 assertStringKey(bundle2, "bundle_array_string2", "bundle_array_string2"); 119 } 120 121 /** 122 * Returns {@code true} if the provided {@code bundle} does NOT match a bundle created using 123 * {@link #createBundle(String)} with the provided {@code id}. 124 */ assertNotEqualToBundle(String id, Bundle value)125 public static void assertNotEqualToBundle(String id, Bundle value) { 126 // This uses an arbitrary value from the test bundle 127 assertWithMessage("Bundle should not be equal to test bundle") 128 .that(value.getString("string")).isNotEqualTo(id); 129 } 130 131 /** 132 * Checks if the provided {@code bundle} list matches exactly the provided list of ids, 133 * irrespective of ordering. Ids should be unique. 134 */ assertEqualToBundleList(List<Bundle> bundles, String... ids)135 public static void assertEqualToBundleList(List<Bundle> bundles, String... ids) { 136 Set<String> idSet = new ArraySet<>(ids); 137 if (idSet.size() != ids.length) { 138 fail("Duplicates in Ids"); 139 } 140 assertWithMessage("Bundle size").that(bundles.size()).isEqualTo(idSet.size()); 141 for (Bundle bundle : bundles) { 142 String id = bundle.getString("string"); 143 assertWithMessage("Unexpected ID %s in bundles", id).that(idSet).contains(id); 144 assertEqualToBundle(id, bundle); 145 idSet.remove(id); 146 } 147 } 148 assertBooleanKey(Bundle bundle, String key, boolean expectedValue)149 private static void assertBooleanKey(Bundle bundle, String key, boolean expectedValue) { 150 151 boolean value = bundle.getBoolean(key); 152 Log.v(TAG, "assertBooleanKey(): " + key + "=" + value); 153 assertWithMessage("bundle's '%s' key", key) 154 .that(value).isEqualTo(expectedValue); 155 } 156 assertIntKey(Bundle bundle, String key, int expectedValue)157 private static void assertIntKey(Bundle bundle, String key, int expectedValue) { 158 int value = bundle.getInt(key); 159 Log.v(TAG, "assertIntKey(): " + key + "=" + value); 160 assertWithMessage("bundle's '%s' key", key) 161 .that(value).isEqualTo(expectedValue); 162 } 163 assertStringKey(Bundle bundle, String key, String expectedValue)164 private static void assertStringKey(Bundle bundle, String key, String expectedValue) { 165 String value = bundle.getString(key); 166 Log.v(TAG, "assertStringKey(): " + key + "=" + value); 167 assertWithMessage("bundle's '%s' key", key) 168 .that(value).isEqualTo(expectedValue); 169 } 170 assertStringsKey(Bundle bundle, String key, String[] expectedValue)171 private static void assertStringsKey(Bundle bundle, String key, String[] expectedValue) { 172 String[] value = bundle.getStringArray(key); 173 Log.v(TAG, "assertStringsKey(): " + key + "=" 174 + (value == null ? "null" : Arrays.toString(value))); 175 176 assertWithMessage("bundle's '%s' key", key).that(value).asList() 177 .containsExactlyElementsIn(expectedValue).inOrder(); 178 } 179 getBundleKey(Bundle bundle, String key)180 private static Bundle getBundleKey(Bundle bundle, String key) { 181 Bundle value = bundle.getBundle(key); 182 Log.v(TAG, "getBundleKey(): " + key + "=" + value); 183 assertWithMessage("bundle's '%s' key", key).that(value).isNotNull(); 184 return value; 185 } 186 } 187