From b20ace9185ea9b174675b77bcc71ee04d2578cc4 Mon Sep 17 00:00:00 2001 From: Oliver Gasser Date: Wed, 17 Sep 2014 03:26:37 +0200 Subject: [PATCH] Add code to handle ownCloud servers running on IDN ownCloud instances can run on servers having an internationalized domain name. This commit adds a conversion function between ASCII and Unicode. The conversion function is used in the Authenticator and Preferences activities. See issue #469. --- .../authentication/AuthenticatorActivity.java | 6 +++- .../android/ui/activity/Preferences.java | 5 +-- .../owncloud/android/utils/DisplayUtils.java | 35 +++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/com/owncloud/android/authentication/AuthenticatorActivity.java b/src/com/owncloud/android/authentication/AuthenticatorActivity.java index 21aab72f4143..9569a532d715 100644 --- a/src/com/owncloud/android/authentication/AuthenticatorActivity.java +++ b/src/com/owncloud/android/authentication/AuthenticatorActivity.java @@ -84,6 +84,7 @@ import com.owncloud.android.ui.dialog.SamlWebViewDialog; import com.owncloud.android.ui.dialog.SslUntrustedCertDialog; import com.owncloud.android.ui.dialog.SslUntrustedCertDialog.OnSslUntrustedCertListener; +import com.owncloud.android.utils.DisplayUtils; import com.owncloud.android.utils.Log_OC; /** @@ -351,7 +352,8 @@ private void initServerPreFragment(Bundle savedInstanceState) { /// step 2 - set properties of UI elements (text, visibility, enabled...) mHostUrlInput = (EditText) findViewById(R.id.hostUrlInput); - mHostUrlInput.setText(mServerInfo.mBaseUrl); + // Convert IDN to Unicode + mHostUrlInput.setText(DisplayUtils.convertIdn(mServerInfo.mBaseUrl, false)); if (mAction != ACTION_CREATE) { /// lock things that should not change mHostUrlInput.setEnabled(false); @@ -727,6 +729,8 @@ private void checkOcServer() { showRefreshButton(false); if (uri.length() != 0) { + // Handle internationalized domain names + uri = DisplayUtils.convertIdn(uri, true); mServerStatusText = R.string.auth_testing_connection; mServerStatusIcon = R.drawable.progress_small; showServerStatus(); diff --git a/src/com/owncloud/android/ui/activity/Preferences.java b/src/com/owncloud/android/ui/activity/Preferences.java index e726efad8a17..e436dbbcad5c 100644 --- a/src/com/owncloud/android/ui/activity/Preferences.java +++ b/src/com/owncloud/android/ui/activity/Preferences.java @@ -103,7 +103,7 @@ public boolean onItemLongClick(AdapterView parent, View view, int position, l if (obj != null && obj instanceof LongClickableCheckBoxPreference) { mShowContextMenu = true; - mAccountName = obj.toString(); + mAccountName = ((LongClickableCheckBoxPreference) obj).getKey(); Preferences.this.openContextMenu(listView); @@ -427,7 +427,8 @@ private void addAccountsCheckboxPreferences() { for (Account a : accounts) { LongClickableCheckBoxPreference accountPreference = new LongClickableCheckBoxPreference(this); accountPreference.setKey(a.name); - accountPreference.setTitle(a.name); + // Handle internationalized domain names + accountPreference.setTitle(DisplayUtils.convertIdn(a.name, false)); mAccountsPrefCategory.addPreference(accountPreference); // Check the current account that is being used diff --git a/src/com/owncloud/android/utils/DisplayUtils.java b/src/com/owncloud/android/utils/DisplayUtils.java index 682d2be09b54..8c4c492b0f25 100644 --- a/src/com/owncloud/android/utils/DisplayUtils.java +++ b/src/com/owncloud/android/utils/DisplayUtils.java @@ -18,6 +18,7 @@ package com.owncloud.android.utils; +import java.net.IDN; import java.util.Arrays; import java.util.Calendar; import java.util.Date; @@ -25,6 +26,9 @@ import java.util.HashSet; import java.util.Set; +import android.annotation.TargetApi; +import android.os.Build; + import com.owncloud.android.R; /** @@ -235,4 +239,35 @@ public static int getSeasonalIconId() { return R.drawable.icon; } } + + /** + * Converts an internationalized domain name (IDN) in an URL to and from ASCII/Unicode. + * @param url the URL where the domain name should be converted + * @param toASCII if true converts from Unicode to ASCII, if false converts from ASCII to Unicode + * @return the URL containing the converted domain name + */ + @TargetApi(Build.VERSION_CODES.GINGERBREAD) + public static String convertIdn(String url, boolean toASCII) { + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { + // Find host name after '//' or '@' + int hostStart = 0; + if (url.indexOf("//") != -1) { + hostStart = url.indexOf("//") + "//".length(); + } else if (url.indexOf("@") != -1) { + hostStart = url.indexOf("@") + "@".length(); + } + + int hostEnd = url.substring(hostStart).indexOf("/"); + // Handle URL which doesn't have a path (path is implicitly '/') + hostEnd = (hostEnd == -1 ? url.length() : hostStart + hostEnd); + + String host = url.substring(hostStart, hostEnd); + host = (toASCII ? IDN.toASCII(host) : IDN.toUnicode(host)); + + return url.substring(0, hostStart) + host + url.substring(hostEnd); + } else { + return url; + } + } }