/***
Copyright (c) 2012-2013 Samuele Rini
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
***
https://github.com/dentex/ytdownloader/
https://sourceforge.net/projects/ytdownloader/
***
Different Licenses and Credits where noted in code comments.
*/
package dentex.youtube.downloader;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import android.app.Activity;
import android.app.Application;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.os.Handler;
import android.support.v4.app.NotificationCompat;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.WindowManager;
import com.bugsense.trace.BugSenseHandler;
import com.impressionapps.vdownload.R;
import dentex.youtube.downloader.queue.QueueThread;
import dentex.youtube.downloader.queue.QueueThreadListener;
import dentex.youtube.downloader.utils.PopUps;
import dentex.youtube.downloader.utils.Utils;
public class YTD extends Application implements QueueThreadListener{
static String DEBUG_TAG = "YTD";
public static Context ctx;
// *** development configurations *** // TODO // for release set to:
// ================================== // =========== // ==================
public static String BugsenseApiKey = "00000000"; // actual api key
public static boolean SHOW_ITAGS_AND_NO_SIZE_FOR_DUBUG = false; // false
public static int SIG_HASH = -1892118308; // final string
//public static int SIG_HASH = -118685648; // dev test: desktop
//public static int SIG_HASH = 1922021506; // dev test: laptop
// **********************************
public static final String JSON_FILENAME = "dashboard.json";
public static final String JSON_FOLDER = "json";
public static File JSON_FILE = null;
public static final String JSON_DATA_ID = "id";
public static final String JSON_DATA_YTID = "ytid";
public static final String JSON_DATA_POS = "pos";
public static final String JSON_DATA_TYPE = "type";
public static final String JSON_DATA_TYPE_V = "VIDEO";
public static final String JSON_DATA_TYPE_A_E = "AUDIO-EXTR";
public static final String JSON_DATA_TYPE_A_M = "AUDIO-MP3";
public static final String JSON_DATA_STATUS = "status";
public static final String JSON_DATA_STATUS_COMPLETED = "COMPLETED";
public static final String JSON_DATA_STATUS_IN_PROGRESS = "IN_PROGRESS";
public static final String JSON_DATA_STATUS_FAILED = "FAILED";
public static final String JSON_DATA_STATUS_PAUSED = "PAUSED";
public static final String JSON_DATA_STATUS_IMPORTED = "IMPORTED";
public static final String JSON_DATA_PATH = "path";
public static final String JSON_DATA_FILENAME = "filename";
public static final String JSON_DATA_BASENAME = "basename";
public static final String JSON_DATA_AUDIO_EXT = "audio_ext";
public static final String JSON_DATA_SIZE = "size";
public static final String ffmpegBinName = "ffmpeg";
public static SharedPreferences settings;
public static SharedPreferences videoinfo;
public static String PREFS_NAME = "com.impressionapps.vdownload_preferences";
public static String VIDEOINFO_NAME = "com.impressionapps.vdownload_videoinfo";
public static String pt1;
public static String pt2;
public static NotificationManager mNotificationManager;
public static NotificationCompat.Builder mBuilder;
public static List<Long> sequence = new ArrayList<Long>();
//public static String USER_AGENT_FIREFOX = "Mozilla/5.0 (X11; Linux i686; rv:10.0) Gecko/20100101 Firefox/10.0";
public static String USER_AGENT_FIREFOX = "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0";
public static File dir_Downloads = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
public static File dir_DCIM = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
public static File dir_Movies = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
public static int uid;
public static final String THUMBS_FOLDER = "thumbs";
public static double reduceFactor;
public static QueueThread queueThread;
public static Handler handler;
public static Drawable slMenuOrigBkg;
@Override
public void onCreate() {
Log.d(DEBUG_TAG, "onCreate");
settings = getSharedPreferences(PREFS_NAME, 0);
videoinfo = getSharedPreferences(VIDEOINFO_NAME, 0);
BugSenseHandler.initAndStartSession(getApplicationContext(), BugsenseApiKey);
queueThread = new QueueThread(this);
queueThread.start();
// Create the Handler. It will implicitly bind to the Looper
// that is internally created for this thread (since it is the UI thread)
handler = new Handler();
//findProcessUid();
ctx = getApplicationContext();
JSON_FILE = new File(ctx.getDir(JSON_FOLDER, 0), JSON_FILENAME);
detectSysDefLang();
detectFirstLaunch();
mBuilder = new NotificationCompat.Builder(ctx);
mNotificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
super.onCreate();
}
/*private void findProcessUid() {
uid = android.os.Process.myUid();
Log.d(DEBUG_TAG, "YTD's UID: " + uid);
}*/
private void detectFirstLaunch() {
if (settings.getBoolean("first_launch", true)) {
Log.i(DEBUG_TAG, "First launch for YTD!");
settings.edit().putBoolean("first_launch", false).apply();
reduceFactor = detectScreenDensity();
JSON_FILE.delete();
videoinfo.edit().clear().apply();
} else {
reduceFactor = Double.parseDouble(settings.getString("REDUCE_FACTOR", "1"));
Log.d(DEBUG_TAG, "Retrieved a REDUCE_FACTOR of " + reduceFactor + " from prefs");
}
}
private void detectSysDefLang() {
String storedDefLang = YTD.settings.getString("DEF_LANG", "");
if (storedDefLang.isEmpty() && storedDefLang != null) {
Locale defLocale = Locale.getDefault();
String defLang = defLocale.getLanguage();
Log.d(DEBUG_TAG, "Storing default system lang: " + defLang);
YTD.settings.edit().putString("DEF_LANG", defLang).commit();
}
}
private double detectScreenDensity() {
DisplayMetrics displayMetrics = new DisplayMetrics();
((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(displayMetrics);
double rf = 1;
int density = displayMetrics.densityDpi;
switch (density) {
case DisplayMetrics.DENSITY_HIGH:
rf = 1.44;
break;
case DisplayMetrics.DENSITY_MEDIUM:
rf = 2;
break;
case DisplayMetrics.DENSITY_LOW:
rf = 3;
}
Log.d(DEBUG_TAG, "DispalyDensity: " + density + " - storing a REDUCE_FACTOR of " + rf + " into prefs");
settings.edit().putString("REDUCE_FACTOR", String.valueOf(rf)).apply();;
return rf;
}
public static void NoDownProvPopUp(Activity act) {
PopUps.showPopUp(act.getString(R.string.no_downloads_sys_app), act.getString(R.string.ytd_useless), "alert", act);
}
public static void NotificationHelper(Context ctx) {
mBuilder = new NotificationCompat.Builder(ctx); // to reset its DEFAULTS
pt1 = ctx.getString(R.string.notification_downloading_pt1);
pt2 = ctx.getString(R.string.notification_downloading_pt2);
Intent notificationIntent = new Intent(ctx, DashboardActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
PendingIntent contentIntent = PendingIntent.getActivity(ctx, 0, notificationIntent, 0);
mBuilder.setSmallIcon(R.drawable.ic_stat_ytd)
.setOngoing(true)
.setContentTitle(ctx.getString(R.string.app_name))
.setContentText(pt1 + " " + sequence.size() + " " + pt2)
.setContentIntent(contentIntent);
mNotificationManager.notify(1, mBuilder.build());
}
public static void removeIdUpdateNotification(long id) {
try {
if (id != 0) {
if (sequence.remove(id)) {
Utils.logger("d", "ID " + id + " REMOVED from Notification", DEBUG_TAG);
} else {
Utils.logger("d", "ID " + id + " Already REMOVED from Notification", DEBUG_TAG);
}
} else {
Utils.logger("w", "ID not found!", DEBUG_TAG);
}
Utils.setNotificationDefaults(mBuilder);
if (sequence.size() > 0) {
mBuilder.setContentText(pt1 + " " + sequence.size() + " " + pt2)
.setOngoing(true);
mNotificationManager.notify(1, mBuilder.build());
} else {
mBuilder.setContentText(ctx.getString(R.string.notification_no_downloads))
.setOngoing(false);
mNotificationManager.notify(1, mBuilder.build());
Utils.logger("d", "No downloads in progress.", DEBUG_TAG);
}
} catch (NullPointerException e) {
Log.e(DEBUG_TAG, "NPE at removeIdUpdateNotification: " + e.getMessage());
BugSenseHandler.sendExceptionMessage("NPE at removeIdUpdateNotification", e.getMessage(), e);
}
}
@Override
public void handleQueueThreadUpdate() {
handler.post(new Runnable() {
@Override
public void run() {
int total = queueThread.getTotalQueued();
int completed = queueThread.getTotalCompleted();
Utils.logger("i", String.format("Auto audio extractions completed: "
+ "%d of %d", completed, total), DEBUG_TAG);
if (completed == total) {
queueThread.resetQueue();
queueThread.pushNotificationText(ctx, ctx.getString(R.string.auto_audio_extr_completed), false);
} else {
queueThread.pushNotificationText(ctx, ctx.getString(R.string.auto_audio_extr_progress, completed, total), true);
}
}
});
}
}