/*
* Copyright 2013-2015 The GDG Frisbee Project
*
* 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 org.gdg.frisbee.android.app;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.os.StrictMode;
import com.crashlytics.android.Crashlytics;
import com.google.android.gms.analytics.GoogleAnalytics;
import com.google.android.gms.analytics.Tracker;
import com.jakewharton.picasso.OkHttp3Downloader;
import com.squareup.leakcanary.LeakCanary;
import com.squareup.leakcanary.RefWatcher;
import com.squareup.picasso.Picasso;
import net.danlew.android.joda.JodaTimeAndroid;
import org.gdg.frisbee.android.BuildConfig;
import org.gdg.frisbee.android.R;
import org.gdg.frisbee.android.api.GdeDirectory;
import org.gdg.frisbee.android.api.GdeDirectoryFactory;
import org.gdg.frisbee.android.api.GdgXHub;
import org.gdg.frisbee.android.api.GdgXHubFactory;
import org.gdg.frisbee.android.api.GitHub;
import org.gdg.frisbee.android.api.GithubFactory;
import org.gdg.frisbee.android.api.GroupDirectory;
import org.gdg.frisbee.android.api.GroupDirectoryFactory;
import org.gdg.frisbee.android.api.OkClientFactory;
import org.gdg.frisbee.android.api.PlusApi;
import org.gdg.frisbee.android.api.PlusApiFactory;
import org.gdg.frisbee.android.api.PlusImageUrlConverter;
import org.gdg.frisbee.android.cache.ModelCache;
import org.gdg.frisbee.android.eventseries.NotificationHandler;
import org.gdg.frisbee.android.eventseries.TaggedEventSeries;
import org.gdg.frisbee.android.eventseries.TaggedEventSeriesFactory;
import org.gdg.frisbee.android.utils.CrashlyticsTree;
import org.gdg.frisbee.android.utils.FileUtils;
import org.gdg.frisbee.android.utils.GingerbreadLastLocationFinder;
import org.gdg.frisbee.android.utils.PrefUtils;
import java.io.File;
import java.util.List;
import io.fabric.sdk.android.Fabric;
import okhttp3.OkHttpClient;
import timber.log.Timber;
public class App extends BaseApp implements LocationListener {
private OkHttpClient okHttpClient;
private GroupDirectory groupDirectory;
private GdgXHub gdgXHub;
private GdeDirectory gdeDirectory;
private GitHub gitHub;
private PlusApi plusApi;
private ModelCache mModelCache;
private Picasso mPicasso;
private Tracker mTracker;
private GingerbreadLastLocationFinder mLocationFinder;
private Location mLastLocation;
private OrganizerChecker mOrganizerChecker;
private List<TaggedEventSeries> mTaggedEventSeriesList;
private RefWatcher refWatcher;
public static App from(Context context) {
return (App) context.getApplicationContext();
}
@Override
public void onCreate() {
super.onCreate();
if (BuildConfig.DEBUG) {
Timber.plant(new Timber.DebugTree());
StrictMode.ThreadPolicy.Builder b = new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
.penaltyLog()
.penaltyFlashScreen();
StrictMode.setThreadPolicy(b.build());
} else {
Fabric.with(this, new Crashlytics());
Crashlytics.setString("commitSha", BuildConfig.COMMIT_SHA);
Crashlytics.setString("commitTime", BuildConfig.COMMIT_TIME);
Timber.plant(new CrashlyticsTree());
}
int storedVersionCode = PrefUtils.getVersionCode(this);
if (storedVersionCode != 0 && storedVersionCode < BuildConfig.VERSION_CODE) {
onAppUpdate(storedVersionCode, BuildConfig.VERSION_CODE);
PrefUtils.setVersionCode(this, BuildConfig.VERSION_CODE);
}
okHttpClient = OkClientFactory.provideOkHttpClient(this);
// Initialize ModelCache
getModelCache();
PrefUtils.increaseAppStartCount(this);
// Initialize Picasso
OkHttpClient picassoClient = okHttpClient.newBuilder()
.cache(OkHttp3Downloader.createDefaultCache(this))
.addInterceptor(new PlusImageUrlConverter(getPlusApi()))
.build();
mPicasso = new Picasso.Builder(this)
.downloader(new OkHttp3Downloader(picassoClient))
.build();
JodaTimeAndroid.init(this);
refWatcher = LeakCanary.install(this);
mOrganizerChecker = new OrganizerChecker(PrefUtils.prefs(this), getGdgXHub());
GoogleAnalytics.getInstance(this).setAppOptOut(PrefUtils.isAnalyticsEnabled(this));
// Init LastLocationFinder
mLocationFinder = new GingerbreadLastLocationFinder(this);
mLocationFinder.setChangedLocationListener(this);
updateLastLocation();
initTaggedEventSeries();
}
@Override
protected void onAppUpdate(int oldVersion, int newVersion) {
super.onAppUpdate(oldVersion, newVersion);
File diskCacheLocation = getDiskCacheLocation();
FileUtils.deleteDirectory(diskCacheLocation);
}
/**
* Init TaggedEventSeries.
*/
private void initTaggedEventSeries() {
mTaggedEventSeriesList = TaggedEventSeriesFactory.createAvailableEventSeries(this);
updateEventSeriesAlarms();
}
private void updateEventSeriesAlarms() {
for (TaggedEventSeries eventSeries : currentTaggedEventSeries()) {
NotificationHandler notificationHandler = new NotificationHandler(this, eventSeries);
if (notificationHandler.shouldSetAlarm()) {
notificationHandler.setAlarmForNotification();
}
}
}
public void updateLastLocation() {
Location loc = mLocationFinder.getLastBestLocation(5000, 60 * 60 * 1000);
if (loc != null) {
mLastLocation = loc;
}
}
public Location getLastLocation() {
return mLastLocation;
}
public Picasso getPicasso() {
return mPicasso;
}
public Tracker getTracker() {
if (mTracker == null) {
// Initialize GA
GoogleAnalytics gaInstance = GoogleAnalytics.getInstance(getApplicationContext());
mTracker = gaInstance.newTracker(getString(R.string.ga_trackingId));
mTracker.setAppName(getString(R.string.app_name));
mTracker.setAnonymizeIp(true);
}
return mTracker;
}
public ModelCache getModelCache() {
if (mModelCache == null) {
final File rootDir = getDiskCacheLocation();
ModelCache.Builder builder = new ModelCache.Builder(this)
.setMemoryCacheEnabled(true);
if (rootDir.mkdirs() || rootDir.isDirectory()) {
builder.setDiskCacheEnabled(true)
.setDiskCacheLocation(rootDir);
}
mModelCache = builder.build();
}
return mModelCache;
}
private File getDiskCacheLocation() {
File cacheDir = getExternalCacheDir();
if (cacheDir == null) {
cacheDir = getCacheDir();
}
return new File(cacheDir, "/model_cache/");
}
@Override
public void onLocationChanged(Location location) {
mLastLocation = location;
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
@Override
public void onProviderEnabled(String s) {
}
@Override
public void onProviderDisabled(String s) {
}
public boolean isOrganizer() {
return mOrganizerChecker.isOrganizer();
}
public void checkOrganizer(OrganizerChecker.Callbacks responseHandler) {
mOrganizerChecker.checkOrganizer(this, responseHandler);
}
public void resetOrganizer() {
mOrganizerChecker.resetOrganizer();
}
/**
* Return the current list of GDG event series occurring in the world.
* This may be empty but cannot be null.
*
* @return List of current event series.
*/
public List<TaggedEventSeries> currentTaggedEventSeries() {
return mTaggedEventSeriesList;
}
public GdgXHub getGdgXHub() {
if (gdgXHub == null) {
gdgXHub = GdgXHubFactory.provideHubApi(okHttpClient);
}
return gdgXHub;
}
public GroupDirectory getGroupDirectory() {
if (groupDirectory == null) {
groupDirectory = GroupDirectoryFactory.provideGroupDirectoryApi(okHttpClient);
}
return groupDirectory;
}
public GdeDirectory getGdeDirectory() {
if (gdeDirectory == null) {
gdeDirectory = GdeDirectoryFactory.provideGdeApi(okHttpClient);
}
return gdeDirectory;
}
public GitHub getGithub() {
if (gitHub == null) {
gitHub = GithubFactory.provideGitHubApi(okHttpClient);
}
return gitHub;
}
public PlusApi getPlusApi() {
if (plusApi == null) {
plusApi = PlusApiFactory.providePlusApi(okHttpClient);
}
return plusApi;
}
public RefWatcher getRefWatcher() {
return refWatcher;
}
}