PackageParserTest.java revision 77029c5b16351775cb2333369ef9a4bc1d9acf58
1/* 2 * Copyright (C) 2016 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 */ 16package com.android.server.pm; 17 18import android.content.pm.ActivityInfo; 19import android.content.pm.ApplicationInfo; 20import android.content.pm.ConfigurationInfo; 21import android.content.pm.FeatureGroupInfo; 22import android.content.pm.FeatureInfo; 23import android.content.pm.InstrumentationInfo; 24import android.content.pm.PackageParser; 25import android.content.pm.ProviderInfo; 26import android.content.pm.ServiceInfo; 27import android.content.pm.Signature; 28import android.os.Bundle; 29import android.os.Parcel; 30import android.support.test.runner.AndroidJUnit4; 31import android.test.suitebuilder.annotation.MediumTest; 32 33import java.io.File; 34import java.lang.reflect.Array; 35import java.lang.reflect.Field; 36import java.nio.charset.StandardCharsets; 37import java.util.ArrayList; 38import java.util.Arrays; 39import java.util.HashSet; 40import java.util.List; 41import java.util.Set; 42 43import static org.junit.Assert.*; 44 45import android.util.ArrayMap; 46import android.util.ArraySet; 47import org.junit.Before; 48import org.junit.Test; 49import org.junit.runner.RunWith; 50 51import libcore.io.IoUtils; 52 53@RunWith(AndroidJUnit4.class) 54@MediumTest 55public class PackageParserTest { 56 private File mTmpDir; 57 private static final File FRAMEWORK = new File("/system/framework/framework-res.apk"); 58 59 @Before 60 public void setUp() { 61 // Create a new temporary directory for each of our tests. 62 mTmpDir = IoUtils.createTemporaryDirectory("PackageParserTest"); 63 } 64 65 @Test 66 public void testParse_noCache() throws Exception { 67 PackageParser pp = new CachePackageNameParser(); 68 PackageParser.Package pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, 69 false /* useCaches */); 70 assertNotNull(pkg); 71 72 pp.setCacheDir(mTmpDir); 73 pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, 74 false /* useCaches */); 75 assertNotNull(pkg); 76 77 // Make sure that we always write out a cache entry for future reference, 78 // whether or not we're asked to use caches. 79 assertEquals(1, mTmpDir.list().length); 80 } 81 82 @Test 83 public void testParse_withCache() throws Exception { 84 PackageParser pp = new CachePackageNameParser(); 85 86 pp.setCacheDir(mTmpDir); 87 // The first parse will write this package to the cache. 88 pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, true /* useCaches */); 89 90 // Now attempt to parse the package again, should return the 91 // cached result. 92 PackageParser.Package pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, 93 true /* useCaches */); 94 assertEquals("cache_android", pkg.packageName); 95 96 // Try again, with useCaches == false, shouldn't return the parsed 97 // result. 98 pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, false /* useCaches */); 99 assertEquals("android", pkg.packageName); 100 101 // We haven't set a cache directory here : the parse should still succeed, 102 // just not using the cached results. 103 pp = new CachePackageNameParser(); 104 pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, true /* useCaches */); 105 assertEquals("android", pkg.packageName); 106 107 pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, false /* useCaches */); 108 assertEquals("android", pkg.packageName); 109 } 110 111 @Test 112 public void test_serializePackage() throws Exception { 113 PackageParser pp = new PackageParser(); 114 pp.setCacheDir(mTmpDir); 115 116 PackageParser.Package pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, 117 true /* useCaches */); 118 119 Parcel p = Parcel.obtain(); 120 pkg.writeToParcel(p, 0 /* flags */); 121 122 p.setDataPosition(0); 123 PackageParser.Package deserialized = new PackageParser.Package(p); 124 125 assertPackagesEqual(pkg, deserialized); 126 } 127 128 @Test 129 public void test_roundTripKnownFields() throws Exception { 130 PackageParser.Package pkg = new PackageParser.Package("foo"); 131 setKnownFields(pkg); 132 133 Parcel p = Parcel.obtain(); 134 pkg.writeToParcel(p, 0 /* flags */); 135 136 p.setDataPosition(0); 137 PackageParser.Package deserialized = new PackageParser.Package(p); 138 assertAllFieldsExist(deserialized); 139 } 140 141 @Test 142 public void test_stringInterning() throws Exception { 143 PackageParser.Package pkg = new PackageParser.Package("foo"); 144 setKnownFields(pkg); 145 146 Parcel p = Parcel.obtain(); 147 pkg.writeToParcel(p, 0 /* flags */); 148 149 p.setDataPosition(0); 150 PackageParser.Package deserialized = new PackageParser.Package(p); 151 152 p.setDataPosition(0); 153 PackageParser.Package deserialized2 = new PackageParser.Package(p); 154 155 assertSame(deserialized.packageName, deserialized2.packageName); 156 assertSame(deserialized.applicationInfo.permission, 157 deserialized2.applicationInfo.permission); 158 assertSame(deserialized.requestedPermissions.get(0), 159 deserialized2.requestedPermissions.get(0)); 160 assertSame(deserialized.protectedBroadcasts.get(0), 161 deserialized2.protectedBroadcasts.get(0)); 162 assertSame(deserialized.usesLibraries.get(0), 163 deserialized2.usesLibraries.get(0)); 164 assertSame(deserialized.usesOptionalLibraries.get(0), 165 deserialized2.usesOptionalLibraries.get(0)); 166 assertSame(deserialized.mVersionName, deserialized2.mVersionName); 167 assertSame(deserialized.mSharedUserId, deserialized2.mSharedUserId); 168 } 169 170 171 /** 172 * A trivial subclass of package parser that only caches the package name, and throws away 173 * all other information. 174 */ 175 public static class CachePackageNameParser extends PackageParser { 176 @Override 177 public byte[] toCacheEntry(Package pkg) { 178 return ("cache_" + pkg.packageName).getBytes(StandardCharsets.UTF_8); 179 } 180 181 @Override 182 public Package fromCacheEntry(byte[] cacheEntry) { 183 return new Package(new String(cacheEntry, StandardCharsets.UTF_8)); 184 } 185 } 186 187 // NOTE: The equality assertions below are based on code autogenerated by IntelliJ. 188 189 public static void assertPackagesEqual(PackageParser.Package a, PackageParser.Package b) { 190 assertEquals(a.baseRevisionCode, b.baseRevisionCode); 191 assertEquals(a.baseHardwareAccelerated, b.baseHardwareAccelerated); 192 assertEquals(a.mVersionCode, b.mVersionCode); 193 assertEquals(a.mSharedUserLabel, b.mSharedUserLabel); 194 assertEquals(a.mPreferredOrder, b.mPreferredOrder); 195 assertEquals(a.installLocation, b.installLocation); 196 assertEquals(a.coreApp, b.coreApp); 197 assertEquals(a.mRequiredForAllUsers, b.mRequiredForAllUsers); 198 assertEquals(a.mTrustedOverlay, b.mTrustedOverlay); 199 assertEquals(a.mCompileSdkVersion, b.mCompileSdkVersion); 200 assertEquals(a.mCompileSdkVersionCodename, b.mCompileSdkVersionCodename); 201 assertEquals(a.use32bitAbi, b.use32bitAbi); 202 assertEquals(a.packageName, b.packageName); 203 assertTrue(Arrays.equals(a.splitNames, b.splitNames)); 204 assertEquals(a.volumeUuid, b.volumeUuid); 205 assertEquals(a.codePath, b.codePath); 206 assertEquals(a.baseCodePath, b.baseCodePath); 207 assertTrue(Arrays.equals(a.splitCodePaths, b.splitCodePaths)); 208 assertTrue(Arrays.equals(a.splitRevisionCodes, b.splitRevisionCodes)); 209 assertTrue(Arrays.equals(a.splitFlags, b.splitFlags)); 210 assertTrue(Arrays.equals(a.splitPrivateFlags, b.splitPrivateFlags)); 211 assertApplicationInfoEqual(a.applicationInfo, b.applicationInfo); 212 213 assertEquals(a.permissions.size(), b.permissions.size()); 214 for (int i = 0; i < a.permissions.size(); ++i) { 215 assertPermissionsEqual(a.permissions.get(i), b.permissions.get(i)); 216 assertSame(a.permissions.get(i).owner, a); 217 assertSame(b.permissions.get(i).owner, b); 218 } 219 220 assertEquals(a.permissionGroups.size(), b.permissionGroups.size()); 221 for (int i = 0; i < a.permissionGroups.size(); ++i) { 222 assertPermissionGroupsEqual(a.permissionGroups.get(i), b.permissionGroups.get(i)); 223 } 224 225 assertEquals(a.activities.size(), b.activities.size()); 226 for (int i = 0; i < a.activities.size(); ++i) { 227 assertActivitiesEqual(a.activities.get(i), b.activities.get(i)); 228 } 229 230 assertEquals(a.receivers.size(), b.receivers.size()); 231 for (int i = 0; i < a.receivers.size(); ++i) { 232 assertActivitiesEqual(a.receivers.get(i), b.receivers.get(i)); 233 } 234 235 assertEquals(a.providers.size(), b.providers.size()); 236 for (int i = 0; i < a.providers.size(); ++i) { 237 assertProvidersEqual(a.providers.get(i), b.providers.get(i)); 238 } 239 240 assertEquals(a.services.size(), b.services.size()); 241 for (int i = 0; i < a.services.size(); ++i) { 242 assertServicesEqual(a.services.get(i), b.services.get(i)); 243 } 244 245 assertEquals(a.instrumentation.size(), b.instrumentation.size()); 246 for (int i = 0; i < a.instrumentation.size(); ++i) { 247 assertInstrumentationEqual(a.instrumentation.get(i), b.instrumentation.get(i)); 248 } 249 250 assertEquals(a.requestedPermissions, b.requestedPermissions); 251 assertEquals(a.protectedBroadcasts, b.protectedBroadcasts); 252 assertEquals(a.parentPackage, b.parentPackage); 253 assertEquals(a.childPackages, b.childPackages); 254 assertEquals(a.libraryNames, b.libraryNames); 255 assertEquals(a.usesLibraries, b.usesLibraries); 256 assertEquals(a.usesOptionalLibraries, b.usesOptionalLibraries); 257 assertTrue(Arrays.equals(a.usesLibraryFiles, b.usesLibraryFiles)); 258 assertEquals(a.mOriginalPackages, b.mOriginalPackages); 259 assertEquals(a.mRealPackage, b.mRealPackage); 260 assertEquals(a.mAdoptPermissions, b.mAdoptPermissions); 261 assertBundleApproximateEquals(a.mAppMetaData, b.mAppMetaData); 262 assertEquals(a.mVersionName, b.mVersionName); 263 assertEquals(a.mSharedUserId, b.mSharedUserId); 264 assertTrue(Arrays.equals(a.mSigningDetails.signatures, b.mSigningDetails.signatures)); 265 assertTrue(Arrays.equals(a.mLastPackageUsageTimeInMills, b.mLastPackageUsageTimeInMills)); 266 assertEquals(a.mExtras, b.mExtras); 267 assertEquals(a.mRestrictedAccountType, b.mRestrictedAccountType); 268 assertEquals(a.mRequiredAccountType, b.mRequiredAccountType); 269 assertEquals(a.mOverlayTarget, b.mOverlayTarget); 270 assertEquals(a.mSigningDetails.publicKeys, b.mSigningDetails.publicKeys); 271 assertEquals(a.mUpgradeKeySets, b.mUpgradeKeySets); 272 assertEquals(a.mKeySetMapping, b.mKeySetMapping); 273 assertEquals(a.cpuAbiOverride, b.cpuAbiOverride); 274 assertTrue(Arrays.equals(a.restrictUpdateHash, b.restrictUpdateHash)); 275 } 276 277 private static void assertBundleApproximateEquals(Bundle a, Bundle b) { 278 if (a == b) { 279 return; 280 } 281 282 // Force the bundles to be unparceled. 283 a.getBoolean("foo"); 284 b.getBoolean("foo"); 285 286 assertEquals(a.toString(), b.toString()); 287 } 288 289 private static void assertComponentsEqual(PackageParser.Component<?> a, 290 PackageParser.Component<?> b) { 291 assertEquals(a.className, b.className); 292 assertBundleApproximateEquals(a.metaData, b.metaData); 293 assertEquals(a.getComponentName(), b.getComponentName()); 294 295 if (a.intents != null && b.intents != null) { 296 assertEquals(a.intents.size(), b.intents.size()); 297 } else if (a.intents == null || b.intents == null) { 298 return; 299 } 300 301 for (int i = 0; i < a.intents.size(); ++i) { 302 PackageParser.IntentInfo aIntent = a.intents.get(i); 303 PackageParser.IntentInfo bIntent = b.intents.get(i); 304 305 assertEquals(aIntent.hasDefault, bIntent.hasDefault); 306 assertEquals(aIntent.labelRes, bIntent.labelRes); 307 assertEquals(aIntent.nonLocalizedLabel, bIntent.nonLocalizedLabel); 308 assertEquals(aIntent.icon, bIntent.icon); 309 assertEquals(aIntent.logo, bIntent.logo); 310 assertEquals(aIntent.banner, bIntent.banner); 311 assertEquals(aIntent.preferred, bIntent.preferred); 312 } 313 } 314 315 private static void assertPermissionsEqual(PackageParser.Permission a, 316 PackageParser.Permission b) { 317 assertComponentsEqual(a, b); 318 assertEquals(a.tree, b.tree); 319 320 // Verify basic flags in PermissionInfo to make sure they're consistent. We don't perform 321 // a full structural equality here because the code that serializes them isn't parser 322 // specific and is tested elsewhere. 323 assertEquals(a.info.protectionLevel, b.info.protectionLevel); 324 assertEquals(a.info.group, b.info.group); 325 assertEquals(a.info.flags, b.info.flags); 326 327 if (a.group != null && b.group != null) { 328 assertPermissionGroupsEqual(a.group, b.group); 329 } else if (a.group != null || b.group != null) { 330 throw new AssertionError(); 331 } 332 } 333 334 private static void assertInstrumentationEqual(PackageParser.Instrumentation a, 335 PackageParser.Instrumentation b) { 336 assertComponentsEqual(a, b); 337 338 // Sanity check for InstrumentationInfo. 339 assertEquals(a.info.targetPackage, b.info.targetPackage); 340 assertEquals(a.info.targetProcesses, b.info.targetProcesses); 341 assertEquals(a.info.sourceDir, b.info.sourceDir); 342 assertEquals(a.info.publicSourceDir, b.info.publicSourceDir); 343 } 344 345 private static void assertServicesEqual(PackageParser.Service a, PackageParser.Service b) { 346 assertComponentsEqual(a, b); 347 348 // Sanity check for ServiceInfo. 349 assertApplicationInfoEqual(a.info.applicationInfo, b.info.applicationInfo); 350 assertEquals(a.info.name, b.info.name); 351 } 352 353 private static void assertProvidersEqual(PackageParser.Provider a, PackageParser.Provider b) { 354 assertComponentsEqual(a, b); 355 356 // Sanity check for ProviderInfo 357 assertApplicationInfoEqual(a.info.applicationInfo, b.info.applicationInfo); 358 assertEquals(a.info.name, b.info.name); 359 } 360 361 private static void assertActivitiesEqual(PackageParser.Activity a, PackageParser.Activity b) { 362 assertComponentsEqual(a, b); 363 364 // Sanity check for ActivityInfo. 365 assertApplicationInfoEqual(a.info.applicationInfo, b.info.applicationInfo); 366 assertEquals(a.info.name, b.info.name); 367 } 368 369 private static void assertPermissionGroupsEqual(PackageParser.PermissionGroup a, 370 PackageParser.PermissionGroup b) { 371 assertComponentsEqual(a, b); 372 373 // Sanity check for PermissionGroupInfo. 374 assertEquals(a.info.name, b.info.name); 375 assertEquals(a.info.descriptionRes, b.info.descriptionRes); 376 } 377 378 private static void assertApplicationInfoEqual(ApplicationInfo a, ApplicationInfo that) { 379 assertEquals(a.descriptionRes, that.descriptionRes); 380 assertEquals(a.theme, that.theme); 381 assertEquals(a.fullBackupContent, that.fullBackupContent); 382 assertEquals(a.uiOptions, that.uiOptions); 383 assertEquals(a.flags, that.flags); 384 assertEquals(a.privateFlags, that.privateFlags); 385 assertEquals(a.requiresSmallestWidthDp, that.requiresSmallestWidthDp); 386 assertEquals(a.compatibleWidthLimitDp, that.compatibleWidthLimitDp); 387 assertEquals(a.largestWidthLimitDp, that.largestWidthLimitDp); 388 assertEquals(a.nativeLibraryRootRequiresIsa, that.nativeLibraryRootRequiresIsa); 389 assertEquals(a.uid, that.uid); 390 assertEquals(a.minSdkVersion, that.minSdkVersion); 391 assertEquals(a.targetSdkVersion, that.targetSdkVersion); 392 assertEquals(a.versionCode, that.versionCode); 393 assertEquals(a.enabled, that.enabled); 394 assertEquals(a.enabledSetting, that.enabledSetting); 395 assertEquals(a.installLocation, that.installLocation); 396 assertEquals(a.networkSecurityConfigRes, that.networkSecurityConfigRes); 397 assertEquals(a.taskAffinity, that.taskAffinity); 398 assertEquals(a.permission, that.permission); 399 assertEquals(a.processName, that.processName); 400 assertEquals(a.className, that.className); 401 assertEquals(a.manageSpaceActivityName, that.manageSpaceActivityName); 402 assertEquals(a.backupAgentName, that.backupAgentName); 403 assertEquals(a.volumeUuid, that.volumeUuid); 404 assertEquals(a.scanSourceDir, that.scanSourceDir); 405 assertEquals(a.scanPublicSourceDir, that.scanPublicSourceDir); 406 assertEquals(a.sourceDir, that.sourceDir); 407 assertEquals(a.publicSourceDir, that.publicSourceDir); 408 assertTrue(Arrays.equals(a.splitSourceDirs, that.splitSourceDirs)); 409 assertTrue(Arrays.equals(a.splitPublicSourceDirs, that.splitPublicSourceDirs)); 410 assertTrue(Arrays.equals(a.resourceDirs, that.resourceDirs)); 411 assertEquals(a.seInfo, that.seInfo); 412 assertTrue(Arrays.equals(a.sharedLibraryFiles, that.sharedLibraryFiles)); 413 assertEquals(a.dataDir, that.dataDir); 414 assertEquals(a.deviceProtectedDataDir, that.deviceProtectedDataDir); 415 assertEquals(a.credentialProtectedDataDir, that.credentialProtectedDataDir); 416 assertEquals(a.nativeLibraryDir, that.nativeLibraryDir); 417 assertEquals(a.secondaryNativeLibraryDir, that.secondaryNativeLibraryDir); 418 assertEquals(a.nativeLibraryRootDir, that.nativeLibraryRootDir); 419 assertEquals(a.primaryCpuAbi, that.primaryCpuAbi); 420 assertEquals(a.secondaryCpuAbi, that.secondaryCpuAbi); 421 } 422 423 public static void setKnownFields(PackageParser.Package pkg) { 424 pkg.baseRevisionCode = 100; 425 pkg.baseHardwareAccelerated = true; 426 pkg.mVersionCode = 100; 427 pkg.mSharedUserLabel = 100; 428 pkg.mPreferredOrder = 100; 429 pkg.installLocation = 100; 430 pkg.coreApp = true; 431 pkg.mRequiredForAllUsers = true; 432 pkg.mTrustedOverlay = true; 433 pkg.use32bitAbi = true; 434 pkg.packageName = "foo"; 435 pkg.splitNames = new String[] { "foo2" }; 436 pkg.volumeUuid = "foo3"; 437 pkg.codePath = "foo4"; 438 pkg.baseCodePath = "foo5"; 439 pkg.splitCodePaths = new String[] { "foo6" }; 440 pkg.splitRevisionCodes = new int[] { 100 }; 441 pkg.splitFlags = new int[] { 100 }; 442 pkg.splitPrivateFlags = new int[] { 100 }; 443 pkg.applicationInfo = new ApplicationInfo(); 444 445 pkg.permissions.add(new PackageParser.Permission(pkg)); 446 pkg.permissionGroups.add(new PackageParser.PermissionGroup(pkg)); 447 448 final PackageParser.ParseComponentArgs dummy = new PackageParser.ParseComponentArgs( 449 pkg, new String[1], 0, 0, 0, 0, 0, 0, null, 0, 0, 0); 450 451 pkg.activities.add(new PackageParser.Activity(dummy, new ActivityInfo())); 452 pkg.receivers.add(new PackageParser.Activity(dummy, new ActivityInfo())); 453 pkg.providers.add(new PackageParser.Provider(dummy, new ProviderInfo())); 454 pkg.services.add(new PackageParser.Service(dummy, new ServiceInfo())); 455 pkg.instrumentation.add(new PackageParser.Instrumentation(dummy, new InstrumentationInfo())); 456 pkg.requestedPermissions.add("foo7"); 457 458 pkg.protectedBroadcasts = new ArrayList<>(); 459 pkg.protectedBroadcasts.add("foo8"); 460 461 pkg.parentPackage = new PackageParser.Package("foo9"); 462 463 pkg.childPackages = new ArrayList<>(); 464 pkg.childPackages.add(new PackageParser.Package("bar")); 465 466 pkg.staticSharedLibName = "foo23"; 467 pkg.staticSharedLibVersion = 100; 468 pkg.usesStaticLibraries = new ArrayList<>(); 469 pkg.usesStaticLibraries.add("foo23"); 470 pkg.usesStaticLibrariesCertDigests = new String[1][]; 471 pkg.usesStaticLibrariesCertDigests[0] = new String[] { "digest" }; 472 pkg.usesStaticLibrariesVersions = new long[] { 100 }; 473 474 pkg.libraryNames = new ArrayList<>(); 475 pkg.libraryNames.add("foo10"); 476 477 pkg.usesLibraries = new ArrayList<>(); 478 pkg.usesLibraries.add("foo11"); 479 480 pkg.usesOptionalLibraries = new ArrayList<>(); 481 pkg.usesOptionalLibraries.add("foo12"); 482 483 pkg.usesLibraryFiles = new String[] { "foo13"}; 484 485 pkg.mOriginalPackages = new ArrayList<>(); 486 pkg.mOriginalPackages.add("foo14"); 487 488 pkg.mRealPackage = "foo15"; 489 490 pkg.mAdoptPermissions = new ArrayList<>(); 491 pkg.mAdoptPermissions.add("foo16"); 492 493 pkg.mAppMetaData = new Bundle(); 494 pkg.mVersionName = "foo17"; 495 pkg.mSharedUserId = "foo18"; 496 pkg.mSigningDetails = 497 new PackageParser.SigningDetails( 498 new Signature[] { new Signature(new byte[16]) }, 499 2, 500 new ArraySet<>(), 501 null, 502 null); 503 pkg.mExtras = new Bundle(); 504 pkg.mRestrictedAccountType = "foo19"; 505 pkg.mRequiredAccountType = "foo20"; 506 pkg.mOverlayTarget = "foo21"; 507 pkg.mOverlayPriority = 100; 508 pkg.mUpgradeKeySets = new ArraySet<>(); 509 pkg.mKeySetMapping = new ArrayMap<>(); 510 pkg.cpuAbiOverride = "foo22"; 511 pkg.restrictUpdateHash = new byte[16]; 512 513 pkg.preferredActivityFilters = new ArrayList<>(); 514 pkg.preferredActivityFilters.add(new PackageParser.ActivityIntentInfo( 515 new PackageParser.Activity(dummy, new ActivityInfo()))); 516 517 pkg.configPreferences = new ArrayList<>(); 518 pkg.configPreferences.add(new ConfigurationInfo()); 519 520 pkg.reqFeatures = new ArrayList<>(); 521 pkg.reqFeatures.add(new FeatureInfo()); 522 523 pkg.featureGroups = new ArrayList<>(); 524 pkg.featureGroups.add(new FeatureGroupInfo()); 525 526 pkg.mCompileSdkVersionCodename = "foo23"; 527 pkg.mCompileSdkVersion = 100; 528 pkg.mVersionCodeMajor = 100; 529 } 530 531 private static void assertAllFieldsExist(PackageParser.Package pkg) throws Exception { 532 Field[] fields = PackageParser.Package.class.getDeclaredFields(); 533 534 Set<String> nonSerializedFields = new HashSet<>(); 535 nonSerializedFields.add("mExtras"); 536 nonSerializedFields.add("packageUsageTimeMillis"); 537 538 for (Field f : fields) { 539 final Class<?> fieldType = f.getType(); 540 541 if (nonSerializedFields.contains(f.getName())) { 542 continue; 543 } 544 545 if (List.class.isAssignableFrom(fieldType)) { 546 // Sanity check for list fields: Assume they're non-null and contain precisely 547 // one element. 548 List<?> list = (List<?>) f.get(pkg); 549 assertNotNull("List was null: " + f, list); 550 assertEquals(1, list.size()); 551 } else if (fieldType.getComponentType() != null) { 552 // Sanity check for array fields: Assume they're non-null and contain precisely 553 // one element. 554 Object array = f.get(pkg); 555 assertNotNull(Array.get(array, 0)); 556 } else if (fieldType == String.class) { 557 // String fields: Check that they're set to "foo". 558 String value = (String) f.get(pkg); 559 560 assertTrue("Bad value for field: " + f, value != null && value.startsWith("foo")); 561 } else if (fieldType == int.class) { 562 // int fields: Check that they're set to 100. 563 int value = (int) f.get(pkg); 564 assertEquals("Bad value for field: " + f, 100, value); 565 } else { 566 // All other fields: Check that they're set. 567 Object o = f.get(pkg); 568 assertNotNull("Field was null: " + f, o); 569 } 570 } 571 } 572} 573 574