@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()]); } }
/** * Retrieve all the info about the requested package types. This is used for the package types * that have one or more instances, each with different versions. The resulting array is sorted * according to the PkgInfo's sort order. * * <p>To force the LocalSdk parser to load <b>everything</b>, simply call this method with the * {@link PkgType#PKG_ALL} argument to load all the known package types. * * <p>Note: you can use this with {@link PkgType#PKG_TOOLS}, {@link PkgType#PKG_PLATFORM_TOOLS} * and {@link PkgType#PKG_DOC} but since there can only be one package of these types, it is more * efficient to use {@link #getPkgInfo(PkgType)} to query them. * * @param filters One or more of {@link PkgType#PKG_ADDON}, {@link PkgType#PKG_PLATFORM}, {@link * PkgType#PKG_BUILD_TOOLS}, {@link PkgType#PKG_EXTRA}, {@link PkgType#PKG_SOURCE}, {@link * PkgType#PKG_SYS_IMAGE} * @return A list (possibly empty) of matching installed packages. Never returns null. */ @NonNull public LocalPkgInfo[] getPkgsInfos(@NonNull EnumSet<PkgType> filters) { List<LocalPkgInfo> list = Lists.newArrayList(); for (PkgType filter : filters) { if (filter == PkgType.PKG_TOOLS || filter == PkgType.PKG_PLATFORM_TOOLS || filter == PkgType.PKG_DOC || filter == PkgType.PKG_NDK) { LocalPkgInfo info = getPkgInfo(filter); if (info != null) { list.add(info); } } else { synchronized (mLocalPackages) { Collection<LocalPkgInfo> existing = mLocalPackages.get(filter); assert existing != null; // Multimap returns an empty set if not found if (!existing.isEmpty()) { list.addAll(existing); continue; } File subDir = new File(mSdkRoot, filter.getFolderName()); if (!mVisitedDirs.containsEntry(filter, new LocalDirInfo.MapComparator(subDir))) { switch (filter) { case PKG_BUILD_TOOLS: scanBuildTools(subDir, existing); break; case PKG_PLATFORM: scanPlatforms(subDir, existing); break; case PKG_SYS_IMAGE: scanSysImages(subDir, existing, false); break; case PKG_ADDON_SYS_IMAGE: scanSysImages(subDir, existing, true); break; case PKG_ADDON: scanAddons(subDir, existing); break; case PKG_SAMPLE: scanSamples(subDir, existing); break; case PKG_SOURCE: scanSources(subDir, existing); break; case PKG_EXTRA: scanExtras(subDir, existing); break; case PKG_TOOLS: case PKG_PLATFORM_TOOLS: case PKG_DOC: case PKG_NDK: break; default: throw new IllegalArgumentException("Unsupported pkg type " + filter.toString()); } mVisitedDirs.put(filter, new LocalDirInfo(mFileOp, subDir)); list.addAll(existing); } } } } Collections.sort(list); return list.toArray(new LocalPkgInfo[list.size()]); }