Revert "Move frameworks/base/tools/ to frameworks/tools/"

This reverts commit 9f6a119c8aa276432ece4fe2118bd8a3c9b1067e.
diff --git a/tools/preload/MemoryUsage.java b/tools/preload/MemoryUsage.java
new file mode 100644
index 0000000..d8f95f4
--- /dev/null
+++ b/tools/preload/MemoryUsage.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.Serializable;
+import java.io.IOException;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * Memory usage information.
+ */
+class MemoryUsage implements Serializable {
+
+    private static final long serialVersionUID = 0;
+
+    static final MemoryUsage NOT_AVAILABLE = new MemoryUsage();
+    
+    static int errorCount = 0;
+
+    // These values are in 1kB increments (not 4kB like you'd expect).
+    final int nativeSharedPages;
+    final int javaSharedPages;
+    final int otherSharedPages;
+    final int nativePrivatePages;
+    final int javaPrivatePages;
+    final int otherPrivatePages;
+
+    final int allocCount;
+    final int allocSize;
+    final int freedCount;
+    final int freedSize;
+    final long nativeHeapSize;
+
+    public MemoryUsage(String line) {
+        String[] parsed = line.split(",");
+
+        nativeSharedPages = Integer.parseInt(parsed[1]);
+        javaSharedPages = Integer.parseInt(parsed[2]);
+        otherSharedPages = Integer.parseInt(parsed[3]);
+        nativePrivatePages = Integer.parseInt(parsed[4]);
+        javaPrivatePages = Integer.parseInt(parsed[5]);
+        otherPrivatePages = Integer.parseInt(parsed[6]);
+        allocCount = Integer.parseInt(parsed[7]);
+        allocSize = Integer.parseInt(parsed[8]);
+        freedCount = Integer.parseInt(parsed[9]);
+        freedSize = Integer.parseInt(parsed[10]);
+        nativeHeapSize = Long.parseLong(parsed[11]);
+    }
+
+    MemoryUsage() {
+        nativeSharedPages = -1;
+        javaSharedPages = -1;
+        otherSharedPages = -1;
+        nativePrivatePages = -1;
+        javaPrivatePages = -1;
+        otherPrivatePages = -1;
+
+        allocCount = -1;
+        allocSize = -1;
+        freedCount = -1;
+        freedSize = -1;
+        nativeHeapSize = -1;
+    }
+
+    MemoryUsage(int nativeSharedPages,
+            int javaSharedPages,
+            int otherSharedPages,
+            int nativePrivatePages,
+            int javaPrivatePages,
+            int otherPrivatePages,
+            int allocCount,
+            int allocSize,
+            int freedCount,
+            int freedSize,
+            long nativeHeapSize) {
+        this.nativeSharedPages = nativeSharedPages;
+        this.javaSharedPages = javaSharedPages;
+        this.otherSharedPages = otherSharedPages;
+        this.nativePrivatePages = nativePrivatePages;
+        this.javaPrivatePages = javaPrivatePages;
+        this.otherPrivatePages = otherPrivatePages;
+        this.allocCount = allocCount;
+        this.allocSize = allocSize;
+        this.freedCount = freedCount;
+        this.freedSize = freedSize;
+        this.nativeHeapSize = nativeHeapSize;
+    }
+
+    MemoryUsage subtract(MemoryUsage baseline) {
+        return new MemoryUsage(
+                nativeSharedPages - baseline.nativeSharedPages,
+                javaSharedPages - baseline.javaSharedPages,
+                otherSharedPages - baseline.otherSharedPages,
+                nativePrivatePages - baseline.nativePrivatePages,
+                javaPrivatePages - baseline.javaPrivatePages,
+                otherPrivatePages - baseline.otherPrivatePages,
+                allocCount - baseline.allocCount,
+                allocSize - baseline.allocSize,
+                freedCount - baseline.freedCount,
+                freedSize - baseline.freedSize,
+                nativeHeapSize - baseline.nativeHeapSize);
+    }
+
+    int javaHeapSize() {
+        return allocSize - freedSize;
+    }
+
+    int totalHeap() {
+        return javaHeapSize() + (int) nativeHeapSize;
+    }
+
+    int javaPagesInK() {
+        return javaSharedPages + javaPrivatePages;
+    }
+
+    int nativePagesInK() {
+        return nativeSharedPages + nativePrivatePages;
+    }
+    int otherPagesInK() {
+        return otherSharedPages + otherPrivatePages;
+    }
+
+    int totalPages() {
+        return javaSharedPages + javaPrivatePages + nativeSharedPages +
+                nativePrivatePages + otherSharedPages + otherPrivatePages;
+    }
+
+    /**
+     * Was this information available?
+     */
+    boolean isAvailable() {
+        return nativeSharedPages != -1;
+    }
+
+    /**
+     * Measures baseline memory usage.
+     */
+    static MemoryUsage baseline() {
+        return forClass(null);
+    }
+
+    private static final String CLASS_PATH = "-Xbootclasspath"
+            + ":/system/framework/core.jar"
+            + ":/system/framework/ext.jar"
+            + ":/system/framework/framework.jar"
+            + ":/system/framework/framework-tests.jar"
+            + ":/system/framework/services.jar"
+            + ":/system/framework/loadclass.jar";
+
+    private static final String[] GET_DIRTY_PAGES = {
+        "adb", "shell", "dalvikvm", CLASS_PATH, "LoadClass" };
+
+    /**
+     * Measures memory usage for the given class.
+     */
+    static MemoryUsage forClass(String className) {
+        MeasureWithTimeout measurer = new MeasureWithTimeout(className);
+
+        new Thread(measurer).start();
+
+        synchronized (measurer) {
+            if (measurer.memoryUsage == null) {
+                // Wait up to 10s.
+                try {
+                    measurer.wait(30000);
+                } catch (InterruptedException e) {
+                    System.err.println("Interrupted waiting for measurement.");
+                    e.printStackTrace();
+                    return NOT_AVAILABLE;
+                }
+
+                // If it's still null.
+                if (measurer.memoryUsage == null) {
+                    System.err.println("Timed out while measuring "
+                            + className + ".");
+                    return NOT_AVAILABLE;
+                }
+            }
+
+            System.err.println("Got memory usage for " + className + ".");
+            return measurer.memoryUsage;
+        }
+    }
+
+    static class MeasureWithTimeout implements Runnable {
+
+        final String className;
+        MemoryUsage memoryUsage = null;
+
+        MeasureWithTimeout(String className) {
+            this.className = className;
+        }
+
+        public void run() {
+            MemoryUsage measured = measure();
+
+            synchronized (this) {
+                memoryUsage = measured;
+                notifyAll();
+            }
+        }
+
+        private MemoryUsage measure() {
+            String[] commands = GET_DIRTY_PAGES;
+            if (className != null) {
+                List<String> commandList = new ArrayList<String>(
+                        GET_DIRTY_PAGES.length + 1);
+                commandList.addAll(Arrays.asList(commands));
+                commandList.add(className);
+                commands = commandList.toArray(new String[commandList.size()]);
+            }
+
+            try {
+                final Process process = Runtime.getRuntime().exec(commands);
+
+                final InputStream err = process.getErrorStream();
+
+                // Send error output to stderr.
+                Thread errThread = new Thread() {
+                    @Override
+                    public void run() {
+                        copy(err, System.err);
+                    }
+                };
+                errThread.setDaemon(true);
+                errThread.start();
+
+                BufferedReader in = new BufferedReader(
+                        new InputStreamReader(process.getInputStream()));
+                String line = in.readLine();
+                if (line == null || !line.startsWith("DECAFBAD,")) {
+                    System.err.println("Got bad response for " + className
+                            + ": " + line + "; command was " + Arrays.toString(commands));
+                    errorCount += 1;
+                    return NOT_AVAILABLE;
+                }
+
+                in.close();
+                err.close();
+                process.destroy();                
+
+                return new MemoryUsage(line);
+            } catch (IOException e) {
+                System.err.println("Error getting stats for "
+                        + className + ".");                
+                e.printStackTrace();
+                return NOT_AVAILABLE;
+            }
+        }
+
+    }
+
+    /**
+     * Copies from one stream to another.
+     */
+    private static void copy(InputStream in, OutputStream out) {
+        byte[] buffer = new byte[1024];
+        int read;
+        try {
+            while ((read = in.read(buffer)) > -1) {
+                out.write(buffer, 0, read);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /** Measures memory usage information and stores it in the model. */
+    public static void main(String[] args) throws IOException,
+            ClassNotFoundException {
+        Root root = Root.fromFile(args[0]);
+        root.baseline = baseline();
+        for (LoadedClass loadedClass : root.loadedClasses.values()) {
+            if (loadedClass.systemClass) {
+                loadedClass.measureMemoryUsage();
+            }
+        }
+        root.toFile(args[0]);
+    }
+}