package us.spotco.malwarescanner; import android.app.Notification; import android.app.NotificationManager; import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.Environment; import android.os.FileObserver; import android.os.IBinder; import android.support.v4.app.NotificationCompat; import java.io.File; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; import gnu.trove.set.hash.THashSet; public class MalwareScannerService extends Service { private THashSet malwareMonitors = new THashSet<>(); private ThreadPoolExecutor threadPoolExecutor = null; private NotificationCompat.Builder foregroundNotification = null; private NotificationManager notificationManager = null; @Override public final IBinder onBind(Intent intent) { return null; } @Override public final int onStartCommand(Intent intent, int flags, int startId) { malwareMonitors.clear(); addMalwareMonitor(Environment.getExternalStorageDirectory().toString()); threadPoolExecutor = (ThreadPoolExecutor) Executors.newScheduledThreadPool(Utils.getMaxThreads() + malwareMonitors.size()); threadPoolExecutor.execute(new Runnable() { @Override public void run() { Database.loadDatabase(getApplicationContext(), true, Database.signatureDatabases); } }); for (final RecursiveFileObserver malwareMonitor : malwareMonitors) { threadPoolExecutor.execute(new Runnable() { @Override public void run() { malwareMonitor.startWatching(); } }); } notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE); setForeground(); return START_STICKY; } private final void addMalwareMonitor(String monitorPath) { malwareMonitors.add(new RecursiveFileObserver(monitorPath) { @Override public void onEvent(int event, String path) { switch (event) { case FileObserver.MOVED_TO: case FileObserver.CLOSE_WRITE: File file = new File(path); if (file.exists() && /*file.length() > 0 &&*/ file.length() <= Utils.MAX_SCAN_SIZE_REALTIME) { THashSet filesToScan = new THashSet<>(); filesToScan.add(file); new MalwareScanner(null, getApplicationContext(), false).executeOnExecutor(threadPoolExecutor, filesToScan); } updateForegroundNotification(); break; } } }); } @Override public final void onDestroy() { for (RecursiveFileObserver malwareMonitor : malwareMonitors) { malwareMonitor.stopWatching(); } malwareMonitors.clear(); System.gc(); //Toast.makeText(this, "Theia: Realtime Scanning Stopped", Toast.LENGTH_SHORT).show(); } private void setForeground() { foregroundNotification = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_notification) .setContentTitle(getText(R.string.lblNotificationRealtimeTitle)) .setContentText(getText(R.string.lblNotificationRealtimeText)) .setPriority(Notification.PRIORITY_MIN) .setShowWhen(false); startForeground(-1, foregroundNotification.build()); } private void updateForegroundNotification() { foregroundNotification.setSubText(Utils.FILES_SCANNED + " files scanned"); notificationManager.notify(-1, foregroundNotification.build()); } }