Release 15: OMS7 preparation

- Added self-destruct mode on OMS when Substratum is uninstalled
- Clean up all files to respect lint warnings
- Limit what can be run from masquerade to the main Substratum
functions like pm/om/overlay
diff --git a/app/build.gradle b/app/build.gradle
index 45a871f..6f7665f 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -20,8 +20,8 @@
         applicationId "masquerade.substratum"
         minSdkVersion 21
         targetSdkVersion 23
-        versionCode 14
-        versionName "fourteen"
+        versionCode 15
+        versionName "fifteen"
     }
 
     buildTypes {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7d34e01..05ebebe 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,7 +1,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="masquerade.substratum"
-          android:versionCode="14"
-          android:versionName="fourteen">
+          android:versionCode="15"
+          android:versionName="fifteen">
 
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
@@ -19,6 +19,12 @@
                 <action android:name="android.intent.action.BOOT_COMPLETED"/>
             </intent-filter>
         </receiver>
+        <receiver android:name=".services.UninstallDetector">
+            <intent-filter>
+                <action android:name="android.intent.action.PACKAGE_REMOVED"/>
+                <data android:scheme="package"/>
+            </intent-filter>
+        </receiver>
         <receiver android:name=".util.Helper">
             <intent-filter>
                 <action android:name="masquerade.substratum.COMMANDS"/>
diff --git a/app/src/main/java/masquerade/substratum/activities/LoaderActivity.java b/app/src/main/java/masquerade/substratum/activities/LoaderActivity.java
index 29279fa..3af5ec3 100644
--- a/app/src/main/java/masquerade/substratum/activities/LoaderActivity.java
+++ b/app/src/main/java/masquerade/substratum/activities/LoaderActivity.java
@@ -6,10 +6,6 @@
 
 import masquerade.substratum.util.Root;
 
-/**
- * @author Nicholas Chum (nicholaschum)
- */
-
 public class LoaderActivity extends Activity {
     @Override
     protected void onCreate(Bundle savedInstanceState) {
diff --git a/app/src/main/java/masquerade/substratum/services/BootDetector.java b/app/src/main/java/masquerade/substratum/services/BootDetector.java
index 70ef491..3981487 100644
--- a/app/src/main/java/masquerade/substratum/services/BootDetector.java
+++ b/app/src/main/java/masquerade/substratum/services/BootDetector.java
@@ -6,10 +6,6 @@
 
 import masquerade.substratum.util.Helper;
 
-/**
- * @author Nicholas Chum (nicholaschum)
- */
-
 public class BootDetector extends BroadcastReceiver {
     @Override
     public void onReceive(Context context, Intent intent) {
diff --git a/app/src/main/java/masquerade/substratum/services/UninstallDetector.java b/app/src/main/java/masquerade/substratum/services/UninstallDetector.java
new file mode 100644
index 0000000..7af387b
--- /dev/null
+++ b/app/src/main/java/masquerade/substratum/services/UninstallDetector.java
@@ -0,0 +1,48 @@
+package masquerade.substratum.services;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Environment;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import masquerade.substratum.util.ReadOverlaysFile;
+import masquerade.substratum.util.Root;
+
+public class UninstallDetector extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if ("android.intent.action.PACKAGE_REMOVED".equals(intent.getAction())) {
+            Uri packageName = intent.getData();
+            if (packageName.toString().substring(8).equals("projekt.substratum")) {
+                new performUninstalls().execute("");
+            }
+        }
+    }
+
+    public class performUninstalls extends AsyncTask<String, Integer, String> {
+        @Override
+        protected String doInBackground(String... sUrl) {
+            // Substratum was uninstalled, uninstall all remaining overlays
+            Log.d("Masquerade",
+                    "Substratum was uninstalled, so all remaining overlays will be removed...");
+            String[] state4 = {Environment.getExternalStorageDirectory()
+                    .getAbsolutePath() + "/.substratum/current_overlays.xml", "4"};
+            String[] state5 = {Environment.getExternalStorageDirectory()
+                    .getAbsolutePath() + "/.substratum/current_overlays.xml", "5"};
+            List<String> state5overlays = ReadOverlaysFile.main(state5);
+            ArrayList<String> all_overlays = new ArrayList<>(ReadOverlaysFile.main(state4));
+            all_overlays.addAll(state5overlays);
+            for (int i = 0; i < all_overlays.size(); i++) {
+                Log.d("Masquerade", "Uninstalling overlay: " + all_overlays.get(i));
+                Root.runCommand("pm uninstall " + all_overlays.get(i));
+            }
+            return null;
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/masquerade/substratum/util/Helper.java b/app/src/main/java/masquerade/substratum/util/Helper.java
index b17da2d..9036324 100644
--- a/app/src/main/java/masquerade/substratum/util/Helper.java
+++ b/app/src/main/java/masquerade/substratum/util/Helper.java
@@ -5,10 +5,6 @@
 import android.content.Intent;
 import android.util.Log;
 
-/**
- * @author Nicholas Chum (nicholaschum)
- */
-
 public class Helper extends BroadcastReceiver {
 
     @Override
@@ -28,15 +24,19 @@
                         "integrity and service activation.");
             }
         } else if (intent.getStringArrayListExtra("pm-uninstall") != null) {
-            new Uninstaller().Uninstaller(intent, "pm-uninstall", false,
+            new Uninstaller().uninstall(intent, "pm-uninstall", false,
                     intent.getBooleanExtra("restart_systemui", false));
         } else if (intent.getStringArrayListExtra("pm-uninstall-specific") != null) {
-            new Uninstaller().Uninstaller(intent, "pm-uninstall-specific", true,
+            new Uninstaller().uninstall(intent, "pm-uninstall-specific", true,
                     intent.getBooleanExtra("restart_systemui", false));
         } else if (intent.getStringExtra("om-commands") != null) {
-            Log.d("Masquerade", "Running command: \"" +
-                    intent.getStringExtra("om-commands") + "\"");
-            Root.runCommand(intent.getStringExtra("om-commands"));
+            if (intent.getStringExtra("om-commands").contains("pm") ||
+                    intent.getStringExtra("om-commands").contains("om") ||
+                    intent.getStringExtra("om-commands").contains("overlay")) {
+                Log.d("Masquerade", "Running command: \"" +
+                        intent.getStringExtra("om-commands") + "\"");
+                Root.runCommand(intent.getStringExtra("om-commands"));
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/masquerade/substratum/util/ReadOverlaysFile.java b/app/src/main/java/masquerade/substratum/util/ReadOverlaysFile.java
index c201ec8..2909ea9 100644
--- a/app/src/main/java/masquerade/substratum/util/ReadOverlaysFile.java
+++ b/app/src/main/java/masquerade/substratum/util/ReadOverlaysFile.java
@@ -9,10 +9,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-/**
- * @author Nicholas Chum (nicholaschum)
- */
-
 public class ReadOverlaysFile {
 
     public static List<String> main(String argv[]) {
diff --git a/app/src/main/java/masquerade/substratum/util/Root.java b/app/src/main/java/masquerade/substratum/util/Root.java
index 6e398e1..7c80720 100644
--- a/app/src/main/java/masquerade/substratum/util/Root.java
+++ b/app/src/main/java/masquerade/substratum/util/Root.java
@@ -2,18 +2,13 @@
 
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
-import java.io.File;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 
 public class Root {
 
-    public static SU su;
-
-    public static boolean isRooted() {
-        return isInPath("su");
-    }
+    private static SU su;
 
     public static boolean requestRootAccess() {
         SU su = getSU();
@@ -21,28 +16,6 @@
         return !su.denied;
     }
 
-    public static boolean isBusyboxInstalled() {
-        return isInPath("busybox");
-    }
-
-    private static boolean isInPath(String binary) {
-        for (String path : System.getenv("PATH").split(":")) {
-            if (!path.endsWith("/")) path += "/";
-            if (new File(path + binary).exists()) return true;
-        }
-        return false;
-    }
-
-    public static void mount(boolean writeable, String mountpoint) {
-        runCommand(writeable ? "mount -o rw,remount " + mountpoint + " " + mountpoint :
-                "mount -o ro,remount " + mountpoint + " " + mountpoint);
-    }
-
-    public static void closeSU() {
-        if (su != null) su.close();
-        su = null;
-    }
-
     public static String runCommand(String command) {
         return getSU().runCommand(command);
     }
@@ -53,7 +26,7 @@
         return su;
     }
 
-    public static class SU {
+    private static class SU {
 
         private Process process;
         private BufferedWriter bufferedWriter;
@@ -62,7 +35,7 @@
         private boolean denied;
         private boolean firstTry;
 
-        public SU() {
+        SU() {
             try {
                 firstTry = true;
                 process = Runtime.getRuntime().exec("su");
@@ -76,7 +49,7 @@
             }
         }
 
-        public synchronized String runCommand(final String command) {
+        synchronized String runCommand(final String command) {
             try {
                 StringBuilder sb = new StringBuilder();
                 String callback = "/shellCallback/";
@@ -106,18 +79,5 @@
             }
             return null;
         }
-
-        public void close() {
-            try {
-                bufferedWriter.write("exit\n");
-                bufferedWriter.flush();
-
-                process.waitFor();
-                closed = true;
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/masquerade/substratum/util/Uninstaller.java b/app/src/main/java/masquerade/substratum/util/Uninstaller.java
index 71fb175..4b1b056 100644
--- a/app/src/main/java/masquerade/substratum/util/Uninstaller.java
+++ b/app/src/main/java/masquerade/substratum/util/Uninstaller.java
@@ -8,19 +8,15 @@
 import java.util.ArrayList;
 import java.util.List;
 
-/**
- * @author Nicholas Chum (nicholaschum)
- */
-
-public class Uninstaller {
+class Uninstaller {
 
     private Intent mIntent;
     private String uninstallString;
     private boolean specific;
     private boolean restartSystemUI;
 
-    public void Uninstaller(Intent mIntent, String uninstallString,
-                            boolean specific, boolean restartSystemUI) {
+    void uninstall(Intent mIntent, String uninstallString,
+                   boolean specific, boolean restartSystemUI) {
         this.mIntent = mIntent;
         this.uninstallString = uninstallString;
         this.specific = specific;
@@ -108,4 +104,4 @@
             }
         }
     }
-}
+}
\ No newline at end of file