ProfileService: Implement the rest of its interface
As per the FIXMEs, the list of profiles should eventually become a map. Since it can only be modified on the main thread anyway, the current code is still safe, and it works, it's just not optimal. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
0ea5ae605c
commit
b6653fd7f0
@ -12,8 +12,10 @@ import android.util.Log;
|
||||
import com.wireguard.config.Profile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@ -47,6 +49,84 @@ public class ProfileService extends Service {
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
private class ProfileAdder extends AsyncTask<Void, Void, Boolean> {
|
||||
private final Profile profile;
|
||||
|
||||
private ProfileAdder(Profile profile) {
|
||||
super();
|
||||
this.profile = profile;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... voids) {
|
||||
Log.i(TAG, "Adding profile " + profile.getName());
|
||||
try {
|
||||
final String configFile = profile.getName() + ".conf";
|
||||
final FileOutputStream stream = openFileOutput(configFile, MODE_PRIVATE);
|
||||
stream.write(profile.toString().getBytes(StandardCharsets.UTF_8));
|
||||
stream.close();
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Could not create profile " + profile.getName(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
if (!result)
|
||||
return;
|
||||
profile.setIsConnected(false);
|
||||
profiles.add(profile);
|
||||
}
|
||||
}
|
||||
|
||||
private class ProfileConnecter extends AsyncTask<Void, Void, Boolean> {
|
||||
private final Profile profile;
|
||||
|
||||
private ProfileConnecter(Profile profile) {
|
||||
super();
|
||||
this.profile = profile;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... voids) {
|
||||
Log.i(TAG, "Running wg-quick up for profile " + profile.getName());
|
||||
final File configFile = new File(getFilesDir(), profile.getName() + ".conf");
|
||||
return RootShell.run(null, "wg-quick up '" + configFile.getPath() + "'") == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
if (!result)
|
||||
return;
|
||||
profile.setIsConnected(true);
|
||||
}
|
||||
}
|
||||
|
||||
private class ProfileDisconnecter extends AsyncTask<Void, Void, Boolean> {
|
||||
private final Profile profile;
|
||||
|
||||
private ProfileDisconnecter(Profile profile) {
|
||||
super();
|
||||
this.profile = profile;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... voids) {
|
||||
Log.i(TAG, "Running wg-quick down for profile " + profile.getName());
|
||||
final File configFile = new File(getFilesDir(), profile.getName() + ".conf");
|
||||
return RootShell.run(null, "wg-quick down '" + configFile.getPath() + "'") == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
if (!result)
|
||||
return;
|
||||
profile.setIsConnected(false);
|
||||
}
|
||||
}
|
||||
|
||||
private class ProfileLoader extends AsyncTask<File, Void, List<Profile>> {
|
||||
@Override
|
||||
protected List<Profile> doInBackground(File... files) {
|
||||
@ -83,9 +163,82 @@ public class ProfileService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
private class ProfileRemover extends AsyncTask<Void, Void, Boolean> {
|
||||
private final Profile profile;
|
||||
|
||||
private ProfileRemover(Profile profile) {
|
||||
super();
|
||||
this.profile = profile;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... voids) {
|
||||
Log.i(TAG, "Removing profile " + profile.getName());
|
||||
final File configFile = new File(getFilesDir(), profile.getName() + ".conf");
|
||||
if (configFile.delete()) {
|
||||
return true;
|
||||
} else {
|
||||
Log.e(TAG, "Could not delete configuration for profile " + profile.getName());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
if (!result)
|
||||
return;
|
||||
profiles.remove(profile);
|
||||
}
|
||||
}
|
||||
|
||||
private class ProfileUpdater extends AsyncTask<Void, Void, Boolean> {
|
||||
private final Profile profile, newProfile;
|
||||
private final boolean wasConnected;
|
||||
|
||||
private ProfileUpdater(Profile profile, Profile newProfile, boolean wasConnected) {
|
||||
super();
|
||||
this.profile = profile;
|
||||
this.newProfile = newProfile;
|
||||
this.wasConnected = wasConnected;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... voids) {
|
||||
Log.i(TAG, "Updating profile " + profile.getName());
|
||||
if (!newProfile.getName().equals(profile.getName()))
|
||||
throw new IllegalStateException("Profile name mismatch: " + profile.getName());
|
||||
try {
|
||||
final String configFile = profile.getName() + ".conf";
|
||||
final FileOutputStream stream = openFileOutput(configFile, MODE_PRIVATE);
|
||||
stream.write(newProfile.toString().getBytes(StandardCharsets.UTF_8));
|
||||
stream.close();
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Could not update profile " + profile.getName(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
if (!result)
|
||||
return;
|
||||
// FIXME: This is also why the list of profiles should be a map.
|
||||
final int index = profiles.indexOf(profile);
|
||||
profiles.set(index, newProfile);
|
||||
if (wasConnected)
|
||||
new ProfileConnecter(newProfile).execute();
|
||||
}
|
||||
}
|
||||
|
||||
private class ProfileServiceBinder extends Binder implements ProfileServiceInterface {
|
||||
@Override
|
||||
public void connectProfile(Profile profile) {
|
||||
if (!profiles.contains(profile))
|
||||
return;
|
||||
if (profile.getIsConnected())
|
||||
return;
|
||||
new ProfileConnecter(profile).execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -97,6 +250,11 @@ public class ProfileService extends Service {
|
||||
|
||||
@Override
|
||||
public void disconnectProfile(Profile profile) {
|
||||
if (!profiles.contains(profile))
|
||||
return;
|
||||
if (!profile.getIsConnected())
|
||||
return;
|
||||
new ProfileDisconnecter(profile).execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -106,10 +264,28 @@ public class ProfileService extends Service {
|
||||
|
||||
@Override
|
||||
public void removeProfile(Profile profile) {
|
||||
if (!profiles.contains(profile))
|
||||
return;
|
||||
if (profile.getIsConnected())
|
||||
new ProfileDisconnecter(profile).execute();
|
||||
new ProfileRemover(profile).execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveProfile(Profile newProfile) {
|
||||
// FIXME: This is why the list of profiles should be a map.
|
||||
Profile profile = null;
|
||||
for (Profile p : profiles)
|
||||
if (p.getName().equals(newProfile.getName()))
|
||||
profile = p;
|
||||
if (profile != null) {
|
||||
final boolean wasConnected = profile.getIsConnected();
|
||||
if (wasConnected)
|
||||
new ProfileDisconnecter(profile).execute();
|
||||
new ProfileUpdater(profile, newProfile, wasConnected).execute();
|
||||
} else {
|
||||
new ProfileAdder(newProfile).execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user