/**
* Copyright 2010 Mark Wyszomierski
*/
package com.joelapenna.foursquared;
import com.joelapenna.foursquare.http.AbstractHttpApi;
import com.joelapenna.foursquared.util.NotificationsUtil;
import org.apache.http.HttpException;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.AuthState;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.webkit.WebView;
import java.io.IOException;
/**
* Displays a special in a webview. Ideally we could use WebView.setHttpAuthUsernamePassword(),
* but it is unfortunately not working. Instead we download the html content manually, then
* feed it to our webview. Not ideal and we should update this in the future.
*
* @date April 4, 2010.
* @author Mark Wyszomierski (markww@gmail.com), foursquare.
*
*/
public class SpecialWebViewActivity extends Activity
{
private static final String TAG = "WebViewActivity";
public static final String EXTRA_CREDENTIALS_USERNAME = Foursquared.PACKAGE_NAME
+ ".SpecialWebViewActivity.EXTRA_CREDENTIALS_USERNAME";
public static final String EXTRA_CREDENTIALS_PASSWORD = Foursquared.PACKAGE_NAME
+ ".SpecialWebViewActivity.EXTRA_CREDENTIALS_PASSWORD";
public static final String EXTRA_SPECIAL_ID = Foursquared.PACKAGE_NAME
+ ".SpecialWebViewActivity.EXTRA_SPECIAL_ID";
private WebView mWebView;
private StateHolder mStateHolder;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.special_webview_activity);
mWebView = (WebView)findViewById(R.id.webView);
mWebView.getSettings().setJavaScriptEnabled(true);
Object retained = getLastNonConfigurationInstance();
if (retained != null && retained instanceof StateHolder) {
mStateHolder = (StateHolder) retained;
mStateHolder.setActivityForTask(this);
if (mStateHolder.getIsRunningTask() == false) {
mWebView.loadDataWithBaseURL("--", mStateHolder.getHtml(), "text/html", "utf-8", "");
}
} else {
mStateHolder = new StateHolder();
if (getIntent().getExtras() != null &&
getIntent().getExtras().containsKey(EXTRA_CREDENTIALS_USERNAME) &&
getIntent().getExtras().containsKey(EXTRA_CREDENTIALS_PASSWORD) &&
getIntent().getExtras().containsKey(EXTRA_SPECIAL_ID))
{
String username = getIntent().getExtras().getString(EXTRA_CREDENTIALS_USERNAME);
String password = getIntent().getExtras().getString(EXTRA_CREDENTIALS_PASSWORD);
String specialid = getIntent().getExtras().getString(EXTRA_SPECIAL_ID);
mStateHolder.startTask(this, username, password, specialid);
} else {
Log.e(TAG, TAG + " intent missing required extras parameters.");
finish();
}
}
}
@Override
public Object onRetainNonConfigurationInstance() {
mStateHolder.setActivityForTask(null);
return mStateHolder;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
private void onTaskComplete(String html, Exception ex) {
mStateHolder.setIsRunningTask(false);
if (html != null) {
mStateHolder.setHtml(html);
mWebView.loadDataWithBaseURL("--", mStateHolder.getHtml(), "text/html", "utf-8", "");
} else {
NotificationsUtil.ToastReasonForFailure(this, ex);
}
}
private static class SpecialTask extends AsyncTask<String, Void, String> {
private SpecialWebViewActivity mActivity;
private Exception mReason;
public SpecialTask(SpecialWebViewActivity activity) {
mActivity = activity;
}
public void setActivity(SpecialWebViewActivity activity) {
mActivity = activity;
}
@Override
protected void onPreExecute() {
}
@Override
protected String doInBackground(String... params) {
String html = null;
try {
String username = params[0];
String password = params[1];
String specialid = params[2];
StringBuilder sbUrl = new StringBuilder(128);
sbUrl.append("https://api.foursquare.com/iphone/special?sid=");
sbUrl.append(specialid);
AuthScope authScope = new AuthScope("api.foursquare.com", 80);
DefaultHttpClient httpClient = AbstractHttpApi.createHttpClient();
httpClient.getCredentialsProvider().setCredentials(authScope,
new UsernamePasswordCredentials(username, password));
httpClient.addRequestInterceptor(preemptiveAuth, 0);
HttpGet httpGet = new HttpGet(sbUrl.toString());
try {
HttpResponse response = httpClient.execute(httpGet);
String responseText = EntityUtils.toString(response.getEntity());
html = responseText.replace("('/img", "('http://www.foursquare.com/img");
} catch (Exception e) {
mReason = e;
}
} catch (Exception e) {
mReason = e;
}
return html;
}
@Override
protected void onPostExecute(String html) {
if (mActivity != null) {
mActivity.onTaskComplete(html, mReason);
}
}
@Override
protected void onCancelled() {
if (mActivity != null) {
mActivity.onTaskComplete(null, new Exception("Special task cancelled."));
}
}
private HttpRequestInterceptor preemptiveAuth = new HttpRequestInterceptor() {
@Override
public void process(final HttpRequest request, final HttpContext context)
throws HttpException, IOException {
AuthState authState = (AuthState)context.getAttribute(ClientContext.TARGET_AUTH_STATE);
CredentialsProvider credsProvider = (CredentialsProvider)context
.getAttribute(ClientContext.CREDS_PROVIDER);
HttpHost targetHost = (HttpHost)context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
// If not auth scheme has been initialized yet
if (authState.getAuthScheme() == null) {
AuthScope authScope = new AuthScope(targetHost.getHostName(), targetHost.getPort());
org.apache.http.auth.Credentials creds = credsProvider.getCredentials(authScope);
if (creds != null) {
authState.setAuthScheme(new BasicScheme());
authState.setCredentials(creds);
}
}
}
};
}
private static class StateHolder {
private String mHtml;
private boolean mIsRunningTask;
private SpecialTask mTask;
public StateHolder() {
mIsRunningTask = false;
}
public void setHtml(String html) {
mHtml = html;
}
public String getHtml() {
return mHtml;
}
public void startTask(SpecialWebViewActivity activity,
String username,
String password,
String specialid)
{
mIsRunningTask = true;
mTask = new SpecialTask(activity);
mTask.execute(username, password, specialid);
}
public void setActivityForTask(SpecialWebViewActivity activity) {
if (mTask != null) {
mTask.setActivity(activity);
}
}
public void setIsRunningTask(boolean isRunningTipTask) {
mIsRunningTask = isRunningTipTask;
}
public boolean getIsRunningTask() {
return mIsRunningTask;
}
}
}