split out new, incoming repo configs into a separate class: NewRepoConfig
The swap stuff will also need to handle incoming Intents that represent new repos, so the parsing logic is now its own class NewRepoConfig, which is something like the Repo class, but using getters instead of properties. Since the new repo data does not change once FDroid receives it, the only way to set the values of a NewRepoConfig is via the constructor. This is based on some incomplete work from @pserwylo:71cb12ef5c (diff-6)
and71cb12ef5c (diff-7)
This commit is contained in:
parent
92199f2f01
commit
a525bca1cf
137
src/org/fdroid/fdroid/data/NewRepoConfig.java
Normal file
137
src/org/fdroid/fdroid/data/NewRepoConfig.java
Normal file
@ -0,0 +1,137 @@
|
||||
|
||||
package org.fdroid.fdroid.data;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import org.fdroid.fdroid.R;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
||||
public class NewRepoConfig {
|
||||
|
||||
private String errorMessage;
|
||||
private boolean isValidRepo;
|
||||
|
||||
private String uriString;
|
||||
private Uri uri;
|
||||
private String host;
|
||||
private int port = -1;
|
||||
private String scheme;
|
||||
private String fingerprint;
|
||||
private String bssid;
|
||||
private String ssid;
|
||||
|
||||
public NewRepoConfig(Context context, Intent intent) {
|
||||
/* an URL from a click, NFC, QRCode scan, etc */
|
||||
uri = intent.getData();
|
||||
if (uri == null) {
|
||||
isValidRepo = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// scheme and host should only ever be pure ASCII aka Locale.ENGLISH
|
||||
scheme = intent.getScheme();
|
||||
host = uri.getHost();
|
||||
port = uri.getPort();
|
||||
if (TextUtils.isEmpty(scheme) || TextUtils.isEmpty(host)) {
|
||||
errorMessage = String.format(context.getString(R.string.malformed_repo_uri),
|
||||
uri);
|
||||
isValidRepo = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Arrays.asList("FDROIDREPO", "FDROIDREPOS").contains(scheme)) {
|
||||
/*
|
||||
* QRCodes are more efficient in all upper case, so QR URIs are
|
||||
* encoded in all upper case, then forced to lower case. Checking if
|
||||
* the special F-Droid scheme being all is upper case means it
|
||||
* should be downcased.
|
||||
*/
|
||||
uri = Uri.parse(uri.toString().toLowerCase(Locale.ENGLISH));
|
||||
} else if (uri.getPath().endsWith("/FDROID/REPO")) {
|
||||
/*
|
||||
* some QR scanners chop off the fdroidrepo:// and just try http://,
|
||||
* then the incoming URI does not get downcased properly, and the
|
||||
* query string is stripped off. So just downcase the path, and
|
||||
* carry on to get something working.
|
||||
*/
|
||||
uri = Uri.parse(uri.toString().toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
// make scheme and host lowercase so they're readable in dialogs
|
||||
scheme = scheme.toLowerCase(Locale.ENGLISH);
|
||||
host = host.toLowerCase(Locale.ENGLISH);
|
||||
fingerprint = uri.getQueryParameter("fingerprint");
|
||||
bssid = uri.getQueryParameter("bssid");
|
||||
ssid = uri.getQueryParameter("ssid");
|
||||
|
||||
Log.i("RepoListFragment", "onCreate " + fingerprint);
|
||||
if (Arrays.asList("fdroidrepos", "fdroidrepo", "https", "http").contains(scheme)) {
|
||||
uriString = sanitizeRepoUri(uri);
|
||||
}
|
||||
|
||||
this.isValidRepo = true;
|
||||
}
|
||||
|
||||
public String getBssid() {
|
||||
return bssid;
|
||||
}
|
||||
|
||||
public String getSsid() {
|
||||
return ssid;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public String getUriString() {
|
||||
return uriString;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public String getScheme() {
|
||||
return scheme;
|
||||
}
|
||||
|
||||
public String getFingerprint() {
|
||||
return fingerprint;
|
||||
}
|
||||
|
||||
public boolean isValidRepo() {
|
||||
return isValidRepo;
|
||||
}
|
||||
|
||||
/*
|
||||
* The port starts out as 8888, but if there is a conflict, it will be
|
||||
* incremented until there is a free port found.
|
||||
*/
|
||||
public boolean looksLikeLocalRepo() {
|
||||
return (port >= 8888 && host.matches("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+"));
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
/** Sanitize and format an incoming repo URI for function and readability */
|
||||
public static String sanitizeRepoUri(Uri uri) {
|
||||
String scheme = uri.getScheme();
|
||||
String host = uri.getHost();
|
||||
return uri.toString()
|
||||
.replaceAll("\\?.*$", "") // remove the whole query
|
||||
.replaceAll("/*$", "") // remove all trailing slashes
|
||||
.replace(host, host.toLowerCase(Locale.ENGLISH))
|
||||
.replace(scheme, scheme.toLowerCase(Locale.ENGLISH))
|
||||
.replace("fdroidrepo", "http") // proper repo address
|
||||
.replace("/FDROID/REPO", "/fdroid/repo"); // for QR FDroid path
|
||||
}
|
||||
}
|
@ -60,6 +60,7 @@ import org.fdroid.fdroid.ProgressListener;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.UpdateService;
|
||||
import org.fdroid.fdroid.compat.ClipboardCompat;
|
||||
import org.fdroid.fdroid.data.NewRepoConfig;
|
||||
import org.fdroid.fdroid.data.Repo;
|
||||
import org.fdroid.fdroid.data.RepoProvider;
|
||||
import org.fdroid.fdroid.net.MDnsHelper;
|
||||
@ -443,73 +444,30 @@ public class ManageReposActivity extends ActionBarActivity {
|
||||
|
||||
private void addRepoFromIntent(Intent intent) {
|
||||
/* an URL from a click, NFC, QRCode scan, etc */
|
||||
Uri uri = intent.getData();
|
||||
if (uri != null) {
|
||||
// scheme and host should only ever be pure ASCII aka Locale.ENGLISH
|
||||
String scheme = intent.getScheme();
|
||||
String host = uri.getHost();
|
||||
if (scheme == null || host == null) {
|
||||
String msg = String.format(getString(R.string.malformed_repo_uri), uri);
|
||||
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
NewRepoConfig newRepoConfig = new NewRepoConfig(this, intent);
|
||||
if (newRepoConfig.isValidRepo()) {
|
||||
importRepo(newRepoConfig.getUriString(), newRepoConfig.getFingerprint());
|
||||
checkIfNewRepoOnSameWifi(newRepoConfig);
|
||||
} else if (newRepoConfig.getErrorMessage() != null) {
|
||||
Toast.makeText(this, newRepoConfig.getErrorMessage(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
if (scheme.equals("FDROIDREPO") || scheme.equals("FDROIDREPOS")) {
|
||||
/*
|
||||
* QRCodes are more efficient in all upper case, so QR URIs are
|
||||
* encoded in all upper case, then forced to lower case.
|
||||
* Checking if the special F-Droid scheme being all is upper
|
||||
* case means it should be downcased.
|
||||
*/
|
||||
uri = Uri.parse(uri.toString().toLowerCase(Locale.ENGLISH));
|
||||
} else if (uri.getPath().startsWith("/FDROID/REPO")) {
|
||||
/*
|
||||
* some QR scanners chop off the fdroidrepo:// and just try
|
||||
* http://, then the incoming URI does not get downcased
|
||||
* properly, and the query string is stripped off. So just
|
||||
* downcase the path, and carry on to get something working.
|
||||
*/
|
||||
uri = Uri.parse(uri.toString().toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
// make scheme and host lowercase so they're readable in dialogs
|
||||
scheme = scheme.toLowerCase(Locale.ENGLISH);
|
||||
host = host.toLowerCase(Locale.ENGLISH);
|
||||
String fingerprint = uri.getQueryParameter("fingerprint");
|
||||
Log.i("RepoListFragment", "onCreate " + fingerprint);
|
||||
if (scheme.equals("fdroidrepos") || scheme.equals("fdroidrepo")
|
||||
|| scheme.equals("https") || scheme.equals("http")) {
|
||||
|
||||
/* sanitize and format for function and readability */
|
||||
String uriString = uri.toString()
|
||||
.replaceAll("\\?.*$", "") // remove the whole query
|
||||
.replaceAll("/*$", "") // remove all trailing slashes
|
||||
.replace(uri.getHost(), host) // downcase host name
|
||||
.replace(intent.getScheme(), scheme) // downcase scheme
|
||||
.replace("fdroidrepo", "http"); // proper repo address
|
||||
importRepo(uriString, fingerprint);
|
||||
|
||||
private void checkIfNewRepoOnSameWifi(NewRepoConfig newRepo) {
|
||||
// if this is a local repo, check we're on the same wifi
|
||||
String uriBssid = uri.getQueryParameter("bssid");
|
||||
if (!TextUtils.isEmpty(uriBssid)) {
|
||||
if (uri.getPort() != 8888
|
||||
&& !host.matches("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+")) {
|
||||
Log.i("ManageRepo", "URI is not local repo: " + uri);
|
||||
return;
|
||||
}
|
||||
if (!TextUtils.isEmpty(newRepo.getBssid())) {
|
||||
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
|
||||
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
|
||||
String bssid = wifiInfo.getBSSID().toLowerCase(Locale.ENGLISH);
|
||||
uriBssid = Uri.decode(uriBssid).toLowerCase(Locale.ENGLISH);
|
||||
if (!bssid.equals(uriBssid)) {
|
||||
String msg = String.format(getString(R.string.not_on_same_wifi),
|
||||
uri.getQueryParameter("ssid"));
|
||||
String newRepoBssid = Uri.decode(newRepo.getBssid()).toLowerCase(Locale.ENGLISH);
|
||||
if (!bssid.equals(newRepoBssid)) {
|
||||
String msg = String.format(getString(R.string.not_on_same_wifi), newRepo.getSsid());
|
||||
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
// TODO we should help the user to the right thing here,
|
||||
// instead of just showing a message!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class RepoListFragment extends ListFragment
|
||||
implements LoaderManager.LoaderCallbacks<Cursor>, RepoAdapter.EnabledListener {
|
||||
|
Loading…
x
Reference in New Issue
Block a user