/** * Parses the given file as properties file if it exists. Returns null if the file does not exist, * cannot be parsed or has no properties. */ private Properties parseProperties(File propsFile) { InputStream fis = null; try { if (mFileOp.exists(propsFile)) { fis = mFileOp.newFileInputStream(propsFile); Properties props = new Properties(); props.load(fis); // To be valid, there must be at least one property in it. if (!props.isEmpty()) { return props; } } } catch (IOException e) { // Ignore } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { } } } return null; }
private void scanPlatforms(File collectionDir, Collection<LocalPkgInfo> outCollection) { for (File platformDir : mFileOp.listFiles(collectionDir)) { if (!shouldVisitDir(PkgType.PKG_PLATFORM, platformDir)) { continue; } Properties props = parseProperties(new File(platformDir, SdkConstants.FN_SOURCE_PROP)); MajorRevision rev = PackageParserUtils.getPropertyMajor(props, PkgProps.PKG_REVISION); if (rev == null) { continue; // skip, no revision } FullRevision minToolsRev = PackageParserUtils.getPropertyFull(props, PkgProps.MIN_TOOLS_REV); if (minToolsRev == null) { minToolsRev = FullRevision.NOT_SPECIFIED; } try { AndroidVersion vers = new AndroidVersion(props); LocalPlatformPkgInfo pkgInfo = new LocalPlatformPkgInfo(this, platformDir, props, vers, rev, minToolsRev); outCollection.add(pkgInfo); } catch (AndroidVersionException e) { continue; // skip invalid or missing android version. } } }
private void scanAddons(File collectionDir, Collection<LocalPkgInfo> outCollection) { for (File addonDir : mFileOp.listFiles(collectionDir)) { if (!shouldVisitDir(PkgType.PKG_ADDON, addonDir)) { continue; } Properties props = parseProperties(new File(addonDir, SdkConstants.FN_SOURCE_PROP)); MajorRevision rev = PackageParserUtils.getPropertyMajor(props, PkgProps.PKG_REVISION); if (rev == null) { continue; // skip, no revision } try { AndroidVersion vers = new AndroidVersion(props); // Starting with addon-4.xsd, we have vendor-id and name-id available // in the add-on source properties so we'll use that directly. String nameId = props.getProperty(PkgProps.ADDON_NAME_ID); String nameDisp = props.getProperty(PkgProps.ADDON_NAME_DISPLAY); String vendorId = props.getProperty(PkgProps.ADDON_VENDOR_ID); String vendorDisp = props.getProperty(PkgProps.ADDON_VENDOR_DISPLAY); if (nameId == null) { // Support earlier add-ons that only had a name display attribute nameDisp = props.getProperty(PkgProps.ADDON_NAME, "Unknown"); nameId = LocalAddonPkgInfo.sanitizeDisplayToNameId(nameDisp); } if (nameId != null && nameDisp == null) { nameDisp = LocalExtraPkgInfo.getPrettyName(null, nameId); } if (vendorId != null && vendorDisp == null) { vendorDisp = LocalExtraPkgInfo.getPrettyName(null, nameId); } if (vendorId == null) { // Support earlier add-ons that only had a vendor display attribute vendorDisp = props.getProperty(PkgProps.ADDON_VENDOR, "Unknown"); vendorId = LocalAddonPkgInfo.sanitizeDisplayToNameId(vendorDisp); } LocalAddonPkgInfo pkgInfo = new LocalAddonPkgInfo( this, addonDir, props, vers, rev, new IdDisplay(vendorId, vendorDisp), new IdDisplay(nameId, nameDisp)); outCollection.add(pkgInfo); } catch (AndroidVersionException e) { continue; // skip invalid or missing android version. } } }
private void scanExtras(File collectionDir, Collection<LocalPkgInfo> outCollection) { for (File vendorDir : mFileOp.listFiles(collectionDir)) { if (!shouldVisitDir(PkgType.PKG_EXTRA, vendorDir)) { continue; } for (File extraDir : mFileOp.listFiles(vendorDir)) { if (!shouldVisitDir(PkgType.PKG_EXTRA, extraDir)) { continue; } Properties props = parseProperties(new File(extraDir, SdkConstants.FN_SOURCE_PROP)); NoPreviewRevision rev = PackageParserUtils.getPropertyNoPreview(props, PkgProps.PKG_REVISION); if (rev == null) { continue; // skip, no revision } String oldPaths = PackageParserUtils.getProperty(props, PkgProps.EXTRA_OLD_PATHS, null); String vendorId = vendorDir.getName(); String vendorDisp = props.getProperty(PkgProps.EXTRA_VENDOR_DISPLAY); if (vendorDisp == null || vendorDisp.isEmpty()) { vendorDisp = vendorId; } String displayName = props.getProperty(PkgProps.EXTRA_NAME_DISPLAY, null); LocalExtraPkgInfo pkgInfo = new LocalExtraPkgInfo( this, extraDir, props, new IdDisplay(vendorId, vendorDisp), extraDir.getName(), displayName, PkgDescExtra.convertOldPaths(oldPaths), rev); outCollection.add(pkgInfo); } } }
/** * Helper used by scanXyz methods below to check whether a directory should be visited. It can be * skipped if it's not a directory or if it's already marked as visited in mVisitedDirs for the * given package type -- in which case the directory is added to the visited map. * * @param pkgType The package type being scanned. * @param directory The file or directory to check. * @return False if directory can/should be skipped. True if directory should be visited, in which * case it's registered in mVisitedDirs. */ private boolean shouldVisitDir(@NonNull PkgType pkgType, @NonNull File directory) { if (!mFileOp.isDirectory(directory)) { return false; } synchronized (mLocalPackages) { if (mVisitedDirs.containsEntry(pkgType, new LocalDirInfo.MapComparator(directory))) { return false; } mVisitedDirs.put(pkgType, new LocalDirInfo(mFileOp, directory)); } return true; }
private void scanBuildTools(File collectionDir, Collection<LocalPkgInfo> outCollection) { // The build-tool root folder contains a list of per-revision folders. for (File buildToolDir : mFileOp.listFiles(collectionDir)) { if (!shouldVisitDir(PkgType.PKG_BUILD_TOOLS, buildToolDir)) { continue; } Properties props = parseProperties(new File(buildToolDir, SdkConstants.FN_SOURCE_PROP)); FullRevision rev = PackageParserUtils.getPropertyFull(props, PkgProps.PKG_REVISION); if (rev == null) { continue; // skip, no revision } BuildToolInfo btInfo = new BuildToolInfo(rev, buildToolDir); LocalBuildToolPkgInfo pkgInfo = new LocalBuildToolPkgInfo(this, buildToolDir, props, rev, btInfo); outCollection.add(pkgInfo); } }
/** Try to find a tools package at the given location. Returns null if not found. */ private LocalToolPkgInfo scanTools(File toolFolder) { // Can we find some properties? Properties props = parseProperties(new File(toolFolder, SdkConstants.FN_SOURCE_PROP)); FullRevision rev = PackageParserUtils.getPropertyFull(props, PkgProps.PKG_REVISION); if (rev == null) { return null; } FullRevision minPlatToolsRev = PackageParserUtils.getPropertyFull(props, PkgProps.MIN_PLATFORM_TOOLS_REV); if (minPlatToolsRev == null) { minPlatToolsRev = FullRevision.NOT_SPECIFIED; } LocalToolPkgInfo info = new LocalToolPkgInfo(this, toolFolder, props, rev, minPlatToolsRev); // We're not going to check that all tools are present. At the very least // we should expect to find android and an emulator adapted to the current OS. boolean hasEmulator = false; boolean hasAndroid = false; String android1 = SdkConstants.androidCmdName().replace(".bat", ".exe"); String android2 = android1.indexOf('.') == -1 ? null : android1.replace(".exe", ".bat"); File[] files = mFileOp.listFiles(toolFolder); for (File file : files) { String name = file.getName(); if (SdkConstants.FN_EMULATOR.equals(name)) { hasEmulator = true; } if (android1.equals(name) || (android2 != null && android2.equals(name))) { hasAndroid = true; } } if (!hasAndroid) { info.appendLoadError("Missing %1$s", SdkConstants.androidCmdName()); } if (!hasEmulator) { info.appendLoadError("Missing %1$s", SdkConstants.FN_EMULATOR); } return info; }
/** Try to find a docs package at the given location. Returns null if not found. */ private LocalDocPkgInfo scanDoc(File docFolder) { // Can we find some properties? Properties props = parseProperties(new File(docFolder, SdkConstants.FN_SOURCE_PROP)); MajorRevision rev = PackageParserUtils.getPropertyMajor(props, PkgProps.PKG_REVISION); if (rev == null) { return null; } try { AndroidVersion vers = new AndroidVersion(props); LocalDocPkgInfo info = new LocalDocPkgInfo(this, docFolder, props, vers, rev); // To start with, a doc folder should have an "index.html" to be acceptable. // We don't actually check the content of the file. if (!mFileOp.isFile(new File(docFolder, "index.html"))) { info.appendLoadError("Missing index.html"); } return info; } catch (AndroidVersionException e) { return null; // skip invalid or missing android version. } }
private void scanSources(File collectionDir, Collection<LocalPkgInfo> outCollection) { // The build-tool root folder contains a list of per-revision folders. for (File platformDir : mFileOp.listFiles(collectionDir)) { if (!shouldVisitDir(PkgType.PKG_SOURCE, platformDir)) { continue; } Properties props = parseProperties(new File(platformDir, SdkConstants.FN_SOURCE_PROP)); MajorRevision rev = PackageParserUtils.getPropertyMajor(props, PkgProps.PKG_REVISION); if (rev == null) { continue; // skip, no revision } try { AndroidVersion vers = new AndroidVersion(props); LocalSourcePkgInfo pkgInfo = new LocalSourcePkgInfo(this, platformDir, props, vers, rev); outCollection.add(pkgInfo); } catch (AndroidVersionException e) { continue; // skip invalid or missing android version. } } }
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. } } }