import android.widget.CheckBox;\r
import android.widget.EditText;\r
import android.widget.Button;\r
-import android.widget.ImageView;\r
import android.widget.TextView;\r
import android.widget.Toast;\r
import android.widget.TextView.OnEditorActionListener;\r
private static final String KEY_SERVER_STATUS_TEXT = "SERVER_STATUS_TEXT";\r
private static final String KEY_SERVER_STATUS_ICON = "SERVER_STATUS_ICON";\r
private static final String KEY_IS_SSL_CONN = "IS_SSL_CONN";\r
+ private static final String KEY_PASSWORD_VISIBLE = "PASSWORD_VISIBLE";\r
private static final String KEY_AUTH_STATUS_TEXT = "AUTH_STATUS_TEXT";\r
private static final String KEY_AUTH_STATUS_ICON = "AUTH_STATUS_ICON";\r
+ private static final String KEY_REFRESH_BUTTON_ENABLED = "KEY_REFRESH_BUTTON_ENABLED";\r
\r
private static final String OAUTH_MODE_ON = "on";\r
private static final String OAUTH_MODE_OFF = "off";\r
\r
public static final byte ACTION_CREATE = 0;\r
public static final byte ACTION_UPDATE_TOKEN = 1;\r
-\r
- public static final String WEBDAV_PATH= "/remote.php/webdav";\r
\r
private String mHostBaseUrl;\r
private OwnCloudVersion mDiscoveredVersion;\r
private byte mAction;\r
private Account mAccount;\r
\r
- private ImageView mViewPasswordButton;\r
private EditText mHostUrlInput;\r
private EditText mUsernameInput;\r
private EditText mPasswordInput;\r
\r
private TextView mOAuthAuthEndpointText;\r
private TextView mOAuthTokenEndpointText;\r
+ \r
+ private boolean mRefreshButtonEnabled;\r
\r
\r
/**\r
\r
/// set view and get references to view elements\r
setContentView(R.layout.account_setup);\r
- mViewPasswordButton = (ImageView) findViewById(R.id.viewPasswordButton);\r
mHostUrlInput = (EditText) findViewById(R.id.hostUrlInput);\r
mUsernameInput = (EditText) findViewById(R.id.account_username);\r
mPasswordInput = (EditText) findViewById(R.id.account_password);\r
mIsSslConn = savedInstanceState.getBoolean(KEY_IS_SSL_CONN);\r
mAuthStatusText = savedInstanceState.getInt(KEY_AUTH_STATUS_TEXT);\r
mAuthStatusIcon = savedInstanceState.getInt(KEY_AUTH_STATUS_ICON);\r
-\r
+ if (savedInstanceState.getBoolean(KEY_PASSWORD_VISIBLE, false)) {\r
+ showPassword();\r
+ }\r
+ \r
/// server data\r
String ocVersion = savedInstanceState.getString(KEY_OC_VERSION);\r
if (ocVersion != null) {\r
// check if server check was interrupted by a configuration change\r
if (savedInstanceState.getBoolean(KEY_SERVER_CHECK_IN_PROGRESS, false)) {\r
checkOcServer();\r
- }\r
+ } \r
+ \r
+ // refresh button enabled\r
+ mRefreshButtonEnabled = savedInstanceState.getBoolean(KEY_REFRESH_BUTTON_ENABLED);\r
\r
}\r
\r
showServerStatus();\r
showAuthStatus();\r
- if (mServerIsChecked && !mServerIsValid) showRefreshButton();\r
+ if (mServerIsChecked && !mServerIsValid && mRefreshButtonEnabled) showRefreshButton();\r
mOkButton.setEnabled(mServerIsValid); // state not automatically recovered in configuration changes\r
\r
if (!OAUTH_MODE_OPTIONAL.equals(getString(R.string.oauth2_mode))) {\r
mHostUrlInput.setOnTouchListener(new RightDrawableOnTouchListener() {\r
@Override\r
public boolean onDrawableTouch(final MotionEvent event) {\r
- AuthenticatorActivity.this.onRefreshClick(mHostUrlInput);\r
+ if (event.getAction() == MotionEvent.ACTION_UP) {\r
+ AuthenticatorActivity.this.onRefreshClick();\r
+ }\r
return true;\r
}\r
});\r
});\r
mPasswordInput.setOnFocusChangeListener(this);\r
mPasswordInput.setImeOptions(EditorInfo.IME_ACTION_DONE);\r
- mPasswordInput.setOnEditorActionListener(this);\r
+ mPasswordInput.setOnEditorActionListener(this);
+ mPasswordInput.setOnTouchListener(new RightDrawableOnTouchListener() {\r
+ @Override\r
+ public boolean onDrawableTouch(final MotionEvent event) {\r
+ if (event.getAction() == MotionEvent.ACTION_UP) {\r
+ AuthenticatorActivity.this.onViewPasswordClick();\r
+ }\r
+ return true;\r
+ }\r
+ });
}\r
\r
/**\r
outState.putBoolean(KEY_SERVER_CHECKED, mServerIsChecked);\r
outState.putBoolean(KEY_SERVER_CHECK_IN_PROGRESS, (!mServerIsValid && mOcServerChkOperation != null));\r
outState.putBoolean(KEY_IS_SSL_CONN, mIsSslConn);\r
+ outState.putBoolean(KEY_PASSWORD_VISIBLE, isPasswordVisible());\r
outState.putInt(KEY_AUTH_STATUS_ICON, mAuthStatusIcon);\r
outState.putInt(KEY_AUTH_STATUS_TEXT, mAuthStatusText);\r
\r
if (mAccount != null) {\r
outState.putParcelable(KEY_ACCOUNT, mAccount);\r
}\r
+ \r
+ // refresh button enabled\r
+ outState.putBoolean(KEY_REFRESH_BUTTON_ENABLED, mRefreshButtonEnabled);\r
\r
}\r
\r
if (view.getId() == R.id.hostUrlInput) { \r
if (!hasFocus) {\r
onUrlInputFocusLost((TextView) view);\r
+ if (!mServerIsValid) {\r
+ showRefreshButton();\r
+ }\r
}\r
else {\r
hideRefreshButton();\r
*/\r
private void onPasswordFocusChanged(TextView passwordInput, boolean hasFocus) {\r
if (hasFocus) {\r
- mViewPasswordButton.setVisibility(View.VISIBLE);\r
+ showViewPasswordButton();\r
} else {\r
- int input_type = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD;\r
- passwordInput.setInputType(input_type);\r
- mViewPasswordButton.setVisibility(View.INVISIBLE);\r
+ hidePassword();\r
+ hidePasswordButton();\r
}\r
}\r
\r
\r
+ private void showViewPasswordButton() {\r
+ //int drawable = android.R.drawable.ic_menu_view;\r
+ int drawable = R.drawable.ic_view;\r
+ if (isPasswordVisible()) {\r
+ //drawable = android.R.drawable.ic_secure;\r
+ drawable = R.drawable.ic_hide;\r
+ }\r
+ mPasswordInput.setCompoundDrawablesWithIntrinsicBounds(0, 0, drawable, 0);\r
+ }\r
\r
+ private boolean isPasswordVisible() {\r
+ return ((mPasswordInput.getInputType() & InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);\r
+ }\r
+ \r
+ private void hidePasswordButton() {\r
+ mPasswordInput.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);\r
+ }\r
+\r
+ private void showPassword() {\r
+ mPasswordInput.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);\r
+ showViewPasswordButton();\r
+ }\r
+ \r
+ private void hidePassword() {\r
+ mPasswordInput.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);\r
+ showViewPasswordButton();\r
+ }\r
+ \r
+ \r
/**\r
* Cancels the authenticator activity\r
* \r
\r
\r
private String trimUrlWebdav(String url){ \r
- if(url.toLowerCase().endsWith(WEBDAV_PATH)){\r
- url = url.substring(0, url.length() - WEBDAV_PATH.length()); \r
- }\r
+ if(url.toLowerCase().endsWith(AccountUtils.WEBDAV_PATH_4_0)){\r
+ url = url.substring(0, url.length() - AccountUtils.WEBDAV_PATH_4_0.length()); \r
+ } else if(url.toLowerCase().endsWith(AccountUtils.WEBDAV_PATH_2_0)){\r
+ url = url.substring(0, url.length() - AccountUtils.WEBDAV_PATH_2_0.length()); \r
+ } else if (url.toLowerCase().endsWith(AccountUtils.WEBDAV_PATH_1_2)){\r
+ url = url.substring(0, url.length() - AccountUtils.WEBDAV_PATH_1_2.length()); \r
+ } \r
return (url != null ? url : "");\r
}\r
\r
\r
finish();\r
\r
- } else {\r
+ } else if (result.isServerFail() || result.isException()) {\r
+ /// if server fail or exception in authorization, the UI is updated as when a server check failed\r
+ mServerIsChecked = true;\r
+ mServerIsValid = false;\r
+ mIsSslConn = false;\r
+ mOcServerChkOperation = null;\r
+ mDiscoveredVersion = null;\r
+ mHostBaseUrl = normalizeUrl(mHostUrlInput.getText().toString());\r
+\r
+ // update status icon and text\r
+ updateServerStatusIconAndText(result);\r
+ showServerStatus();\r
+ mAuthStatusIcon = 0;\r
+ mAuthStatusText = 0;\r
+ showAuthStatus();\r
+ \r
+ // update input controls state\r
+ showRefreshButton();\r
+ mOkButton.setEnabled(false);\r
+\r
+ // very special case (TODO: move to a common place for all the remote operations) (dangerous here?)\r
+ if (result.getCode() == ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED) {\r
+ mLastSslUntrustedServerResult = result;\r
+ showDialog(DIALOG_SSL_VALIDATOR); \r
+ }\r
+\r
+ } else { // authorization fail due to client side - probably wrong credentials\r
updateAuthStatusIconAndText(result);\r
showAuthStatus();\r
Log_OC.d(TAG, "Access failed: " + result.getLogMessage());\r
\r
private void showRefreshButton() {\r
mHostUrlInput.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_action_refresh_black, 0);\r
+ mRefreshButtonEnabled = true;\r
}\r
\r
private void hideRefreshButton() {\r
mHostUrlInput.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);\r
+ mRefreshButtonEnabled = false;\r
}\r
\r
/**\r
* \r
* @param view Refresh 'button'\r
*/\r
- public void onRefreshClick(View view) {\r
+ public void onRefreshClick() {\r
checkOcServer();\r
}\r
-\r
-\r
+ \r
+ \r
/**\r
* Called when the eye icon in the password field is clicked.\r
* \r
* Toggles the visibility of the password in the field. \r
- * \r
- * @param view 'View password' 'button'\r
*/\r
- public void onViewPasswordClick(View view) {\r
+ public void onViewPasswordClick() {\r
int selectionStart = mPasswordInput.getSelectionStart();\r
int selectionEnd = mPasswordInput.getSelectionEnd();\r
- int input_type = mPasswordInput.getInputType();\r
- if ((input_type & InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) {\r
- input_type = InputType.TYPE_CLASS_TEXT\r
- | InputType.TYPE_TEXT_VARIATION_PASSWORD;\r
+ if (isPasswordVisible()) {\r
+ hidePassword();\r
} else {\r
- input_type = InputType.TYPE_CLASS_TEXT\r
- | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;\r
+ showPassword();\r
}\r
- mPasswordInput.setInputType(input_type);\r
mPasswordInput.setSelection(selectionStart, selectionEnd);\r
} \r
\r
mOAuthTokenEndpointText.setVisibility(View.VISIBLE);\r
mUsernameInput.setVisibility(View.GONE);\r
mPasswordInput.setVisibility(View.GONE);\r
- mViewPasswordButton.setVisibility(View.GONE);\r
} else {\r
mOAuthAuthEndpointText.setVisibility(View.GONE);\r
mOAuthTokenEndpointText.setVisibility(View.GONE);\r
mUsernameInput.setVisibility(View.VISIBLE);\r
mPasswordInput.setVisibility(View.VISIBLE);\r
- mViewPasswordButton.setVisibility(View.INVISIBLE);\r
} \r
\r
} \r
\r
private abstract static class RightDrawableOnTouchListener implements OnTouchListener {\r
\r
- private int fuzz = 10;\r
-\r
+ private int fuzz = 75;\r
+ \r
/**\r
* {@inheritDoc}\r
*/\r
@Override\r
public boolean onTouch(View view, MotionEvent event) {\r
- if (event.getAction() == MotionEvent.ACTION_DOWN) {\r
- Drawable rightDrawable = null;\r
- if (view instanceof TextView) {\r
- Drawable[] drawables = ((TextView)view).getCompoundDrawables();\r
- if (drawables.length > 2) {\r
- rightDrawable = drawables[2];\r
- }\r
+ Drawable rightDrawable = null;\r
+ if (view instanceof TextView) {\r
+ Drawable[] drawables = ((TextView)view).getCompoundDrawables();\r
+ if (drawables.length > 2) {\r
+ rightDrawable = drawables[2];\r
}\r
- if (rightDrawable != null) {\r
- final int x = (int) event.getX();\r
- final int y = (int) event.getY();\r
- final Rect bounds = rightDrawable.getBounds();\r
- if (x >= (view.getRight() - bounds.width() - fuzz) && x <= (view.getRight() - view.getPaddingRight() + fuzz)\r
- && y >= (view.getPaddingTop() - fuzz) && y <= (view.getHeight() - view.getPaddingBottom()) + fuzz) {\r
-\r
- return onDrawableTouch(event);\r
- }\r
+ }\r
+ if (rightDrawable != null) {\r
+ final int x = (int) event.getX();\r
+ final int y = (int) event.getY();\r
+ final Rect bounds = rightDrawable.getBounds();\r
+ if (x >= (view.getRight() - bounds.width() - fuzz) && x <= (view.getRight() - view.getPaddingRight() + fuzz)\r
+ && y >= (view.getPaddingTop() - fuzz) && y <= (view.getHeight() - view.getPaddingBottom()) + fuzz) {\r
+ \r
+ return onDrawableTouch(event);\r
}\r
}\r
return false;\r