package de.bsd.zwitscher.account;
import java.util.concurrent.ExecutionException;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
import de.bsd.zwitscher.R;
import de.bsd.zwitscher.TabWidget;
import de.bsd.zwitscher.TwitterHelper;
import twitter4j.auth.RequestToken;
/**
* Activity to run the login at Twitter via OAuth game.
* This displays a web view, which Twitter shows where the
* user enters his credentials. Then on load of the result page
* it gets the content of the page (via injecting JavaScript, that
* calls us back) and then runs the TwitterHelper#generateAccountWithOauth
* to obtain the account tokens. We then forward to the main view.
*
* @author Heiko W. Rupp
*/
public class TwitterLoginActivity extends Activity {
WebView myWebView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.twitter_login_webview);
myWebView = (WebView) findViewById(R.id.WebView);
WebSettings webSettings = myWebView.getSettings();
webSettings.setSavePassword(false);
webSettings.setSaveFormData(false);
webSettings.setJavaScriptEnabled(true);
myWebView.setWebViewClient(new MyWebViewClient());
myWebView.addJavascriptInterface(new MyJavaScriptClient(), "HTMLOUT");
try {
RequestToken rt = new GetRequestTokenTask().execute().get();
if (rt==null) {
Toast.makeText(this,"Failure to create token. Perhaps the server is down? Please retry later",Toast.LENGTH_LONG).show();
return;
}
String token = rt.getToken();
myWebView.loadUrl("https://api.twitter.com/oauth/authorize?force_login=true&oauth_token="+token);
} catch (InterruptedException e) {
e.printStackTrace(); // TODO: Customise this generated block
} catch (ExecutionException e) {
e.printStackTrace(); // TODO: Customise this generated block
}
}
private class GetRequestTokenTask extends AsyncTask<Void,Void,RequestToken> {
@Override
protected RequestToken doInBackground(Void... voids) {
RequestToken rt;
try {
TwitterHelper th = new TwitterHelper(TwitterLoginActivity.this,null);
rt = th.getRequestToken(true);
return rt;
} catch (Exception e) {
e.printStackTrace(); // TODO: Customise this generated block
}
return null;
}
}
private class GenerateAccountWithOauthTask extends AsyncTask<String,Void,Account> {
@Override
protected Account doInBackground(String... strings) {
TwitterHelper th = new TwitterHelper(TwitterLoginActivity.this,null);
String pin = strings[0];
Account acct;
try {
acct = th.generateAccountWithOauth(pin);
return acct;
} catch (Exception e) {
System.err.println("-- GenerateAccountWithOAuth failed");
e.printStackTrace(); // TODO: Customise this generated block
}
return null;
}
@Override
protected void onPostExecute(Account account) {
Activity context = TwitterLoginActivity.this;
// Switch to this new account
AccountHolder.getInstance(context).setAccount(account);
Intent i = new Intent().setClass(context, TabWidget.class);
context.startActivity(i);
context.finish();
}
}
/**
* Class that injects the JavaScript callback when the 2nd auth
* page was reached.
*/
private class MyWebViewClient extends WebViewClient {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (url.equals("https://api.twitter.com/oauth/authorize")) {
myWebView.loadUrl("javascript:window.HTMLOUT.obtain(document.body.innerHTML);");
// not sure why the following fails, but doesn't really matter
// myWebView.loadUrl("javascript:window.HTMLOUT.setHTML(document.getElementById('code-desc'));");
}
}
}
/**
* This class holds the callback that we inject in MyWebViewClient#onPageFinished
*/
public class MyJavaScriptClient {
/**
* Called from the java script in the web view. We parse the
* html obtained and then generate an account with the help of the
* passed pin
* @param html Html as evaluated by the javascript
*/
@SuppressWarnings("unused")
public void obtain(String html) {
int i = html.indexOf("<code>");
if (i!=-1) {
html = html.substring(i+6);
i = html.indexOf("</code>");
html = html.substring(0,i);
try {
new GenerateAccountWithOauthTask().execute(html).get();
Intent intent = new Intent().setClass(TwitterLoginActivity.this, TabWidget.class);
startActivity(intent);
finish();
} catch (Exception e) {
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
}
}
}