/* Hypatia: An realtime malware scanner for Android Copyright (c) 2017-2018 Divested Computing, Inc. 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 . */ package us.spotco.malwarescanner; import android.app.ActivityManager; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.Build; import java.io.File; import java.util.HashSet; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; class Utils { public final static int MAX_SCAN_SIZE = (1000 * 1000) * 80; //80MB public final static int MAX_SCAN_SIZE_REALTIME = MAX_SCAN_SIZE / 2; //40MB public final static int MAX_HASH_LENGTH = 16; public static int FILES_SCANNED = 0; private static ThreadPoolExecutor threadPoolExecutor = null; public static ThreadPoolExecutor getThreadPoolExecutor() { if (threadPoolExecutor == null) { threadPoolExecutor = (ThreadPoolExecutor) Executors.newScheduledThreadPool(getMaxThreads()); } return threadPoolExecutor; } public static int getMaxThreads() { int maxTheads = Runtime.getRuntime().availableProcessors(); if (maxTheads >= 2) { maxTheads /= 2; } return maxTheads; } public static HashSet getFilesRecursive(File root) { HashSet filesAll = new HashSet<>(); File[] files = root.listFiles(); if (files != null && files.length > 0) { for (File f : files) { if (f.isDirectory()) { HashSet filesTmp = getFilesRecursive(f); if (filesTmp != null) { filesAll.addAll(filesTmp); } } else { if (f.length() <= MAX_SCAN_SIZE && f.canRead()) {//Exclude files larger than limit for performance filesAll.add(f); } } } } return filesAll; } //Credit: https://stackoverflow.com/a/5921190 public static boolean isServiceRunning(Class serviceClass, Context context) { ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { if (serviceClass.getName().equals(service.service.getClassName())) { return true; } } return false; } public static void considerStartService(Context context) { if (!Utils.isServiceRunning(MalwareScannerService.class, context)) { SharedPreferences prefs = context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE); boolean autostart = prefs.getBoolean("autostart", false); if (autostart) { Intent realtimeScanner = new Intent(context, MalwareScannerService.class); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { context.startForegroundService(realtimeScanner); } else { context.startService(realtimeScanner); } } } } }