diff --git a/docs-android/app/app.iml b/docs-android/app/app.iml
index 1a8f311d..0df93fa8 100644
--- a/docs-android/app/app.iml
+++ b/docs-android/app/app.iml
@@ -61,13 +61,6 @@
-
-
-
-
-
-
-
@@ -75,6 +68,13 @@
+
+
+
+
+
+
+
@@ -88,6 +88,7 @@
+
diff --git a/docs-android/app/build.gradle b/docs-android/app/build.gradle
index bddc240f..3c6ad05c 100644
--- a/docs-android/app/build.gradle
+++ b/docs-android/app/build.gradle
@@ -3,7 +3,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.0.0-alpha5'
+ classpath 'com.android.tools.build:gradle:2.0.0-alpha7'
}
}
apply plugin: 'com.android.application'
diff --git a/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentEditActivity.java b/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentEditActivity.java
index 148e61b9..6214b2fe 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentEditActivity.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentEditActivity.java
@@ -17,7 +17,7 @@ import com.sismics.docs.adapter.LanguageAdapter;
import com.sismics.docs.adapter.TagAutoCompleteAdapter;
import com.sismics.docs.event.DocumentAddEvent;
import com.sismics.docs.event.DocumentEditEvent;
-import com.sismics.docs.listener.JsonHttpResponseHandler;
+import com.sismics.docs.listener.HttpCallback;
import com.sismics.docs.resource.DocumentResource;
import com.sismics.docs.ui.form.Validator;
import com.sismics.docs.ui.form.validator.Required;
@@ -35,7 +35,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import cz.msebera.android.httpclient.Header;
import de.greenrobot.event.EventBus;
/**
@@ -174,9 +173,9 @@ public class DocumentEditActivity extends AppCompatActivity {
});
// Server callback
- JsonHttpResponseHandler callback = new JsonHttpResponseHandler() {
+ HttpCallback callback = new HttpCallback() {
@Override
- public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
+ public void onSuccess(JSONObject response) {
// Build a fake document JSON to update the UI
final JSONObject outputDoc = new JSONObject();
try {
@@ -211,7 +210,7 @@ public class DocumentEditActivity extends AppCompatActivity {
}
@Override
- public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) {
+ public void onFailure(JSONObject json, Exception e) {
Toast.makeText(DocumentEditActivity.this, R.string.error_editing_document, Toast.LENGTH_LONG).show();
}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentViewActivity.java b/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentViewActivity.java
index d3b9f07d..8c90f2c5 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentViewActivity.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentViewActivity.java
@@ -46,6 +46,7 @@ import com.sismics.docs.event.FileAddEvent;
import com.sismics.docs.event.FileDeleteEvent;
import com.sismics.docs.fragment.DocExportPdfFragment;
import com.sismics.docs.fragment.DocShareFragment;
+import com.sismics.docs.listener.HttpCallback;
import com.sismics.docs.listener.JsonHttpResponseHandler;
import com.sismics.docs.model.application.ApplicationContext;
import com.sismics.docs.resource.CommentResource;
@@ -487,14 +488,14 @@ public class DocumentViewActivity extends AppCompatActivity {
// Actual delete server call
final String documentId = document.optString("id");
- DocumentResource.delete(DocumentViewActivity.this, documentId, new JsonHttpResponseHandler() {
+ DocumentResource.delete(DocumentViewActivity.this, documentId, new HttpCallback() {
@Override
- public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
+ public void onSuccess(JSONObject response) {
EventBus.getDefault().post(new DocumentDeleteEvent(documentId));
}
@Override
- public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) {
+ public void onFailure(JSONObject json, Exception e) {
Toast.makeText(DocumentViewActivity.this, R.string.document_delete_failure, Toast.LENGTH_LONG).show();
}
@@ -646,9 +647,9 @@ public class DocumentViewActivity extends AppCompatActivity {
// Silently get the document to know if it is writable by the current user
// If this call fails or is slow and the document is read-only,
// write actions will be allowed and will fail
- DocumentResource.get(this, document.optString("id"), new JsonHttpResponseHandler() {
+ DocumentResource.get(this, document.optString("id"), new HttpCallback() {
@Override
- public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
+ public void onSuccess(JSONObject response) {
document = response;
boolean writable = document.optBoolean("writable");
diff --git a/docs-android/app/src/main/java/com/sismics/docs/adapter/CommentListAdapter.java b/docs-android/app/src/main/java/com/sismics/docs/adapter/CommentListAdapter.java
index 8c725572..6983d5e3 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/adapter/CommentListAdapter.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/adapter/CommentListAdapter.java
@@ -81,7 +81,7 @@ public class CommentListAdapter extends BaseAdapter {
// Gravatar image
String gravatarUrl = "http://www.gravatar.com/avatar/" + comment.optString("creator_gravatar") + "?s=128d=identicon";
- OkHttpUtil.picasso(context, null)
+ OkHttpUtil.picasso(context)
.load(gravatarUrl)
.into(gravatarImageView);
diff --git a/docs-android/app/src/main/java/com/sismics/docs/adapter/FilePagerAdapter.java b/docs-android/app/src/main/java/com/sismics/docs/adapter/FilePagerAdapter.java
index e2bd5067..8b04cede 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/adapter/FilePagerAdapter.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/adapter/FilePagerAdapter.java
@@ -66,9 +66,9 @@ public class FilePagerAdapter extends PagerAdapter {
String fileUrl = PreferenceUtil.getServerUrl(context) + "/api/file/" + file.optString("id") + "/data?size=web";
// Load image
- OkHttpUtil.picasso(context, authToken)
+ OkHttpUtil.picasso(context)
.load(fileUrl)
- .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
+ .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE) // Don't memory cache the images
.into(fileImageView, new Callback.EmptyCallback() {
@Override
public void onSuccess() {
@@ -109,7 +109,7 @@ public class FilePagerAdapter extends PagerAdapter {
* @return Object
*/
public JSONObject getObjectAt(int position) {
- if (files == null) {
+ if (files == null || position < 0 || position >= files.size()) {
return null;
}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/fragment/DocShareFragment.java b/docs-android/app/src/main/java/com/sismics/docs/fragment/DocShareFragment.java
index 0a39fa6c..aa85a063 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/fragment/DocShareFragment.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/fragment/DocShareFragment.java
@@ -21,6 +21,7 @@ import com.sismics.docs.R;
import com.sismics.docs.adapter.ShareListAdapter;
import com.sismics.docs.event.ShareDeleteEvent;
import com.sismics.docs.event.ShareSendEvent;
+import com.sismics.docs.listener.HttpCallback;
import com.sismics.docs.listener.JsonHttpResponseHandler;
import com.sismics.docs.resource.DocumentResource;
import com.sismics.docs.resource.ShareResource;
@@ -122,9 +123,9 @@ public class DocShareFragment extends DialogFragment {
final ProgressBar shareProgressBar = (ProgressBar) view.findViewById(R.id.shareProgressBar);
shareListView.setEmptyView(shareProgressBar);
- DocumentResource.get(getActivity(), getArguments().getString("id"), new JsonHttpResponseHandler() {
+ DocumentResource.get(getActivity(), getArguments().getString("id"), new HttpCallback() {
@Override
- public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
+ public void onSuccess(JSONObject response) {
document = response;
JSONArray acls = response.optJSONArray("acls");
shareProgressBar.setVisibility(View.GONE);
@@ -133,7 +134,7 @@ public class DocShareFragment extends DialogFragment {
}
@Override
- public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) {
+ public void onFailure(JSONObject json, Exception e) {
getDialog().cancel();
Toast.makeText(getActivity(), R.string.error_loading_shares, Toast.LENGTH_SHORT).show();
}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/resource/BaseResource.java b/docs-android/app/src/main/java/com/sismics/docs/resource/BaseResource.java
index 985c69b3..c0f421cb 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/resource/BaseResource.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/resource/BaseResource.java
@@ -9,11 +9,7 @@ import com.sismics.docs.util.ApplicationUtil;
import com.sismics.docs.util.PreferenceUtil;
import java.io.IOException;
-import java.net.CookieManager;
-import java.net.CookiePolicy;
-import java.net.HttpCookie;
import java.net.Socket;
-import java.net.URI;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
@@ -22,18 +18,12 @@ import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Locale;
-import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import cz.msebera.android.httpclient.conn.ssl.SSLSocketFactory;
-import okhttp3.Interceptor;
-import okhttp3.JavaNetCookieJar;
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
-import okhttp3.Response;
/**
* Base class for API access.
@@ -41,7 +31,6 @@ import okhttp3.Response;
* @author bgamard
*/
public class BaseResource {
-
/**
* User-Agent to use.
*/
@@ -57,11 +46,6 @@ public class BaseResource {
*/
protected static AsyncHttpClient client = new AsyncHttpClient();
- /**
- * OkHttp client.
- */
- protected static OkHttpClient okHttpClient = new OkHttpClient();
-
static {
// 20sec default timeout
client.setTimeout(60000);
@@ -76,43 +60,6 @@ public class BaseResource {
} catch (Exception e) {
// NOP
}
-
- // OkHttp configuration
- try {
- // Create a trust manager that does not validate certificate chains
- final TrustManager[] trustAllCerts = new TrustManager[] {
- new X509TrustManager() {
- @Override
- public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
- }
-
- @Override
- public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
- }
-
- @Override
- public java.security.cert.X509Certificate[] getAcceptedIssuers() {
- return null;
- }
- }
- };
-
- // Install the all-trusting trust manager
- final SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
- final javax.net.ssl.SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
-
- // Configure OkHttpClient
- okHttpClient = okHttpClient.newBuilder()
- .connectTimeout(30, TimeUnit.SECONDS)
- .readTimeout(30, TimeUnit.SECONDS)
- .writeTimeout(30, TimeUnit.SECONDS)
- .hostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
- .sslSocketFactory(sslSocketFactory)
- .build();
- } catch (Exception e) {
- // NOP
- }
}
/**
@@ -135,46 +82,6 @@ public class BaseResource {
}
}
- /**
- * Build an OkHttpClient.
- *
- * @param context Context
- * @return OkHttpClient
- */
- protected static OkHttpClient buildOkHttpClient(final Context context) {
- // Header computation
- if (USER_AGENT == null) {
- USER_AGENT = "Sismics Docs Android " + ApplicationUtil.getVersionName(context) + "/Android " + Build.VERSION.RELEASE + "/" + Build.MODEL;
- }
-
- if (ACCEPT_LANGUAGE == null) {
- Locale locale = Locale.getDefault();
- ACCEPT_LANGUAGE = locale.getLanguage() + "_" + locale.getCountry();
- }
-
- // Cookie handling
- com.sismics.docs.resource.cookie.PersistentCookieStore cookieStore = new com.sismics.docs.resource.cookie.PersistentCookieStore(context);
- CookieManager cookieManager = new CookieManager(cookieStore, CookiePolicy.ACCEPT_ALL);
- cookieStore.add(URI.create(PreferenceUtil.getServerUrl(context)),
- new HttpCookie("auth_token", PreferenceUtil.getAuthToken(context))); // TODO Remove me when async http is ditched
-
- // Runtime configuration
- return okHttpClient.newBuilder()
- .cookieJar(new JavaNetCookieJar(cookieManager))
- .addNetworkInterceptor(new Interceptor() {
- @Override
- public Response intercept(Chain chain) throws IOException {
- Request originalRequest = chain.request();
- return chain.proceed(originalRequest.newBuilder()
- .header("User-Agent", USER_AGENT)
- .header("Accept-Language", ACCEPT_LANGUAGE)
- // TODO necessary?? .method(originalRequest.method(), originalRequest.body())
- .build());
- }
- })
- .build();
- }
-
/**
* Socket factory to allow self-signed certificates for Async HTTP Client.
*
diff --git a/docs-android/app/src/main/java/com/sismics/docs/resource/DocumentResource.java b/docs-android/app/src/main/java/com/sismics/docs/resource/DocumentResource.java
index 65c8a0ed..474590bf 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/resource/DocumentResource.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/resource/DocumentResource.java
@@ -2,12 +2,12 @@ package com.sismics.docs.resource;
import android.content.Context;
-import com.loopj.android.http.RequestParams;
import com.sismics.docs.listener.HttpCallback;
-import com.sismics.docs.listener.JsonHttpResponseHandler;
+import com.sismics.docs.util.OkHttpUtil;
import java.util.Set;
+import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.Request;
@@ -35,8 +35,9 @@ public class DocumentResource extends BaseResource {
.addQueryParameter("asc", "false")
.addQueryParameter("search", query)
.build())
+ .get()
.build();
- buildOkHttpClient(context)
+ OkHttpUtil.buildClient(context)
.newCall(request)
.enqueue(HttpCallback.buildOkHttpCallback(callback));
}
@@ -46,12 +47,16 @@ public class DocumentResource extends BaseResource {
*
* @param context Context
* @param id ID
- * @param responseHandler Callback
+ * @param callback Callback
*/
- public static void get(Context context, String id, JsonHttpResponseHandler responseHandler) {
- init(context);
-
- client.get(getApiUrl(context) + "/document/" + id, responseHandler);
+ public static void get(Context context, String id, HttpCallback callback) {
+ Request request = new Request.Builder()
+ .url(HttpUrl.parse(getApiUrl(context) + "/document/" + id))
+ .get()
+ .build();
+ OkHttpUtil.buildClient(context)
+ .newCall(request)
+ .enqueue(HttpCallback.buildOkHttpCallback(callback));
}
/**
@@ -59,12 +64,16 @@ public class DocumentResource extends BaseResource {
*
* @param context Context
* @param id ID
- * @param responseHandler Callback
+ * @param callback Callback
*/
- public static void delete(Context context, String id, JsonHttpResponseHandler responseHandler) {
- init(context);
-
- client.delete(getApiUrl(context) + "/document/" + id, responseHandler);
+ public static void delete(Context context, String id, HttpCallback callback) {
+ Request request = new Request.Builder()
+ .url(HttpUrl.parse(getApiUrl(context) + "/document/" + id))
+ .delete()
+ .build();
+ OkHttpUtil.buildClient(context)
+ .newCall(request)
+ .enqueue(HttpCallback.buildOkHttpCallback(callback));
}
/**
@@ -76,19 +85,27 @@ public class DocumentResource extends BaseResource {
* @param tagIdList Tags ID list
* @param language Language
* @param createDate Create date
- * @param responseHandler Callback
+ * @param callback Callback
*/
public static void add(Context context, String title, String description,
- Set tagIdList, String language, long createDate, JsonHttpResponseHandler responseHandler) {
- init(context);
+ Set tagIdList, String language, long createDate, HttpCallback callback) {
+ FormBody.Builder formBuilder = new FormBody.Builder()
+ .add("title", title)
+ .add("description", description)
+ .add("language", language)
+ .add("create_date", Long.toString(createDate));
+ String[] tagIdArray = tagIdList.toArray(new String[tagIdList.size()]);
+ for (int i = 0; i < tagIdArray.length; i++) {
+ formBuilder.add("tags", tagIdArray[i]);
+ }
- RequestParams params = new RequestParams();
- params.put("title", title);
- params.put("description", description);
- params.put("tags", tagIdList);
- params.put("language", language);
- params.put("create_date", createDate);
- client.put(getApiUrl(context) + "/document", params, responseHandler);
+ Request request = new Request.Builder()
+ .url(HttpUrl.parse(getApiUrl(context) + "/document"))
+ .put(formBuilder.build())
+ .build();
+ OkHttpUtil.buildClient(context)
+ .newCall(request)
+ .enqueue(HttpCallback.buildOkHttpCallback(callback));
}
/**
@@ -101,19 +118,27 @@ public class DocumentResource extends BaseResource {
* @param tagIdList Tags ID list
* @param language Language
* @param createDate Create date
- * @param responseHandler Callback
+ * @param callback Callback
*/
public static void edit(Context context, String id, String title, String description,
- Set tagIdList, String language, long createDate, JsonHttpResponseHandler responseHandler) {
- init(context);
+ Set tagIdList, String language, long createDate, HttpCallback callback) {
+ FormBody.Builder formBuilder = new FormBody.Builder()
+ .add("title", title)
+ .add("description", description)
+ .add("language", language)
+ .add("create_date", Long.toString(createDate));
+ String[] tagIdArray = tagIdList.toArray(new String[tagIdList.size()]);
+ for (int i = 0; i < tagIdArray.length; i++) {
+ formBuilder.add("tags", tagIdArray[i]);
+ }
- RequestParams params = new RequestParams();
- params.put("title", title);
- params.put("description", description);
- params.put("tags", tagIdList);
- params.put("language", language);
- params.put("create_date", createDate);
- client.post(getApiUrl(context) + "/document/" + id, params, responseHandler);
+ Request request = new Request.Builder()
+ .url(HttpUrl.parse(getApiUrl(context) + "/document/" + id))
+ .post(formBuilder.build())
+ .build();
+ OkHttpUtil.buildClient(context)
+ .newCall(request)
+ .enqueue(HttpCallback.buildOkHttpCallback(callback));
}
/**
diff --git a/docs-android/app/src/main/java/com/sismics/docs/util/OkHttpUtil.java b/docs-android/app/src/main/java/com/sismics/docs/util/OkHttpUtil.java
index be3cdc39..e6756cdf 100644
--- a/docs-android/app/src/main/java/com/sismics/docs/util/OkHttpUtil.java
+++ b/docs-android/app/src/main/java/com/sismics/docs/util/OkHttpUtil.java
@@ -1,23 +1,29 @@
package com.sismics.docs.util;
import android.content.Context;
+import android.os.Build;
import android.util.Log;
import com.jakewharton.picasso.OkHttp3Downloader;
+import com.sismics.docs.resource.cookie.PersistentCookieStore;
import com.squareup.picasso.Picasso;
import java.io.IOException;
+import java.net.CookieManager;
+import java.net.CookiePolicy;
+import java.net.HttpCookie;
+import java.net.URI;
import java.security.cert.CertificateException;
+import java.util.Locale;
+import java.util.concurrent.TimeUnit;
-import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import okhttp3.Cache;
import okhttp3.Interceptor;
+import okhttp3.JavaNetCookieJar;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
@@ -29,57 +35,27 @@ import okhttp3.Response;
*/
public class OkHttpUtil {
/**
- * Build a Picasso object with base config.
- *
- * @param context Context
- * @param authToken Auth token
- * @return Picasso object
+ * OkHttp singleton client.
*/
- public static Picasso picasso(Context context, final String authToken) {
- OkHttpClient okHttpClient = buildOkHttpClient()
- .addInterceptor(new Interceptor() {
- @Override
- public Response intercept(Interceptor.Chain chain) throws IOException {
- final Request original = chain.request();
- final Request.Builder requestBuilder = original.newBuilder()
- .header("Cookie", "auth_token=" + authToken)
- .header("Cache-Control", "max-age=" + (3600 * 24 * 365))
- .method(original.method(), original.body());
- return chain.proceed(requestBuilder.build());
- }
- })
- .cache(new Cache(context.getCacheDir(),
- PreferenceUtil.getIntegerPreference(context, PreferenceUtil.PREF_CACHE_SIZE, 0) * 1000000))
- .build();
-
- Picasso picasso = new Picasso.Builder(context)
- .downloader(new OkHttp3Downloader(okHttpClient))
- .build();
- picasso.setIndicatorsEnabled(false);
- return picasso;
- }
+ private static OkHttpClient okHttpClient = new OkHttpClient();
/**
- * Clear the cache.
- *
- * @param context Context
+ * Singleton cache.
*/
- public static void clearCache(Context context) {
- Cache cache = new Cache(context.getCacheDir(),
- PreferenceUtil.getIntegerPreference(context, PreferenceUtil.PREF_CACHE_SIZE, Integer.MAX_VALUE));
- try {
- cache.evictAll();
- } catch (IOException e) {
- Log.e("OKHttpUtil", "Error clearing cache", e);
- }
- }
+ private static Cache cache = null;
/**
- * Build a OkHttpClient accepting all SSL certificates.
- *
- * @return OkHttpClient.Builder
+ * User-Agent to use.
*/
- private static OkHttpClient.Builder buildOkHttpClient() {
+ protected static String userAgent = null;
+
+ /**
+ * Accept-Language header.
+ */
+ protected static String acceptLanguage = null;
+
+ static {
+ // OkHttp configuration
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[] {
@@ -102,22 +78,114 @@ public class OkHttpUtil {
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
+ final javax.net.ssl.SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
- // Create an ssl socket factory with our all-trusting manager
- final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
-
- OkHttpClient.Builder builder = new OkHttpClient.Builder();
- builder.sslSocketFactory(sslSocketFactory);
- builder.hostnameVerifier(new HostnameVerifier() {
- @Override
- public boolean verify(String hostname, SSLSession session) {
- return true;
- }
- });
-
- return builder;
+ // Configure OkHttpClient
+ okHttpClient = okHttpClient.newBuilder()
+ .connectTimeout(30, TimeUnit.SECONDS)
+ .readTimeout(30, TimeUnit.SECONDS)
+ .writeTimeout(30, TimeUnit.SECONDS)
+ .sslSocketFactory(sslSocketFactory)
+ .build();
} catch (Exception e) {
- throw new RuntimeException(e);
+ // NOP
}
}
+
+ /**
+ * Build a Picasso object with base config.
+ *
+ * @param context Context
+ * @return Picasso object
+ */
+ public static Picasso picasso(Context context) {
+ OkHttpClient okHttpClient = buildClient(context)
+ .newBuilder()
+ .addInterceptor(new Interceptor() {
+ @Override
+ public Response intercept(Interceptor.Chain chain) throws IOException { // Override cache configuration
+ final Request original = chain.request();
+ final Request.Builder requestBuilder = original.newBuilder()
+ .header("Cache-Control", "max-age=" + (3600 * 24 * 365))
+ .method(original.method(), original.body());
+ return chain.proceed(requestBuilder.build());
+ }
+ })
+ .cache(getCache(context))
+ .build();
+
+ Picasso picasso = new Picasso.Builder(context)
+ .downloader(new OkHttp3Downloader(okHttpClient))
+ .build();
+ picasso.setIndicatorsEnabled(false); // Debug stuff
+ return picasso;
+ }
+
+ /**
+ * Get and eventually build the singleton cache.
+ *
+ * @param context Context
+ * @return Cache
+ */
+ private static Cache getCache(Context context) {
+ if (cache == null) {
+ cache = new Cache(context.getCacheDir(),
+ PreferenceUtil.getIntegerPreference(context, PreferenceUtil.PREF_CACHE_SIZE, 0) * 1000000);
+ }
+ return cache;
+ }
+
+ /**
+ * Clear the HTTP cache.
+ *
+ * @param context Context
+ */
+ public static void clearCache(Context context) {
+ Cache cache = getCache(context);
+ try {
+ cache.evictAll();
+ } catch (IOException e) {
+ Log.e("OKHttpUtil", "Error clearing cache", e);
+ }
+ }
+
+ /**
+ * Build an OkHttpClient.
+ *
+ * @param context Context
+ * @return OkHttpClient
+ */
+ public static OkHttpClient buildClient(final Context context) {
+ // One-time header computation
+ if (userAgent == null) {
+ userAgent = "Sismics Docs Android " + ApplicationUtil.getVersionName(context) + "/Android " + Build.VERSION.RELEASE + "/" + Build.MODEL;
+ }
+
+ if (acceptLanguage == null) {
+ Locale locale = Locale.getDefault();
+ acceptLanguage = locale.getLanguage() + "_" + locale.getCountry();
+ }
+
+ // Cookie handling
+ PersistentCookieStore cookieStore = new PersistentCookieStore(context);
+ CookieManager cookieManager = new CookieManager(cookieStore, CookiePolicy.ACCEPT_ALL);
+ cookieStore.add(URI.create(PreferenceUtil.getServerUrl(context)),
+ new HttpCookie("auth_token", PreferenceUtil.getAuthToken(context))); // TODO Remove me when async http is ditched
+
+ // Runtime configuration
+ return okHttpClient.newBuilder()
+ .cookieJar(new JavaNetCookieJar(cookieManager))
+ .addNetworkInterceptor(new Interceptor() {
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Request originalRequest = chain.request();
+ return chain.proceed(originalRequest.newBuilder()
+ .header("User-Agent", userAgent)
+ .header("Accept-Language", acceptLanguage)
+ // TODO necessary?? .method(originalRequest.method(), originalRequest.body())
+ .build());
+ }
+ })
+ .build();
+ }
}