From aa1b9e6696dc9181ca898a50743023126b4756a2 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 25 Apr 2014 21:34:30 -0400 Subject: [PATCH] allow incoming repos via Intent when on ManageRepo view Since before, incoming repo Intents where handled in the Fragment's onCreate(), an Intent that was received while the Fragment was visible was just ignored. Activities have onNewIntent() for that, but Fragments don't so the repo Intent handling had to be moved to the ManageRepo Activity. That makes for a more direct relationship anyway, since ManageRepo is what is configured as receiving all those Intents in AndroidManifest.xml. --- src/org/fdroid/fdroid/ManageRepo.java | 90 +++++++++++++++++++ .../views/fragments/RepoListFragment.java | 87 +++--------------- 2 files changed, 100 insertions(+), 77 deletions(-) diff --git a/src/org/fdroid/fdroid/ManageRepo.java b/src/org/fdroid/fdroid/ManageRepo.java index 665f8bd6c..733f0e063 100644 --- a/src/org/fdroid/fdroid/ManageRepo.java +++ b/src/org/fdroid/fdroid/ManageRepo.java @@ -20,17 +20,25 @@ package org.fdroid.fdroid; import android.app.Activity; +import android.content.Context; import android.content.Intent; +import android.net.Uri; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.app.NavUtils; +import android.text.TextUtils; import android.util.Log; import android.view.MenuItem; import android.widget.LinearLayout; +import android.widget.Toast; + import org.fdroid.fdroid.compat.ActionBarCompat; import org.fdroid.fdroid.views.fragments.RepoListFragment; +import java.util.Locale; public class ManageRepo extends FragmentActivity { /** @@ -68,6 +76,18 @@ public class ManageRepo extends FragmentActivity { ActionBarCompat.create(this).setDisplayHomeAsUpEnabled(true); } + @Override + protected void onResume() { + super.onResume(); + /* let's see if someone is trying to send us a new repo */ + addRepoFromIntent(getIntent()); + } + + @Override + protected void onNewIntent(Intent intent) { + addRepoFromIntent(intent); + } + @Override public void finish() { Intent ret = new Intent(); @@ -99,4 +119,74 @@ public class ManageRepo extends FragmentActivity { } return super.onOptionsItemSelected(item); } + + 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; + } + 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 + listFragment.importRepo(uriString, fingerprint); + + // 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; + } + 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")); + 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! + } + } + } + } } diff --git a/src/org/fdroid/fdroid/views/fragments/RepoListFragment.java b/src/org/fdroid/fdroid/views/fragments/RepoListFragment.java index fa43cb82b..7f04bd64f 100644 --- a/src/org/fdroid/fdroid/views/fragments/RepoListFragment.java +++ b/src/org/fdroid/fdroid/views/fragments/RepoListFragment.java @@ -63,8 +63,6 @@ public class RepoListFragment extends ListFragment private final int UPDATE_REPOS = 2; private final int SCAN_FOR_REPOS = 3; - private WifiManager wifiManager; - public boolean hasChanged() { return changed; } @@ -85,13 +83,11 @@ public class RepoListFragment extends ListFragment @Override public void onLoadFinished(Loader cursorLoader, Cursor cursor) { - Log.i("FDroid", "Repo cursor loaded."); repoAdapter.swapCursor(cursor); } @Override public void onLoaderReset(Loader cursorLoader) { - Log.i("FDroid", "Repo cursor reset."); repoAdapter.swapCursor(null); } @@ -186,79 +182,6 @@ public class RepoListFragment extends ListFragment super.onCreate(savedInstanceState); setHasOptionsMenu(true); - - /* let's see if someone is trying to send us a new repo */ - Intent intent = getActivity().getIntent(); - /* 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(getActivity(), msg, Toast.LENGTH_LONG).show(); - return; - } - 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"); - if (scheme.equals("fdroidrepos") || scheme.equals("fdroidrepo") - || scheme.equals("https") || scheme.equals("http")) { - - isImportingRepo = true; - - /* 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 - showAddRepo(uriString, fingerprint); - - // 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; - } - Activity a = getActivity(); - if (wifiManager == null) - wifiManager = (WifiManager) a.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")); - Toast.makeText(a, msg, Toast.LENGTH_LONG).show(); - } - // TODO we should help the user to the right thing here, - // instead of just showing a message! - } - } - } } @Override @@ -375,6 +298,11 @@ public class RepoListFragment extends ListFragment nsdHelper.discoverServices(); } + public void importRepo(String uri, String fingerprint) { + isImportingRepo = true; + showAddRepo(uri, fingerprint); + } + private void showAddRepo() { showAddRepo(getNewRepoUri(), null); } @@ -385,6 +313,11 @@ public class RepoListFragment extends ListFragment final EditText uriEditText = (EditText) view.findViewById(R.id.edit_uri); final EditText fingerprintEditText = (EditText) view.findViewById(R.id.edit_fingerprint); + /* + * If the "add new repo" dialog is launched by an action outside of + * FDroid, i.e. a URL, then check to see if any existing repos match, + * and change the action accordingly. + */ final Repo repo = (newAddress != null && isImportingRepo) ? RepoProvider.Helper.findByAddress(getActivity(), newAddress) : null;