\r
private static final String KEY_HOST_URL_TEXT = "HOST_URL_TEXT";\r
private static final String KEY_OC_VERSION = "OC_VERSION";\r
+ private static final String KEY_ACCOUNT = "ACCOUNT";\r
private static final String KEY_STATUS_TEXT = "STATUS_TEXT";\r
private static final String KEY_STATUS_ICON = "STATUS_ICON";\r
private static final String KEY_STATUS_CORRECT = "STATUS_CORRECT";\r
\r
public static final byte ACTION_CREATE = 0;\r
public static final byte ACTION_UPDATE_TOKEN = 1;\r
- \r
+\r
\r
private String mHostBaseUrl;\r
private OwnCloudVersion mDiscoveredVersion;\r
\r
private AccountManager mAccountMgr;\r
private boolean mJustCreated;\r
+ private byte mAction;\r
+ private Account mAccount;\r
\r
private ImageView mRefreshButton;\r
private ImageView mViewPasswordButton;\r
/// initialization\r
mAccountMgr = AccountManager.get(this);\r
mNewCapturedUriFromOAuth2Redirection = null; // TODO save?\r
+ mAction = getIntent().getByteExtra(EXTRA_ACTION, ACTION_CREATE); \r
+ mAccount = null;\r
\r
if (savedInstanceState == null) {\r
/// connection state and info\r
mOAuth2Check.setChecked(oAuthRequired);\r
changeViewByOAuth2Check(oAuthRequired);\r
\r
- Account account = getIntent().getExtras().getParcelable(EXTRA_ACCOUNT);\r
- if (account != null) {\r
- String ocVersion = mAccountMgr.getUserData(account, AccountAuthenticator.KEY_OC_VERSION);\r
+ mAccount = getIntent().getExtras().getParcelable(EXTRA_ACCOUNT);\r
+ if (mAccount != null) {\r
+ String ocVersion = mAccountMgr.getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION);\r
if (ocVersion != null) {\r
mDiscoveredVersion = new OwnCloudVersion(ocVersion);\r
}\r
- mHostBaseUrl = mAccountMgr.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL);\r
+ mHostBaseUrl = mAccountMgr.getUserData(mAccount, AccountAuthenticator.KEY_OC_BASE_URL);\r
mHostUrlInput.setText(mHostBaseUrl);\r
- String userName = account.name.substring(0, account.name.lastIndexOf('@'));\r
+ String userName = mAccount.name.substring(0, mAccount.name.lastIndexOf('@'));\r
mUsernameInput.setText(userName);\r
}\r
\r
loadSavedInstanceState(savedInstanceState);\r
}\r
\r
- if (getIntent().getByteExtra(EXTRA_ACTION, ACTION_CREATE) == ACTION_UPDATE_TOKEN) {\r
+ if (mAction == ACTION_UPDATE_TOKEN) {\r
/// lock things that should not change\r
mHostUrlInput.setEnabled(false);\r
mUsernameInput.setEnabled(false);\r
outState.putString(KEY_OC_VERSION, mDiscoveredVersion.toString());\r
outState.putString(KEY_HOST_URL_TEXT, mHostBaseUrl);\r
\r
+ /// account data, if updating\r
+ if (mAccount != null)\r
+ outState.putParcelable(KEY_ACCOUNT, mAccount);\r
+ \r
// Saving the state of oAuth2 components.\r
outState.putInt(KEY_OAUTH2_STATUS_ICON, mOAuth2StatusIcon);\r
outState.putInt(KEY_OAUTH2_STATUS_TEXT, mOAuth2StatusText);\r
mDiscoveredVersion = new OwnCloudVersion(ocVersion);\r
mHostBaseUrl = savedInstanceState.getString(KEY_HOST_URL_TEXT);\r
\r
+ // account data, if updating\r
+ mAccount = savedInstanceState.getParcelable(KEY_ACCOUNT);\r
+ \r
// state of oAuth2 components\r
mOAuth2StatusIcon = savedInstanceState.getInt(KEY_OAUTH2_STATUS_ICON);\r
mOAuth2StatusText = savedInstanceState.getInt(KEY_OAUTH2_STATUS_TEXT);\r
super.onResume();\r
// the state of mOAuth2Check is automatically recovered between configuration changes, but not before onCreate() finishes; so keep the next lines here\r
changeViewByOAuth2Check(mOAuth2Check.isChecked()); \r
- if (getIntent().getByteExtra(EXTRA_ACTION, ACTION_CREATE) == ACTION_UPDATE_TOKEN && mJustCreated) {\r
+ if (mAction == ACTION_UPDATE_TOKEN && mJustCreated) {\r
if (mOAuth2Check.isChecked())\r
Toast.makeText(this, R.string.auth_expired_oauth_token_toast, Toast.LENGTH_LONG).show();\r
else\r
// NOTHING TO DO ; can't find out what situation that leads to the exception in this code, but user logs signal that it happens\r
}\r
\r
- boolean isOAuth = mOAuth2Check.isChecked();\r
-\r
if (result.isSuccess()) {\r
Log.d(TAG, "Successful access - time to save the account");\r
\r
- /// create and save new ownCloud account\r
- Uri uri = Uri.parse(mHostBaseUrl);\r
- String username = isOAuth ?\r
- "OAuth_user" + (new java.util.Random(System.currentTimeMillis())).nextLong() :\r
- mUsernameInput.getText().toString().trim();\r
- // TODO a better way to set an account name\r
- String accountName = username + "@" + uri.getHost();\r
- if (uri.getPort() >= 0) {\r
- accountName += ":" + uri.getPort();\r
- }\r
- Account account = new Account(accountName, AccountAuthenticator.ACCOUNT_TYPE);\r
- AccountManager accManager = AccountManager.get(this);\r
- if (isOAuth) {\r
- accManager.addAccountExplicitly(account, "", null); // with our implementation, the password is never input in the app\r
+ if (mAction == ACTION_CREATE) {\r
+ createAccount();\r
+ \r
} else {\r
- accManager.addAccountExplicitly(account, mPasswordInput.getText().toString(), null);\r
- }\r
-\r
- /// add the new account as default in preferences, if there is none already\r
- Account defaultAccount = AccountUtils.getCurrentOwnCloudAccount(this);\r
- if (defaultAccount == null) {\r
- SharedPreferences.Editor editor = PreferenceManager\r
- .getDefaultSharedPreferences(this).edit();\r
- editor.putString("select_oc_account", accountName);\r
- editor.commit();\r
- }\r
-\r
-\r
- /// prepare result to return to the Authenticator\r
- // TODO check again what the Authenticator makes with it; probably has the same effect as addAccountExplicitly, but it's not well done\r
- final Intent intent = new Intent(); // TODO check if the intent can be retrieved from getIntent(), passed from AccountAuthenticator \r
- intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, AccountAuthenticator.ACCOUNT_TYPE);\r
- intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name);\r
- if (!isOAuth)\r
- intent.putExtra(AccountManager.KEY_AUTHTOKEN, AccountAuthenticator.ACCOUNT_TYPE); // TODO check this; not sure it's right; maybe\r
- intent.putExtra(AccountManager.KEY_USERDATA, username);\r
- if (isOAuth) {\r
- accManager.setAuthToken(account, AccountAuthenticator.AUTH_TOKEN_TYPE_ACCESS_TOKEN, mOAuthAccessToken);\r
+ updateToken();\r
}\r
- /// add user data to the new account; TODO probably can be done in the last parameter addAccountExplicitly, or in KEY_USERDATA\r
- accManager.setUserData(account, AccountAuthenticator.KEY_OC_VERSION, mDiscoveredVersion.toString());\r
- accManager.setUserData(account, AccountAuthenticator.KEY_OC_BASE_URL, mHostBaseUrl);\r
- if (isOAuth)\r
- accManager.setUserData(account, AccountAuthenticator.KEY_SUPPORTS_OAUTH2, "TRUE"); // TODO this flag should be unnecessary\r
-\r
- setAccountAuthenticatorResult(intent.getExtras());\r
- setResult(RESULT_OK, intent);\r
\r
- /// immediately request for the synchronization of the new account\r
- Bundle bundle = new Bundle();\r
- bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);\r
- ContentResolver.requestSync(account, AccountAuthenticator.AUTHORITY, bundle);\r
-\r
finish();\r
- \r
- } else {\r
- /*\r
- if (!isOAuth) {\r
- mUsernameInput.setError(result.getLogMessage() + " "); \r
- // the extra spaces are a workaround for an ugly bug: \r
- // 1. insert wrong credentials and connect\r
- // 2. put the focus on the user name field with using hardware controls (don't touch the screen); the error is shown UNDER the field\r
- // 3. touch the user name field; the software keyboard appears; the error popup is moved OVER the field and SHRINKED in width, losing the last word\r
- // Seen, at least, in Android 2.x devices \r
\r
- } else {\r
- mOAuthAuthEndpointText.setError(result.getLogMessage() + " ");\r
- }*/\r
+ } else {\r
updateStatusIconAndText(result);\r
updateAuthStatus();\r
Log.d(TAG, "Access failed: " + result.getLogMessage());\r
}\r
\r
\r
+ /**\r
+ * Sets the proper response to get that the Account Authenticator that started this activity saves \r
+ * a new authorization token for mAccount.\r
+ */\r
+ private void updateToken() {\r
+ Bundle response = new Bundle();\r
+ response.putString(AccountManager.KEY_ACCOUNT_NAME, mAccount.name);\r
+ response.putString(AccountManager.KEY_ACCOUNT_TYPE, mAccount.type);\r
+ boolean isOAuth = mOAuth2Check.isChecked();\r
+ if (isOAuth) {\r
+ response.putString(AccountManager.KEY_AUTHTOKEN, mOAuthAccessToken);\r
+ // the next line is unnecessary; the AccountManager does it when receives the response Bundle\r
+ // mAccountMgr.setAuthToken(mAccount, AccountAuthenticator.AUTH_TOKEN_TYPE_ACCESS_TOKEN, mOAuthAccessToken);\r
+ } else {\r
+ response.putString(AccountManager.KEY_AUTHTOKEN, mPasswordInput.getText().toString());\r
+ // the next line is not really necessary, because we are using the password as if it was an auth token; but let's keep it there by now\r
+ mAccountMgr.setPassword(mAccount, mPasswordInput.getText().toString());\r
+ }\r
+ setAccountAuthenticatorResult(response);\r
+ }\r
+\r
+\r
+ /**\r
+ * Creates a new account through the Account Authenticator that started this activity. \r
+ * \r
+ * This makes the account permanent.\r
+ * \r
+ * TODO Decide how to name the OAuth accounts\r
+ * TODO Minimize the direct interactions with the account manager; seems that not all the operations \r
+ * in the current code are really necessary, provided that right extras are returned to the Account\r
+ * Authenticator through setAccountAuthenticatorResult \r
+ */\r
+ private void createAccount() {\r
+ /// create and save new ownCloud account\r
+ boolean isOAuth = mOAuth2Check.isChecked();\r
+ \r
+ Uri uri = Uri.parse(mHostBaseUrl);\r
+ String username = mUsernameInput.getText().toString().trim();\r
+ if (isOAuth) {\r
+ username = "OAuth_user" + (new java.util.Random(System.currentTimeMillis())).nextLong(); // TODO change this to something readable\r
+ } \r
+ String accountName = username + "@" + uri.getHost();\r
+ if (uri.getPort() >= 0) {\r
+ accountName += ":" + uri.getPort();\r
+ }\r
+ mAccount = new Account(accountName, AccountAuthenticator.ACCOUNT_TYPE);\r
+ if (isOAuth) {\r
+ mAccountMgr.addAccountExplicitly(mAccount, "", null); // with our implementation, the password is never input in the app\r
+ } else {\r
+ mAccountMgr.addAccountExplicitly(mAccount, mPasswordInput.getText().toString(), null);\r
+ }\r
+\r
+ /// add the new account as default in preferences, if there is none already\r
+ Account defaultAccount = AccountUtils.getCurrentOwnCloudAccount(this);\r
+ if (defaultAccount == null) {\r
+ SharedPreferences.Editor editor = PreferenceManager\r
+ .getDefaultSharedPreferences(this).edit();\r
+ editor.putString("select_oc_account", accountName);\r
+ editor.commit();\r
+ }\r
+\r
+ /// prepare result to return to the Authenticator\r
+ // TODO check again what the Authenticator makes with it; probably has the same effect as addAccountExplicitly, but it's not well done\r
+ final Intent intent = new Intent(); \r
+ intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, AccountAuthenticator.ACCOUNT_TYPE);\r
+ intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, mAccount.name);\r
+ if (!isOAuth)\r
+ intent.putExtra(AccountManager.KEY_AUTHTOKEN, AccountAuthenticator.ACCOUNT_TYPE); // TODO check this; not sure it's right; maybe\r
+ intent.putExtra(AccountManager.KEY_USERDATA, username);\r
+ if (isOAuth) {\r
+ mAccountMgr.setAuthToken(mAccount, AccountAuthenticator.AUTH_TOKEN_TYPE_ACCESS_TOKEN, mOAuthAccessToken);\r
+ }\r
+ /// add user data to the new account; TODO probably can be done in the last parameter addAccountExplicitly, or in KEY_USERDATA\r
+ mAccountMgr.setUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION, mDiscoveredVersion.toString());\r
+ mAccountMgr.setUserData(mAccount, AccountAuthenticator.KEY_OC_BASE_URL, mHostBaseUrl);\r
+ if (isOAuth)\r
+ mAccountMgr.setUserData(mAccount, AccountAuthenticator.KEY_SUPPORTS_OAUTH2, "TRUE"); // TODO this flag should be unnecessary\r
\r
+ setAccountAuthenticatorResult(intent.getExtras());\r
+ setResult(RESULT_OK, intent);\r
+ \r
+ /// immediately request for the synchronization of the new account\r
+ Bundle bundle = new Bundle();\r
+ bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);\r
+ ContentResolver.requestSync(mAccount, AccountAuthenticator.AUTHORITY, bundle);\r
+ }\r
+\r
+\r
/**\r
* {@inheritDoc}\r
* \r