@NonNull public IAndroidTarget[] getMissingTargets() { synchronized (mLocalPackages) { if (mCachedMissingTargets == null) { Map<MissingTarget, MissingTarget> result = Maps.newHashMap(); Set<ISystemImage> seen = Sets.newHashSet(); for (IAndroidTarget target : getTargets()) { Collections.addAll(seen, target.getSystemImages()); } for (LocalPkgInfo local : getPkgsInfos(PkgType.PKG_ADDON_SYS_IMAGE)) { LocalAddonSysImgPkgInfo info = (LocalAddonSysImgPkgInfo) local; ISystemImage image = info.getSystemImage(); if (!seen.contains(image)) { addOrphanedSystemImage(image, info.getDesc(), result); } } for (LocalPkgInfo local : getPkgsInfos(PkgType.PKG_SYS_IMAGE)) { LocalSysImgPkgInfo info = (LocalSysImgPkgInfo) local; ISystemImage image = info.getSystemImage(); if (!seen.contains(image)) { addOrphanedSystemImage(image, info.getDesc(), result); } } mCachedMissingTargets = result.keySet(); } return mCachedMissingTargets.toArray(new IAndroidTarget[mCachedMissingTargets.size()]); } }
private void scanSysImages( File collectionDir, Collection<LocalPkgInfo> outCollection, boolean scanAddons) { List<File> propFiles = Lists.newArrayList(); PkgType type = scanAddons ? PkgType.PKG_ADDON_SYS_IMAGE : PkgType.PKG_SYS_IMAGE; // Create a list of folders that contains a source.properties file matching these patterns: // sys-img/target/tag/abi // sys-img/target/abis // sys-img/add-on-target/abi // sys-img/target/add-on/abi for (File platformDir : mFileOp.listFiles(collectionDir)) { if (!shouldVisitDir(type, platformDir)) { continue; } for (File dir1 : mFileOp.listFiles(platformDir)) { // dir1 might be either a tag or an abi folder. if (!shouldVisitDir(type, dir1)) { continue; } File prop1 = new File(dir1, SdkConstants.FN_SOURCE_PROP); if (mFileOp.isFile(prop1)) { // dir1 was a legacy abi folder. if (!propFiles.contains(prop1)) { propFiles.add(prop1); } } else { File[] dir1Files = mFileOp.listFiles(dir1); for (File dir2 : dir1Files) { // dir2 should be an abi folder in a tag folder. if (!shouldVisitDir(type, dir2)) { continue; } File prop2 = new File(dir2, SdkConstants.FN_SOURCE_PROP); if (mFileOp.isFile(prop2)) { if (!propFiles.contains(prop2)) { propFiles.add(prop2); } } } } } } for (File propFile : propFiles) { Properties props = parseProperties(propFile); MajorRevision rev = PackageParserUtils.getPropertyMajor(props, PkgProps.PKG_REVISION); if (rev == null) { continue; // skip, no revision } try { AndroidVersion vers = new AndroidVersion(props); IdDisplay tag = LocalSysImgPkgInfo.extractTagFromProps(props); String vendorId = props.getProperty(PkgProps.ADDON_VENDOR_ID, null); File abiDir = propFile.getParentFile(); if (vendorId == null && !scanAddons) { LocalSysImgPkgInfo pkgInfo = new LocalSysImgPkgInfo(this, abiDir, props, vers, tag, abiDir.getName(), rev); outCollection.add(pkgInfo); } else if (vendorId != null && scanAddons) { String vendorDisp = props.getProperty(PkgProps.ADDON_VENDOR_DISPLAY, vendorId); IdDisplay vendor = new IdDisplay(vendorId, vendorDisp); LocalAddonSysImgPkgInfo pkgInfo = new LocalAddonSysImgPkgInfo( this, abiDir, props, vers, vendor, tag, abiDir.getName(), rev); outCollection.add(pkgInfo); } } catch (AndroidVersionException e) { continue; // skip invalid or missing android version. } } }