diff --git a/app/src/main/java/eu/faircode/email/EmailProvider.java b/app/src/main/java/eu/faircode/email/EmailProvider.java index 5f8531d815..e293c51817 100644 --- a/app/src/main/java/eu/faircode/email/EmailProvider.java +++ b/app/src/main/java/eu/faircode/email/EmailProvider.java @@ -360,13 +360,23 @@ public class EmailProvider implements Parcelable { return result; } + interface IDiscovery { + void onStatus(String status); + } + @NonNull static List fromDomain(Context context, String domain, Discover discover) throws IOException { - return fromEmail(context, domain, discover); + return fromEmail(context, domain, discover, + new IDiscovery() { + @Override + public void onStatus(String status) { + // Do nothing + } + }); } @NonNull - static List fromEmail(Context context, String email, Discover discover) throws IOException { + static List fromEmail(Context context, String email, Discover discover, IDiscovery intf) throws IOException { int at = email.indexOf('@'); String domain = (at < 0 ? email : email.substring(at + 1)); if (at < 0) @@ -400,7 +410,7 @@ public class EmailProvider implements Parcelable { } List candidates = - new ArrayList<>(_fromDomain(context, domain.toLowerCase(Locale.ROOT), email, discover)); + new ArrayList<>(_fromDomain(context, domain.toLowerCase(Locale.ROOT), email, discover, intf)); if (false) // Unsafe: the password could be sent to an unrelated email server try { @@ -421,7 +431,7 @@ public class EmailProvider implements Parcelable { InetAddress ialt = InetAddress.getByName(altName); if (!ialt.equals(iaddr)) { EntityLog.log(context, "Using website common name=" + altName); - candidates.addAll(_fromDomain(context, altName.toLowerCase(Locale.ROOT), email, discover)); + candidates.addAll(_fromDomain(context, altName.toLowerCase(Locale.ROOT), email, discover, intf)); } } catch (Throwable ex) { Log.w(ex); @@ -465,7 +475,7 @@ public class EmailProvider implements Parcelable { } while (candidates.size() == 0 && target.indexOf('.') > 0) { - candidates.addAll(_fromDomain(context, target, email, discover)); + candidates.addAll(_fromDomain(context, target, email, discover, intf)); int dot = target.indexOf('.'); target = target.substring(dot + 1); if (UriHelper.isTld(context, target)) @@ -565,13 +575,13 @@ public class EmailProvider implements Parcelable { } @NonNull - private static List _fromDomain(Context context, String domain, String email, Discover discover) { + private static List _fromDomain(Context context, String domain, String email, Discover discover, IDiscovery intf) { List result = new ArrayList<>(); try { // Assume the provider knows best Log.i("Provider from DNS domain=" + domain); - result.add(fromDNS(context, domain, discover)); + result.add(fromDNS(context, domain, discover, intf)); } catch (Throwable ex) { Log.w(ex); } @@ -579,7 +589,7 @@ public class EmailProvider implements Parcelable { try { // Check ISPDB Log.i("Provider from ISPDB domain=" + domain); - result.add(fromISPDB(context, domain, email)); + result.add(fromISPDB(context, domain, email, intf)); } catch (Throwable ex) { Log.w(ex); } @@ -587,7 +597,7 @@ public class EmailProvider implements Parcelable { try { // Scan ports Log.i("Provider from scan domain=" + domain); - result.add(fromScan(context, domain, discover)); + result.add(fromScan(context, domain, discover, intf)); } catch (Throwable ex) { Log.w(ex); } @@ -596,27 +606,28 @@ public class EmailProvider implements Parcelable { } @NonNull - private static EmailProvider fromISPDB(Context context, String domain, String email) throws Throwable { + private static EmailProvider fromISPDB(Context context, String domain, String email, IDiscovery intf) throws Throwable { // https://wiki.mozilla.org/Thunderbird:Autoconfiguration for (String link : Misc.getISPDBUrls(domain, email)) try { URL url = new URL(link); - return getISPDB(context, domain, url); + return getISPDB(context, domain, url, intf); } catch (Throwable ex) { Log.i(ex); } URL url = new URL("https://autoconfig.thunderbird.net/v1.1/" + domain); - return getISPDB(context, domain, url); + return getISPDB(context, domain, url, intf); } @NonNull - private static EmailProvider getISPDB(Context context, String domain, URL url) throws IOException, XmlPullParserException { + private static EmailProvider getISPDB(Context context, String domain, URL url, IDiscovery intf) throws IOException, XmlPullParserException { EmailProvider provider = new EmailProvider(domain); HttpURLConnection request = null; try { Log.i("Fetching " + url); + intf.onStatus(url.toString()); request = (HttpURLConnection) url.openConnection(); request.setRequestMethod("GET"); @@ -805,14 +816,16 @@ public class EmailProvider implements Parcelable { } @NonNull - private static EmailProvider fromDNS(Context context, String domain, Discover discover) throws UnknownHostException { + private static EmailProvider fromDNS(Context context, String domain, Discover discover, IDiscovery intf) throws UnknownHostException { // https://tools.ietf.org/html/rfc6186 EmailProvider provider = new EmailProvider(domain); if (discover == Discover.ALL || discover == Discover.IMAP) { try { // Identifies an IMAP server where TLS is initiated directly upon connection to the IMAP server. - DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, "_imaps._tcp." + domain, "srv"); + String name = "_imaps._tcp." + domain; + intf.onStatus(name); + DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, name, "srv"); if (records.length == 0) throw new UnknownHostException(domain); // ... service is not supported at all at a particular domain by setting the target of an SRV RR to "." @@ -837,7 +850,9 @@ public class EmailProvider implements Parcelable { if (discover == Discover.ALL || discover == Discover.SMTP) try { // Note that this covers connections both with and without Transport Layer Security (TLS) - DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, "_submission._tcp." + domain, "srv"); + String name = "_submission._tcp." + domain; + intf.onStatus(name); + DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, name, "srv"); if (records.length == 0) throw new UnknownHostException(domain); provider.smtp.score = 50; @@ -863,7 +878,7 @@ public class EmailProvider implements Parcelable { } @NonNull - private static EmailProvider fromScan(Context context, String domain, Discover discover) + private static EmailProvider fromScan(Context context, String domain, Discover discover, IDiscovery intf) throws ExecutionException, InterruptedException, UnknownHostException { // https://tools.ietf.org/html/rfc8314 Server imap = null; @@ -885,6 +900,7 @@ public class EmailProvider implements Parcelable { Server untrusted = null; for (Server server : imaps) { + intf.onStatus(server.toString()); Boolean result = server.isReachable.get(); if (result == null) { if (untrusted == null) @@ -918,6 +934,7 @@ public class EmailProvider implements Parcelable { Server untrusted = null; for (Server server : smtps) { + intf.onStatus(server.toString()); Boolean result = server.isReachable.get(); if (result == null) { if (untrusted == null) diff --git a/app/src/main/java/eu/faircode/email/FragmentQuickSetup.java b/app/src/main/java/eu/faircode/email/FragmentQuickSetup.java index 53f8dc3c98..1c3f122ecc 100644 --- a/app/src/main/java/eu/faircode/email/FragmentQuickSetup.java +++ b/app/src/main/java/eu/faircode/email/FragmentQuickSetup.java @@ -76,6 +76,7 @@ public class FragmentQuickSetup extends FragmentBase { private Button btnCheck; private ContentLoadingProgressBar pbCheck; private TextView tvPatience; + private TextView tvProgress; private TextView tvError; private TextView tvErrorHint; @@ -141,6 +142,7 @@ public class FragmentQuickSetup extends FragmentBase { btnCheck = view.findViewById(R.id.btnCheck); pbCheck = view.findViewById(R.id.pbCheck); tvPatience = view.findViewById(R.id.tvPatience); + tvProgress = view.findViewById(R.id.tvProgress); tvError = view.findViewById(R.id.tvError); tvErrorHint = view.findViewById(R.id.tvErrorHint); @@ -248,6 +250,7 @@ public class FragmentQuickSetup extends FragmentBase { tvSmtpFingerprint.setText(null); pbCheck.setVisibility(View.GONE); tvPatience.setVisibility(View.GONE); + tvProgress.setVisibility(View.GONE); pbSave.setVisibility(View.GONE); tvInstructions.setVisibility(View.GONE); tvInstructions.setMovementMethod(LinkMovementMethod.getInstance()); @@ -302,6 +305,7 @@ public class FragmentQuickSetup extends FragmentBase { Helper.setViewsEnabled(view, true); pbCheck.setVisibility(View.GONE); tvPatience.setVisibility(View.GONE); + tvProgress.setVisibility(View.GONE); pbSave.setVisibility(View.GONE); } @@ -333,13 +337,20 @@ public class FragmentQuickSetup extends FragmentBase { Throwable fail = null; List providers; if (best == null) - providers = EmailProvider.fromEmail(context, email, EmailProvider.Discover.ALL); + providers = EmailProvider.fromEmail(context, email, EmailProvider.Discover.ALL, + new EmailProvider.IDiscovery() { + @Override + public void onStatus(String status) { + postProgress(status); + } + }); else providers = Arrays.asList(best); for (EmailProvider provider : providers) try { EntityLog.log(context, "Checking" + " imap=" + provider.imap + " smtp=" + provider.smtp); + postProgress(provider.imap + "/" + provider.smtp); if (fail == null) args.putParcelable("provider", provider); @@ -621,6 +632,12 @@ public class FragmentQuickSetup extends FragmentBase { return null; } + @Override + protected void onProgress(CharSequence status, Bundle data) { + tvProgress.setText(status); + tvProgress.setVisibility(View.VISIBLE); + } + @Override protected void onExecuted(Bundle args, EmailProvider result) { setManual(false); diff --git a/app/src/main/res/layout/fragment_quick_setup.xml b/app/src/main/res/layout/fragment_quick_setup.xml index ac30b9d049..78075d5222 100644 --- a/app/src/main/res/layout/fragment_quick_setup.xml +++ b/app/src/main/res/layout/fragment_quick_setup.xml @@ -30,10 +30,10 @@ android:layout_marginTop="6dp" android:drawableEnd="@drawable/twotone_open_in_new_12" android:drawablePadding="6dp" - app:drawableTint="?android:attr/textColorLink" android:text="@string/title_privacy_policy" android:textAppearance="@style/TextAppearance.AppCompat.Small" android:textColor="?android:attr/textColorLink" + app:drawableTint="?android:attr/textColorLink" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tvTitle" /> @@ -143,6 +143,16 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/btnCheck" /> + + + app:layout_constraintTop_toBottomOf="@id/tvProgress" /> @@ -225,10 +235,10 @@ android:backgroundTint="?attr/colorInfoBackground" android:drawableEnd="@drawable/twotone_help_24" android:drawablePadding="6dp" - app:drawableTint="?attr/colorInfoForeground" android:text="@string/title_setup_help" android:textColor="?attr/colorInfoForeground" android:textStyle="bold" + app:drawableTint="?attr/colorInfoForeground" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@id/tvInstructions" />