* @param abiDir The SDK/system-images/android-N/tag/abi folder
* @param props The properties located in {@code abiDir} or null if not found.
* @return A new {@link BrokenPackage} that represents this installed package.
*/
public static Package createBroken(File abiDir, Properties props) {
AndroidVersion version = null;
String abiType = abiDir.getName();
String error = null;
IdDisplay tag = null;
// Try to load the android version, tag & ABI from the sources.props.
// If we don't find them, it would explain why this package is broken.
if (props == null) {
error = String.format("Missing file %1$s", SdkConstants.FN_SOURCE_PROP);
} else {
try {
version = new AndroidVersion(props);
tag = LocalSysImgPkgInfo.extractTagFromProps(props);
String abi = props.getProperty(PkgProps.SYS_IMG_ABI);
if (abi != null) {
abiType = abi;
} else {
error = String.format("Invalid file %1$s: Missing property %2$s",
SdkConstants.FN_SOURCE_PROP,
PkgProps.SYS_IMG_ABI);
}
} catch (AndroidVersionException e) {
error = String.format("Invalid file %1$s: %2$s",
SdkConstants.FN_SOURCE_PROP,
e.getMessage());
}
}
try {
// Try to parse the first number out of the platform folder name.
// Also try to parse the tag if not known yet.
// Folder structure should be:
// Tools < 22.6 / API < 20: sdk/system-images/android-N/abi/
// Tools >=22.6 / API >=20: sdk/system-images/android-N/tag/abi/
String[] segments = abiDir.getAbsolutePath().split(Pattern.quote(File.separator));
int len = segments.length;
for (int i = len - 2; version == null && i >= 0; i--) {
if (SdkConstants.FD_SYSTEM_IMAGES.equals(segments[i])) {
if (version == null) {
String platform = segments[i+1];
try {
platform = platform.replaceAll("[^0-9]+", " ").trim(); //$NON-NLS-1$ //$NON-NLS-2$
int pos = platform.indexOf(' ');
if (pos >= 0) {
platform = platform.substring(0, pos);
}
int apiLevel = Integer.parseInt(platform);
version = new AndroidVersion(apiLevel, null /*codename*/);
} catch (Exception ignore) {}
}
if (tag == null && i+2 < len) {
// If we failed to find a tag id in the properties, check whether
// we can guess one from the system image folder path. It should
// match the limited tag id character set and not be one of the
// known ABIs.
String abiOrTag = segments[i+2].trim();
if (abiOrTag.matches("[A-Za-z0-9_-]+")) {
if (Abi.getEnum(abiOrTag) == null) {
tag = new IdDisplay(abiOrTag,
LocalSysImgPkgInfo.tagIdToDisplay(abiOrTag));
}
}
}
}
}
} catch (Exception ignore) {}
if (tag == null) {
// No tag? Use the default.
tag = SystemImage.DEFAULT_TAG;
}
assert tag != null;
StringBuilder sb = new StringBuilder(
String.format("Broken %1$s System Image", getAbiDisplayNameInternal(abiType)));
if (version != null) {
sb.append(String.format(", API %1$s", version.getApiString()));
}
String shortDesc = sb.toString();
if (error != null) {
sb.append('\n').append(error);
}
String longDesc = sb.toString();
IPkgDesc desc = PkgDesc.newSysImg(
version != null ? version : new AndroidVersion(0, null),
tag,
abiType,
new MajorRevision(MajorRevision.MISSING_MAJOR_REV));
return new BrokenPackage(props, shortDesc, longDesc,
IMinApiLevelDependency.MIN_API_LEVEL_NOT_SPECIFIED,
version==null ? IExactApiLevelDependency.API_LEVEL_INVALID : version.getApiLevel(),
abiDir.getAbsolutePath(),
desc);
}