mirror of
https://github.com/syncthing/syncthing-android.git
synced 2024-11-26 06:11:19 +00:00
Merge branch 'master' of https://github.com/syncthing/syncthing-android into fixDoubleBinaryStarts
This commit is contained in:
commit
17098106eb
3 changed files with 93 additions and 52 deletions
|
@ -9,6 +9,7 @@ import android.os.Bundle;
|
|||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toast;
|
||||
|
@ -21,6 +22,7 @@ import javax.inject.Inject;
|
|||
|
||||
public class FirstStartActivity extends Activity implements Button.OnClickListener {
|
||||
|
||||
private static String TAG = "FirstStartActivity";
|
||||
private static final int REQUEST_WRITE_STORAGE = 142;
|
||||
|
||||
@Inject SharedPreferences mPreferences;
|
||||
|
@ -32,18 +34,13 @@ public class FirstStartActivity extends Activity implements Button.OnClickListen
|
|||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
((SyncthingApp) getApplication()).component().inject(this);
|
||||
startService(new Intent(this, SyncthingService.class));
|
||||
|
||||
if (!isFirstStart()) {
|
||||
if (haveStoragePermission()) {
|
||||
startApp();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
requestStoragePermission();
|
||||
}
|
||||
startApp();
|
||||
return;
|
||||
}
|
||||
|
||||
// Show first start UI.
|
||||
setContentView(R.layout.activity_first_start);
|
||||
Button cont = findViewById(R.id.cont);
|
||||
cont.setOnClickListener(this);
|
||||
|
@ -54,11 +51,23 @@ public class FirstStartActivity extends Activity implements Button.OnClickListen
|
|||
}
|
||||
|
||||
private void startApp() {
|
||||
if (!haveStoragePermission()) {
|
||||
requestStoragePermission();
|
||||
/**
|
||||
* startApp will be called in {@link #onRequestPermissionsResult()}
|
||||
* after permission was granted.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isFirstStart = isFirstStart();
|
||||
if (isFirstStart) {
|
||||
Log.v(TAG, "User completed first start UI.");
|
||||
mPreferences.edit().putBoolean("first_start", false).apply();
|
||||
}
|
||||
|
||||
startService(new Intent(this, SyncthingService.class));
|
||||
|
||||
// In case start_into_web_gui option is enabled, start both activities so that back
|
||||
// navigation works as expected.
|
||||
Intent mainIntent = new Intent(this, MainActivity.class);
|
||||
|
@ -86,12 +95,7 @@ public class FirstStartActivity extends Activity implements Button.OnClickListen
|
|||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (!haveStoragePermission()) {
|
||||
requestStoragePermission();
|
||||
}
|
||||
else {
|
||||
startApp();
|
||||
}
|
||||
startApp();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -8,6 +8,8 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
public class Constants {
|
||||
|
||||
public static final String FILENAME_SYNCTHING_BINARY = "libsyncthing.so";
|
||||
|
||||
public static final String PREF_ALWAYS_RUN_IN_BACKGROUND = "always_run_in_background";
|
||||
public static final String PREF_SYNC_ONLY_WIFI = "sync_only_wifi";
|
||||
public static final String PREF_SYNC_ONLY_WIFI_SSIDS = "sync_only_wifi_ssids_set";
|
||||
|
@ -81,7 +83,7 @@ public class Constants {
|
|||
}
|
||||
|
||||
static File getSyncthingBinary(Context context) {
|
||||
return new File(context.getApplicationInfo().nativeLibraryDir, "libsyncthing.so");
|
||||
return new File(context.getApplicationInfo().nativeLibraryDir, FILENAME_SYNCTHING_BINARY);
|
||||
}
|
||||
|
||||
static File getLogFile(Context context) {
|
||||
|
|
|
@ -12,6 +12,7 @@ import com.google.common.base.Charsets;
|
|||
import com.google.common.io.Files;
|
||||
import com.nutomic.syncthingandroid.R;
|
||||
import com.nutomic.syncthingandroid.SyncthingApp;
|
||||
import com.nutomic.syncthingandroid.service.Constants;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
|
@ -24,7 +25,9 @@ import java.io.InputStream;
|
|||
import java.io.InputStreamReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.security.InvalidParameterException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
|
@ -208,6 +211,51 @@ public class SyncthingRunnable implements Runnable {
|
|||
return mPreferences.getBoolean(Constants.PREF_USE_WAKE_LOCK, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for running libsyncthing.so processes and return an array
|
||||
* containing the PIDs of found instances.
|
||||
*/
|
||||
private List<String> getSyncthingPIDs() {
|
||||
List<String> libSyncthingPID = new ArrayList<String>();
|
||||
Process ps = null;
|
||||
DataOutputStream psOut = null;
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
ps = Runtime.getRuntime().exec((mUseRoot) ? "su" : "sh");
|
||||
psOut = new DataOutputStream(ps.getOutputStream());
|
||||
psOut.writeBytes("ps\n");
|
||||
psOut.writeBytes("exit\n");
|
||||
psOut.flush();
|
||||
ps.waitFor();
|
||||
br = new BufferedReader(new InputStreamReader(ps.getInputStream(), "UTF-8"));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
if (line.contains(Constants.FILENAME_SYNCTHING_BINARY)) {
|
||||
String syncthingPID = line.trim().split("\\s+")[1];
|
||||
Log.v(TAG, "getSyncthingPIDs: Found process PID [" + syncthingPID + "]");
|
||||
libSyncthingPID.add(syncthingPID);
|
||||
}
|
||||
}
|
||||
} catch (IOException | InterruptedException e) {
|
||||
Log.w(TAG_KILL, "Failed list Syncthing processes", e);
|
||||
} finally {
|
||||
try {
|
||||
if (br != null) {
|
||||
br.close();
|
||||
}
|
||||
if (psOut != null) {
|
||||
psOut.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG_KILL, "Failed close the psOut stream", e);
|
||||
}
|
||||
if (ps != null) {
|
||||
ps.destroy();
|
||||
}
|
||||
}
|
||||
return libSyncthingPID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for a running libsyncthing.so process and nice its IO.
|
||||
*/
|
||||
|
@ -219,15 +267,22 @@ public class SyncthingRunnable implements Runnable {
|
|||
int ret = 1;
|
||||
try {
|
||||
Thread.sleep(1000); // Wait a second before getting the pid
|
||||
nice = Runtime.getRuntime().exec((mUseRoot) ? "su" : "sh");
|
||||
niceOut = new DataOutputStream(nice.getOutputStream());
|
||||
niceOut.writeBytes("set `ps | grep libsyncthing.so`\n");
|
||||
niceOut.writeBytes("ionice $2 be 7\n"); // best-effort, low priority
|
||||
niceOut.writeBytes("exit\n");
|
||||
log(nice.getErrorStream(), Log.WARN, false);
|
||||
niceOut.flush();
|
||||
ret = nice.waitFor();
|
||||
Log.i(TAG_NICE, "ionice performed on libsyncthing.so");
|
||||
List<String> libSyncthingPID = getSyncthingPIDs();
|
||||
if (libSyncthingPID.isEmpty()) {
|
||||
Log.w(TAG, "niceSyncthing: Found no running instances of " + Constants.FILENAME_SYNCTHING_BINARY);
|
||||
} else {
|
||||
nice = Runtime.getRuntime().exec((mUseRoot) ? "su" : "sh");
|
||||
niceOut = new DataOutputStream(nice.getOutputStream());
|
||||
for (String runningPID : libSyncthingPID) {
|
||||
// Set best-effort, low priority using ionice.
|
||||
niceOut.writeBytes("ionice " + runningPID + " be 7\n");
|
||||
}
|
||||
niceOut.writeBytes("exit\n");
|
||||
log(nice.getErrorStream(), Log.WARN, false);
|
||||
niceOut.flush();
|
||||
ret = nice.waitFor();
|
||||
Log.i(TAG_NICE, "ionice performed on " + Constants.FILENAME_SYNCTHING_BINARY);
|
||||
}
|
||||
} catch (IOException | InterruptedException e) {
|
||||
Log.e(TAG_NICE, "Failed to execute ionice binary", e);
|
||||
} finally {
|
||||
|
@ -259,34 +314,14 @@ public class SyncthingRunnable implements Runnable {
|
|||
public void killSyncthing(OnSyncthingKilled onKilledListener) {
|
||||
new Thread(() -> {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
Process ps = null;
|
||||
DataOutputStream psOut = null;
|
||||
try {
|
||||
ps = Runtime.getRuntime().exec((mUseRoot) ? "su" : "sh");
|
||||
psOut = new DataOutputStream(ps.getOutputStream());
|
||||
psOut.writeBytes("ps | grep libsyncthing.so\n");
|
||||
psOut.writeBytes("exit\n");
|
||||
psOut.flush();
|
||||
ps.waitFor();
|
||||
InputStreamReader isr = new InputStreamReader(ps.getInputStream(), "UTF-8");
|
||||
BufferedReader br = new BufferedReader(isr);
|
||||
String id;
|
||||
while ((id = br.readLine()) != null) {
|
||||
id = id.trim().split("\\s+")[1];
|
||||
killProcessId(id, i > 0);
|
||||
}
|
||||
} catch (IOException | InterruptedException e) {
|
||||
Log.w(TAG_KILL, "Failed list Syncthing processes", e);
|
||||
} finally {
|
||||
try {
|
||||
if (psOut != null)
|
||||
psOut.close();
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG_KILL, "Failed close the psOut stream", e);
|
||||
}
|
||||
if (ps != null) {
|
||||
ps.destroy();
|
||||
}
|
||||
List<String> libSyncthingPID = getSyncthingPIDs();
|
||||
if (libSyncthingPID.isEmpty()) {
|
||||
Log.d(TAG, "killSyncthing: Found no more running instances of " + Constants.FILENAME_SYNCTHING_BINARY);
|
||||
break;
|
||||
}
|
||||
|
||||
for (String runningPID : libSyncthingPID) {
|
||||
killProcessId(runningPID, i > 0);
|
||||
}
|
||||
}
|
||||
onKilledListener.onKilled();
|
||||
|
|
Loading…
Reference in a new issue