/*
* Copyright (c) 2016 Ha Duy Trung
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.hidroh.materialistic;
import android.content.Context;
import android.util.Log;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import io.github.hidroh.materialistic.data.AlgoliaClient;
import io.github.hidroh.materialistic.data.HackerNewsClient;
import io.github.hidroh.materialistic.data.ReadabilityClient;
import io.github.hidroh.materialistic.data.RestServiceFactory;
import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.Call;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
@Module(library = true, complete = false)
class NetworkModule {
private static final String TAG_OK_HTTP = "OkHttp";
private static final long CACHE_SIZE = 20 * 1024 * 1024; // 20 MB
@Provides @Singleton
public RestServiceFactory provideRestServiceFactory(Call.Factory callFactory) {
return new RestServiceFactory.Impl(callFactory);
}
@Provides @Singleton
public Call.Factory provideCallFactory(Context context) {
return new OkHttpClient.Builder()
.cache(new Cache(context.getApplicationContext().getCacheDir(), CACHE_SIZE))
.addNetworkInterceptor(new CacheOverrideNetworkInterceptor())
.addInterceptor(new ConnectionAwareInterceptor(context))
.addInterceptor(new LoggingInterceptor())
.followRedirects(false)
.build();
}
static class ConnectionAwareInterceptor implements Interceptor {
static final Map<String, String> CACHE_ENABLED_HOSTS = new HashMap<>();
static {
CACHE_ENABLED_HOSTS.put(HackerNewsClient.HOST,
RestServiceFactory.CACHE_CONTROL_MAX_AGE_30M);
CACHE_ENABLED_HOSTS.put(AlgoliaClient.HOST,
RestServiceFactory.CACHE_CONTROL_MAX_AGE_30M);
CACHE_ENABLED_HOSTS.put(ReadabilityClient.HOST,
RestServiceFactory.CACHE_CONTROL_MAX_AGE_24H);
}
private final Context mContext;
ConnectionAwareInterceptor(Context context) {
mContext = context.getApplicationContext();
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
boolean forceCache = CACHE_ENABLED_HOSTS.containsKey(request.url().host()) &&
!AppUtils.hasConnection(mContext);
return chain.proceed(forceCache ?
request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build() :
request);
}
}
static class CacheOverrideNetworkInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
if (!ConnectionAwareInterceptor.CACHE_ENABLED_HOSTS
.containsKey(request.url().host())) {
return response;
} else {
return response.newBuilder()
.header("Cache-Control",
ConnectionAwareInterceptor.CACHE_ENABLED_HOSTS
.get(request.url().host()))
.build();
}
}
}
static class LoggingInterceptor implements Interceptor {
private final Interceptor debugInterceptor = new HttpLoggingInterceptor(
message -> Log.d(TAG_OK_HTTP, message))
.setLevel(BuildConfig.DEBUG ?
HttpLoggingInterceptor.Level.BODY :
HttpLoggingInterceptor.Level.NONE);
@Override
public Response intercept(Chain chain) throws IOException {
return debugInterceptor.intercept(chain);
}
}
}