Android Open Source - Mountie Root Class






From Project

Back to project page Mountie.

License

The source code is released under:

GNU General Public License

If you think the Android project Mountie listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.stericson.RootTools.containers;
//from w  ww . j a  v  a  2s .  c  o  m
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/* #ANNOTATIONS @SupportedAnnotationTypes("com.stericson.RootTools.containers.RootClass.Candidate") */
/* #ANNOTATIONS @SupportedSourceVersion(SourceVersion.RELEASE_6) */
public class RootClass /* #ANNOTATIONS extends AbstractProcessor */ {

    /* #ANNOTATIONS
    @Override
    public boolean process(Set<? extends TypeElement> typeElements, RoundEnvironment roundEnvironment) {
        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "I was invoked!!!");

        return false;
    }
    */

    static String PATH_TO_DX = "/Users/Chris/Projects/android-sdk-macosx/build-tools/18.0.1/dx";
    enum READ_STATE { STARTING, FOUND_ANNOTATION; };

    public RootClass(String[] args) throws ClassNotFoundException, NoSuchMethodException,
            IllegalAccessException, InvocationTargetException, InstantiationException {

        // Note: rather than calling System.load("/system/lib/libandroid_runtime.so");
        // which would leave a bunch of unresolved JNI references,
        // we are using the 'withFramework' class as a preloader.
        // So, yeah, russian dolls: withFramework > RootClass > actual method

        String className = args[0];
        RootArgs actualArgs = new RootArgs();
        actualArgs.args = new String[args.length - 1];
        System.arraycopy(args, 1, actualArgs.args, 0, args.length - 1);
        Class<?> classHandler = Class.forName(className);
        Constructor<?> classConstructor = classHandler.getConstructor(RootArgs.class);
        classConstructor.newInstance(actualArgs);
    }

    public @interface Candidate {};

    public class RootArgs {
        public String args[];
    }

    static void displayError(Exception e) {
        // Not using system.err to make it easier to capture from
        // calling library.
        System.out.println("##ERR##" + e.getMessage() + "##");
        e.printStackTrace();
    }

    // I reckon it would be better to investigate classes using getAttribute()
    // however this method allows the developer to simply select "Run" on RootClass
    // and immediately re-generate the necessary jar file.
    static public class AnnotationsFinder {

        private final String AVOIDDIRPATH = "stericson" + File.separator + "RootTools" + File.separator;
        private List<File> classFiles;

        public AnnotationsFinder() throws IOException {
            System.out.println("Discovering root class annotations...");
            classFiles = new ArrayList<File>();
            lookup(new File("src"), classFiles);
            System.out.println("Done discovering annotations. Building jar file.");
            File builtPath = getBuiltPath();
            if(null != builtPath) {
                // Android! Y U no have com.google.common.base.Joiner class?
                String rc1 = "com" + File.separator
                        + "stericson" + File.separator
                        + "RootTools" + File.separator
                        + "containers" + File.separator
                        + "RootClass.class";
                String rc2 = "com" + File.separator
                        + "stericson" + File.separator
                        + "RootTools" + File.separator
                        + "containers" + File.separator
                        + "RootClass$RootArgs.class";
                String rc3 = "com" + File.separator
                        + "stericson" + File.separator
                        + "RootTools" + File.separator
                        + "containers" + File.separator
                        + "RootClass$AnnotationsFinder.class";
                String rc4 = "com" + File.separator
                        + "stericson" + File.separator
                        + "RootTools" + File.separator
                        + "containers" + File.separator
                        + "RootClass$AnnotationsFinder$1.class";
                String rc5 = "com" + File.separator
                        + "stericson" + File.separator
                        + "RootTools" + File.separator
                        + "containers" + File.separator
                        + "RootClass$AnnotationsFinder$2.class";
                String [] cmd;
                boolean onWindows = (-1 != System.getProperty("os.name").toLowerCase().indexOf("win"));
                if(onWindows) {
                    StringBuilder sb = new StringBuilder(
                            " " + rc1 + " " + rc2 + " " + rc3 + " " + rc4 + " " + rc5
                    );
                    for(File file:classFiles) {
                        sb.append(" " + file.getPath());
                    }
                    cmd = new String[] {
                            "cmd", "/C",
                            "jar cvf" +
                            " anbuild.jar" +
                            sb.toString()
                    };
                }
                else {
                    ArrayList<String> al = new ArrayList<String>();
                    al.add("jar");
                    al.add("cf");
                    al.add("anbuild.jar");
                    al.add(rc1);
                    al.add(rc2);
                    al.add(rc3);
                    al.add(rc4);
                    al.add(rc5);
                    for(File file:classFiles) {
                        al.add(file.getPath());
                    }
                    cmd = al.toArray(new String[al.size()]);
                }
                ProcessBuilder jarBuilder = new ProcessBuilder(cmd);
                jarBuilder.directory(builtPath);
                try {
                    jarBuilder.start().waitFor();
                } catch (IOException e) {} catch (InterruptedException e) {}
                
                File rawFolder = new File("res/raw");
                if (!rawFolder.exists()) {
                  rawFolder.mkdirs();
                }
                
                
                System.out.println("Done building jar file. Creating dex file.");
                if(onWindows) {
                    cmd = new String[] {
                            "cmd", "/C",
                            "dx --dex --output=res/raw/anbuild.dex "
                            + builtPath + File.separator + "anbuild.jar"
                    };
                }
                else {
                    cmd = new String[] {
                            getPathToDx(),
                            "--dex",
                            "--output=res/raw/anbuild.dex",
                            builtPath + File.separator + "anbuild.jar"
                    };
                }
                ProcessBuilder dexBuilder = new ProcessBuilder(cmd);
                try {
                    dexBuilder.start().waitFor();
                } catch (IOException e) {} catch (InterruptedException e) {}
            }
            System.out.println("All done. ::: anbuild.dex should now be in your project's res/raw/ folder :::");
        }

