package com.nostra13.socialsharing.twitter; import java.util.regex.Matcher; import java.util.regex.Pattern; import android.annotation.SuppressLint; import android.app.Dialog; import android.app.ProgressDialog; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Color; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.Window; import android.webkit.JavascriptInterface; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.FrameLayout; import android.widget.LinearLayout; import com.nostra13.socialsharing.common.AuthListener; import com.nostra13.socialsharing.twitter.extpack.winterwell.jtwitter.TwitterException; /** * @author Sergey Tarasevich (nostra13[at]gmail[dot]com) */ class TwitterDialog extends Dialog { public static final String TAG = "twitter"; static final FrameLayout.LayoutParams FILL = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); static final String JS_HTML_EXTRACTOR = "javascript:window.HTMLOUT.processHTML('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');"; static final String OAUTH_PIN_BLOCK_REGEXP = "id=\\\"oauth_pin((.|\\n)*)(\\d{7})"; static final String OAUTH_PIN_REGEXP = "\\d{7}"; private ProgressDialog spinner; private WebView browser; private FrameLayout content; private AsyncTwitter twitter; private String requestUrl; private AuthListener authListener; public TwitterDialog(Context context, AsyncTwitter twitter) { super(context, android.R.style.Theme_Translucent_NoTitleBar); this.twitter = twitter; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); spinner = new ProgressDialog(getContext()); spinner.requestWindowFeature(Window.FEATURE_NO_TITLE); spinner.setMessage("Loading..."); requestWindowFeature(Window.FEATURE_NO_TITLE); content = new FrameLayout(getContext()); setUpWebView(10); addContentView(content, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); } @Override public void show() { super.show(); browser.setVisibility(View.INVISIBLE); spinner.show(); if (requestUrl == null) { retrieveRequestToken(); } else { browser.loadUrl(requestUrl); } } private void retrieveRequestToken() { twitter.getOAuthRequestToken(new AuthRequestListener() { @Override public void onAuthRequestFailed(Exception e) { Log.e(TAG, e.getMessage(), e); String errorMessage = e.getMessage(); if (errorMessage == null) { errorMessage = e.getMessage(); } TwitterEvents.onLoginError(errorMessage); spinner.dismiss(); dismiss(); } @Override public void onAuthRequestComplete(String requestUrl) { TwitterDialog.this.requestUrl = requestUrl; browser.loadUrl(requestUrl); } }); } @SuppressLint("SetJavaScriptEnabled") private void setUpWebView(int margin) { LinearLayout webViewContainer = new LinearLayout(getContext()); browser = new WebView(getContext()); browser.setVerticalScrollBarEnabled(false); browser.setHorizontalScrollBarEnabled(false); browser.setWebViewClient(new TwitterDialog.TwWebViewClient()); browser.getSettings().setJavaScriptEnabled(true); browser.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT"); browser.setLayoutParams(FILL); webViewContainer.setPadding(margin, margin, margin, margin); webViewContainer.addView(browser); content.addView(webViewContainer); } public void setAuthListener(AuthListener authListener) { this.authListener = authListener; } private class TwWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); if (authListener != null) authListener.onAuthFail(description); TwitterEvents.onLoginError(description); TwitterDialog.this.dismiss(); } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { Log.d(TAG, "WebView loading URL: " + url); super.onPageStarted(view, url, favicon); spinner.show(); } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); browser.loadUrl(JS_HTML_EXTRACTOR); content.setBackgroundColor(Color.TRANSPARENT); browser.setVisibility(View.VISIBLE); } } class MyJavaScriptInterface { @JavascriptInterface public void processHTML(String html) { String blockWithPin = findExpression(html, OAUTH_PIN_BLOCK_REGEXP); if (blockWithPin != null) { String pin = findExpression(blockWithPin, OAUTH_PIN_REGEXP); if (pin != null) { autorizeApp(pin); spinner.dismiss(); dismiss(); } } spinner.dismiss(); } private String findExpression(String text, String regExp) { Pattern p = Pattern.compile(regExp); Matcher m = p.matcher(text); if (m.find()) { return m.group(0); } else { return null; } } private void autorizeApp(String pin) { try { AccessToken accessToken = twitter.getOAuthAccessToken(pin); TwitterSessionStore.save(accessToken, getContext()); if (authListener != null) authListener.onAuthSucceed(); TwitterEvents.onLoginSuccess(); } catch (TwitterException e) { Log.e(TAG, e.getMessage(), e); if (authListener != null) authListener.onAuthFail(e.getMessage()); TwitterEvents.onLoginError(e.getMessage()); } } } }