package fr.prcaen.externalresources; import android.content.Context; import android.content.res.Configuration; import android.support.annotation.NonNull; import com.squareup.okhttp.CacheControl; import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.Request; import com.squareup.okhttp.Response; import fr.prcaen.externalresources.converter.Converter; import fr.prcaen.externalresources.exception.ExternalResourceException; import fr.prcaen.externalresources.exception.ResponseException; import fr.prcaen.externalresources.model.Resources; import fr.prcaen.externalresources.url.Url; import java.io.IOException; import java.util.concurrent.TimeUnit; import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION_CODES.HONEYCOMB_MR2; import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1; public final class Downloader { private static final int CONNECT_TIMEOUT_MILLIS = 15 * 1000; // 15s private static final int READ_TIMEOUT_MILLIS = 20 * 1000; // 20s private static final int WRITE_TIMEOUT_MILLIS = 20 * 1000; // 20s @NonNull private final Context context; @NonNull private final OkHttpClient client; @NonNull private final Converter converter; @NonNull private final Url url; @NonNull private final Options options; public Downloader(@NonNull Context context, @NonNull Converter converter, @NonNull Url url, @NonNull Options options) { this(context, new OkHttpClient(), converter, url, options); } public Downloader(@NonNull Context context, @NonNull OkHttpClient client, @NonNull Converter converter, @NonNull Url url, @NonNull Options options) { this.context = context.getApplicationContext(); this.client = client; this.url = url; this.options = options; this.converter = converter; Cache cache = new Cache(context.getApplicationContext()); client.setConnectTimeout(CONNECT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); client.setReadTimeout(READ_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); client.setWriteTimeout(WRITE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); client.setCache(new com.squareup.okhttp.Cache(cache.getCacheDir(), cache.getCacheSize())); } public Resources load(@Cache.Policy int policy) throws ExternalResourceException { buildUrl(); Logger.i(ExternalResources.TAG, "Load configuration from url: " + url.build()); final CacheControl cacheControl; switch (policy) { case Cache.POLICY_NONE: cacheControl = new CacheControl.Builder().noCache().noStore().build(); break; case Cache.POLICY_OFFLINE: cacheControl = CacheControl.FORCE_CACHE; break; case Cache.POLICY_ALL: default: cacheControl = new CacheControl.Builder().build(); break; } Logger.v(ExternalResources.TAG, "CachePolicy: " + policy); Request request = new Request.Builder().url(url.build()).cacheControl(cacheControl).build(); try { Response response = client.newCall(request).execute(); int responseCode = response.code(); Logger.d(ExternalResources.TAG, "Response code: " + responseCode); if (responseCode >= 300) { response.body().close(); throw new ResponseException(responseCode + " " + response.message(), policy, responseCode); } return converter.fromReader(response.body().charStream()); } catch (IOException e) { throw new ExternalResourceException(e); } } protected void buildUrl() { Configuration configuration = context.getResources().getConfiguration(); if (options.isUseFontScale()) { url.fontScale(configuration.fontScale); } if (options.isUseHardKeyboardHidden()) { url.hardKeyboardHidden(configuration.hardKeyboardHidden); } if (options.isUseKeyboard()) { url.keyboard(configuration.keyboard); } if (options.isUseKeyboardHidden()) { url.keyboardHidden(configuration.keyboardHidden); } if (options.isUseLocale()) { url.locale(configuration.locale); } if (options.isUseMcc()) { url.mcc(configuration.mcc); } if (options.isUseMnc()) { url.mnc(configuration.mnc); } if (options.isUseNavigation()) { url.navigation(configuration.navigation); } if (options.isUseNavigationHidden()) { url.navigationHidden(configuration.navigationHidden); } if (options.isUseOrientation()) { url.orientation(configuration.orientation); } if (options.isUseScreenLayout()) { url.screenLayout(configuration.screenLayout); } if (options.isUseTouchscreen()) { url.touchscreen(configuration.touchscreen); } if (options.isUseUiMode()) { url.uiMode(configuration.uiMode); } if (options.isUseDensityDpi() && SDK_INT >= JELLY_BEAN_MR1) { url.densityDpi(configuration.densityDpi); } if (SDK_INT >= HONEYCOMB_MR2) { if (options.isUseScreenWidthDp()) { url.screenWidthDp(configuration.screenWidthDp); } if (options.isUseScreenHeightDp()) { url.screenHeightDp(configuration.screenHeightDp); } if (options.isUseSmallestScreenWidthDp()) { url.smallestScreenWidthDp(configuration.smallestScreenWidthDp); } } } }