VpnService: Add helper for importing configs

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Samuel Holland 2017-11-08 00:49:44 -06:00
parent 70156381a7
commit cd6a124c84

View File

@ -2,8 +2,10 @@ package com.wireguard.android;
import android.app.Service; import android.app.Service;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Binder; import android.os.Binder;
import android.os.Build; import android.os.Build;
@ -21,7 +23,10 @@ import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
@ -112,6 +117,10 @@ public class VpnService extends Service
return configurations; return configurations;
} }
public void importFrom(final Uri... uris) {
new ConfigImporter().execute(uris);
}
@Override @Override
public IBinder onBind(final Intent intent) { public IBinder onBind(final Intent intent) {
instance = this; instance = this;
@ -268,6 +277,47 @@ public class VpnService extends Service
} }
} }
private class ConfigImporter extends AsyncTask<Uri, Void, List<File>> {
@Override
protected List<File> doInBackground(final Uri... uris) {
final ContentResolver contentResolver = getContentResolver();
final List<File> files = new ArrayList<>(uris.length);
for (final Uri uri : uris) {
if (isCancelled())
return null;
String name = Uri.decode(uri.getLastPathSegment());
if (name.indexOf('/') >= 0)
name = name.substring(name.lastIndexOf('/'));
if (!name.endsWith(".conf"))
name = name + ".conf";
final File output = new File(getFilesDir(), name);
if (output.exists()) {
Log.w(getClass().getSimpleName(), "Config file for " + uri + " already exists");
continue;
}
try (final InputStream in = contentResolver.openInputStream(uri);
final OutputStream out = new FileOutputStream(output, false)) {
if (in == null)
throw new IOException("Failed to open input");
// FIXME: This is a rather arbitrary size.
final byte[] buffer = new byte[4096];
int bytes;
while ((bytes = in.read(buffer)) != -1)
out.write(buffer, 0, bytes);
files.add(output);
} catch (final IOException e) {
Log.w(getClass().getSimpleName(), "Failed to import config from " + uri, e);
}
}
return files;
}
@Override
protected void onPostExecute(final List<File> files) {
new ConfigLoader().execute(files.toArray(new File[files.size()]));
}
}
private class ConfigLoader extends AsyncTask<File, Void, List<Config>> { private class ConfigLoader extends AsyncTask<File, Void, List<Config>> {
@Override @Override
protected List<Config> doInBackground(final File... files) { protected List<Config> doInBackground(final File... files) {