diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_DeviceAccountLogin.java b/mobile/src/com/cradle/iitc_mobile/IITC_DeviceAccountLogin.java index 601425c4..ba0ce3d1 100644 --- a/mobile/src/com/cradle/iitc_mobile/IITC_DeviceAccountLogin.java +++ b/mobile/src/com/cradle/iitc_mobile/IITC_DeviceAccountLogin.java @@ -18,7 +18,13 @@ import android.widget.BaseAdapter; import android.widget.TextView; import android.widget.Toast; +/** + * this class manages automatic login using the Google account stored on the device + */ public class IITC_DeviceAccountLogin implements AccountManagerCallback { + /** + * Adapter to show available accounts in a ListView. Accounts are read from mAccounts + */ private class AccountAdapter extends BaseAdapter { @Override public int getCount() { @@ -56,11 +62,15 @@ public class IITC_DeviceAccountLogin implements AccountManagerCallback { private AlertDialog mProgressbar; private WebView mWebView; + /** + * This listener is invoked when an item in the account list is selected. (It is also used when the 'cancel' button + * is clicked, (in which case `index` is <0) + */ private DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() { @Override - public void onClick(DialogInterface dialog, int which) { - if (which >= 0 && which < mAccounts.length) { - mAccount = mAccounts[which]; + public void onClick(DialogInterface dialog, int index) { + if (index >= 0 && index < mAccounts.length) { + mAccount = mAccounts[index]; startAuthentication(); } dialog.cancel(); @@ -73,12 +83,16 @@ public class IITC_DeviceAccountLogin implements AccountManagerCallback { mAccountManager = AccountManager.get(activity); mAccountAdapter = new AccountAdapter(); + // dialog that serves as a progress bar overlay mProgressbar = new AlertDialog.Builder(mActivity) .setCancelable(false) .setView(mActivity.getLayoutInflater().inflate(R.layout.dialog_progressbar, null)) .create(); } + /** + * display all available accounts to the user + */ private void displayAccountList() { AlertDialog.Builder builder = new AlertDialog.Builder(mActivity) .setTitle(R.string.choose_account_to_login) @@ -89,23 +103,38 @@ public class IITC_DeviceAccountLogin implements AccountManagerCallback { dialog.show(); } + /** + * called when something failed. Shows a toast message. Classic login is still available + */ private void onLoginFailed() { Toast.makeText(mActivity, R.string.login_failed, Toast.LENGTH_SHORT).show(); } + /** + * called to start authenticating using AccountManager. + * + * After a token is created, AccountManager will call the run() method. + */ private void startAuthentication() { mProgressbar.show(); mAccountManager.getAuthToken(mAccount, mAuthToken, null, mActivity, this, null); } + /** + * called by IITC_Mobile when the authentication activity has finished. + */ public void onActivityResult(int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) + // authentication activity succeeded, request token again startAuthentication(); else onLoginFailed(); } + /** + * called by AccountManager + */ @Override public void run(AccountManagerFuture value) { mProgressbar.hide(); @@ -113,12 +142,16 @@ public class IITC_DeviceAccountLogin implements AccountManagerCallback { try { Intent launch = (Intent) value.getResult().get(AccountManager.KEY_INTENT); if (launch != null) { + // There is a reason we need to start the given activity if we want an authentication token. + // (Could be user confirmation or something else. Whatever, we have to start it) + // IITC_Mobile will call it using startActivityForResult mActivity.startLoginActivity(launch); return; } String result = value.getResult().getString(AccountManager.KEY_AUTHTOKEN); if (result != null) { + // authentication succeded, we can load the given url, which will redirect back to the intel map mWebView.loadUrl(result); mActivity.loginSucceded(); } else { @@ -129,6 +162,12 @@ public class IITC_DeviceAccountLogin implements AccountManagerCallback { } } + /** + * start authentication + * + * if we already have a username (e.g. because the existing login has timed out), we can directly start + * authentication if an account with that username is found. + */ public void startLogin(String realm, String accountName, String args) { mAccounts = mAccountManager.getAccountsByType(realm); mAccountAdapter.notifyDataSetChanged(); diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java b/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java index 3d11abcc..e937c686 100644 --- a/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java +++ b/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java @@ -47,6 +47,7 @@ public class IITC_Mobile extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + // enable progress bar above action bar requestWindowFeature(Window.FEATURE_PROGRESS); // TODO build an async task for url.openStream() in IITC_WebViewClient @@ -361,14 +362,19 @@ public class IITC_Mobile extends Activity { return this.iitc_view; } + /** + * It can occur that in order to authenticate, an external activity has to be launched. (This could for example be a + * confirmation dialog.) + */ public void startLoginActivity(Intent launch) { - startActivityForResult(launch, REQUEST_LOGIN); + startActivityForResult(launch, REQUEST_LOGIN); // REQUEST_LOGIN is to recognize the result } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQUEST_LOGIN : + // authentication activity has returned. mLogin will continue authentication mLogin.onActivityResult(resultCode, data); break; @@ -377,13 +383,20 @@ public class IITC_Mobile extends Activity { } } + /** + * called by IITC_WebViewClient when the Google login form is opened. + */ public void onReceivedLoginRequest(IITC_WebViewClient client, WebView view, String realm, String account, String args) { mLogin = new IITC_DeviceAccountLogin(this, view, client); mLogin.startLogin(realm, account, args); } + /** + * called after successful login + */ public void loginSucceded() { + // garbage collection mLogin = null; } } diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_WebView.java b/mobile/src/com/cradle/iitc_mobile/IITC_WebView.java index e11e1d09..b3a752a3 100644 --- a/mobile/src/com/cradle/iitc_mobile/IITC_WebView.java +++ b/mobile/src/com/cradle/iitc_mobile/IITC_WebView.java @@ -41,14 +41,20 @@ public class IITC_WebView extends WebView { this.addJavascriptInterface(js_interface, "android"); this.setWebChromeClient(new WebChromeClient() { + /** + * our webchromeclient should share geolocation with the iitc script + * + * allow access by default + */ @Override public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) { - // our webchromeclient should share geolocation with the iitc script - // allow access by default callback.invoke(origin, true, false); } + /** + * display progress bar in activity + */ @Override public void onProgressChanged(WebView view, int newProgress) { super.onProgressChanged(view, newProgress); diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_WebViewClient.java b/mobile/src/com/cradle/iitc_mobile/IITC_WebViewClient.java index 647e8189..6f75ab6f 100644 --- a/mobile/src/com/cradle/iitc_mobile/IITC_WebViewClient.java +++ b/mobile/src/com/cradle/iitc_mobile/IITC_WebViewClient.java @@ -133,6 +133,9 @@ public class IITC_WebViewClient extends WebViewClient { handler.proceed(); }; + /** + * this method is called automatically when the Google login form is opened. + */ @Override public void onReceivedLoginRequest(WebView view, String realm, String account, String args) { ((IITC_Mobile) context).onReceivedLoginRequest(this, view, realm, account, args);