Many changes

- More settings work
- Add back Utils and RecursiveFileObserver
- More scaffolding
- Add colors to nav bar
- Fix fragment scrolling
This commit is contained in:
Tad 2018-10-21 20:42:49 -04:00
parent a15aeb5c5e
commit a13afeec83
11 changed files with 253 additions and 5 deletions

View file

@ -0,0 +1,4 @@
package us.spotco.malwarescanner;
public class Database {
}

View file

@ -0,0 +1,4 @@
package us.spotco.malwarescanner;
public class DatabaseManager {
}

View file

@ -0,0 +1,4 @@
package us.spotco.malwarescanner;
public class EventReceiver {
}

View file

@ -25,7 +25,7 @@ public class MainActivity extends FragmentActivity {
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
navigation.setItemIconTintList(null);
fragmentManager.beginTransaction().add(R.id.main_fragment, logFragment, "History").hide(logFragment).commit();
fragmentManager.beginTransaction().add(R.id.main_fragment, databaseFragment, "Databases").hide(databaseFragment).commit();

View file

@ -0,0 +1,91 @@
package us.spotco.malwarescanner;
import android.os.FileObserver;
import java.io.File;
import java.util.HashSet;
import java.util.Stack;
/**
* Copyright (C) 2012 Bartek Przybylski
* Copyright (C) 2015 ownCloud Inc.
* Copyright (C) 2016 Daniel Gultsch
* Taken from siacs/Conversations and tweaked a bit
*/
abstract class RecursiveFileObserver {
private final String path;
private final HashSet<SingleFileObserver> mObservers = new HashSet<>();
public RecursiveFileObserver(String path) {
this.path = path;
}
public final synchronized void startWatching() {
Stack<String> stack = new Stack<>();
stack.push(path);
while (!stack.empty()) {
String parent = stack.pop();
mObservers.add(new SingleFileObserver(parent));
final File path = new File(parent);
final File[] files = path.listFiles();
if (files == null) {
continue;
}
for (File file : files) {
if (file.isDirectory() && !file.getName().equals(".") && !file.getName().equals("..")) {
final String currentPath = file.getAbsolutePath();
if (depth(file) <= 8 && !stack.contains(currentPath) && !observing(currentPath)) {
stack.push(currentPath);
}
}
}
}
for (FileObserver observer : mObservers) {
observer.startWatching();
}
}
private static int depth(File file) {
int depth = 0;
while ((file = file.getParentFile()) != null) {
depth++;
}
return depth;
}
private boolean observing(String path) {
for (SingleFileObserver observer : mObservers) {
if (path.equals(observer.path)) {
return true;
}
}
return false;
}
public final synchronized void stopWatching() {
for (FileObserver observer : mObservers) {
observer.stopWatching();
}
mObservers.clear();
}
abstract public void onEvent(int event, String path);
private class SingleFileObserver extends FileObserver {
private final String path;
public SingleFileObserver(String path) {
super(path);
this.path = path;
}
@Override
public final void onEvent(int event, String filename) {
RecursiveFileObserver.this.onEvent(event, path + '/' + filename);
}
}
}

View file

@ -0,0 +1,4 @@
package us.spotco.malwarescanner;
public class Scanner {
}

View file

@ -0,0 +1,4 @@
package us.spotco.malwarescanner;
public class ScannerService {
}

View file

@ -0,0 +1,126 @@
package us.spotco.malwarescanner;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import java.io.File;
import java.net.Socket;
import java.util.HashSet;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
public class Utils {
private static SharedPreferences prefs = null;
public Utils(Context context) {
prefs = context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE);
}
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<File> getFilesRecursive(File root) {
HashSet<File> filesAll = new HashSet<>();
File[] files = root.listFiles();
if (files != null && files.length > 0) {
for (File f : files) {
if (f.isDirectory()) {
HashSet<File> filesTmp = getFilesRecursive(f);
if (filesTmp != null) {
filesAll.addAll(filesTmp);
}
} else {
if (f.length() <= (prefs.getInt("scanner_max_file_size", (1000 * 1000) * 80) * (1000 * 1000)) && 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;
}
//Credit: https://stackoverflow.com/a/6758962
public static boolean isPackageInstalled(Context context, String packageID) {
PackageManager pm = context.getPackageManager();
try {
pm.getPackageInfo(packageID, PackageManager.GET_META_DATA);
} catch (PackageManager.NameNotFoundException e) {
return false;
}
return true;
}
public static boolean isOrbotInstalled(Context context) {
return isPackageInstalled(context, "org.torproject.android");
}
//Credit: OrbotHelper/NetCipher
public static void requestStartOrbot(Context context) {
Intent intent = new Intent("org.torproject.android.intent.action.START");
intent.setPackage("org.torproject.android");
intent.putExtra("org.torproject.android.intent.extra.PACKAGE_NAME", context.getPackageName());
context.sendBroadcast(intent);
}
//Credit: https://www.geekality.net/2013/04/30/java-simple-check-to-see-if-a-server-is-listening-on-a-port/
public static boolean isPortListening(String host, int port) {
Socket s = null;
try {
s = new Socket(host, port);
return true;
} catch (Exception e) {
return false;
} finally {
if (s != null) {
try {
s.close();
} catch (Exception e1) {
}
}
}
}
public static boolean waitUntilOrbotIsAvailable() {
int tries = 0;
boolean listening;
while (!(listening = isPortListening("127.0.0.1", 9050)) && tries <= 60) {
tries++;
try {
Thread.sleep(1000);
} catch (Exception e) {
}
}
return listening;
}
}

View file

@ -7,11 +7,14 @@
android:layout_height="match_parent"
tools:context="us.spotco.malwarescanner.MainActivity">
<!-- TODO: FIX SCROLLING! -->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/navigation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<android.support.design.widget.BottomNavigationView
android:id="@+id/navigation"

View file

@ -21,13 +21,15 @@
<string name="settings_pref_scanner_realtime_path_system_summary">Alert on changes to /system</string>
<string name="settings_category_optimizations">Optimizations</string>
<string name="settings_pref_optimizations_scanner_max_size">Max file size</string>
<string name="settings_pref_optimizations_scanner_max_size_summary">Files larger than this in megabytes won\'t be scanned</string>
<string name="settings_pref_optimizations_database_hash_length">Max hash length</string>
<string name="settings_pref_optimizations_database_hash_length_summary">Memory savings at risk of increased false positives</string>
<string name="settings_pref_optimizations_database_trim">Trim variant names</string>
<string name="settings_pref_optimizations_database_trim_summary">Memory savings at cost of detailed detection names</string>
<string name="settings_category_network">Network</string>
<string name="settings_pref_network_tor">Onion Routing</string>
<string name="settings_pref_network_tor">Onion routing</string>
<string name="settings_pref_network_tor_summary">Perform all network requests over Tor</string>
<string name="settings_category_other">Other</string>

View file

@ -26,6 +26,12 @@
</PreferenceCategory>
<PreferenceCategory android:title="@string/settings_category_optimizations">
<EditTextPreference
android:key="scanner_max_file_size"
android:title="@string/settings_pref_optimizations_scanner_max_size"
android:summary="@string/settings_pref_optimizations_scanner_max_size_summary"
android:defaultValue="80"
android:inputType="number" />
<EditTextPreference
android:key="database_hash_length"
android:title="@string/settings_pref_optimizations_database_hash_length"