forked from community/device-mgt-plugins
Merge branch 'master' of https://github.com/wso2/carbon-device-mgt-plugins into devicetype-3.1.0
commit
dc3420cadb
@ -0,0 +1,55 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
~
|
||||||
|
~ WSO2 Inc. licenses this file to you under the Apache License,
|
||||||
|
~ Version 2.0 (the "License"); you may not use this file except
|
||||||
|
~ in compliance with the License.
|
||||||
|
~ You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing,
|
||||||
|
~ software distributed under the License is distributed on an
|
||||||
|
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
~ KIND, either express or implied. See the License for the
|
||||||
|
~ specific language governing permissions and limitations
|
||||||
|
~ under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>android-plugin</artifactId>
|
||||||
|
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
|
||||||
|
<version>4.0.5-SNAPSHOT</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>org.wso2.carbon.device.mgt.mobile.android.emulator</artifactId>
|
||||||
|
<name>AndroidTryIt Emulator</name>
|
||||||
|
<description>Android Virtual Device</description>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>EmulatorJava</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<!-- Build an executable JAR -->
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<addClasspath>true</addClasspath>
|
||||||
|
<classpathPrefix>lib/</classpathPrefix>
|
||||||
|
<mainClass>org.carbon.android.emulator.TryIt</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||||
|
* Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.carbon.android.emulator;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class has the constant strings used and the system properties.
|
||||||
|
*/
|
||||||
|
class Constants {
|
||||||
|
static final String OS_NAME_PROPERTY = "os.name";
|
||||||
|
static final String USER_HOME_PROPERTY = "user.home";
|
||||||
|
static final String USER_DIRECTORY_PROPERTY = "user.dir";
|
||||||
|
static final String MAC_OS = "macosx";
|
||||||
|
static final String MAC = "mac";
|
||||||
|
static final String WINDOWS_OS = "windows";
|
||||||
|
static final String WINDOWS_EXTENSION_EXE = ".exe";
|
||||||
|
static final String WINDOWS_EXTENSION_BAT = ".bat";
|
||||||
|
static final String MAC_HAXM_EXTENSION = ".sh";
|
||||||
|
static final String MAC_DARWIN = "darwin";
|
||||||
|
// System properties
|
||||||
|
static final String SDK_TOOLS_URL = "sdk.tools.url";
|
||||||
|
static final String PLATFORM_TOOLS_URL = "platform.tools.url";
|
||||||
|
static final String BUILD_TOOL_URL = "build.tools.url";
|
||||||
|
static final String PLATFORM_URL = "platform.url";
|
||||||
|
static final String SYSTEM_IMAGE_URL = "sys.img.url";
|
||||||
|
static final String HAXM_URL = "haxm.url";
|
||||||
|
static final String DOWNLOADED_BUILD_TOOL_NAME = "downloaded.build.tool.name";
|
||||||
|
static final String BUILD_TOOLS_VERSION = "build.tool.version";
|
||||||
|
static final String DOWNLOADED_PLATFORM_NAME = "downloaded.platform.name";
|
||||||
|
static final String TARGET_VERSION = "target.version";
|
||||||
|
static final String OS_TARGET = "os.target";
|
||||||
|
// WSO2 AVD specific variables
|
||||||
|
static final String WSO2_AVD_NAME = "WSO2_AVD";
|
||||||
|
static final String APK_LOCATION = File.separator + "resources" + File.separator + "android-agent.apk";
|
||||||
|
static final String WSO2_CONFIG_LOCATION = File.separator + "resources" + File.separator + "config.ini";
|
||||||
|
}
|
@ -0,0 +1,886 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||||
|
* Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.carbon.android.emulator;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.Scanner;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class creates an Android TryIt Emulator to be used as virtual device to connect to WSO2 IOT Cloud
|
||||||
|
* or Product-iot.
|
||||||
|
*/
|
||||||
|
public class TryIt {
|
||||||
|
private String osSuffix;
|
||||||
|
private String androidSdkHome;
|
||||||
|
private String userHome;
|
||||||
|
private String workingDirectory;
|
||||||
|
private String adbLocation; // location of executable file abd
|
||||||
|
private String emulatorLocation; // location of executable file emulator
|
||||||
|
private File sdkConfigFile; // file in which SDK location is written
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gets the system specific variables.
|
||||||
|
*/
|
||||||
|
private TryIt() {
|
||||||
|
osSuffix = System.getProperty(Constants.OS_NAME_PROPERTY);
|
||||||
|
if (osSuffix == null) {
|
||||||
|
sysPropertyError(Constants.OS_NAME_PROPERTY, "OS Name");
|
||||||
|
} else {
|
||||||
|
osSuffix = osSuffix.toLowerCase();
|
||||||
|
}
|
||||||
|
userHome = System.getProperty(Constants.USER_HOME_PROPERTY);
|
||||||
|
if (userHome == null) {
|
||||||
|
sysPropertyError(Constants.USER_HOME_PROPERTY, "Home Directory");
|
||||||
|
}
|
||||||
|
workingDirectory = System.getProperty(Constants.USER_DIRECTORY_PROPERTY);
|
||||||
|
if (workingDirectory == null) {
|
||||||
|
sysPropertyError(Constants.USER_DIRECTORY_PROPERTY, "Current Working Directory");
|
||||||
|
}
|
||||||
|
if (osSuffix.contains(Constants.WINDOWS_OS)) {
|
||||||
|
osSuffix = Constants.WINDOWS_OS;
|
||||||
|
}
|
||||||
|
if (osSuffix.contains(Constants.MAC)) {
|
||||||
|
osSuffix = Constants.MAC_OS;
|
||||||
|
}
|
||||||
|
System.out.println("Detected OS " + osSuffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method creates an android virtual device.
|
||||||
|
*
|
||||||
|
* @param args commandline arguments.
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
TryIt tryIt = new TryIt();
|
||||||
|
tryIt.setAndroidSDK();
|
||||||
|
tryIt.checkBuildTools();
|
||||||
|
tryIt.startAVD();
|
||||||
|
tryIt.checkEmulatorBoot();
|
||||||
|
String[] agents = tryIt.checkForAgent();
|
||||||
|
System.out.println("Starting Agent ...");
|
||||||
|
tryIt.startPackage(agents);
|
||||||
|
ProcessBuilder startShellProcessBuilder = new ProcessBuilder(tryIt.adbLocation, "shell");
|
||||||
|
try {
|
||||||
|
startShellProcessBuilder.redirectInput(ProcessBuilder.Redirect.INHERIT);
|
||||||
|
startShellProcessBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
|
||||||
|
Process startShell = startShellProcessBuilder.start();
|
||||||
|
System.out.println("Connected to device shell");
|
||||||
|
startShell.waitFor();
|
||||||
|
} catch (IOException e) {
|
||||||
|
tryIt.handleException("Unable to start the shell", e);
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
System.out.println("\nGood Bye!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method downloads the artifacts from remote url.
|
||||||
|
*
|
||||||
|
* @param remotePath - remote url
|
||||||
|
* @param localPath - local path to download
|
||||||
|
*/
|
||||||
|
private void downloadArtifacts(String remotePath, String localPath) {
|
||||||
|
BufferedInputStream in = null;
|
||||||
|
FileOutputStream out = null;
|
||||||
|
long startingTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
try {
|
||||||
|
URL url = new URL(remotePath);
|
||||||
|
URLConnection conn = url.openConnection();
|
||||||
|
int size = conn.getContentLength();
|
||||||
|
in = new BufferedInputStream(url.openStream());
|
||||||
|
out = new FileOutputStream(localPath);
|
||||||
|
byte data[] = new byte[1024];
|
||||||
|
int count;
|
||||||
|
double sumCount = 0.0;
|
||||||
|
|
||||||
|
while ((count = in.read(data, 0, 1024)) != -1) {
|
||||||
|
out.write(data, 0, count);
|
||||||
|
sumCount += count;
|
||||||
|
if ((size > 0 && (System.currentTimeMillis() - startingTime > 5000))
|
||||||
|
|| (sumCount / size * 100.0) == 100) {
|
||||||
|
System.out.println("Downloading: "
|
||||||
|
+ new DecimalFormat("#.##").format((sumCount / size * 100.0)) + " %");
|
||||||
|
startingTime = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
System.out.println("Error in download URL of " + localPath);
|
||||||
|
System.out.println("URL provided " + remotePath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (!new File(localPath).delete()) {
|
||||||
|
System.out.println("Delete " + localPath + " and try again");
|
||||||
|
}
|
||||||
|
handleException("Downloading " + localPath + " failed.", e);
|
||||||
|
} finally {
|
||||||
|
if (in != null)
|
||||||
|
try {
|
||||||
|
in.close();
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
if (out != null)
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called when then is an error in getting system properties
|
||||||
|
*
|
||||||
|
* @param property -property type
|
||||||
|
* @param hint - property name
|
||||||
|
*/
|
||||||
|
private void sysPropertyError(String property, String hint) {
|
||||||
|
System.out.println("Unable to get the " + property + " property of your system (" + hint + ")");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method validates the Android SDK location provided by the user and write it to the file
|
||||||
|
* sdkConfigFile.
|
||||||
|
*/
|
||||||
|
private void setSDKPath() {
|
||||||
|
System.out.println("Please provide android SDK location : ");
|
||||||
|
String response = new Scanner(System.in, StandardCharsets.UTF_8.toString()).next();
|
||||||
|
String emulatorLocationPath = response + File.separator + "tools" + File.separator + "emulator";
|
||||||
|
if (osSuffix.equals(Constants.WINDOWS_OS)) {
|
||||||
|
emulatorLocationPath += Constants.WINDOWS_EXTENSION_BAT;
|
||||||
|
}
|
||||||
|
if (new File(emulatorLocationPath).exists()) {
|
||||||
|
androidSdkHome = response;
|
||||||
|
writeToSdkConfigFile(response);
|
||||||
|
} else {
|
||||||
|
System.out.println("Invalid SDK location");
|
||||||
|
setSDKPath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method writes the SDK location to a file sdkConfigFile for future use.
|
||||||
|
*
|
||||||
|
* @param string - SDK location.
|
||||||
|
*/
|
||||||
|
private void writeToSdkConfigFile(String string) {
|
||||||
|
Writer writer = null;
|
||||||
|
try {
|
||||||
|
writer = new OutputStreamWriter(new FileOutputStream(sdkConfigFile), StandardCharsets.UTF_8);
|
||||||
|
writer.write(string);
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("Writing to " + sdkConfigFile.toString() + " failed.");
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (writer != null) {
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method creates a folder named android-sdk and downloads the minimum tools for SDK
|
||||||
|
* and write the sdk-location to the file sdkConfigFile.
|
||||||
|
*/
|
||||||
|
private void getAndroidSDK() {
|
||||||
|
String androidSdkFolderName = "android-sdk";
|
||||||
|
if (!new File(workingDirectory + File.separator + androidSdkFolderName).exists()) {
|
||||||
|
if (!new File(workingDirectory + File.separator + androidSdkFolderName).mkdir()) {
|
||||||
|
System.out.println("Unable to make folder named " + androidSdkFolderName + " in " + workingDirectory);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
androidSdkHome = workingDirectory + File.separator + androidSdkFolderName;
|
||||||
|
getTools(System.getProperty(Constants.SDK_TOOLS_URL), "_Android-sdk-tools.zip");
|
||||||
|
getTools(System.getProperty(Constants.PLATFORM_TOOLS_URL), "_Android-platform-tools.zip");
|
||||||
|
writeToSdkConfigFile(androidSdkHome);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method downloads and extracts the tools.
|
||||||
|
*
|
||||||
|
* @param url - the URL to download from.
|
||||||
|
* @param folderName - the folder name where to download.
|
||||||
|
*/
|
||||||
|
private void getTools(String url, String folderName) {
|
||||||
|
System.out.println("Downloading " + folderName);
|
||||||
|
downloadArtifacts(url, androidSdkHome + File.separator + folderName);
|
||||||
|
System.out.println("Configuring " + folderName);
|
||||||
|
extractFolder(androidSdkHome + File.separator + folderName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method starts the AVD specified by the user.
|
||||||
|
*/
|
||||||
|
private void startAVD() {
|
||||||
|
String wso2AvdLocation = userHome + File.separator + ".android" + File.separator + "avd" + File.separator
|
||||||
|
+ Constants.WSO2_AVD_NAME + ".avd";
|
||||||
|
checkForPlatform();
|
||||||
|
checkForSystemImages();
|
||||||
|
if (!new File(wso2AvdLocation).isDirectory()) {
|
||||||
|
Scanner read = new Scanner(System.in, StandardCharsets.UTF_8.toString());
|
||||||
|
System.out.print("Do you want to create WSO2_AVD with default configs (Y/n)?: ");
|
||||||
|
if (read.next().toLowerCase().matches("y")) {
|
||||||
|
createAVD();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("+----------------------------------------------------------------+");
|
||||||
|
System.out.println("| WSO2 Android TryIt |");
|
||||||
|
System.out.println("+----------------------------------------------------------------+");
|
||||||
|
|
||||||
|
emulatorLocation = androidSdkHome + File.separator + "tools" + File.separator + "emulator";
|
||||||
|
if (osSuffix.equals(Constants.WINDOWS_OS)) {
|
||||||
|
emulatorLocation += Constants.WINDOWS_EXTENSION_EXE;
|
||||||
|
}
|
||||||
|
setExecutePermission(emulatorLocation);
|
||||||
|
listAVDs();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gets the available AVDs' name from the system.
|
||||||
|
*/
|
||||||
|
private void listAVDs() {
|
||||||
|
ArrayList<String> devices = new ArrayList<>();
|
||||||
|
BufferedReader reader = null;
|
||||||
|
try {
|
||||||
|
ProcessBuilder listAVDsProcessBuilder = new ProcessBuilder(emulatorLocation, "-list-avds");
|
||||||
|
Process listAVDsProcess = listAVDsProcessBuilder.start();
|
||||||
|
reader = new BufferedReader(new InputStreamReader(listAVDsProcess.getInputStream(),
|
||||||
|
StandardCharsets.UTF_8.toString()));
|
||||||
|
String readLine;
|
||||||
|
while ((readLine = reader.readLine()) != null) {
|
||||||
|
devices.add(readLine);
|
||||||
|
}
|
||||||
|
selectAVD(devices);
|
||||||
|
} catch (IOException e) {
|
||||||
|
handleException("Unable to list the available AVDs", e);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (reader != null) {
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
// exception in finally block
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method makes the thread wait.
|
||||||
|
*
|
||||||
|
* @param milliSec -time to wait for
|
||||||
|
*/
|
||||||
|
private void delay(long milliSec) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(milliSec);
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
// interruption in main thread
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method enables the user to select an AVD form available AVDs.
|
||||||
|
*
|
||||||
|
* @param devices - list of available AVDs.
|
||||||
|
*/
|
||||||
|
private void selectAVD(ArrayList<String> devices) {
|
||||||
|
if (devices.size() == 0) {
|
||||||
|
System.out.println("No AVDs available in the system ");
|
||||||
|
startAVD();
|
||||||
|
} else if (devices.size() == 1) {
|
||||||
|
runEmulator(devices.get(0));
|
||||||
|
} else {
|
||||||
|
System.out.println("\nAvailable AVDs in the system\n");
|
||||||
|
int count = 1;
|
||||||
|
for (String device : devices) {
|
||||||
|
System.out.println(count + ") " + device);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
System.out.print("\nEnter AVD number to start (eg: 1) :");
|
||||||
|
Scanner read = new Scanner(System.in, StandardCharsets.UTF_8.toString());
|
||||||
|
int avdNo = read.nextInt();
|
||||||
|
runEmulator(devices.get(--avdNo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method creates WSO2_AVD with the specific configurations.
|
||||||
|
*/
|
||||||
|
private void createAVD() {
|
||||||
|
String avdManagerPath = androidSdkHome + File.separator + "tools" + File.separator + "bin"
|
||||||
|
+ File.separator + "avdmanager";
|
||||||
|
String androidPath = androidSdkHome + File.separator + "tools" + File.separator + "android";
|
||||||
|
if (osSuffix.equals(Constants.WINDOWS_OS)) {
|
||||||
|
avdManagerPath += Constants.WINDOWS_EXTENSION_BAT;
|
||||||
|
androidPath += Constants.WINDOWS_EXTENSION_BAT;
|
||||||
|
}
|
||||||
|
setExecutePermission(androidPath);
|
||||||
|
System.out.println("Creating a new AVD device");
|
||||||
|
try {
|
||||||
|
if (new File(avdManagerPath).exists()) {
|
||||||
|
setExecutePermission(avdManagerPath);
|
||||||
|
ProcessBuilder createAvdProcessBuilder = new ProcessBuilder(avdManagerPath, "create", "avd", "-k",
|
||||||
|
"system-images;android-23;default;x86", "-n", Constants.WSO2_AVD_NAME);
|
||||||
|
createAvdProcessBuilder.redirectInput(ProcessBuilder.Redirect.INHERIT);
|
||||||
|
createAvdProcessBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
|
||||||
|
Process createAvdProcess = createAvdProcessBuilder.start();
|
||||||
|
createAvdProcess.waitFor();
|
||||||
|
} else {
|
||||||
|
ProcessBuilder createAvd = new ProcessBuilder(androidPath, "create", "avd", "-n",
|
||||||
|
Constants.WSO2_AVD_NAME, "-t", "android-23");
|
||||||
|
createAvd.redirectInput(ProcessBuilder.Redirect.INHERIT);
|
||||||
|
createAvd.redirectOutput(ProcessBuilder.Redirect.INHERIT);
|
||||||
|
Process createAvdProcess = createAvd.start();
|
||||||
|
createAvdProcess.waitFor();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
handleException("Unable to create " + Constants.WSO2_AVD_NAME, e);
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
// interruption in main thread
|
||||||
|
}
|
||||||
|
copyDefaultWSO2Configs();
|
||||||
|
startAVD();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method replaces the default configurations provided in the resources to the WSoO2 AVD created
|
||||||
|
*/
|
||||||
|
private void copyDefaultWSO2Configs() {
|
||||||
|
String configFileLocation = workingDirectory + Constants.WSO2_CONFIG_LOCATION;
|
||||||
|
String wso2ConfigFile = userHome + File.separator + ".android" + File.separator + "avd" + File.separator
|
||||||
|
+ Constants.WSO2_AVD_NAME + ".avd" + File.separator + "config.ini";
|
||||||
|
try {
|
||||||
|
Files.copy(Paths.get(configFileLocation), Paths.get(wso2ConfigFile), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
System.out.println("WARN : Failed to have WSO2 default AVD configurations");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method runs the Android Emulator for the name specified by deviceId.
|
||||||
|
*
|
||||||
|
* @param deviceId String name of the device.
|
||||||
|
*/
|
||||||
|
private void runEmulator(String deviceId) {
|
||||||
|
if (osSuffix.equals(Constants.MAC_OS) || osSuffix.equals(Constants.WINDOWS_OS)) {
|
||||||
|
installHAXM();
|
||||||
|
}
|
||||||
|
System.out.println("Starting : " + deviceId);
|
||||||
|
startEmulator(deviceId);
|
||||||
|
checkCacheImg(deviceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method checks for the availability of android build tools in SDK location to run the AVD.
|
||||||
|
*/
|
||||||
|
private void checkBuildTools() {
|
||||||
|
File buildTools = new File(androidSdkHome + File.separator + "build-tools"
|
||||||
|
+ File.separator + System.getProperty(Constants.BUILD_TOOLS_VERSION));
|
||||||
|
if (!buildTools.exists()) {
|
||||||
|
getTools(System.getProperty(Constants.BUILD_TOOL_URL), "_Android-build-tool.zip");
|
||||||
|
File buildTool = new File(androidSdkHome + File.separator
|
||||||
|
+ System.getProperty(Constants.DOWNLOADED_BUILD_TOOL_NAME));
|
||||||
|
if (!new File(androidSdkHome + File.separator + "build-tools").exists()
|
||||||
|
&& !new File(androidSdkHome + File.separator + "build-tools").mkdir()) {
|
||||||
|
makeDirectoryError("build-tools", androidSdkHome);
|
||||||
|
}
|
||||||
|
buildTool.renameTo(new File(androidSdkHome + File.separator + "build-tools"
|
||||||
|
+ File.separator + System.getProperty(Constants.BUILD_TOOLS_VERSION)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method make sure whether the directory can be created.
|
||||||
|
*
|
||||||
|
* @param name - name of the folder to be made
|
||||||
|
* @param location - location to make folder
|
||||||
|
*/
|
||||||
|
private void makeDirectoryError(String name, String location) {
|
||||||
|
System.out.println("Unable to make folder named " + name + " in " + location);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method halts the system until the emulator is fully booted
|
||||||
|
* if boot process is not completed successfully, rest of the tasks won't be continued.
|
||||||
|
*/
|
||||||
|
private void checkEmulatorBoot() {
|
||||||
|
BufferedReader reader = null;
|
||||||
|
String readLine;
|
||||||
|
Boolean sysBootComplete = false;
|
||||||
|
do {
|
||||||
|
ProcessBuilder systemBoot = new ProcessBuilder(adbLocation, "shell", "getprop",
|
||||||
|
"sys.boot_completed");
|
||||||
|
try {
|
||||||
|
Process systemBootProcess = systemBoot.start();
|
||||||
|
systemBootProcess.waitFor();
|
||||||
|
reader = new BufferedReader(new InputStreamReader(systemBootProcess.getInputStream(),
|
||||||
|
StandardCharsets.UTF_8));
|
||||||
|
while ((readLine = reader.readLine()) != null) {
|
||||||
|
// if boot process is success the process gives 1 as output
|
||||||
|
if (readLine.contains("1")) {
|
||||||
|
sysBootComplete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.print(".");
|
||||||
|
delay(1000);
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("WARN : Unable to check boot process");
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
//interruption in main thread
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (reader != null) {
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (!sysBootComplete);
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gets the Android SDK location if available and sets the SDK path else downloads the SDK.
|
||||||
|
*/
|
||||||
|
private void setAndroidSDK() {
|
||||||
|
sdkConfigFile = new File("sdkConfigLocation");
|
||||||
|
if (!(sdkConfigFile.exists() && !sdkConfigFile.isDirectory())) {
|
||||||
|
//TODO
|
||||||
|
Scanner read = new Scanner(System.in, StandardCharsets.UTF_8.toString());
|
||||||
|
System.out.print("Do you have an Android SDK installed on your computer (y/N) ? : ");
|
||||||
|
String response = read.next().toLowerCase();
|
||||||
|
if (response.matches("y")) {
|
||||||
|
setSDKPath();
|
||||||
|
} else {
|
||||||
|
getAndroidSDK();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Scanner scanner = null;
|
||||||
|
try {
|
||||||
|
scanner = new Scanner(sdkConfigFile, StandardCharsets.UTF_8.toString());
|
||||||
|
androidSdkHome = scanner.useDelimiter("\\Z").next();
|
||||||
|
} catch (FileNotFoundException ignored) {
|
||||||
|
//
|
||||||
|
} finally {
|
||||||
|
if (scanner != null) {
|
||||||
|
scanner.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
adbLocation = androidSdkHome + File.separator + "platform-tools" + File.separator + "adb";
|
||||||
|
if (osSuffix.equals(Constants.WINDOWS_OS)) {
|
||||||
|
adbLocation += Constants.WINDOWS_EXTENSION_EXE;
|
||||||
|
}
|
||||||
|
setExecutePermission(adbLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this method prints the exception and terminate the program.
|
||||||
|
*
|
||||||
|
* @param message -exception method to be printed
|
||||||
|
* @param ex - exception caught
|
||||||
|
*/
|
||||||
|
private void handleException(String message, Exception ex) {
|
||||||
|
System.out.println(message);
|
||||||
|
ex.printStackTrace();
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method check for the android agent in the specified AVD and installs it if not available.
|
||||||
|
*
|
||||||
|
* @return package name and act name.
|
||||||
|
*/
|
||||||
|
private String[] checkForAgent() {
|
||||||
|
String pkg = null;
|
||||||
|
String activity = null;
|
||||||
|
String readLine;
|
||||||
|
BufferedReader reader = null;
|
||||||
|
String apkFileLocation = workingDirectory + Constants.APK_LOCATION;
|
||||||
|
String aaptLocation = androidSdkHome + File.separator + "build-tools" + File.separator
|
||||||
|
+ System.getProperty(Constants.BUILD_TOOLS_VERSION) + File.separator + "aapt";
|
||||||
|
if (osSuffix.equals(Constants.WINDOWS_OS)) {
|
||||||
|
aaptLocation += Constants.WINDOWS_EXTENSION_EXE;
|
||||||
|
}
|
||||||
|
setExecutePermission(aaptLocation);
|
||||||
|
ProcessBuilder badgingApkFileProcessBuilder = new ProcessBuilder(aaptLocation, "d", "badging",
|
||||||
|
apkFileLocation);
|
||||||
|
try {
|
||||||
|
Process badgingApkFileProcess = badgingApkFileProcessBuilder.start();
|
||||||
|
reader = new BufferedReader(new InputStreamReader(badgingApkFileProcess.getInputStream(),
|
||||||
|
StandardCharsets.UTF_8));
|
||||||
|
while ((readLine = reader.readLine()) != null) {
|
||||||
|
if (readLine.contains("package")) {
|
||||||
|
Pattern pattern = Pattern.compile("'(.*?)'");
|
||||||
|
Matcher matcher = pattern.matcher(readLine);
|
||||||
|
if (matcher.find()) {
|
||||||
|
pkg = matcher.group(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (readLine.contains("launchable-activity")) {
|
||||||
|
Pattern pattern = Pattern.compile("'(.*?)'");
|
||||||
|
Matcher matcher = pattern.matcher(readLine);
|
||||||
|
if (matcher.find()) {
|
||||||
|
activity = matcher.group(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
System.out.println("WARN : Failed to get the available packages");
|
||||||
|
} finally {
|
||||||
|
if (reader != null) {
|
||||||
|
try {
|
||||||
|
reader.close();
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!checkForPackage(pkg)) {
|
||||||
|
installAgent();
|
||||||
|
}
|
||||||
|
return new String[]{pkg, activity};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method check whether the package is available in the AVD.
|
||||||
|
*
|
||||||
|
* @param pkg - name og package to check for.
|
||||||
|
* @return - available or not.
|
||||||
|
*/
|
||||||
|
private boolean checkForPackage(String pkg) {
|
||||||
|
String readLine;
|
||||||
|
BufferedReader reader = null;
|
||||||
|
Boolean hasAgent = false;
|
||||||
|
ProcessBuilder listPackages = new ProcessBuilder(adbLocation, "shell", "pm", "list", "packages");
|
||||||
|
try {
|
||||||
|
Process listPackagesProcess = listPackages.start();
|
||||||
|
listPackagesProcess.waitFor();
|
||||||
|
reader = new BufferedReader(new InputStreamReader(listPackagesProcess.getInputStream(),
|
||||||
|
StandardCharsets.UTF_8));
|
||||||
|
while ((readLine = reader.readLine()) != null) {
|
||||||
|
if (readLine.contains("package:" + pkg)) {
|
||||||
|
hasAgent = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException | InterruptedException ignored) {
|
||||||
|
System.out.println("WARN : Failed to check the available packages, agent will be installed");
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (reader != null) {
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hasAgent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method installs the Android Agent ( WSO2 iot agent ).
|
||||||
|
*/
|
||||||
|
private void installAgent() {
|
||||||
|
String androidAgentLocation = workingDirectory + Constants.APK_LOCATION;
|
||||||
|
System.out.println("Installing agent ...");
|
||||||
|
ProcessBuilder installAgentProcessBuilder = new ProcessBuilder(adbLocation, "install",
|
||||||
|
androidAgentLocation);
|
||||||
|
try {
|
||||||
|
Process installAgentProcess = installAgentProcessBuilder.start();
|
||||||
|
installAgentProcess.waitFor();
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("WSO2 Agent installation failed");
|
||||||
|
//TODO
|
||||||
|
Scanner read = new Scanner(System.in, StandardCharsets.UTF_8.toString());
|
||||||
|
System.out.println("Do you want to install agent again (Y/N) ? ");
|
||||||
|
if (read.next().toLowerCase().matches("y")) {
|
||||||
|
installAgent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method starts the package (wso2.iot.agent).
|
||||||
|
*
|
||||||
|
* @param agents package name and launchable activity name.
|
||||||
|
*/
|
||||||
|
private void startPackage(String[] agents) {
|
||||||
|
String pkg = agents[0];
|
||||||
|
String activity = agents[1];
|
||||||
|
ProcessBuilder pkgStartProcessBuilder = new ProcessBuilder(adbLocation, "shell", "am", "start",
|
||||||
|
"-n", pkg + "/" + activity);
|
||||||
|
try {
|
||||||
|
Process pkgStartProcess = pkgStartProcessBuilder.start();
|
||||||
|
pkgStartProcess.waitFor();
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
//
|
||||||
|
} catch (IOException e) {
|
||||||
|
handleException("Unable to start WSO2 package", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method checks for the availability of Android Platform in SDK and if not available downloads it.
|
||||||
|
*/
|
||||||
|
private void checkForPlatform() {
|
||||||
|
File platform = new File(androidSdkHome + File.separator + "platforms" + File.separator
|
||||||
|
+ System.getProperty(Constants.TARGET_VERSION));
|
||||||
|
if (!platform.isDirectory()) {
|
||||||
|
getTools(System.getProperty(Constants.PLATFORM_URL), "_Android-platforms.zip");
|
||||||
|
if (!new File(androidSdkHome + File.separator + "platforms").exists()
|
||||||
|
&& !new File(androidSdkHome + File.separator + "platforms").mkdir()) {
|
||||||
|
makeDirectoryError("platforms", androidSdkHome);
|
||||||
|
}
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
new File(androidSdkHome + File.separator + System.getProperty(Constants.DOWNLOADED_PLATFORM_NAME)).
|
||||||
|
renameTo(new File(androidSdkHome + File.separator + "platforms"
|
||||||
|
+ File.separator + System.getProperty(Constants.TARGET_VERSION)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method checks for the system images in the Android SDK and downloads if not available.
|
||||||
|
*/
|
||||||
|
private void checkForSystemImages() {
|
||||||
|
File systemImages = new File(androidSdkHome + File.separator + "system-images"
|
||||||
|
+ File.separator + System.getProperty(Constants.TARGET_VERSION) + File.separator + "default");
|
||||||
|
|
||||||
|
if (!systemImages.isDirectory()) {
|
||||||
|
getTools(System.getProperty(Constants.SYSTEM_IMAGE_URL), "_sys-images.zip");
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
new File(androidSdkHome + File.separator + "system-images" + File.separator
|
||||||
|
+ System.getProperty(Constants.TARGET_VERSION) + File.separator + "default").mkdirs();
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
new File(androidSdkHome + File.separator + System.getProperty(Constants.OS_TARGET))
|
||||||
|
.renameTo(new File(androidSdkHome + File.separator + "system-images" + File.separator
|
||||||
|
+ System.getProperty(Constants.TARGET_VERSION) + File.separator + "default"
|
||||||
|
+ File.separator + System.getProperty(Constants.OS_TARGET)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method install Hardware_Accelerated Execution_Manager in mac and windows os.
|
||||||
|
*/
|
||||||
|
private void installHAXM() {
|
||||||
|
String haxmLocation = androidSdkHome + File.separator + "extras" + File.separator + "intel"
|
||||||
|
+ File.separator + "Hardware_Accelerated_Execution_Manager";
|
||||||
|
|
||||||
|
if (!new File(haxmLocation).isDirectory()) {
|
||||||
|
//System.out.println("Downloading intel HAXM...");
|
||||||
|
if (!new File(haxmLocation).mkdirs()) {
|
||||||
|
makeDirectoryError(haxmLocation, androidSdkHome);
|
||||||
|
}
|
||||||
|
String folderName = "_haxm.zip";
|
||||||
|
getTools(System.getProperty(Constants.HAXM_URL), haxmLocation + File.separator
|
||||||
|
+ folderName);
|
||||||
|
String haxmInstaller = haxmLocation + File.separator + "silent_install";
|
||||||
|
if (osSuffix.equals(Constants.WINDOWS_OS)) {
|
||||||
|
haxmInstaller += Constants.WINDOWS_EXTENSION_BAT;
|
||||||
|
} else {
|
||||||
|
haxmInstaller += Constants.MAC_HAXM_EXTENSION;
|
||||||
|
}
|
||||||
|
setExecutePermission(haxmInstaller);
|
||||||
|
|
||||||
|
ProcessBuilder processBuilder = new ProcessBuilder(haxmInstaller, "-m", "2048", "-log",
|
||||||
|
workingDirectory + File.separator + "haxmSilentRun.log");
|
||||||
|
processBuilder.directory(new File(haxmLocation));
|
||||||
|
processBuilder.redirectInput(ProcessBuilder.Redirect.INHERIT);
|
||||||
|
processBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
|
||||||
|
try {
|
||||||
|
Process process = processBuilder.start();
|
||||||
|
process.waitFor();
|
||||||
|
} catch (IOException | InterruptedException e) {
|
||||||
|
System.out.println("HAXM installation failed, install HAXM and try again");
|
||||||
|
}
|
||||||
|
System.out.println("Please restart your machine and run again.");
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method starts the Android emulator for specific device name.
|
||||||
|
*
|
||||||
|
* @param deviceId - name of the device to start the emulator.
|
||||||
|
*/
|
||||||
|
private void startEmulator(String deviceId) {
|
||||||
|
String qemuSystemFileLocation = androidSdkHome + File.separator + "tools" + File.separator
|
||||||
|
+ "qemu" + File.separator;
|
||||||
|
|
||||||
|
switch (osSuffix) {
|
||||||
|
case Constants.MAC_OS:
|
||||||
|
qemuSystemFileLocation += Constants.MAC_DARWIN + "-x86_64" + File.separator + "qemu-system-i386";
|
||||||
|
break;
|
||||||
|
case Constants.WINDOWS_OS:
|
||||||
|
qemuSystemFileLocation += osSuffix + "-x86_64" + File.separator + "qemu-system-i386.exe";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qemuSystemFileLocation += osSuffix + "-x86_64" + File.separator + "qemu-system-i386";
|
||||||
|
}
|
||||||
|
killServer();
|
||||||
|
setExecutePermission(qemuSystemFileLocation);
|
||||||
|
ExecutorService service = Executors.newSingleThreadExecutor();
|
||||||
|
service.execute(new TryItEmulator(deviceId, emulatorLocation));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method ensures device properly starts.
|
||||||
|
*/
|
||||||
|
private void killServer() {
|
||||||
|
ProcessBuilder processBuilderKillServer = new ProcessBuilder(adbLocation, "kill-server");
|
||||||
|
Process processKillServer = null;
|
||||||
|
try {
|
||||||
|
processKillServer = processBuilderKillServer.start();
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
System.out.println("If the device doesn't start properly, stop running the script and restart again");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (processKillServer != null) {
|
||||||
|
processKillServer.waitFor();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
System.out.println("If the device doesn't start properly, stop running the script and restart again");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method halts the system the cache.img file is created for the particular AVD started.
|
||||||
|
*
|
||||||
|
* @param deviceId - name of the AVD.
|
||||||
|
*/
|
||||||
|
private void checkCacheImg(String deviceId) {
|
||||||
|
File cacheImg = new File(userHome + File.separator + ".android"
|
||||||
|
+ File.separator + "avd" + File.separator + deviceId + ".avd" + File.separator + "cache.img");
|
||||||
|
while (!cacheImg.exists()) {
|
||||||
|
System.out.print(".");
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the executable permission for the specified file,
|
||||||
|
* if the files are not the executable, the process cannot be continued.
|
||||||
|
*
|
||||||
|
* @param fileName name of the file to set execution permission.
|
||||||
|
*/
|
||||||
|
private void setExecutePermission(String fileName) {
|
||||||
|
if (!new File(fileName).canExecute()) {
|
||||||
|
if (!new File(fileName).setExecutable(true)) {
|
||||||
|
System.out.println("Unable to set the execute permission of : " + fileName);
|
||||||
|
System.out.println("Please set the executable permission for file "
|
||||||
|
+ new File(fileName).getAbsolutePath() + " to continue");
|
||||||
|
System.exit(1); // if can't execute, unable to proceed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method extracts the zip folder.
|
||||||
|
*
|
||||||
|
* @param zipFile -Name of zip to extract
|
||||||
|
*/
|
||||||
|
private void extractFolder(String zipFile) {
|
||||||
|
int BUFFER = 2048;
|
||||||
|
File file = new File(zipFile);
|
||||||
|
ZipFile zip;
|
||||||
|
try {
|
||||||
|
zip = new ZipFile(file);
|
||||||
|
String newPath = zipFile.substring(0, zipFile.lastIndexOf(File.separator));
|
||||||
|
new File(newPath).mkdirs();
|
||||||
|
Enumeration zipFileEntries = zip.entries();
|
||||||
|
while (zipFileEntries.hasMoreElements()) {
|
||||||
|
// grab a zip file entry
|
||||||
|
ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
|
||||||
|
String currentEntry = entry.getName();
|
||||||
|
File destFile = new File(newPath, currentEntry);
|
||||||
|
File destinationParent = destFile.getParentFile();
|
||||||
|
if (destinationParent == null) {
|
||||||
|
destFile.mkdirs();
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
destinationParent.mkdirs();
|
||||||
|
}
|
||||||
|
if (!entry.isDirectory()) {
|
||||||
|
BufferedInputStream is;
|
||||||
|
try {
|
||||||
|
is = new BufferedInputStream(zip.getInputStream(entry));
|
||||||
|
int currentByte;
|
||||||
|
// establish buffer for writing file
|
||||||
|
byte data[] = new byte[BUFFER];
|
||||||
|
// write the current file to disk
|
||||||
|
FileOutputStream fos = new FileOutputStream(destFile);
|
||||||
|
BufferedOutputStream dest = new BufferedOutputStream(fos,
|
||||||
|
BUFFER);
|
||||||
|
// read and write until last byte is encountered
|
||||||
|
while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
|
||||||
|
dest.write(data, 0, currentByte);
|
||||||
|
}
|
||||||
|
dest.flush();
|
||||||
|
dest.close();
|
||||||
|
is.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zip.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
handleException("Extraction of " + zipFile + " failed", e);
|
||||||
|
}
|
||||||
|
if (!new File(zipFile).delete()) {
|
||||||
|
System.out.println("Downloaded zip : " + zipFile + " - not deleted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||||
|
* Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.carbon.android.emulator;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class starts the Emulator with the name ID specified and log the output to emulator.log.
|
||||||
|
*/
|
||||||
|
public class TryItEmulator implements Runnable {
|
||||||
|
private String deviceId; // name of the AVD to start
|
||||||
|
private String emulatorLocation; // location of the executable file emulator
|
||||||
|
|
||||||
|
TryItEmulator(String id, String emulator) {
|
||||||
|
deviceId = id;
|
||||||
|
emulatorLocation = emulator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
String readLine;
|
||||||
|
BufferedReader reader = null;
|
||||||
|
Writer writer = null;
|
||||||
|
ProcessBuilder processBuilder = new ProcessBuilder(emulatorLocation, "-avd", deviceId);
|
||||||
|
try {
|
||||||
|
Process process = processBuilder.start();
|
||||||
|
reader = new BufferedReader(new InputStreamReader(process.getInputStream(),
|
||||||
|
StandardCharsets.UTF_8));
|
||||||
|
writer = new OutputStreamWriter(new FileOutputStream(new File("emulator.log")),
|
||||||
|
StandardCharsets.UTF_8);
|
||||||
|
while ((readLine = reader.readLine()) != null) {
|
||||||
|
writer.append(readLine);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("Error in starting " + deviceId);
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (reader != null) {
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
if (writer != null) {
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
}
|
@ -1,21 +1,20 @@
|
|||||||
Prerequisites
|
Prerequisites
|
||||||
===============
|
===============
|
||||||
1. You should have curl in your computer.
|
1. Java 8.
|
||||||
2. Java 7 or higher.
|
|
||||||
|
|
||||||
Instructions
|
Instructions
|
||||||
=================
|
============
|
||||||
|
|
||||||
1. Run 'start' script in your terminal.
|
1. For Linux/Mac : Run 'startEmulator.sh' script in your terminal from the current directory.
|
||||||
|
For Windows : Run 'startEmulator.bat' script in your terminal from the current directory.
|
||||||
2. If you already have android sdk in your computer, please provide location of the sdk.
|
2. If you already have android sdk in your computer, please provide location of the sdk.
|
||||||
Otherwise this tool will download and install minimum SDK components which needs to run the emulator.
|
Otherwise this tool will download and install minimum SDK components which needs to run the emulator.
|
||||||
This is a one time process.
|
This is a one time process.
|
||||||
3. This tool will ask to create AVD if you don't have any in your computer.
|
3. This tool will ask to create AVD if you don't have any in your computer.
|
||||||
Otherwise you can select existing AVD to try out IoT Agent.
|
Otherwise you can select existing AVD to try out IoT Agent.
|
||||||
|
|
||||||
|
|
||||||
Troubleshooting
|
Troubleshooting
|
||||||
==================
|
==================
|
||||||
|
|
||||||
1. If your exisitng SDK doen't work or giving any errors, delete 'sdklocation' file and try agin without selecting the existing SDK path.
|
1. If your existing SDK does not work or giving any errors, delete 'sdkConfigLocation' file and try again without selecting the existing SDK path.
|
||||||
2. If your emulator does not start correctly, please remove all files and directories in $HOME/.android/avd/ directory. Then try again with a new emulator.
|
2. If your emulator does not start correctly, please remove all files and directories in $HOME/.android/avd/ directory. Then try again with a new emulator.
|
||||||
|
@ -1,244 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
#Make sure we have got everything we need
|
|
||||||
command -v curl >/dev/null || { echo "curl is not installed. Aborting." >&2; exit 1; }
|
|
||||||
command -v unzip >/dev/null || { echo "unzip is not installed. Aborting." >&2; exit 1; }
|
|
||||||
|
|
||||||
SCRIPT_HOME=$PWD
|
|
||||||
|
|
||||||
OS_SUFFIX="linux"
|
|
||||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
||||||
OS_SUFFIX="macosx"
|
|
||||||
fi
|
|
||||||
|
|
||||||
downloadArtifacts() {
|
|
||||||
curl -D headers -O $1
|
|
||||||
httpStatus=$(head -1 headers | awk '{print $2}')
|
|
||||||
[ "$httpStatus" != "200" ] && { echo "Download failed. Aborting." ; exit 1 ;}
|
|
||||||
rm headers
|
|
||||||
echo
|
|
||||||
}
|
|
||||||
|
|
||||||
setSDKPath () {
|
|
||||||
echo -n "Please provide Android SDK location (ex: /mnt/tools/android-sdk):"
|
|
||||||
read answer
|
|
||||||
emulator="$answer/tools/emulator"
|
|
||||||
if [ -f "$emulator" ]; then
|
|
||||||
echo "$answer" > sdklocation
|
|
||||||
else
|
|
||||||
echo "Invalid SDK location"
|
|
||||||
setSDKPath
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
getAndroidSDK() {
|
|
||||||
echo
|
|
||||||
echo "Downloading Android SDK tools..."
|
|
||||||
mkdir android-sdk
|
|
||||||
cd android-sdk
|
|
||||||
|
|
||||||
downloadArtifacts "https://dl.google.com/android/repository/tools_r25.2.5-$OS_SUFFIX.zip"
|
|
||||||
echo -n "Configuring Android SDK tools..."
|
|
||||||
unzip -q tools_r25.2.5-$OS_SUFFIX.zip
|
|
||||||
rm tools_r25.2.5-$OS_SUFFIX.zip
|
|
||||||
echo " Done!"
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "Downloading Android platform tools..."
|
|
||||||
downloadArtifacts "http://dl.google.com/android/repository/platform-tools_r25.0.3-$OS_SUFFIX.zip"
|
|
||||||
|
|
||||||
echo -n "Configuring Android platform tools..."
|
|
||||||
unzip -q platform-tools_r25.0.3-$OS_SUFFIX.zip
|
|
||||||
rm platform-tools_r25.0.3-$OS_SUFFIX.zip
|
|
||||||
cd ..
|
|
||||||
echo "$PWD/android-sdk" > sdklocation
|
|
||||||
echo " Done!"
|
|
||||||
}
|
|
||||||
|
|
||||||
createAVD() {
|
|
||||||
if [ ! -d "$ANDROID_TRYIT_SDK_HOME/platforms/android-23" ]; then
|
|
||||||
echo
|
|
||||||
echo "Downloading Android platform..."
|
|
||||||
cd $ANDROID_TRYIT_SDK_HOME
|
|
||||||
downloadArtifacts "https://dl.google.com/android/repository/platform-23_r03.zip"
|
|
||||||
echo -n "Configuring Android platform..."
|
|
||||||
unzip -q platform-23_r03.zip
|
|
||||||
mkdir -p platforms/android-23
|
|
||||||
mv android-6.0/* platforms/android-23/
|
|
||||||
rm -r android-6.0
|
|
||||||
rm platform-23_r03.zip
|
|
||||||
cd ..
|
|
||||||
echo " Done!"
|
|
||||||
fi
|
|
||||||
if [ ! -d "$ANDROID_TRYIT_SDK_HOME/system-images/android-23/default" ]; then
|
|
||||||
echo "Downloading Android system image..."
|
|
||||||
cd $ANDROID_TRYIT_SDK_HOME
|
|
||||||
downloadArtifacts "https://dl.google.com/android/repository/sys-img/android/x86-23_r09.zip"
|
|
||||||
echo -n "Configuring Android system image..."
|
|
||||||
unzip -q x86-23_r09.zip
|
|
||||||
mkdir -p system-images/android-23/default
|
|
||||||
mv x86 system-images/android-23/default
|
|
||||||
rm x86-23_r09.zip
|
|
||||||
cd ..
|
|
||||||
echo " Done!"
|
|
||||||
fi
|
|
||||||
echo "Creating a new AVD device"
|
|
||||||
if [ -f "$ANDROID_TRYIT_SDK_HOME/tools/bin/avdmanager" ]; then
|
|
||||||
$ANDROID_TRYIT_SDK_HOME/tools/bin/avdmanager create avd -k 'system-images;android-23;default;x86' -n WSO2_AVD
|
|
||||||
else
|
|
||||||
$ANDROID_TRYIT_SDK_HOME/tools/android create avd -n WSO2_AVD -t android-23
|
|
||||||
fi
|
|
||||||
rm $HOME/.android/avd/WSO2_AVD.avd/config.ini
|
|
||||||
cp $SCRIPT_HOME/resources/config.ini $HOME/.android/avd/WSO2_AVD.avd/
|
|
||||||
startAVD
|
|
||||||
}
|
|
||||||
|
|
||||||
startAVD() {
|
|
||||||
if [ ! -d "$HOME/.android/avd/WSO2_AVD.avd" ]; then
|
|
||||||
echo -n "Looks you don't have the WSO2_AVD. Do you want to create WSO2_AVD with default configs (Y/n)?: "
|
|
||||||
read answer
|
|
||||||
if ! echo "$answer" | grep -iq "^n" ;then
|
|
||||||
createAVD
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
echo
|
|
||||||
echo "------------------------------"
|
|
||||||
echo "Available AVDs in the system:"
|
|
||||||
echo "------------------------------"
|
|
||||||
devices=()
|
|
||||||
count=0
|
|
||||||
if [ ! -f "mypipe" ]; then
|
|
||||||
mkfifo mypipe
|
|
||||||
fi
|
|
||||||
$ANDROID_TRYIT_SDK_HOME/tools/emulator -list-avds > mypipe &
|
|
||||||
while IFS= read -r line
|
|
||||||
do
|
|
||||||
let count++
|
|
||||||
echo "$count) $line"
|
|
||||||
devices+=($line)
|
|
||||||
done < mypipe
|
|
||||||
rm mypipe
|
|
||||||
echo "------------------------------"
|
|
||||||
echo
|
|
||||||
if [ $count = 0 ]; then
|
|
||||||
echo -n "No AVDs found on your system. Do you want to create new AVD (Y/n)?: "
|
|
||||||
read answer
|
|
||||||
if echo "$answer" | grep -iq "^n" ;then
|
|
||||||
exit;
|
|
||||||
else
|
|
||||||
createAVD
|
|
||||||
fi
|
|
||||||
elif [ $count = 1 ]; then
|
|
||||||
runEmulator ${devices[0]}
|
|
||||||
else
|
|
||||||
echo -n "Enter AVD number to start (eg: 1): "
|
|
||||||
read answer
|
|
||||||
let answer--
|
|
||||||
runEmulator ${devices[$answer]}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
runEmulator(){
|
|
||||||
if [ $OS_SUFFIX = "macosx" -a ! -d $ANDROID_TRYIT_SDK_HOME/extras/intel/Hardware_Accelerated_Execution_Manager ]; then
|
|
||||||
cd $ANDROID_TRYIT_SDK_HOME
|
|
||||||
echo "Downloading intel HAXM..."
|
|
||||||
mkdir -p extras/intel/Hardware_Accelerated_Execution_Manager
|
|
||||||
cd extras/intel/Hardware_Accelerated_Execution_Manager
|
|
||||||
downloadArtifacts "https://dl.google.com/android/repository/extras/intel/haxm-macosx_r6_0_5.zip"
|
|
||||||
echo -n "Configuring HAXM..."
|
|
||||||
unzip -q haxm-macosx_r6_0_5.zip
|
|
||||||
rm haxm-macosx_r6_0_5.zip
|
|
||||||
./"HAXM installation" -m 2048 -log $SCRIPT_HOME/haxm_silent_run.log
|
|
||||||
echo " Done!"
|
|
||||||
echo "Please restart your computer and run this script again."
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
cd $SCRIPT_HOME
|
|
||||||
$ANDROID_TRYIT_SDK_HOME/platform-tools/adb kill-server
|
|
||||||
echo "Starting AVD $1"
|
|
||||||
$ANDROID_TRYIT_SDK_HOME/tools/emulator -avd $1 > emulator.log &
|
|
||||||
while [ ! -f "$HOME/.android/avd/$1.avd/cache.img" ]
|
|
||||||
do
|
|
||||||
sleep 1
|
|
||||||
echo -n "."
|
|
||||||
done
|
|
||||||
count=0
|
|
||||||
while [ $count -lt 5 ]
|
|
||||||
do
|
|
||||||
sleep 1
|
|
||||||
echo -n "."
|
|
||||||
let count++
|
|
||||||
done
|
|
||||||
echo
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "+----------------------------------------------------------------+"
|
|
||||||
echo "| WSO2 Android Tryit |"
|
|
||||||
echo "+----------------------------------------------------------------+"
|
|
||||||
echo "Detected OS: " $OSTYPE
|
|
||||||
if [ ! -f "sdklocation" ]; then
|
|
||||||
echo -n "Do you have an Android SDK installed on your computer (y/N)?: "
|
|
||||||
read answer
|
|
||||||
if echo "$answer" | grep -iq "^y" ;then
|
|
||||||
setSDKPath
|
|
||||||
else
|
|
||||||
getAndroidSDK
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
export ANDROID_TRYIT_SDK_HOME=$(<sdklocation)
|
|
||||||
|
|
||||||
if [ ! -d "$ANDROID_TRYIT_SDK_HOME/build-tools/25.0.2" ]; then
|
|
||||||
echo
|
|
||||||
echo "Downloading Android build tools..."
|
|
||||||
cd $ANDROID_TRYIT_SDK_HOME
|
|
||||||
downloadArtifacts "https://dl.google.com/android/repository/build-tools_r25.0.2-$OS_SUFFIX.zip"
|
|
||||||
echo -n "Configuring Android build tools..."
|
|
||||||
unzip -q build-tools_r25.0.2-$OS_SUFFIX.zip
|
|
||||||
mkdir -p build-tools/25.0.2
|
|
||||||
mv android-7.1.1/* build-tools/25.0.2/
|
|
||||||
rm -r android-7.1.1
|
|
||||||
rm build-tools_r25.0.2-$OS_SUFFIX.zip
|
|
||||||
echo " Done!"
|
|
||||||
fi
|
|
||||||
|
|
||||||
startAVD
|
|
||||||
|
|
||||||
while [ "`$ANDROID_TRYIT_SDK_HOME/platform-tools/adb shell getprop sys.boot_completed | tr -d '\r' `" != "1" ] ; do sleep 1; done
|
|
||||||
echo "AVD Started!"
|
|
||||||
|
|
||||||
sleep 1
|
|
||||||
if [ ! -f "mypipe" ]; then
|
|
||||||
mkfifo mypipe
|
|
||||||
fi
|
|
||||||
|
|
||||||
app=$SCRIPT_HOME/resources/android-agent.apk
|
|
||||||
pkg=$($ANDROID_TRYIT_SDK_HOME/build-tools/25.0.2/aapt dump badging $app|awk -F" " '/package/ {print $2}'|awk -F"'" '/name=/ {print $2}')
|
|
||||||
act=$($ANDROID_TRYIT_SDK_HOME/build-tools/25.0.2/aapt dump badging $app|awk -F" " '/launchable-activity/ {print $2}'|awk -F"'" '/name=/ {print $2}')
|
|
||||||
|
|
||||||
hasAgent=false
|
|
||||||
|
|
||||||
$ANDROID_TRYIT_SDK_HOME/platform-tools/adb shell pm list packages > mypipe &
|
|
||||||
while IFS= read -r line
|
|
||||||
do
|
|
||||||
if [ $line = "package:$pkg" ]; then
|
|
||||||
let hasAgent=true
|
|
||||||
fi
|
|
||||||
done < mypipe
|
|
||||||
rm mypipe
|
|
||||||
|
|
||||||
if [ $hasAgent = false ]; then
|
|
||||||
echo
|
|
||||||
echo "Installing agent..."
|
|
||||||
cd $SCRIPT_HOME/resources
|
|
||||||
$ANDROID_TRYIT_SDK_HOME/platform-tools/adb install android-agent.apk
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "Staring agent..."
|
|
||||||
$ANDROID_TRYIT_SDK_HOME/platform-tools/adb shell am start -n $pkg/$act
|
|
||||||
echo
|
|
||||||
echo "Connected to device shell"
|
|
||||||
$ANDROID_TRYIT_SDK_HOME/platform-tools/adb shell
|
|
||||||
echo
|
|
||||||
echo "Good bye!"
|
|
@ -0,0 +1,17 @@
|
|||||||
|
@echo off
|
||||||
|
echo Welcome
|
||||||
|
|
||||||
|
java^
|
||||||
|
-Dsdk.tools.url="https://dl.google.com/android/repository/tools_r25.2.5-windows.zip"^
|
||||||
|
-Dplatform.tools.url="http://dl.google.com/android/repository/platform-tools_r25.0.3-windows.zip"^
|
||||||
|
-Dbuild.tools.url="https://dl.google.com/android/repository/build-tools_r25.0.2-windows.zip"^
|
||||||
|
-Dplatform.url="https://dl.google.com/android/repository/platform-23_r03.zip"^
|
||||||
|
-Dsys.img.url="https://dl.google.com/android/repository/sys-img/android/x86-23_r09.zip"^
|
||||||
|
-Dhaxm.url="https://dl.google.com/android/repository/extras/intel/haxm-windows_r6_0_5.zip"^
|
||||||
|
-Ddownloaded.build.tool.name="android-7.1.1"^
|
||||||
|
-Dbuild.tool.version="25.0.2"^
|
||||||
|
-Ddownloaded.platform.name="android-6.0"^
|
||||||
|
-Dtarget.version="android-23"^
|
||||||
|
-Dos.target="x86"^
|
||||||
|
-jar JavaApp.jar
|
||||||
|
|
@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
echo Welcome
|
||||||
|
|
||||||
|
OS_SUFFIX="linux"
|
||||||
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
|
OS_SUFFIX="macosx"
|
||||||
|
fi
|
||||||
|
|
||||||
|
java\
|
||||||
|
-Dsdk.tools.url="https://dl.google.com/android/repository/tools_r25.2.5-$OS_SUFFIX.zip"\
|
||||||
|
-Dplatform.tools.url="http://dl.google.com/android/repository/platform-tools_r25.0.3-$OS_SUFFIX.zip"\
|
||||||
|
-Dbuild.tools.url="https://dl.google.com/android/repository/build-tools_r25.0.2-$OS_SUFFIX.zip"\
|
||||||
|
-Dplatform.url="https://dl.google.com/android/repository/platform-23_r03.zip"\
|
||||||
|
-Dsys.img.url="https://dl.google.com/android/repository/sys-img/android/x86-23_r09.zip"\
|
||||||
|
-Dhaxm.url="https://dl.google.com/android/repository/extras/intel/haxm-macosx_r6_0_5.zip"\
|
||||||
|
-Ddownloaded.build.tool.name="android-7.1.1"\
|
||||||
|
-Dbuild.tool.version="25.0.2"\
|
||||||
|
-Ddownloaded.platform.name="android-6.0"\
|
||||||
|
-Dtarget.version="android-23"\
|
||||||
|
-Dos.target="x86"\
|
||||||
|
-jar JavaApp.jar
|
||||||
|
|
After Width: | Height: | Size: 7.3 KiB |
@ -1,31 +1,9 @@
|
|||||||
<div class="wr-app-listing">
|
|
||||||
<div class="wr-applist">
|
|
||||||
{{#each applications}}
|
{{#each applications}}
|
||||||
<a style="text-align: center; width: 110px; height: 140px;">
|
<div class="application">
|
||||||
{{#equal platform "android"}}<i class="icon fw fw-android"></i>{{/equal}}
|
<img src="">
|
||||||
{{#equal platform "ios"}}<i class="icon fw fw-apple"></i>{{/equal}}
|
<div class="app-info">
|
||||||
{{#equal platform "windows"}}<i class="icon fw fw-windows"></i>{{/equal}}
|
<h4>{{name}}</h4>
|
||||||
{{#equal isActive true}}
|
<p>v{{version}}</p>
|
||||||
<span style="word-wrap: break-word;">
|
|
||||||
<i class="fw fw-success icon-success" style="font-size: 14px;"></i>
|
|
||||||
Active
|
|
||||||
</span>
|
|
||||||
<span style="word-wrap: break-word;"><b>{{name}}</b></span>
|
|
||||||
<span style="word-wrap: break-word;"><b>V:{{version}}</b></span>
|
|
||||||
{{#if memoryUsage}}
|
|
||||||
<span style="word-wrap: break-word;">
|
|
||||||
Memory Usage
|
|
||||||
</span>
|
|
||||||
<span style="word-wrap: break-word;">
|
|
||||||
( {{memoryUsage}} Bytes )
|
|
||||||
</span>
|
|
||||||
{{/if}}
|
|
||||||
{{/equal}}
|
|
||||||
{{#equal isActive false}}
|
|
||||||
<span style="word-wrap: break-word;">{{name}}</span>
|
|
||||||
<span style="word-wrap: break-word;"><b>V:{{version}}</b></span>
|
|
||||||
{{/equal}}
|
|
||||||
</a>
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
Loading…
Reference in new issue