        protected void lookup(File path, List<File> fileList) {
            String desourcedPath = path.toString().replace("src/", "");
            File[] files = path.listFiles();
            for(File file:files) {
                if(file.isDirectory()) {
                    if(-1 == file.getAbsolutePath().indexOf(AVOIDDIRPATH)) {
                        lookup(file, fileList);
                    }
                }
                else {
                    if(file.getName().endsWith(".java")) {
                        if(hasClassAnnotation(file)) {
                            final String fileNamePrefix = file.getName().replace(".java", "");
                            final File compiledPath = new File(getBuiltPath().toString() + File.separator + desourcedPath);
                            File[] classAndInnerClassFiles = compiledPath.listFiles(new FilenameFilter() {
                                @Override
                                public boolean accept(File dir, String filename) {
                                    return filename.startsWith(fileNamePrefix);
                                }
                            });
                            for(final File matchingFile:classAndInnerClassFiles) {
                                fileList.add(new File(desourcedPath + File.separator +  matchingFile.getName()));
                            }

                        }
                    }
                }
            }
        }

        protected boolean hasClassAnnotation(File file) {
            READ_STATE readState = READ_STATE.STARTING;
            Pattern p = Pattern.compile(" class ([A-Za-z0-9_]+)");
            try {
                BufferedReader reader = new BufferedReader(new FileReader(file));
                String line;
                while(null != (line = reader.readLine())) {
                    switch(readState) {
                        case STARTING:
                            if(-1 < line.indexOf("@RootClass.Candidate"))
                                readState = READ_STATE.FOUND_ANNOTATION;
                            break;
                        case FOUND_ANNOTATION:
                            Matcher m = p.matcher(line);
                            if(m.find()) {
                                System.out.println(" Found annotated class: " + m.group(0));
                                return true;
                            }
                            else {
                                System.err.println("Error: unmatched annotation in " +
                                        file.getAbsolutePath());
                                readState = READ_STATE.STARTING;
                            }
                            break;
                    }
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return false;
        }

        protected String getPathToDx() throws IOException {
            String androidHome = System.getenv("ANDROID_HOME");
            if(null == androidHome) {
                throw new IOException("Error: you need to set $ANDROID_HOME globally");
            }
            String dxPath = null;
            File[] files = new File(androidHome + File.separator + "build-tools").listFiles();
            int recentSdkVersion = 0;
            for(File file:files) {
                
              String fileName = null;
              if (file.getName().contains("-")) {
                String[] splitFileName = file.getName().split("-");
                if (splitFileName[1].contains("W")) {
                  char[] fileNameChars = splitFileName[1].toCharArray();
                  fileName = String.valueOf(fileNameChars[0]);
                } else {
                  fileName = splitFileName[1];
                }
              } else {
                fileName = file.getName();
              }
              
              int sdkVersion;
                
                String[] sdkVersionBits = fileName.split("[.]");
                sdkVersion = Integer.parseInt(sdkVersionBits[0]) * 10000;
                if(sdkVersionBits.length > 1) {
                    sdkVersion += Integer.parseInt(sdkVersionBits[1]) * 100;
                    if(sdkVersionBits.length > 2) {
                        sdkVersion += Integer.parseInt(sdkVersionBits[2]);
                    }
                }
                if(sdkVersion > recentSdkVersion) {
                    String tentativePath = file.getAbsolutePath() + File.separator + "dx";
                    if(new File(tentativePath).exists()) {
                    recentSdkVersion = sdkVersion;
                        dxPath = tentativePath;
                    }
                }
            }
            if(dxPath == null) {
                throw new IOException("Error: unable to find dx binary in $ANDROID_HOME");
            }
            return dxPath;
        }

        protected File getBuiltPath() {
            File foundPath = null;

            File ideaPath = new File("out" + File.separator + "production"); // IntelliJ
            if(ideaPath.isDirectory()) {
                File[] children = ideaPath.listFiles(new FileFilter() {
                    @Override
                    public boolean accept(File pathname) {
                        return pathname.isDirectory();
                    }
                });
                if(children.length > 0) {
                    foundPath = new File(ideaPath.getAbsolutePath() + File.separator + children[0].getName());
                }
            }
            if(null == foundPath) {
                File eclipsePath = new File("bin" + File.separator + "classes"); // Eclipse IDE
                if(eclipsePath.isDirectory()) {
                    foundPath = eclipsePath;
                }
            }

            return foundPath;
        }


    };

    public static void main (String [] args) {
        try {
            if(args.length == 0) {
                new AnnotationsFinder();
            }
            else {
                new RootClass(args);
            }
        } catch (Exception e) {
            displayError(e);
        }
    }
}




Java Source Code List

com.morlunk.mountie.ApplicationTest.java
com.morlunk.mountie.Automounter.java
com.morlunk.mountie.Constants.java
com.morlunk.mountie.MountieActivity.java
com.morlunk.mountie.MountieBootReceiver.java
com.morlunk.mountie.MountieNotification.java
com.morlunk.mountie.MountieService.java
com.morlunk.mountie.UsbHotplugReceiver.java
com.morlunk.mountie.command.BlkidCommand.java
com.morlunk.mountie.fs.BlockDeviceObserver.java
com.morlunk.mountie.fs.BlockDevice.java
com.morlunk.mountie.fs.MountException.java
com.morlunk.mountie.fs.MountListener.java
com.morlunk.mountie.fs.Mount.java
com.morlunk.mountie.fs.PartitionListener.java
com.morlunk.mountie.fs.Partition.java
com.morlunk.mountie.fs.UnmountListener.java
com.morlunk.mountie.fs.Volume.java
com.morlunk.mountie.jni.Native.java
com.morlunk.mountie.util.Filesystems.java
com.stericson.RootTools.Constants.java
com.stericson.RootTools.RootTools.java
com.stericson.RootTools.containers.Mount.java
com.stericson.RootTools.containers.Permissions.java
com.stericson.RootTools.containers.RootClass.java
com.stericson.RootTools.containers.Symlink.java
com.stericson.RootTools.exceptions.RootDeniedException.java
com.stericson.RootTools.execution.CommandCapture.java
com.stericson.RootTools.execution.Command.java
com.stericson.RootTools.execution.JavaCommandCapture.java
com.stericson.RootTools.execution.Shell.java
com.stericson.RootTools.internal.Installer.java
com.stericson.RootTools.internal.InternalVariables.java
com.stericson.RootTools.internal.Remounter.java
com.stericson.RootTools.internal.RootToolsInternalMethods.java
com.stericson.RootTools.internal.Runner.java