/*
* Firetweet - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.getlantern.firetweet.app;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.PackageManager;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.AsyncTask;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.multidex.MultiDexApplication;
import android.util.Log;
import com.crashlytics.android.Crashlytics;
import com.nostra13.universalimageloader.cache.disc.DiskCache;
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.nostra13.universalimageloader.core.download.ImageDownloader;
import com.nostra13.universalimageloader.utils.L;
import com.squareup.otto.Bus;
import com.google.common.net.HostAndPort;
import io.fabric.sdk.android.Fabric;
import org.getlantern.firetweet.Constants;
import org.getlantern.firetweet.activity.MainActivity;
import org.getlantern.firetweet.activity.MainHondaJOJOActivity;
import org.getlantern.firetweet.service.RefreshService;
import org.getlantern.firetweet.util.AsyncTaskManager;
import org.getlantern.firetweet.util.AsyncTwitterWrapper;
import org.getlantern.firetweet.util.MediaLoaderWrapper;
import org.getlantern.firetweet.util.MessagesManager;
import org.getlantern.firetweet.util.MultiSelectManager;
import org.getlantern.firetweet.util.ReadStateManager;
import org.getlantern.firetweet.util.StrictModeUtils;
import org.getlantern.firetweet.util.Utils;
import org.getlantern.firetweet.util.VideoLoader;
import org.getlantern.firetweet.util.content.FiretweetSQLiteOpenHelper;
import org.getlantern.firetweet.util.imageloader.FiretweetImageDownloader;
import org.getlantern.firetweet.util.imageloader.URLFileNameGenerator;
import org.getlantern.firetweet.util.net.FiretweetHostAddressResolver;
import java.io.File;
import org.lantern.mobilesdk.Lantern;
import edu.ucdavis.earlybird.UCDService;
import twitter4j.http.HostAddressResolver;
import static org.getlantern.firetweet.util.UserColorNameUtils.initUserColor;
import static org.getlantern.firetweet.util.Utils.getBestCacheDir;
import static org.getlantern.firetweet.util.Utils.getInternalCacheDir;
import static org.getlantern.firetweet.util.Utils.initAccountColor;
import static org.getlantern.firetweet.util.Utils.startRefreshServiceIfNeeded;
public class FiretweetApplication extends MultiDexApplication implements Constants,
OnSharedPreferenceChangeListener {
private static final String KEY_UCD_DATA_PROFILING = "ucd_data_profiling";
private static final String TAG = "FireTweet";
public static String PROXY_HOST = "127.0.0.1";
public static int PROXY_PORT = 8787;
private Handler mHandler;
private MediaLoaderWrapper mMediaLoaderWrapper;
private ImageLoader mImageLoader;
private AsyncTaskManager mAsyncTaskManager;
private SharedPreferences mPreferences;
private AsyncTwitterWrapper mTwitterWrapper;
private MultiSelectManager mMultiSelectManager;
private FiretweetImageDownloader mImageDownloader, mFullImageDownloader;
private DiskCache mDiskCache, mFullDiskCache;
private MessagesManager mCroutonsManager;
private SQLiteOpenHelper mSQLiteOpenHelper;
private HostAddressResolver mResolver;
private SQLiteDatabase mDatabase;
private Bus mMessageBus;
private VideoLoader mVideoLoader;
private ReadStateManager mReadStateManager;
public AsyncTaskManager getAsyncTaskManager() {
if (mAsyncTaskManager != null) return mAsyncTaskManager;
return mAsyncTaskManager = AsyncTaskManager.getInstance();
}
public DiskCache getDiskCache() {
if (mDiskCache != null) return mDiskCache;
return mDiskCache = createDiskCache(DIR_NAME_IMAGE_CACHE);
}
public DiskCache getFullDiskCache() {
if (mFullDiskCache != null) return mFullDiskCache;
return mFullDiskCache = createDiskCache(DIR_NAME_FULL_IMAGE_CACHE);
}
public ImageDownloader getFullImageDownloader() {
if (mFullImageDownloader != null) return mFullImageDownloader;
return mFullImageDownloader = new FiretweetImageDownloader(this, true, true);
}
public Handler getHandler() {
return mHandler;
}
public HostAddressResolver getHostAddressResolver() {
if (mResolver != null) return mResolver;
return mResolver = new FiretweetHostAddressResolver(this);
}
public ReadStateManager getReadStateManager() {
if (mReadStateManager != null) return mReadStateManager;
return mReadStateManager = new ReadStateManager(this);
}
public ImageDownloader getImageDownloader() {
if (mImageDownloader != null) return mImageDownloader;
return mImageDownloader = new FiretweetImageDownloader(this, false, true);
}
public ImageLoader getImageLoader() {
if (mImageLoader != null) return mImageLoader;
final ImageLoader loader = ImageLoader.getInstance();
final ImageLoaderConfiguration.Builder cb = new ImageLoaderConfiguration.Builder(this);
cb.threadPriority(Thread.NORM_PRIORITY - 2);
cb.denyCacheImageMultipleSizesInMemory();
cb.tasksProcessingOrder(QueueProcessingType.LIFO);
// cb.memoryCache(new ImageMemoryCache(40));
cb.diskCache(getDiskCache());
cb.imageDownloader(getImageDownloader());
L.writeDebugLogs(Utils.isDebugBuild());
loader.init(cb.build());
return mImageLoader = loader;
}
public VideoLoader getVideoLoader() {
if (mVideoLoader != null) return mVideoLoader;
final VideoLoader loader = new VideoLoader(this);
return mVideoLoader = loader;
}
public MediaLoaderWrapper getMediaLoaderWrapper() {
if (mMediaLoaderWrapper != null) return mMediaLoaderWrapper;
return mMediaLoaderWrapper = new MediaLoaderWrapper(getImageLoader(), getVideoLoader());
}
@NonNull
public static FiretweetApplication getInstance(@NonNull final Context context) {
return (FiretweetApplication) context.getApplicationContext();
}
public Bus getMessageBus() {
return mMessageBus;
}
public MessagesManager getMessagesManager() {
if (mCroutonsManager != null) return mCroutonsManager;
return mCroutonsManager = new MessagesManager(this);
}
public MultiSelectManager getMultiSelectManager() {
if (mMultiSelectManager != null) return mMultiSelectManager;
return mMultiSelectManager = new MultiSelectManager();
}
public SQLiteDatabase getSQLiteDatabase() {
if (mDatabase != null) return mDatabase;
return mDatabase = getSQLiteOpenHelper().getWritableDatabase();
}
public SQLiteOpenHelper getSQLiteOpenHelper() {
if (mSQLiteOpenHelper != null) return mSQLiteOpenHelper;
return mSQLiteOpenHelper = new FiretweetSQLiteOpenHelper(this, DATABASES_NAME, DATABASES_VERSION);
}
public AsyncTwitterWrapper getTwitterWrapper() {
if (mTwitterWrapper != null) return mTwitterWrapper;
return mTwitterWrapper = AsyncTwitterWrapper.getInstance(this);
}
@Override
public void onCreate() {
StrictModeUtils.detectAll();
super.onCreate();
Fabric.with(this, new Crashlytics());
final Context context = this.getApplicationContext();
File f = context.getFilesDir();
String path = "";
if (f != null) {
path = f.getPath();
}
int startupTimeoutMillis = 30000;
String trackingId = "UA-21408036-4";
try {
org.lantern.mobilesdk.StartResult result = Lantern.enable(context, startupTimeoutMillis,
true, trackingId, null);
HostAndPort hp = HostAndPort.fromString(result.getHTTPAddr());
PROXY_HOST = hp.getHostText();
PROXY_PORT = hp.getPort();
Log.d(TAG, "Proxy host --> " + PROXY_HOST + " " + PROXY_PORT);
} catch (Exception e) {
Log.d(TAG, "Unable to start Lantern: " + e.getMessage());
}
mHandler = new Handler();
mMessageBus = new Bus();
//mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE);
//mPreferences.registerOnSharedPreferenceChangeListener(this);
initializeAsyncTask();
initAccountColor(this);
initUserColor(this);
final PackageManager pm = getPackageManager();
final ComponentName main = new ComponentName(this, MainActivity.class);
final ComponentName main2 = new ComponentName(this, MainHondaJOJOActivity.class);
final boolean mainDisabled = pm.getComponentEnabledSetting(main) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
final boolean main2Disabled = pm.getComponentEnabledSetting(main2) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
final boolean noEntry = mainDisabled && main2Disabled;
if (noEntry) {
pm.setComponentEnabledSetting(main, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
} else if (!mainDisabled) {
pm.setComponentEnabledSetting(main2, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
startRefreshServiceIfNeeded(this);
}
@Override
public void onLowMemory() {
if (mMediaLoaderWrapper != null) {
mMediaLoaderWrapper.clearMemoryCache();
}
super.onLowMemory();
}
@Override
public void onSharedPreferenceChanged(final SharedPreferences preferences, final String key) {
if (KEY_REFRESH_INTERVAL.equals(key)) {
stopService(new Intent(this, RefreshService.class));
startRefreshServiceIfNeeded(this);
} else if (KEY_ENABLE_PROXY.equals(key) || KEY_CONNECTION_TIMEOUT.equals(key) || KEY_PROXY_HOST.equals(key)
|| KEY_PROXY_PORT.equals(key) || KEY_FAST_IMAGE_LOADING.equals(key)) {
reloadConnectivitySettings();
} else if (KEY_USAGE_STATISTICS.equals(key)) {
stopService(new Intent(this, UCDService.class));
//startUsageStatisticsServiceIfNeeded(this);
//spice
//stopService(new Intent(this, SpiceService.class));
//startUsageStatisticsServiceIfNeeded(this);
//end
} else if (KEY_CONSUMER_KEY.equals(key) || KEY_CONSUMER_SECRET.equals(key) || KEY_API_URL_FORMAT.equals(key)
|| KEY_AUTH_TYPE.equals(key) || KEY_SAME_OAUTH_SIGNING_URL.equals(key) || KEY_THUMBOR_ENABLED.equals(key)
|| KEY_THUMBOR_ADDRESS.equals(key) || KEY_THUMBOR_SECURITY_KEY.equals(key)) {
final SharedPreferences.Editor editor = preferences.edit();
editor.putLong(KEY_API_LAST_CHANGE, System.currentTimeMillis());
editor.apply();
}
}
public void reloadConnectivitySettings() {
if (mImageDownloader != null) {
mImageDownloader.reloadConnectivitySettings();
}
if (mFullImageDownloader != null) {
mFullImageDownloader.reloadConnectivitySettings();
}
}
private DiskCache createDiskCache(final String dirName) {
final File cacheDir = getBestCacheDir(this, dirName);
final File fallbackCacheDir = getInternalCacheDir(this, dirName);
return new UnlimitedDiscCache(cacheDir, fallbackCacheDir, new URLFileNameGenerator());
}
private void initializeAsyncTask() {
// AsyncTask class needs to be loaded in UI thread.
// So we load it here to comply the rule.
try {
Class.forName(AsyncTask.class.getName());
} catch (final ClassNotFoundException ignore) {
}
}
}