Skip to content

Commit bff4f23

Browse files
committed
download system image, properly detect installed ABIs
1 parent 10f689d commit bff4f23

File tree

2 files changed

+121
-59
lines changed

2 files changed

+121
-59
lines changed

src/processing/mode/android/AVD.java

Lines changed: 68 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,13 @@ public AVD(final String name, final String target) {
9191

9292
private void initializeAbiList() {
9393
if (abiList.size() == 0) {
94-
//The order in this list determines the preference of one abi over the other
95-
abiList.add("armeabi");
96-
abiList.add("x86");
97-
abiList.add("x86_64");
94+
// The order in this list determines the preference of one abi over the other
95+
abiList.add("default/x86");
96+
abiList.add("google_apis/x86");
97+
abiList.add("default/x86_64");
98+
abiList.add("google_apis/x86_64");
99+
abiList.add("default/armeabi-v7a");
100+
abiList.add("google_apis/armeabi-v7a");
98101
}
99102
}
100103

@@ -170,42 +173,67 @@ protected boolean badness() {
170173

171174
protected boolean create(final AndroidSDK sdk) throws IOException {
172175

173-
final String[] list_abi = {
174-
sdk.getAndroidToolPath(),
175-
"list", "targets"
176-
};
177-
178-
ProcessHelper p = new ProcessHelper(list_abi);
179-
try {
180-
final ProcessResult abiListResult = p.execute();
181-
String api = null;
182-
String abi = null;
183-
for (String line : abiListResult) {
184-
String[] m = PApplet.match(line, "API\\slevel:\\s(\\S+)");
185-
if (m != null) {
186-
api = m[1];
187-
}
188-
189-
m = PApplet.match(line, "Tag\\/ABIs\\s:\\sdefault\\/(\\S+)");
190-
if (m != null) {
191-
abi = m[1];
192-
193-
if (api != null && abi != null) {
194-
if (preferredAbi.get(api) == null) {
195-
preferredAbi.put(api, abi);
196-
} else if (abiList.indexOf(preferredAbi.get(api)) < abiList.indexOf(abi)) {
197-
preferredAbi.put(api, abi);
198-
}
199-
api = null;
200-
abi = null;
201-
}
202-
}
203-
}
204-
} catch (InterruptedException e) {}
176+
final String[] list_abi = {
177+
sdk.getAndroidToolPath(),
178+
"list", "targets"
179+
};
180+
181+
ProcessHelper p = new ProcessHelper(list_abi);
182+
try {
183+
final ProcessResult abiListResult = p.execute();
184+
185+
String api = null;
186+
String[] abis = null;
187+
for (String line : abiListResult) {
188+
line = line.trim();
189+
if (line.equals("")) continue;
190+
191+
if (-1 < line.indexOf("API level")) {
192+
api = line.split(":")[1];
193+
api = api.trim();
194+
}
195+
196+
if (-1 < line.indexOf("Tag/ABIs")) {
197+
String str = line.split(":")[1];
198+
abis = str.split(",");
199+
for (int i = 0; i < abis.length; i++) {
200+
abis[i] = abis[i].trim();
201+
}
202+
}
205203

206-
if (preferredAbi.get(AndroidBuild.sdkVersion) == null) {
207-
return false;
208-
}
204+
if (api != null && abis != null) {
205+
for (String abi: abis) {
206+
if (preferredAbi.get(api) == null) {
207+
preferredAbi.put(api, abi);
208+
} else if (abiList.indexOf(preferredAbi.get(api)) < abiList.indexOf(abi)) {
209+
preferredAbi.put(api, abi);
210+
}
211+
}
212+
api = null;
213+
abis = null;
214+
}
215+
216+
// String[] m = PApplet.match(line, "API\\slevel:\\s(\\S+)");
217+
// if (m != null) {
218+
// api = m[1];
219+
// }
220+
//
221+
// m = PApplet.match(line, "Tag\\/ABIs\\s:\\sdefault\\/(\\S+)");
222+
// if (m != null) {
223+
// abi = m[1];
224+
//
225+
// if (api != null && abi != null) {
226+
// if (preferredAbi.get(api) == null) {
227+
// preferredAbi.put(api, abi);
228+
// } else if (abiList.indexOf(preferredAbi.get(api)) < abiList.indexOf(abi)) {
229+
// preferredAbi.put(api, abi);
230+
// }
231+
// api = null;
232+
// abi = null;
233+
// }
234+
// }
235+
}
236+
} catch (InterruptedException e) {}
209237

210238
final String[] params = {
211239
sdk.getAndroidToolPath(),
@@ -216,29 +244,24 @@ protected boolean create(final AndroidSDK sdk) throws IOException {
216244
"-s", DEFAULT_SKIN,
217245
"--abi", preferredAbi.get(AndroidBuild.sdkVersion)
218246
};
219-
247+
220248
// Set the list to null so that exists() will check again
221249
avdList = null;
222250

223251
p = new ProcessHelper(params);
224252
try {
225253
// Passes 'no' to "Do you wish to create a custom hardware profile [no]"
226-
// System.out.println("CREATE AVD STARTING");
227254
final ProcessResult createAvdResult = p.execute("no");
228-
// System.out.println("CREATE AVD HAS COMPLETED");
229255
if (createAvdResult.succeeded()) {
230256
return true;
231257
}
232258
if (createAvdResult.toString().contains("Target id is not valid")) {
233259
// They didn't install the Google APIs
234260
Messages.showWarningTiered("Android Error", AVD_TARGET_PRIMARY, AVD_TARGET_SECONDARY, null);
235-
// throw new IOException("Missing required SDK components");
236261
} else {
237262
// Just generally not working
238-
// Base.showWarning("Android Error", AVD_CREATE_ERROR, null);
239263
Messages.showWarningTiered("Android Error", AVD_CREATE_PRIMARY, AVD_CREATE_SECONDARY, null);
240264
System.out.println(createAvdResult);
241-
// throw new IOException("Error creating the AVD");
242265
}
243266
//System.err.println(createAvdResult);
244267
} catch (final InterruptedException ie) { }
@@ -250,21 +273,16 @@ protected boolean create(final AndroidSDK sdk) throws IOException {
250273
static public boolean ensureProperAVD(final AndroidSDK sdk) {
251274
try {
252275
if (defaultAVD.exists(sdk)) {
253-
// System.out.println("the avd exists");
254276
return true;
255277
}
256-
// if (badList.contains(defaultAVD)) {
257278
if (defaultAVD.badness()) {
258-
// Base.showWarning("Android Error", AVD_CANNOT_LOAD, null);
259279
Messages.showWarningTiered("Android Error", AVD_LOAD_PRIMARY, AVD_LOAD_SECONDARY, null);
260280
return false;
261281
}
262282
if (defaultAVD.create(sdk)) {
263-
// System.out.println("the avd was created");
264283
return true;
265284
}
266285
} catch (final Exception e) {
267-
// Base.showWarning("Android Error", AVD_CREATE_ERROR, e);
268286
Messages.showWarningTiered("Android Error", AVD_CREATE_PRIMARY,
269287
String.format(AVD_CREATE_SECONDARY,
270288
AndroidBuild.sdkVersion), null);

src/processing/mode/android/SDKDownloader.java

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,21 @@
5151
import java.util.zip.ZipEntry;
5252
import java.util.zip.ZipFile;
5353

54+
// http://dl-ssl.google.com/android/repository/sys-img/android/sys-img.xml
55+
// http://dl-ssl.google.com/android/repository/sys-img/android-wear/sys-img.xml
56+
// http://dl-ssl.google.com/android/repository/sys-img/android-wear/android-wear-sys-img.xml
57+
5458
@SuppressWarnings("serial")
5559
public class SDKDownloader extends JDialog implements PropertyChangeListener {
5660
private static final String PLATFORM_API_LEVEL = "23";
5761

5862
private static final String URL_REPOSITORY = "https://dl-ssl.google.com/android/repository/repository-11.xml";
5963
private static final String URL_REPOSITORY_FOLDER = "http://dl-ssl.google.com/android/repository/";
6064
private static final String URL_USB_DRIVER = "https://dl-ssl.google.com//android/repository/latest_usb_driver_windows.zip";
65+
private static final String URL_SYS_IMAGES = "https://dl-ssl.google.com/android/repository/sys-img/android/sys-img.xml";
66+
private static final String URL_SYS_IMAGES_FOLDER = "http://dl-ssl.google.com/android/repository/sys-img/android/";
67+
private static final String SYSTEM_IMAGE = "Intel x86 Atom System Image";
68+
// private static final String URL_SYS_IMAGES_WEAR = "https://dl-ssl.google.com/android/repository/sys-img/android-wear/sys-img.xml";
6169

6270
private static final String PROPERTY_CHANGE_EVENT_TOTAL = "total";
6371
private static final String PROPERTY_CHANGE_EVENT_DOWNLOADED = "downloaded";
@@ -77,8 +85,8 @@ public class SDKDownloader extends JDialog implements PropertyChangeListener {
7785

7886
class SDKUrlHolder {
7987
public String platformVersion;
80-
public String platformToolsUrl, buildToolsUrl, platformUrl, toolsUrl;
81-
public String platformToolsFilename, buildToolsFilename, platformFilename, toolsFilename;
88+
public String platformToolsUrl, buildToolsUrl, platformUrl, sysImgUrl, sysImgTag, toolsUrl;
89+
public String platformToolsFilename, buildToolsFilename, platformFilename, sysImgFilename, toolsFilename;
8290
public int totalSize = 0;
8391
}
8492

@@ -104,6 +112,8 @@ protected Object doInBackground() throws Exception {
104112
if (!platformsFolder.exists()) platformsFolder.mkdir();
105113
File buildToolsFolder = new File(sdkFolder, "build-tools");
106114
if (!buildToolsFolder.exists()) buildToolsFolder.mkdir();
115+
File sysImgFolder = new File(sdkFolder, "system-images");
116+
if (!sysImgFolder.exists()) sysImgFolder.mkdir();
107117
File extrasFolder = new File(sdkFolder, "extras");
108118
if(!extrasFolder.exists()) extrasFolder.mkdir();
109119

@@ -112,7 +122,7 @@ protected Object doInBackground() throws Exception {
112122
if (!tempFolder.exists()) tempFolder.mkdir();
113123

114124
try {
115-
SDKUrlHolder downloadUrls = getDownloadUrls(URL_REPOSITORY, Platform.getName());
125+
SDKUrlHolder downloadUrls = getDownloadUrls(URL_REPOSITORY, URL_SYS_IMAGES, Platform.getName());
116126
firePropertyChange(PROPERTY_CHANGE_EVENT_TOTAL, 0, downloadUrls.totalSize);
117127
totalSize = downloadUrls.totalSize;
118128

@@ -132,13 +142,21 @@ protected Object doInBackground() throws Exception {
132142
File downloadedPlatform = new File(tempFolder, downloadUrls.platformFilename);
133143
downloadAndUnpack(downloadUrls.platformUrl, downloadedPlatform, platformsFolder, false);
134144

145+
// system images
146+
File downloadedSysImg = new File(tempFolder, downloadUrls.sysImgFilename);
147+
File tmp = new File(sysImgFolder, "android-" + PLATFORM_API_LEVEL);
148+
if (!tmp.exists()) tmp.mkdir();
149+
File sysImgFinalFolder = new File(tmp, downloadUrls.sysImgTag);
150+
if (!sysImgFinalFolder.exists()) sysImgFinalFolder.mkdir();
151+
downloadAndUnpack(downloadUrls.sysImgUrl, downloadedSysImg, sysImgFinalFolder, false);
152+
135153
// usb driver
136154
if (Platform.isWindows()) {
137155
File usbDriverFolder = new File(extrasFolder, "google");
138156
File downloadedFolder = new File(tempFolder, "latest_usb_driver_windows.zip");
139157
downloadAndUnpack(URL_USB_DRIVER, downloadedFolder, usbDriverFolder, false);
140158
}
141-
159+
142160
if (Platform.isLinux() || Platform.isMacOS()) {
143161
Runtime.getRuntime().exec("chmod -R 755 " + sdkFolder.getAbsolutePath());
144162
}
@@ -215,7 +233,9 @@ private void downloadAndUnpack(String urlString, File saveTo,
215233
extractFolder(saveTo, unpackTo, setExec);
216234
}
217235

218-
private SDKUrlHolder getDownloadUrls(String repositoryUrl, String requiredHostOs) throws ParserConfigurationException, IOException, SAXException {
236+
private SDKUrlHolder getDownloadUrls(String repositoryUrl,
237+
String repositorySysImgUrlString, String requiredHostOs)
238+
throws ParserConfigurationException, IOException, SAXException {
219239
SDKUrlHolder urlHolder = new SDKUrlHolder();
220240

221241
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
@@ -225,7 +245,7 @@ private SDKUrlHolder getDownloadUrls(String repositoryUrl, String requiredHostOs
225245
// platform
226246
String platformDescription = "Android SDK Platform " + PLATFORM_API_LEVEL;
227247
NodeList platformList = doc.getElementsByTagName("sdk:platform");
228-
for(int i = 0; i < platformList.getLength(); i++) {
248+
for (int i = 0; i < platformList.getLength(); i++) {
229249
Node platform = platformList.item(i);
230250
NodeList version = ((Element) platform).getElementsByTagName("sdk:version");
231251
NodeList level = ((Element) platform).getElementsByTagName("sdk:api-level");
@@ -248,7 +268,7 @@ private SDKUrlHolder getDownloadUrls(String repositoryUrl, String requiredHostOs
248268
Node platformToolItem = doc.getElementsByTagName("sdk:platform-tool").item(0);
249269
Node archiveListItem = ((Element) platformToolItem).getElementsByTagName("sdk:archives").item(0);
250270
NodeList archiveList = ((Element) archiveListItem).getElementsByTagName("sdk:archive");
251-
for(int i = 0; i < archiveList.getLength(); i++) {
271+
for (int i = 0; i < archiveList.getLength(); i++) {
252272
Node archive = archiveList.item(i);
253273
String hostOs = ((Element) archive).getElementsByTagName("sdk:host-os").item(0).getTextContent();
254274
if (hostOs.equals(requiredHostOs)) {
@@ -263,7 +283,7 @@ private SDKUrlHolder getDownloadUrls(String repositoryUrl, String requiredHostOs
263283
Node buildToolsItem = doc.getElementsByTagName("sdk:build-tool").item(doc.getElementsByTagName("sdk:build-tool").getLength()-1);
264284
archiveListItem = ((Element) buildToolsItem).getElementsByTagName("sdk:archives").item(0);
265285
archiveList = ((Element) archiveListItem).getElementsByTagName("sdk:archive");
266-
for(int i = 0; i < archiveList.getLength(); i++) {
286+
for (int i = 0; i < archiveList.getLength(); i++) {
267287
Node archive = archiveList.item(i);
268288
String hostOs = ((Element) archive).getElementsByTagName("sdk:host-os").item(0).getTextContent();
269289
if (hostOs.equals(requiredHostOs)) {
@@ -278,7 +298,7 @@ private SDKUrlHolder getDownloadUrls(String repositoryUrl, String requiredHostOs
278298
Node toolsItem = doc.getElementsByTagName("sdk:tool").item(0);
279299
archiveListItem = ((Element) toolsItem).getElementsByTagName("sdk:archives").item(0);
280300
archiveList = ((Element) archiveListItem).getElementsByTagName("sdk:archive");
281-
for(int i = 0; i < archiveList.getLength(); i++) {
301+
for (int i = 0; i < archiveList.getLength(); i++) {
282302
Node archive = archiveList.item(i);
283303
String hostOs = ((Element) archive).getElementsByTagName("sdk:host-os").item(0).getTextContent();
284304
if (hostOs.equals(requiredHostOs)) {
@@ -288,6 +308,30 @@ private SDKUrlHolder getDownloadUrls(String repositoryUrl, String requiredHostOs
288308
break;
289309
}
290310
}
311+
312+
// system image
313+
Document docSysImg = db.parse(new URL(repositorySysImgUrlString).openStream());
314+
NodeList sysImgList = docSysImg.getElementsByTagName("sdk:system-image");
315+
for (int i = 0; i < sysImgList.getLength(); i++) {
316+
Node img = sysImgList.item(i);
317+
NodeList level = ((Element) img).getElementsByTagName("sdk:api-level");
318+
NodeList desc = ((Element) img).getElementsByTagName("sdk:description");
319+
NodeList codename = ((Element) img).getElementsByTagName("sdk:codename");
320+
// Only considering nodes without a codename, which correspond to the platform
321+
// pre-releases.
322+
if (level.item(0).getTextContent().equals(PLATFORM_API_LEVEL) &&
323+
desc.item(0).getTextContent().equals(SYSTEM_IMAGE) &&
324+
codename.item(0) == null) {
325+
NodeList tag = ((Element) img).getElementsByTagName("sdk:tag-id");
326+
urlHolder.sysImgTag = tag.item(0).getTextContent();
327+
archiveListItem = ((Element) img).getElementsByTagName("sdk:archives").item(0);
328+
Node archiveItem = ((Element) archiveListItem).getElementsByTagName("sdk:archive").item(0);
329+
urlHolder.sysImgFilename = ((Element) archiveItem).getElementsByTagName("sdk:url").item(0).getTextContent();
330+
urlHolder.sysImgUrl = URL_SYS_IMAGES_FOLDER + urlHolder.sysImgFilename;
331+
urlHolder.totalSize += Integer.parseInt(((Element) archiveItem).getElementsByTagName("sdk:size").item(0).getTextContent());
332+
break;
333+
}
334+
}
291335

292336
return urlHolder;
293337
}

0 commit comments

Comments
 (0)