fixed multi-core support; cleaned up some bugs

This commit is contained in:
HappyZ 2017-01-27 15:46:01 -08:00
parent 8149f6f021
commit 111c5b6116
3 changed files with 235 additions and 160 deletions

View File

@ -40,7 +40,6 @@ public class MainActivity extends Activity {
protected static final String udpserver_pathport = "~/mobileRDMABeach/UDPServer 32000 "; protected static final String udpserver_pathport = "~/mobileRDMABeach/UDPServer 32000 ";
protected static final String binaryFolderPath = "/data/local/tmp/"; protected static final String binaryFolderPath = "/data/local/tmp/";
protected static final String binary_tcpdump = "tcpdump"; protected static final String binary_tcpdump = "tcpdump";
protected static final int oneMB = 1048576;
private static final String TAG = "MainActivity"; private static final String TAG = "MainActivity";
private static final int mVersion = Build.VERSION.SDK_INT; private static final int mVersion = Build.VERSION.SDK_INT;
// the configs // the configs
@ -66,7 +65,7 @@ public class MainActivity extends Activity {
protected static int UDPfinishTime = 0; protected static int UDPfinishTime = 0;
protected static double reportedFinishTime = 0.0; protected static double reportedFinishTime = 0.0;
protected static int repeatCounts = 3; protected static int repeatCounts = 3;
protected static int bytes2send = 10 * oneMB; // default 10MB protected static int bytes2send = 10 * Utilities.oneMB; // default 10MB
protected static int currentBandwidth = -1; // bps, default is -1, indicating unlimited protected static int currentBandwidth = -1; // bps, default is -1, indicating unlimited
protected static TextView txt_results; protected static TextView txt_results;
protected static Handler myHandler; protected static Handler myHandler;
@ -550,9 +549,10 @@ public class MainActivity extends Activity {
} }
/** /**
* Intialize parameters etc. * Initialize parameters etc.
*/ */
protected void initialization() { protected void initialization() {
// must have root privilege in order to run // must have root privilege in order to run
try { try {
Runtime.getRuntime().exec("su"); Runtime.getRuntime().exec("su");
@ -561,12 +561,26 @@ public class MainActivity extends Activity {
} catch (Throwable e) { } catch (Throwable e) {
Toast.makeText(this, R.string.warn_root, Toast.LENGTH_LONG).show(); Toast.makeText(this, R.string.warn_root, Toast.LENGTH_LONG).show();
} }
// must have storage permission // must have storage permission
Utilities.verifyStoragePermissions(this); Utilities.verifyStoragePermissions(this);
// permission error
if (!Utilities.canWriteOnExternalStorage()) {
Log.d(TAG, "Permission error: cannot write on external storage.");
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Can't write on external storage!\n");
}
});
}
// handler that updates the ui at main thread // handler that updates the ui at main thread
// it's used in sslogger thus will be modded in receiver activity also // it's used in sslogger thus will be modded in receiver activity also
// do not modify this // do not modify this
myHandler = new Handler(); myHandler = new Handler();
// sslogger intent // sslogger intent
intentSSLogger = new Intent(this, SSLogger.class); intentSSLogger = new Intent(this, SSLogger.class);
// grab WiFi service and check if wifi is enabled // grab WiFi service and check if wifi is enabled
@ -638,39 +652,39 @@ public class MainActivity extends Activity {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
final CharSequence[] mItems={ final CharSequence[] mItems={
(bytes2send == (oneMB/2))?"Current: 0.5MB":"0.5MB", (bytes2send == (Utilities.oneMB/2))?"Current: 0.5MB":"0.5MB",
(bytes2send == (oneMB))?"Current: 1MB":"1MB", (bytes2send == (Utilities.oneMB))?"Current: 1MB":"1MB",
(bytes2send == (2*oneMB))?"Current: 2MB":"2MB", (bytes2send == (2*Utilities.oneMB))?"Current: 2MB":"2MB",
(bytes2send == (5*oneMB))?"Current: 5MB":"5MB", (bytes2send == (5*Utilities.oneMB))?"Current: 5MB":"5MB",
(bytes2send == (10*oneMB))?"Current: 10MB":"10MB", (bytes2send == (10*Utilities.oneMB))?"Current: 10MB":"10MB",
(bytes2send == (20*oneMB))?"Current: 20MB":"20MB", (bytes2send == (20*Utilities.oneMB))?"Current: 20MB":"20MB",
(bytes2send == (50*oneMB))?"Current: 50MB":"50MB", (bytes2send == (50*Utilities.oneMB))?"Current: 50MB":"50MB",
(bytes2send == (100*oneMB))?"Current: 100MB":"100MB", (bytes2send == (100*Utilities.oneMB))?"Current: 100MB":"100MB",
(bytes2send == (200*oneMB))?"Current: 200MB":"200MB", (bytes2send == (200*Utilities.oneMB))?"Current: 200MB":"200MB",
(bytes2send == (500*oneMB))?"Current: 500MB":"500MB", (bytes2send == (500*Utilities.oneMB))?"Current: 500MB":"500MB",
(bytes2send == (1000*oneMB))?"Current: 1GB":"1GB"}; (bytes2send == (1000*Utilities.oneMB))?"Current: 1GB":"1GB"};
AlertDialog.Builder mDialog = new AlertDialog.Builder(MainActivity.this); AlertDialog.Builder mDialog = new AlertDialog.Builder(MainActivity.this);
mDialog.setItems(mItems, new DialogInterface.OnClickListener() { mDialog.setItems(mItems, new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
if (which < 3) { if (which < 3) {
bytes2send = oneMB/2; bytes2send = Utilities.oneMB/2;
for (int i = 0; i < which; ++i) for (int i = 0; i < which; ++i)
bytes2send *= 2; bytes2send *= 2;
} else if (which < 6) { } else if (which < 6) {
bytes2send = 5 * oneMB; bytes2send = 5 * Utilities.oneMB;
for (int i = 3; i < which; ++i) for (int i = 3; i < which; ++i)
bytes2send *= 2; bytes2send *= 2;
} else if (which < 9) { } else if (which < 9) {
bytes2send = 50 * oneMB; bytes2send = 50 * Utilities.oneMB;
for (int i = 6; i < which; ++i) for (int i = 6; i < which; ++i)
bytes2send *= 2; bytes2send *= 2;
} else if (which == 9) { } else if (which == 9) {
bytes2send = 500 * oneMB; bytes2send = 500 * Utilities.oneMB;
} else if (which == 10) { } else if (which == 10) {
bytes2send = 1000 * oneMB; bytes2send = 1000 * Utilities.oneMB;
} else { } else {
bytes2send = 10 * oneMB; // default 10MB bytes2send = 10 * Utilities.oneMB; // default 10MB
} }
if (isVerbose) { if (isVerbose) {
Log.d(TAG, "outgoing/incoming bytes is set to " + bytes2send); Log.d(TAG, "outgoing/incoming bytes is set to " + bytes2send);
@ -716,7 +730,7 @@ public class MainActivity extends Activity {
out.add("Disable TCPDump"); out.add("Disable TCPDump");
} }
try { try {
Process proc = Runtime.getRuntime().exec("ls /sys/class/net"); Process proc = Runtime.getRuntime().exec("su -c ls /sys/class/net");
proc.waitFor(); proc.waitFor();
String line; String line;
BufferedReader is = new BufferedReader(new InputStreamReader(proc.getInputStream())); BufferedReader is = new BufferedReader(new InputStreamReader(proc.getInputStream()));

View File

@ -57,13 +57,6 @@ public class SSLogger extends Service {
String[] cpuUsage = new String[MainActivity.coreNum + 1]; // placeholder for each core String[] cpuUsage = new String[MainActivity.coreNum + 1]; // placeholder for each core
String[] cpuFreq = new String[MainActivity.coreNum]; // placeholder for each core String[] cpuFreq = new String[MainActivity.coreNum]; // placeholder for each core
// first line to write is instruction
tmp = "# timestamp totalUsage";
for (i = 0; i < MainActivity.coreNum; ++i) {
tmp += " cpu" + i + " freq" + i;
}
tmp += "\n";
// if SSLogger is set to run // if SSLogger is set to run
while(isRunning) { while(isRunning) {
@ -77,7 +70,7 @@ public class SSLogger extends Service {
readFrequency(cpuFreq); readFrequency(cpuFreq);
// construct bytes for cpuRaw log // construct bytes for cpuRaw log
tmp += mTime + " " + cpuUsage[0]; tmp = mTime + " " + cpuUsage[0];
for (i = 0; i < MainActivity.coreNum; ++i) { for (i = 0; i < MainActivity.coreNum; ++i) {
tmp += " " + cpuUsage[i + 1] + " " + cpuFreq[i]; tmp += " " + cpuUsage[i + 1] + " " + cpuFreq[i];
} }
@ -186,12 +179,6 @@ public class SSLogger extends Service {
// permission error // permission error
if (!Utilities.canWriteOnExternalStorage()) { if (!Utilities.canWriteOnExternalStorage()) {
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Can't write sdcard\n");
}
});
onDestroy(); onDestroy();
} }

View File

@ -24,6 +24,7 @@ import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.Locale;
/** /**
* Created by yanzi on 10/1/15. * Created by yanzi on 10/1/15.
@ -33,8 +34,9 @@ public class Utilities {
private static final String TAG = "Utilities"; private static final String TAG = "Utilities";
// variables // variables
protected static String myInetIP = "127.0.0.1"; static int oneMB = 1048576;
protected static String myMAC = ""; static String myInetIP = null;
static String myMAC = null;
// Storage Permissions // Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1; private static final int REQUEST_EXTERNAL_STORAGE = 1;
@ -43,13 +45,15 @@ public class Utilities {
Manifest.permission.WRITE_EXTERNAL_STORAGE Manifest.permission.WRITE_EXTERNAL_STORAGE
}; };
/** /**
* Android 6.0 + required * Android 6.0 + required
* Checks if the app has permission to write to device storage * Checks if the app has permission to write to device storage
* If the app does not has permission then the user will be prompted to grant permissions * If the app does not has permission then the user will be prompted to grant permissions
* @param activity * @param activity:
*/ */
public static void verifyStoragePermissions(Activity activity) { static void verifyStoragePermissions(Activity activity) {
// Check if we have write permission // Check if we have write permission
int permission = ActivityCompat.checkSelfPermission( int permission = ActivityCompat.checkSelfPermission(
activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
@ -69,7 +73,7 @@ public class Utilities {
* check if we can write on external storage * check if we can write on external storage
* @return true/false * @return true/false
*/ */
public static boolean canWriteOnExternalStorage() { static boolean canWriteOnExternalStorage() {
String state = Environment.getExternalStorageState(); String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) { if (Environment.MEDIA_MOUNTED.equals(state)) {
return true; return true;
@ -80,11 +84,13 @@ public class Utilities {
/** /**
* get the ip and mac addresses * get the ip and mac addresses
*/ */
protected static void getSelfIdentity(String interface_name, boolean useIPv4) { static void getSelfIdentity(String interface_name, boolean useIPv4) {
String name; String name;
Enumeration<NetworkInterface> networks; Enumeration<NetworkInterface> networks;
Enumeration<InetAddress> inetAddresses; Enumeration<InetAddress> inetAddresses;
NetworkInterface network; NetworkInterface network;
myInetIP = null;
myMAC = null;
try { try {
networks = NetworkInterface.getNetworkInterfaces(); networks = NetworkInterface.getNetworkInterfaces();
@ -109,7 +115,6 @@ public class Utilities {
} }
myMAC = sb.toString(); myMAC = sb.toString();
} }
Log.d(TAG, "myMAC: " + myMAC);
// get the ip address // get the ip address
inetAddresses = network.getInetAddresses(); inetAddresses = network.getInetAddresses();
@ -132,21 +137,32 @@ public class Utilities {
} }
} }
} }
Log.d(TAG, "myIP: " + myInetIP);
} }
} catch (SocketException e) { } catch (SocketException e) {
e.printStackTrace(); e.printStackTrace();
} }
if (myMAC == null) {
Log.d(TAG, "Failed to get MAC from interface " + interface_name);
myMAC = "00:00:00:00:00:00";
}
if (myInetIP == null) {
Log.d(TAG, "Failed to get IP from interface " + interface_name);
myInetIP = "127.0.0.1";
}
Log.d(TAG, "myMAC: " + myMAC);
Log.d(TAG, "myIP: " + myInetIP);
} }
/** /**
* parse binary file output * parse binary file output
* @param output * @param output:
* @return double * @return double
*/ */
protected static double parseBinOutput(String output) { static double parseBinOutput(String output) {
String[] toks = output.trim().split(":"); String[] toks = output.trim().split(":");
if (toks.length == 2) { if (toks.length == 2) {
return Double.parseDouble(toks[1]); return Double.parseDouble(toks[1]);
@ -158,7 +174,7 @@ public class Utilities {
* get the number of cores of device * get the number of cores of device
* @return int > 0 * @return int > 0
*/ */
protected static int getNumCores() { static int getNumCores() {
Process proc; Process proc;
BufferedReader stdout_buf; BufferedReader stdout_buf;
String stdout; String stdout;
@ -202,40 +218,45 @@ public class Utilities {
*/ */
protected static int getMyPID(String inName, boolean flag) { protected static int getMyPID(String inName, boolean flag) {
String commd; String commd;
Process proc;
BufferedReader stdout_buf;
String stdout;
// get commd ready
if (flag) if (flag)
commd = "su -c busybox ps | grep " commd = "su -c busybox ps | grep "
+ inName + " | grep -v grep | head -1 | awk '{print $1}'"; + inName + " | grep -v grep | head -1 | awk '{print $1}'";
else else
commd = "su -c busybox ps | grep " commd = "su -c busybox ps | grep "
+ inName + " | grep -v grep | head -1 | awk '{print $3}'"; + inName + " | grep -v grep | head -1 | awk '{print $3}'";
try { try {
Process proc = Runtime.getRuntime().exec(commd); proc = Runtime.getRuntime().exec(commd);
proc.waitFor(); proc.waitFor();
String line;
StringBuilder out = new StringBuilder(); // read std out
BufferedReader is = new BufferedReader( stdout_buf = new BufferedReader(new InputStreamReader(
new InputStreamReader(proc.getInputStream())); proc.getInputStream()));
while ((line = is.readLine()) != null) {
out.append(line).append("\n"); stdout = stdout_buf.readLine();
stdout_buf.close();
if (! stdout.equals("")) {
Log.d(TAG, inName + "PID: " + stdout);
return Integer.parseInt(stdout);
} }
String tmp = out.toString().trim(); } catch (InterruptedException | IOException ignored) {
if (!tmp.equals("")) { Log.d(TAG, "Faild to fetch PID for " + inName);
return Integer.parseInt(tmp);
}
} catch (InterruptedException unimportant) {
Log.d(TAG, "InterruptedException but unimportant");
} catch (IOException e) {
Log.d(TAG, "IOException but unimportant");
} }
return -1; return -1;
} }
/** /**
* check if a file exists * check if a file exists
* @param myFile * @param myFile:
* @return true/false * @return true/false
*/ */
protected static boolean fileExist(String myFile) { static boolean fileExist(String myFile) {
File file = new File(myFile); File file = new File(myFile);
if (file.exists() && file.isFile()) if (file.exists() && file.isFile())
return true; return true;
@ -244,11 +265,11 @@ public class Utilities {
/** /**
* check if a directory exists * check if a directory exists
* @param myDirectory * @param myDirectory:
* @param createIfNot: try to create the folder if directory does not exist * @param createIfNot: try to create the folder if directory does not exist
* @return true/false * @return true/false
*/ */
protected static boolean dirExist(String myDirectory, boolean createIfNot) { static boolean dirExist(String myDirectory, boolean createIfNot) {
File file = new File(myDirectory); File file = new File(myDirectory);
if (file.exists() && file.isDirectory()) if (file.exists() && file.isDirectory())
return true; return true;
@ -264,47 +285,73 @@ public class Utilities {
} }
/** /**
* parse CPU for a folder * post parse CPU for a folder
* @param folderName * @param folderName:
* @return true/false * @return true/false
*/ */
protected static boolean parseCPUforFolder(String folderName) { static boolean parseCPUforFolder(String folderName) {
Process proc;
BufferedReader stdout_buf, br;
FileOutputStream os_cpu;
String cpuFile, line, tmp;
int i, offset;
try { try {
Process proc = Runtime.getRuntime().exec( proc = Runtime.getRuntime().exec(
"su && cd " + MainActivity.outFolderPath + "/" "su && cd " + MainActivity.outFolderPath + "/"
+ folderName + " && ls *.cpuRaw"); + folderName + " && ls *.cpuRaw");
proc.waitFor(); proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20]; // read std out
int read; stdout_buf = new BufferedReader(new InputStreamReader(
StringBuilder out = new StringBuilder(); proc.getInputStream()));
while(true){
read = stdout.read(buffer); while ((cpuFile = stdout_buf.readLine()) != null) {
if(read<0){ br = new BufferedReader(new FileReader(
Log.d(TAG, "Failed in parseCPUforFolder: ls nothing");
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
if (!out.toString().equals("")) {
String[] cpuFiles = out.toString().split("\\n");
for (int i = 0; i < cpuFiles.length; ++i) {
try {
BufferedReader br = new BufferedReader(
new FileReader(
MainActivity.outFolderPath + "/" MainActivity.outFolderPath + "/"
+ folderName + "/" + cpuFiles[i])); + folderName + "/" + cpuFile));
FileOutputStream os_cpu = new FileOutputStream(
new File( os_cpu = new FileOutputStream(new File(
MainActivity.outFolderPath + "/" MainActivity.outFolderPath + "/"
+ folderName, + folderName + "/" + cpuFile.replace("cpuRaw", "cpu")));
cpuFiles[i].replace("cpuRaw", "cpu")));
String line;
while ((line = br.readLine()) != null) { while ((line = br.readLine()) != null) {
String[] toks = line.split("\\s+");
String[] s = line.split("\\s+");
/*
* each line format as the following
* [ // 0 1 2 3 4 5 6 7 8 9-11
* timestamp, "cpu", user, nice, system, idle, iowait, irq, softirq, 0, 0, 0,
* // 12 13 14 15 16 17 18 19 20-22 23
* "cpu0", user, nice, system, idle, iowait, irq, softirq, 0, 0, 0, frequency,
* ...
* ]
*/
tmp = s[0] + " " // timestamp
+ s[5] + " " // cpu_total idle
+ parseUsedCPU(s, 1); // cpu_total used
for (i = 0; i < MainActivity.coreNum; ++i) {
offset = (i + 1) * 12;
tmp += " " + s[4 + offset] // cpu_i idle
+ " " + parseUsedCPU(s, offset) // cpu_i used
+ " " + s[offset + 11]; // cpu_i frequency
}
tmp += "\n";
/*
* convert to parsed format (each line):
* [
* timestamp, cpu_total idle, cpu_total used,
* cpu_0 idle, cpu_0 used, cpu_0 frequency,
* ...
* ]
*/
os_cpu.write(tmp.getBytes());
// format for Ana's script: // format for Ana's script:
// time // time
// cpuTotal idle // cpuTotal idle
@ -325,55 +372,67 @@ public class Utilities {
// cpu0 IO // cpu0 IO
// cpu0 hardware interrupts // cpu0 hardware interrupts
// cpu0 software interrupts // cpu0 software interrupts
os_cpu.write((toks[0] + " " // time // os_cpu.write((toks[0] + " " // time
// cpuTotal toks[1-11] // // cpuTotal toks[1-11]
+ toks[5] + " " // cpuTotal idle // + toks[5] + " " // cpuTotal idle
// cpuTotal used // // cpuTotal used
+ (Long.parseLong(toks[2]) + Long.parseLong(toks[3]) // + (Long.parseLong(toks[2]) + Long.parseLong(toks[3])
+ Long.parseLong(toks[4]) + Long.parseLong(toks[6]) // + Long.parseLong(toks[4]) + Long.parseLong(toks[6])
+ Long.parseLong(toks[7]) + Long.parseLong(toks[8])) + " " // + Long.parseLong(toks[7]) + Long.parseLong(toks[8])) + " "
// cpu 0 toks[12-22] // // cpu 0 toks[12-22]
+ toks[16] + " " // cpu0 idle // + toks[16] + " " // cpu0 idle
// cpu0 used // // cpu0 used
+ (Long.parseLong(toks[13]) + Long.parseLong(toks[14]) // + (Long.parseLong(toks[13]) + Long.parseLong(toks[14])
+ Long.parseLong(toks[15]) + Long.parseLong(toks[17]) // + Long.parseLong(toks[15]) + Long.parseLong(toks[17])
+ Long.parseLong(toks[18]) + Long.parseLong(toks[19])) + " " // + Long.parseLong(toks[18]) + Long.parseLong(toks[19])) + " "
// cpu 0 freq toks[23] // // cpu 0 freq toks[23]
+ toks[23] + " " // + toks[23] + " "
// cpu 1 freq toks[35] // // cpu 1 freq toks[35]
+ toks[35] + " " // + toks[35] + " "
// cpuTotal details // // cpuTotal details
+ toks[2] + " " + toks[3] + " " + toks[4] + " " // + toks[2] + " " + toks[3] + " " + toks[4] + " "
+ toks[6] + " " + toks[7] + " " + toks[8] + " " // + toks[6] + " " + toks[7] + " " + toks[8] + " "
// cpu0 details // // cpu0 details
+ toks[13] + " " + toks[14] + " " + toks[15] + " " // + toks[13] + " " + toks[14] + " " + toks[15] + " "
+ toks[17] + " " + toks[18] + " " + toks[19]).getBytes()); // + toks[17] + " " + toks[18] + " " + toks[19]).getBytes());
// cpu 1 toks[24-34] // // cpu 1 toks[24-34]
os_cpu.write("\n".getBytes()); // os_cpu.write("\n".getBytes());
os_cpu.flush();
} }
br.close();
os_cpu.close(); os_cpu.close();
} catch (IOException unimportant) {
return false;
} }
}
} stdout_buf.close();
} catch (IOException e) {
// e.printStackTrace(); } catch (IOException | InterruptedException ignore) {
return false;
} catch (InterruptedException e) {
// e.printStackTrace();
return false; return false;
} }
return true; return true;
} }
/**
* parse the cpu usage (used)
* @param tmp: cpu usage
* @return long: used cpu usage
*/
static Long parseUsedCPU(String[] tmp, int offset) {
return (Long.parseLong(tmp[1 + offset])
+ Long.parseLong(tmp[2 + offset])
+ Long.parseLong(tmp[3 + offset])
+ Long.parseLong(tmp[5 + offset])
+ Long.parseLong(tmp[6 + offset])
+ Long.parseLong(tmp[7 + offset]));
}
/** /**
* Translate the selection index into throughput setup * Translate the selection index into throughput setup
* @param myI * @param myI:
* @return * @return integer
*/ */
protected static int findCorrespondingThrpt(int myI) { static int findCorrespondingThrpt(int myI) {
if (myI < 19) { if (myI < 19) {
return (800 - (myI * 40)) * 1000000; return (800 - (myI * 40)) * 1000000;
} else if (myI < 37) { } else if (myI < 37) {
@ -390,8 +449,18 @@ public class Utilities {
} }
} }
protected static void estimateTime(int numRepeats, int numSelectedItems, int totalBytes, ArrayList<Integer> selectedItemsThrpt) { /**
* Estimate how much time left
* @param numRepeats:
* @param numSelectedItems:
* @param totalBytes:
* @param selectedItemsThrpt:
*/
static void estimateTime(
int numRepeats, int numSelectedItems, int totalBytes,
ArrayList<Integer> selectedItemsThrpt) {
int time = 0; int time = 0;
if (MainActivity.isLocal) { if (MainActivity.isLocal) {
for (int k = 0; k < selectedItemsThrpt.size(); ++k) for (int k = 0; k < selectedItemsThrpt.size(); ++k)
time += (Math.max(totalBytes / findCorrespondingThrpt(selectedItemsThrpt.get(k)) + 20, 20)); time += (Math.max(totalBytes / findCorrespondingThrpt(selectedItemsThrpt.get(k)) + 20, 20));
@ -399,8 +468,13 @@ public class Utilities {
for (int k = 0; k < selectedItemsThrpt.size(); ++k) for (int k = 0; k < selectedItemsThrpt.size(); ++k)
time += (Math.max(totalBytes / findCorrespondingThrpt(selectedItemsThrpt.get(k)) + 20, 60)); time += (Math.max(totalBytes / findCorrespondingThrpt(selectedItemsThrpt.get(k)) + 20, 60));
} }
time = (time + 15) * numSelectedItems * numRepeats * 1000; time = (time + 15) * numSelectedItems * numRepeats * 1000;
final String estimatedTime = new SimpleDateFormat("MM/dd HH:mm:ss").format(new Date(System.currentTimeMillis() + time));
final String estimatedTime =
new SimpleDateFormat("MM/dd HH:mm:ss", Locale.US).format(
new Date(System.currentTimeMillis() + time));
MainActivity.myHandler.post(new Runnable() { MainActivity.myHandler.post(new Runnable() {
@Override @Override
public void run() { public void run() {