diff --git a/cmds/input/Android.bp b/cmds/input/Android.bp
index a0ebde6..1ee9dd3 100644
--- a/cmds/input/Android.bp
+++ b/cmds/input/Android.bp
@@ -1,8 +1,7 @@
 // Copyright 2008 The Android Open Source Project
 //
 
-java_binary {
+sh_binary {
     name: "input",
-    wrapper: "input",
-    srcs: ["**/*.java"],
+    src: "input",
 }
diff --git a/cmds/input/input b/cmds/input/input
index 2625eba..d7d0414 100755
--- a/cmds/input/input
+++ b/cmds/input/input
@@ -1,3 +1,2 @@
 #!/system/bin/sh
-export CLASSPATH=/system/framework/input.jar
-exec app_process /system/bin com.android.commands.input.Input "$@"
+cmd input "$@"
diff --git a/cmds/input/src/com/android/commands/input/Input.java b/cmds/input/src/com/android/commands/input/Input.java
deleted file mode 100644
index 08216d9..0000000
--- a/cmds/input/src/com/android/commands/input/Input.java
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * Copyright (C) 2007 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.
- */
-
-package com.android.commands.input;
-
-import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.Display.INVALID_DISPLAY;
-
-import android.hardware.input.InputManager;
-import android.os.SystemClock;
-import android.view.InputDevice;
-import android.view.KeyCharacterMap;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.ViewConfiguration;
-
-import com.android.internal.os.BaseCommand;
-
-import java.io.PrintStream;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Command that sends key events to the device, either by their keycode, or by
- * desired character output.
- */
-
-public class Input extends BaseCommand {
-    private static final String TAG = "Input";
-    private static final String INVALID_ARGUMENTS = "Error: Invalid arguments for command: ";
-    private static final String INVALID_DISPLAY_ARGUMENTS =
-            "Error: Invalid arguments for display ID.";
-
-    private static final float DEFAULT_PRESSURE = 1.0f;
-    private static final float NO_PRESSURE = 0.0f;
-
-    private static final Map<String, Integer> SOURCES = new HashMap<String, Integer>() {{
-        put("keyboard", InputDevice.SOURCE_KEYBOARD);
-        put("dpad", InputDevice.SOURCE_DPAD);
-        put("gamepad", InputDevice.SOURCE_GAMEPAD);
-        put("touchscreen", InputDevice.SOURCE_TOUCHSCREEN);
-        put("mouse", InputDevice.SOURCE_MOUSE);
-        put("stylus", InputDevice.SOURCE_STYLUS);
-        put("trackball", InputDevice.SOURCE_TRACKBALL);
-        put("touchpad", InputDevice.SOURCE_TOUCHPAD);
-        put("touchnavigation", InputDevice.SOURCE_TOUCH_NAVIGATION);
-        put("joystick", InputDevice.SOURCE_JOYSTICK);
-    }};
-
-    private static final Map<String, InputCmd> COMMANDS = new HashMap<String, InputCmd>();
-
-    /**
-     * Command-line entry point.
-     *
-     * @param args The command-line arguments
-     */
-    public static void main(String[] args) {
-        (new Input()).run(args);
-    }
-
-    Input() {
-        COMMANDS.put("text", new InputText());
-        COMMANDS.put("keyevent", new InputKeyEvent());
-        COMMANDS.put("tap", new InputTap());
-        COMMANDS.put("swipe", new InputSwipe());
-        COMMANDS.put("draganddrop", new InputDragAndDrop());
-        COMMANDS.put("press", new InputPress());
-        COMMANDS.put("roll", new InputRoll());
-        COMMANDS.put("motionevent", new InputMotionEvent());
-    }
-
-    @Override
-    public void onRun() throws Exception {
-        String arg = nextArgRequired();
-        int inputSource = InputDevice.SOURCE_UNKNOWN;
-
-        // Get source (optional).
-        if (SOURCES.containsKey(arg)) {
-            inputSource = SOURCES.get(arg);
-            arg = nextArgRequired();
-        }
-
-        // Get displayId (optional).
-        int displayId = INVALID_DISPLAY;
-        if ("-d".equals(arg)) {
-            displayId = getDisplayId();
-            arg = nextArgRequired();
-        }
-
-        // Get command and run.
-        InputCmd cmd = COMMANDS.get(arg);
-        if (cmd != null) {
-            try {
-                cmd.run(inputSource, displayId);
-                return;
-            } catch (NumberFormatException ex) {
-                throw new IllegalArgumentException(INVALID_ARGUMENTS + arg);
-            }
-        }
-
-        throw new IllegalArgumentException("Error: Unknown command: " + arg);
-    }
-
-    private int getDisplayId() {
-        String displayArg = nextArgRequired();
-        if ("INVALID_DISPLAY".equalsIgnoreCase(displayArg)) {
-            return INVALID_DISPLAY;
-        } else if ("DEFAULT_DISPLAY".equalsIgnoreCase(displayArg)) {
-            return DEFAULT_DISPLAY;
-        } else {
-            try {
-                final int displayId = Integer.parseInt(displayArg);
-                if (displayId == INVALID_DISPLAY) {
-                    return INVALID_DISPLAY;
-                }
-                return Math.max(displayId, 0);
-            } catch (NumberFormatException e) {
-                throw new IllegalArgumentException(INVALID_DISPLAY_ARGUMENTS);
-            }
-        }
-    }
-
-    class InputText implements InputCmd {
-        @Override
-        public void run(int inputSource, int displayId) {
-            inputSource = getSource(inputSource, InputDevice.SOURCE_KEYBOARD);
-            sendText(inputSource, nextArgRequired(), displayId);
-        }
-
-        /**
-         * Convert the characters of string text into key event's and send to
-         * device.
-         *
-         * @param text is a string of characters you want to input to the device.
-         */
-        private void sendText(int source, final String text, int displayId) {
-            final StringBuffer buff = new StringBuffer(text);
-            boolean escapeFlag = false;
-            for (int i = 0; i < buff.length(); i++) {
-                if (escapeFlag) {
-                    escapeFlag = false;
-                    if (buff.charAt(i) == 's') {
-                        buff.setCharAt(i, ' ');
-                        buff.deleteCharAt(--i);
-                    }
-                }
-                if (buff.charAt(i) == '%') {
-                    escapeFlag = true;
-                }
-            }
-
-            final char[] chars = buff.toString().toCharArray();
-            final KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
-            final KeyEvent[] events = kcm.getEvents(chars);
-            for (int i = 0; i < events.length; i++) {
-                KeyEvent e = events[i];
-                if (source != e.getSource()) {
-                    e.setSource(source);
-                }
-                e.setDisplayId(displayId);
-                injectKeyEvent(e);
-            }
-        }
-    }
-
-    class InputKeyEvent implements InputCmd {
-        @Override
-        public void run(int inputSource, int displayId) {
-            String arg = nextArgRequired();
-            final boolean longpress = "--longpress".equals(arg);
-            if (longpress) {
-                arg = nextArgRequired();
-            }
-
-            do {
-                final int keycode = KeyEvent.keyCodeFromString(arg);
-                sendKeyEvent(inputSource, keycode, longpress, displayId);
-            } while ((arg = nextArg()) != null);
-        }
-
-        private void sendKeyEvent(int inputSource, int keyCode, boolean longpress, int displayId) {
-            final long now = SystemClock.uptimeMillis();
-            int repeatCount = 0;
-
-            KeyEvent event = new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, repeatCount,
-                    0 /*metaState*/, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /*scancode*/, 0 /*flags*/,
-                    inputSource);
-            event.setDisplayId(displayId);
-
-            injectKeyEvent(event);
-            if (longpress) {
-                repeatCount++;
-                injectKeyEvent(KeyEvent.changeTimeRepeat(event, now, repeatCount,
-                        KeyEvent.FLAG_LONG_PRESS));
-            }
-            injectKeyEvent(KeyEvent.changeAction(event, KeyEvent.ACTION_UP));
-        }
-    }
-
-    class InputTap implements InputCmd {
-        @Override
-        public void run(int inputSource, int displayId) {
-            inputSource = getSource(inputSource, InputDevice.SOURCE_TOUCHSCREEN);
-            sendTap(inputSource, Float.parseFloat(nextArgRequired()),
-                    Float.parseFloat(nextArgRequired()), displayId);
-        }
-
-        void sendTap(int inputSource, float x, float y, int displayId) {
-            final long now = SystemClock.uptimeMillis();
-            injectMotionEvent(inputSource, MotionEvent.ACTION_DOWN, now, now, x, y, 1.0f,
-                    displayId);
-            injectMotionEvent(inputSource, MotionEvent.ACTION_UP, now, now, x, y, 0.0f, displayId);
-        }
-    }
-
-    class InputPress extends InputTap {
-        @Override
-        public void run(int inputSource, int displayId) {
-            inputSource = getSource(inputSource, InputDevice.SOURCE_TRACKBALL);
-            sendTap(inputSource, 0.0f, 0.0f, displayId);
-        }
-    }
-
-    class InputSwipe implements InputCmd {
-        @Override
-        public void run(int inputSource, int displayId) {
-            inputSource = getSource(inputSource, InputDevice.SOURCE_TOUCHSCREEN);
-            sendSwipe(inputSource, displayId, false);
-        }
-
-        void sendSwipe(int inputSource, int displayId, boolean isDragDrop) {
-            // Parse two points and duration.
-            final float x1 = Float.parseFloat(nextArgRequired());
-            final float y1 = Float.parseFloat(nextArgRequired());
-            final float x2 = Float.parseFloat(nextArgRequired());
-            final float y2 = Float.parseFloat(nextArgRequired());
-            String durationArg = nextArg();
-            int duration = durationArg != null ? Integer.parseInt(durationArg) : -1;
-            if (duration < 0) {
-                duration = 300;
-            }
-
-            final long down = SystemClock.uptimeMillis();
-            injectMotionEvent(inputSource, MotionEvent.ACTION_DOWN, down, down, x1, y1, 1.0f,
-                    displayId);
-            if (isDragDrop) {
-                // long press until drag start.
-                try {
-                    Thread.sleep(ViewConfiguration.getLongPressTimeout());
-                } catch (InterruptedException e) {
-                    throw new RuntimeException(e);
-                }
-            }
-            long now = SystemClock.uptimeMillis();
-            final long endTime = down + duration;
-            while (now < endTime) {
-                final long elapsedTime = now - down;
-                final float alpha = (float) elapsedTime / duration;
-                injectMotionEvent(inputSource, MotionEvent.ACTION_MOVE, down, now,
-                        lerp(x1, x2, alpha), lerp(y1, y2, alpha), 1.0f, displayId);
-                now = SystemClock.uptimeMillis();
-            }
-            injectMotionEvent(inputSource, MotionEvent.ACTION_UP, down, now, x2, y2, 0.0f,
-                    displayId);
-        }
-    }
-
-    class InputDragAndDrop extends InputSwipe {
-        @Override
-        public void run(int inputSource, int displayId) {
-            inputSource = getSource(inputSource, InputDevice.SOURCE_TOUCHSCREEN);
-            sendSwipe(inputSource, displayId, true);
-        }
-    }
-
-    class InputRoll implements InputCmd {
-        @Override
-        public void run(int inputSource, int displayId) {
-            inputSource = getSource(inputSource, InputDevice.SOURCE_TRACKBALL);
-            sendMove(inputSource, Float.parseFloat(nextArgRequired()),
-                    Float.parseFloat(nextArgRequired()), displayId);
-        }
-
-        /**
-         * Sends a simple zero-pressure move event.
-         *
-         * @param inputSource the InputDevice.SOURCE_* sending the input event
-         * @param dx change in x coordinate due to move
-         * @param dy change in y coordinate due to move
-         */
-        private void sendMove(int inputSource, float dx, float dy, int displayId) {
-            final long now = SystemClock.uptimeMillis();
-            injectMotionEvent(inputSource, MotionEvent.ACTION_MOVE, now, now, dx, dy, 0.0f,
-                    displayId);
-        }
-    }
-
-    class InputMotionEvent implements InputCmd {
-        @Override
-        public void run(int inputSource, int displayId) {
-            inputSource = getSource(inputSource, InputDevice.SOURCE_TOUCHSCREEN);
-            sendMotionEvent(inputSource, nextArgRequired(), Float.parseFloat(nextArgRequired()),
-                    Float.parseFloat(nextArgRequired()), displayId);
-        }
-
-        private void sendMotionEvent(int inputSource, String motionEventType, float x, float y,
-                int displayId) {
-            final int action;
-            final float pressure;
-
-            switch (motionEventType.toUpperCase()) {
-                case "DOWN":
-                    action = MotionEvent.ACTION_DOWN;
-                    pressure = DEFAULT_PRESSURE;
-                    break;
-                case "UP":
-                    action = MotionEvent.ACTION_UP;
-                    pressure = NO_PRESSURE;
-                    break;
-                case "MOVE":
-                    action = MotionEvent.ACTION_MOVE;
-                    pressure = DEFAULT_PRESSURE;
-                    break;
-                default:
-                    throw new IllegalArgumentException("Unknown motionevent " + motionEventType);
-            }
-
-            final long now = SystemClock.uptimeMillis();
-            injectMotionEvent(inputSource, action, now, now, x, y, pressure, displayId);
-        }
-    }
-
-    /**
-     * Abstract class for command
-     * use nextArgRequired or nextArg to check next argument if necessary.
-     */
-    private interface InputCmd {
-        void run(int inputSource, int displayId);
-    }
-
-    private static void injectKeyEvent(KeyEvent event) {
-        InputManager.getInstance().injectInputEvent(event,
-                InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
-    }
-
-    private static int getInputDeviceId(int inputSource) {
-        final int DEFAULT_DEVICE_ID = 0;
-        int[] devIds = InputDevice.getDeviceIds();
-        for (int devId : devIds) {
-            InputDevice inputDev = InputDevice.getDevice(devId);
-            if (inputDev.supportsSource(inputSource)) {
-                return devId;
-            }
-        }
-        return DEFAULT_DEVICE_ID;
-    }
-
-    /**
-     * Builds a MotionEvent and injects it into the event stream.
-     *
-     * @param inputSource the InputDevice.SOURCE_* sending the input event
-     * @param action the MotionEvent.ACTION_* for the event
-     * @param downTime the value of the ACTION_DOWN event happened
-     * @param when the value of SystemClock.uptimeMillis() at which the event happened
-     * @param x x coordinate of event
-     * @param y y coordinate of event
-     * @param pressure pressure of event
-     */
-    private static void injectMotionEvent(int inputSource, int action, long downTime, long when,
-            float x, float y, float pressure, int displayId) {
-        final float DEFAULT_SIZE = 1.0f;
-        final int DEFAULT_META_STATE = 0;
-        final float DEFAULT_PRECISION_X = 1.0f;
-        final float DEFAULT_PRECISION_Y = 1.0f;
-        final int DEFAULT_EDGE_FLAGS = 0;
-        MotionEvent event = MotionEvent.obtain(downTime, when, action, x, y, pressure, DEFAULT_SIZE,
-                DEFAULT_META_STATE, DEFAULT_PRECISION_X, DEFAULT_PRECISION_Y,
-                getInputDeviceId(inputSource), DEFAULT_EDGE_FLAGS);
-        event.setSource(inputSource);
-        if (displayId == INVALID_DISPLAY && (inputSource & InputDevice.SOURCE_CLASS_POINTER) != 0) {
-            displayId = DEFAULT_DISPLAY;
-        }
-        event.setDisplayId(displayId);
-        InputManager.getInstance().injectInputEvent(event,
-                InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
-    }
-
-    private static final float lerp(float a, float b, float alpha) {
-        return (b - a) * alpha + a;
-    }
-
-    private static final int getSource(int inputSource, int defaultSource) {
-        return inputSource == InputDevice.SOURCE_UNKNOWN ? defaultSource : inputSource;
-    }
-
-    @Override
-    public void onShowUsage(PrintStream out) {
-        out.println("Usage: input [<source>] [-d DISPLAY_ID] <command> [<arg>...]");
-        out.println();
-        out.println("The sources are: ");
-        for (String src : SOURCES.keySet()) {
-            out.println("      " + src);
-        }
-        out.println();
-        out.printf("-d: specify the display ID.\n"
-                + "      (Default: %d for key event, %d for motion event if not specified.)",
-                INVALID_DISPLAY, DEFAULT_DISPLAY);
-        out.println();
-        out.println("The commands and default sources are:");
-        out.println("      text <string> (Default: touchscreen)");
-        out.println("      keyevent [--longpress] <key code number or name> ..."
-                + " (Default: keyboard)");
-        out.println("      tap <x> <y> (Default: touchscreen)");
-        out.println("      swipe <x1> <y1> <x2> <y2> [duration(ms)]"
-                + " (Default: touchscreen)");
-        out.println("      draganddrop <x1> <y1> <x2> <y2> [duration(ms)]"
-                + " (Default: touchscreen)");
-        out.println("      press (Default: trackball)");
-        out.println("      roll <dx> <dy> (Default: trackball)");
-        out.println("      motionevent <DOWN|UP|MOVE> <x> <y> (Default: touchscreen)");
-    }
-}
