diff --git a/display/BrailleDisplayProperties.aidl b/display/BrailleDisplayProperties.aidl
new file mode 100644
index 0000000..5a7f410
--- /dev/null
+++ b/display/BrailleDisplayProperties.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ *
+ * 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.googlecode.eyesfree.braille.display;
+
+parcelable BrailleDisplayProperties;
diff --git a/display/BrailleDisplayProperties.java b/display/BrailleDisplayProperties.java
new file mode 100644
index 0000000..606476f
--- /dev/null
+++ b/display/BrailleDisplayProperties.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ *
+ * 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.googlecode.eyesfree.braille.display;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Properties of a braille display such as dimensions and keyboard
+ * configuration.
+ */
+public class BrailleDisplayProperties implements Parcelable {
+    private final int mNumTextCells;
+    private final int mNumStatusCells;
+    private final BrailleKeyBinding[] mKeyBindings;
+    private final Map<String, String> mFriendlyKeyNames;
+
+    public BrailleDisplayProperties(int numTextCells, int numStatusCells,
+            BrailleKeyBinding[] keyBindings,
+            Map<String, String> friendlyKeyNames) {
+        mNumTextCells = numTextCells;
+        mNumStatusCells = numStatusCells;
+        mKeyBindings = keyBindings;
+        mFriendlyKeyNames = friendlyKeyNames;
+    }
+
+    /**
+     * Returns the number of cells on the main display intended for display of
+     * text or other content.
+     */
+    public int getNumTextCells() {
+        return mNumTextCells;
+    }
+
+    /**
+     * Returns the number of status cells that are separated from the main
+     * display.  This value will be {@code 0} for displays without any separate
+     * status cells.
+     */
+    public int getNumStatusCells() {
+        return mNumStatusCells;
+    }
+
+    /**
+     * Returns the list of key bindings for this display.
+     */
+    public BrailleKeyBinding[] getKeyBindings() {
+        return mKeyBindings;
+    }
+
+    /**
+     * Returns an unmodifiable map mapping key names in {@link BrailleKeyBinding}
+     * objects to localized user-friendly key names.
+     */
+    public Map<String, String> getFriendlyKeyNames() {
+        return mFriendlyKeyNames;
+    }
+
+    @Override
+    public String toString() {
+        return String.format(
+            "BrailleDisplayProperties [numTextCells: %d, numStatusCells: %d, "
+            + "keyBindings: %d]",
+            mNumTextCells, mNumStatusCells, mKeyBindings.length);
+    }
+
+    // For Parcelable support.
+
+    public static final Parcelable.Creator<BrailleDisplayProperties> CREATOR =
+        new Parcelable.Creator<BrailleDisplayProperties>() {
+            @Override
+            public BrailleDisplayProperties createFromParcel(Parcel in) {
+                return new BrailleDisplayProperties(in);
+            }
+
+            @Override
+            public BrailleDisplayProperties[] newArray(int size) {
+                return new BrailleDisplayProperties[size];
+            }
+        };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mNumTextCells);
+        out.writeInt(mNumStatusCells);
+        out.writeTypedArray(mKeyBindings, flags);
+        out.writeInt(mFriendlyKeyNames.size());
+        for (Map.Entry<String, String> entry : mFriendlyKeyNames.entrySet()) {
+            out.writeString(entry.getKey());
+            out.writeString(entry.getValue());
+        }
+    }
+
+    private BrailleDisplayProperties(Parcel in) {
+        mNumTextCells = in.readInt();
+        mNumStatusCells = in.readInt();
+        mKeyBindings = in.createTypedArray(BrailleKeyBinding.CREATOR);
+        int size = in.readInt();
+        Map<String, String> names = new HashMap<String, String>(size);
+        for (int i = 0; i < size; ++i) {
+            names.put(in.readString(), in.readString());
+        }
+        mFriendlyKeyNames = Collections.unmodifiableMap(names);
+    }
+}
diff --git a/display/BrailleInputEvent.aidl b/display/BrailleInputEvent.aidl
new file mode 100644
index 0000000..f64c080
--- /dev/null
+++ b/display/BrailleInputEvent.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ *
+ * 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.googlecode.eyesfree.braille.display;
+
+parcelable BrailleInputEvent;
diff --git a/display/BrailleInputEvent.java b/display/BrailleInputEvent.java
new file mode 100644
index 0000000..1c2ffb4
--- /dev/null
+++ b/display/BrailleInputEvent.java
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ *
+ * 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.googlecode.eyesfree.braille.display;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.SparseArray;
+
+import java.util.HashMap;
+
+/**
+ * An input event, originating from a braille display.
+ *
+ * An event contains a command that is a high-level representation of the
+ * key or key combination that was pressed on the display such as a
+ * navigation key or braille keyboard combination.  For some commands, there is
+ * also an integer argument that contains additional information.
+ */
+public class BrailleInputEvent implements Parcelable {
+
+    // Movement commands.
+
+    /** Keyboard command: Used when there is no actual command. */
+    public static final int CMD_NONE = -1;
+
+    /** Keyboard command: Navigate upwards. */
+    public static final int CMD_NAV_LINE_PREVIOUS = 1;
+    /** Keyboard command: Navigate downwards. */
+    public static final int CMD_NAV_LINE_NEXT = 2;
+    /** Keyboard command: Navigate left one item. */
+    public static final int CMD_NAV_ITEM_PREVIOUS = 3;
+    /** Keyboard command: Navigate right one item. */
+    public static final int CMD_NAV_ITEM_NEXT = 4;
+    /** Keyboard command: Navigate one display window to the left. */
+    public static final int CMD_NAV_PAN_LEFT = 5;
+    /** Keyboard command: Navigate one display window to the right. */
+    public static final int CMD_NAV_PAN_RIGHT = 6;
+    /** Keyboard command: Navigate to the top or beginning. */
+    public static final int CMD_NAV_TOP = 7;
+    /** Keyboard command: Navigate to the bottom or end. */
+    public static final int CMD_NAV_BOTTOM = 8;
+
+    // Activation commands.
+
+    /** Keyboard command: Activate the currently selected/focused item. */
+    public static final int CMD_ACTIVATE_CURRENT = 20;
+
+    // Scrolling.
+
+    /** Keyboard command: Scroll backward. */
+    public static final int CMD_SCROLL_BACKWARD = 30;
+    /** Keyboard command: Scroll forward. */
+    public static final int CMD_SCROLL_FORWARD = 31;
+
+    // Selection commands.
+
+    /** Keyboard command: Set the start ot the selection. */
+    public static final int CMD_SELECTION_START = 40;
+    /** Keyboard command: Set the end of the selection. */
+    public static final int CMD_SELECTION_END = 41;
+    /** Keyboard command: Select all content of the current field. */
+    public static final int CMD_SELECTION_SELECT_ALL = 42;
+    /** Keyboard command: Cut the content of the selection. */
+    public static final int CMD_SELECTION_CUT = 43;
+    /** Keyboard command: Copy the current selection. */
+    public static final int CMD_SELECTION_COPY = 44;
+    /**
+     * Keyboard command: Paste the content of the clipboard at the current
+     * insertion point.
+     */
+    public static final int CMD_SELECTION_PASTE = 45;
+
+    /**
+     * Keyboard command: Primary routing key pressed, typically
+     * used to move the insertion point or click/tap on the item
+     * under the key.
+     * The argument is the zero-based position, relative to the first cell
+     * on the display, of the cell that is closed to the key that
+     * was pressed.
+     */
+    public static final int CMD_ROUTE = 50;
+
+    // Braille keyboard input.
+
+    /**
+     * Keyboard command: A key combination was pressed on the braille
+     * keyboard.
+     * The argument contains the dots that were pressed as a bitmask.
+     */
+    public static final int CMD_BRAILLE_KEY = 60;
+
+    // Editing keys.
+
+    /** Keyboard command: Enter key. */
+    public static final int CMD_KEY_ENTER = 70;
+    /** Keyboard command: Delete backward. */
+    public static final int CMD_KEY_DEL = 71;
+    /** Keyboard command: Delete forward. */
+    public static final int CMD_KEY_FORWARD_DEL = 72;
+
+    // Glboal navigation keys.
+
+    /** Keyboard command: Back button. */
+    public static final int CMD_GLOBAL_BACK = 90;
+    /** Keyboard command: Home button. */
+    public static final int CMD_GLOBAL_HOME = 91;
+    /** Keyboard command: Recent apps button. */
+    public static final int CMD_GLOBAL_RECENTS = 92;
+    /** Keyboard command: Show notificaitons. */
+    public static final int CMD_GLOBAL_NOTIFICATIONS = 93;
+
+    // Miscelanous commands.
+
+    /** Keyboard command: Invoke keyboard help. */
+    public static final int CMD_HELP = 100;
+
+    // Meanings of the argument to a command.
+
+    /** This command doesn't have an argument. */
+    public static final int ARGUMENT_NONE = 0;
+    /**
+     * The lower order bits of the arguemnt to this command represent braille
+     * dots.  Dot 1 is represented by the rightmost bit and so on until dot 8,
+     * which is represented by bit 7, counted from the right.
+     */
+    public static final int ARGUMENT_DOTS = 1;
+    /**
+     * The argument represents a 0-based position on the display counted from
+     * the leftmost cell.
+     */
+    public static final int ARGUMENT_POSITION = 2;
+
+    private static final SparseArray<String> CMD_NAMES =
+            new SparseArray<String>();
+    private static final HashMap<String, Integer> NAMES_TO_CMDS
+            = new HashMap<String, Integer>();
+    static {
+        CMD_NAMES.append(CMD_NAV_LINE_PREVIOUS, "CMD_NAV_LINE_PREVIOUS");
+        CMD_NAMES.append(CMD_NAV_LINE_NEXT, "CMD_NAV_LINE_NEXT");
+        CMD_NAMES.append(CMD_NAV_ITEM_PREVIOUS, "CMD_NAV_ITEM_PREVIOUS");
+        CMD_NAMES.append(CMD_NAV_ITEM_NEXT, "CMD_NAV_ITEM_NEXT");
+        CMD_NAMES.append(CMD_NAV_PAN_LEFT, "CMD_NAV_PAN_LEFT");
+        CMD_NAMES.append(CMD_NAV_PAN_RIGHT, "CMD_NAV_PAN_RIGHT");
+        CMD_NAMES.append(CMD_NAV_TOP, "CMD_NAV_TOP");
+        CMD_NAMES.append(CMD_NAV_BOTTOM, "CMD_NAV_BOTTOM");
+        CMD_NAMES.append(CMD_ACTIVATE_CURRENT, "CMD_ACTIVATE_CURRENT");
+        CMD_NAMES.append(CMD_SCROLL_BACKWARD, "CMD_SCROLL_BACKWARD");
+        CMD_NAMES.append(CMD_SCROLL_FORWARD, "CMD_SCROLL_FORWARD");
+        CMD_NAMES.append(CMD_SELECTION_START, "CMD_SELECTION_START");
+        CMD_NAMES.append(CMD_SELECTION_END, "CMD_SELECTION_END");
+        CMD_NAMES.append(CMD_SELECTION_SELECT_ALL, "CMD_SELECTION_SELECT_ALL");
+        CMD_NAMES.append(CMD_SELECTION_CUT, "CMD_SELECTION_CUT");
+        CMD_NAMES.append(CMD_SELECTION_COPY, "CMD_SELECTION_COPY");
+        CMD_NAMES.append(CMD_SELECTION_PASTE, "CMD_SELECTION_PASTE");
+        CMD_NAMES.append(CMD_ROUTE, "CMD_ROUTE");
+        CMD_NAMES.append(CMD_BRAILLE_KEY, "CMD_BRAILLE_KEY");
+        CMD_NAMES.append(CMD_KEY_ENTER, "CMD_KEY_ENTER");
+        CMD_NAMES.append(CMD_KEY_DEL, "CMD_KEY_DEL");
+        CMD_NAMES.append(CMD_KEY_FORWARD_DEL, "CMD_KEY_FORWARD_DEL");
+        CMD_NAMES.append(CMD_GLOBAL_BACK, "CMD_GLOBAL_BACK");
+        CMD_NAMES.append(CMD_GLOBAL_HOME, "CMD_GLOBAL_HOME");
+        CMD_NAMES.append(CMD_GLOBAL_RECENTS, "CMD_GLOBAL_RECENTS");
+        CMD_NAMES.append(CMD_GLOBAL_NOTIFICATIONS, "CMD_GLOBAL_NOTIFICATIONS");
+        CMD_NAMES.append(CMD_HELP, "CMD_HELP");
+        for (int i = 0; i < CMD_NAMES.size(); ++i) {
+            NAMES_TO_CMDS.put(CMD_NAMES.valueAt(i),
+                    CMD_NAMES.keyAt(i));
+        }
+    }
+
+    private final int mCommand;
+    private final int mArgument;
+    private final long mEventTime;
+
+    public BrailleInputEvent(int command, int argument, long eventTime) {
+        mCommand = command;
+        mArgument = argument;
+        mEventTime = eventTime;
+    }
+
+    /**
+     * Returns the keyboard command that this event represents.
+     */
+    public int getCommand() {
+        return mCommand;
+    }
+
+    /**
+     * Returns the command-specific argument of the event, or zero if the
+     * command doesn't have an argument.  See the individual command constants
+     * for more details.
+     */
+    public int getArgument() {
+        return mArgument;
+    }
+
+    /**
+     * Returns the approximate time when this event happened as
+     * returned by {@link android.os.SystemClock#uptimeMillis}.
+     */
+    public long getEventTime() {
+        return mEventTime;
+    }
+
+    /**
+     * Returns a string representation of {@code command}, or the string
+     * {@code (unknown)} if the command is unknown.
+     */
+    public static String commandToString(int command) {
+        String ret = CMD_NAMES.get(command);
+        return ret != null ? ret : "(unknown)";
+    }
+
+    /**
+     * Returns the command corresponding to {@code commandName}, or
+     * {@link #CMD_NONE} if the name doesn't match any existing command.
+     */
+    public static int stringToCommand(String commandName) {
+        Integer command = NAMES_TO_CMDS.get(commandName);
+        if (command == null) {
+            return CMD_NONE;
+        }
+        return command;
+    }
+
+    /**
+     * Returns the type of argument for the given {@code command}.
+     */
+    public static int argumentType(int command) {
+        switch (command) {
+            case CMD_SELECTION_START:
+            case CMD_SELECTION_END:
+            case CMD_ROUTE:
+                return ARGUMENT_POSITION;
+            case CMD_BRAILLE_KEY:
+                return ARGUMENT_DOTS;
+            default:
+                return ARGUMENT_NONE;
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("BrailleInputEvent {");
+        sb.append("amd=");
+        sb.append(commandToString(mCommand));
+        sb.append(", arg=");
+        sb.append(mArgument);
+        sb.append("}");
+        return sb.toString();
+    }
+
+    // For Parcelable support.
+
+    public static final Parcelable.Creator<BrailleInputEvent> CREATOR =
+        new Parcelable.Creator<BrailleInputEvent>() {
+            @Override
+            public BrailleInputEvent createFromParcel(Parcel in) {
+                return new BrailleInputEvent(in);
+            }
+
+            @Override
+            public BrailleInputEvent[] newArray(int size) {
+                return new BrailleInputEvent[size];
+            }
+        };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mCommand);
+        out.writeInt(mArgument);
+        out.writeLong(mEventTime);
+    }
+
+    private BrailleInputEvent(Parcel in) {
+        mCommand = in.readInt();
+        mArgument = in.readInt();
+        mEventTime = in.readLong();
+    }
+}
diff --git a/display/BrailleKeyBinding.java b/display/BrailleKeyBinding.java
new file mode 100644
index 0000000..92b58d0
--- /dev/null
+++ b/display/BrailleKeyBinding.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ *
+ * 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.googlecode.eyesfree.braille.display;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Represents a binding between a combination of braille device keys and a
+ * command as declared in {@link BrailleInputEvent}.
+ */
+public class BrailleKeyBinding implements Parcelable {
+    private int mCommand;
+    private String[] mKeyNames;
+
+    public BrailleKeyBinding() {
+    }
+
+    public BrailleKeyBinding(int command, String[] keyNames) {
+        mCommand = command;
+        mKeyNames = keyNames;
+    }
+
+    /**
+     * Sets the command for this binding.
+     */
+    public BrailleKeyBinding setCommand(int command) {
+        mCommand = command;
+        return this;
+    }
+
+    /**
+     * Sets the key names for this binding.
+     */
+    public BrailleKeyBinding setKeyNames(String[] keyNames) {
+        mKeyNames = keyNames;
+        return this;
+    }
+
+    /**
+     * Returns the command for this key binding.
+     * @see {@link BrailleInputEvent}.
+     */
+    public int getCommand() {
+        return mCommand;
+    }
+
+    /**
+     * Returns the list of device-specific keys that, when pressed
+     * at the same time, will yield the command of this key binding.
+     */
+    public String[] getKeyNames() {
+        return mKeyNames;
+    }
+
+    // For Parcelable support.
+
+    public static final Parcelable.Creator<BrailleKeyBinding> CREATOR =
+        new Parcelable.Creator<BrailleKeyBinding>() {
+            @Override
+            public BrailleKeyBinding createFromParcel(Parcel in) {
+                return new BrailleKeyBinding(in);
+            }
+
+            @Override
+            public BrailleKeyBinding[] newArray(int size) {
+                return new BrailleKeyBinding[size];
+            }
+        };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mCommand);
+        out.writeStringArray(mKeyNames);
+    }
+
+    private BrailleKeyBinding(Parcel in) {
+        mCommand = in.readInt();
+        mKeyNames = in.createStringArray();
+    }
+}
diff --git a/display/Display.java b/display/Display.java
new file mode 100644
index 0000000..54a57a2
--- /dev/null
+++ b/display/Display.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ *
+ * 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.googlecode.eyesfree.braille.display;
+
+import android.os.Message;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * A client for the braille display service.
+ */
+public class Display {
+    private static final String LOG_TAG = Display.class.getSimpleName();
+    /** Service name used for connecting to the service. */
+    public static final String ACTION_DISPLAY_SERVICE =
+            "com.googlecode.eyesfree.braille.service.ACTION_DISPLAY_SERVICE";
+
+    /** Initial value, which is never reported to the listener. */
+    private static final int STATE_UNKNOWN = -2;
+    public static final int STATE_ERROR = -1;
+    public static final int STATE_NOT_CONNECTED = 0;
+    public static final int STATE_CONNECTED = 1;
+
+    private final OnConnectionStateChangeListener
+            mConnectionStateChangeListener;
+    private final Context mContext;
+    private final DisplayHandler mHandler;
+    private volatile OnInputEventListener mInputEventListener;
+    private static final Intent mServiceIntent =
+            new Intent(ACTION_DISPLAY_SERVICE);
+    private Connection mConnection;
+    private int currentConnectionState = STATE_UNKNOWN;
+    private BrailleDisplayProperties mDisplayProperties;
+    private ServiceCallback mServiceCallback = new ServiceCallback();
+    /**
+     * Delay before the first rebind attempt on bind error or service
+     * disconnect.
+     */
+    private static final int REBIND_DELAY_MILLIS = 500;
+    private static final int MAX_REBIND_ATTEMPTS = 5;
+    private int mNumFailedBinds = 0;
+
+    /**
+     * A callback interface to get informed about connection state changes.
+     */
+    public interface OnConnectionStateChangeListener {
+        void onConnectionStateChanged(int state);
+    }
+
+    /**
+     * A callback interface for input from the braille display.
+     */
+    public interface OnInputEventListener {
+        void onInputEvent(BrailleInputEvent inputEvent);
+    }
+    
+    /**
+     * Constructs an instance and connects to the braille display service.
+     * The current thread must have an {@link android.os.Looper} associated
+     * with it.  Callbacks from this object will all be executed on the
+     * current thread.  Connection state will be reported to {@code listener).
+     */
+    public Display(Context context, OnConnectionStateChangeListener listener) {
+        this(context, listener, null);
+    }
+
+    /**
+     * Constructs an instance and connects to the braille display service.
+     * Callbacks from this object will all be executed on the thread
+     * associated with {@code handler}.  If {@code handler} is {@code null},
+     * the current thread must have an {@link android.os.Looper} associated
+     * with it, which will then be used to execute callbacks.  Connection
+     * state will be reported to {@code listener).
+     */
+    public Display(Context context, OnConnectionStateChangeListener listener,
+            Handler handler) {
+        mContext = context;
+        mConnectionStateChangeListener = listener;
+        if (handler == null) {
+            mHandler = new DisplayHandler();
+        } else {
+            mHandler = new DisplayHandler(handler);
+        }
+            
+        doBindService();
+    }
+
+    /**
+     * Sets a {@code listener} for input events.  {@code listener} can be
+     * {@code null} to remove a previously set listener.
+     */
+    public void setOnInputEventListener(OnInputEventListener listener) {
+        mInputEventListener = listener;
+    }
+
+    /**
+     * Returns the display properties, or {@code null} if not connected
+     * to a display.
+     */
+    public BrailleDisplayProperties getDisplayProperties() {
+        return mDisplayProperties;
+    }
+
+    /**
+     * Displays a given dots configuration on the braille display.
+     * @param patterns Dots configuration to be displayed.
+     */
+    public void displayDots(byte[] patterns) {
+        IBrailleService localService = getBrailleService();
+        if (localService != null) {
+            try {
+                localService.displayDots(patterns);
+            } catch (RemoteException ex) {
+                Log.e(LOG_TAG, "Error in displayDots", ex);
+            }
+        } else {
+            Log.v(LOG_TAG, "Error in displayDots: service not connected");
+        }
+    }
+
+    /**
+     * Unbinds from the braille display service and deallocates any
+     * resources.  This method should be called when the braille display
+     * is no longer in use by this client.
+     */
+    public void shutdown() {
+        doUnbindService();
+    }
+
+    // NOTE: The methods in this class will be executed in the main
+    // application thread.
+    private class Connection implements ServiceConnection {
+        private volatile IBrailleService mService;
+
+        @Override
+        public void onServiceConnected(ComponentName className,
+                IBinder binder) {
+            Log.i(LOG_TAG, "Connected to braille service");
+            IBrailleService localService =
+                IBrailleService.Stub.asInterface(binder);
+            try {
+                localService.registerCallback(mServiceCallback);
+                mService = localService;
+                synchronized (mHandler) {
+                    mNumFailedBinds = 0;
+                }
+            } catch (RemoteException e) {
+                // In this case the service has crashed before we could even do
+                // anything with it.
+                Log.e(LOG_TAG, "Failed to register callback on service", e);
+                // We should get a disconnected call and the rebind
+                // and failure reporting happens in that handler.
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName className) {
+            mService = null;
+            Log.e(LOG_TAG, "Disconnected from braille service");
+            // Report display disconnected for now, this will turn into a
+            // connected state or error state depending on how the retrying
+            // goes.
+            mHandler.reportConnectionState(STATE_NOT_CONNECTED, null);
+            mHandler.scheduleRebind();
+        }
+    }
+
+    // NOTE: The methods of this class will be executed in the IPC
+    // thread pool and not on the main application thread.
+    private class ServiceCallback extends IBrailleServiceCallback.Stub {
+        @Override
+        public void onDisplayConnected(
+            BrailleDisplayProperties displayProperties) {
+            mHandler.reportConnectionState(STATE_CONNECTED, displayProperties);
+        }
+
+        @Override
+        public void onDisplayDisconnected() {
+            mHandler.reportConnectionState(STATE_NOT_CONNECTED, null);
+        }
+
+        @Override
+        public void onInput(BrailleInputEvent inputEvent) {
+            mHandler.reportInputEvent(inputEvent);
+        }
+    }
+
+    private void doBindService() {
+        Connection localConnection = new Connection();
+        if (!mContext.bindService(mServiceIntent, localConnection,
+                Context.BIND_AUTO_CREATE)) {
+            Log.e(LOG_TAG, "Failed to bind Service");
+            mHandler.scheduleRebind();
+            return;
+        }
+        mConnection = localConnection;
+        Log.i(LOG_TAG, "Bound to braille service");
+    }
+
+    private void doUnbindService() {
+        IBrailleService localService = getBrailleService();
+        if (localService != null) {
+            try {
+                localService.unregisterCallback(mServiceCallback);
+            } catch (RemoteException e) {
+                // Nothing to do if the service can't be reached.
+            }
+        }
+        if (mConnection != null) {
+            mContext.unbindService(mConnection);
+            mConnection = null;
+        }
+    }
+
+    private IBrailleService getBrailleService() {
+        Connection localConnection = mConnection;
+        if (localConnection != null) {
+            return localConnection.mService;
+        }
+        return null;
+    }
+
+    private class DisplayHandler extends Handler {
+        private static final int MSG_REPORT_CONNECTION_STATE = 1;
+        private static final int MSG_REPORT_INPUT_EVENT = 2;
+        private static final int MSG_REBIND_SERVICE = 3;
+
+        public DisplayHandler() {
+        }
+
+        public DisplayHandler(Handler handler) {
+            super(handler.getLooper());
+        }
+
+        public void reportConnectionState(final int newState,
+                final BrailleDisplayProperties displayProperties) {
+            obtainMessage(MSG_REPORT_CONNECTION_STATE, newState, 0,
+                    displayProperties)
+                    .sendToTarget();
+        }
+
+        public void reportInputEvent(BrailleInputEvent event) {
+            obtainMessage(MSG_REPORT_INPUT_EVENT, event).sendToTarget();
+        }
+
+        public void scheduleRebind() {
+            synchronized (this) {
+                if (mNumFailedBinds < MAX_REBIND_ATTEMPTS) {
+                    int delay = REBIND_DELAY_MILLIS << mNumFailedBinds;
+                    sendEmptyMessageDelayed(MSG_REBIND_SERVICE, delay);
+                    ++mNumFailedBinds;
+                    Log.w(LOG_TAG, String.format(
+                        "Will rebind to braille service in %d ms.", delay));
+                } else {
+                    reportConnectionState(STATE_ERROR, null);
+                }
+            }
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_REPORT_CONNECTION_STATE:
+                    handleReportConnectionState(msg.arg1,
+                            (BrailleDisplayProperties) msg.obj);
+                    break;
+                case MSG_REPORT_INPUT_EVENT:
+                    handleReportInputEvent((BrailleInputEvent) msg.obj);
+                    break;
+                case MSG_REBIND_SERVICE:
+                    handleRebindService();
+                    break;
+            }
+        }
+
+        private void handleReportConnectionState(int newState,
+                BrailleDisplayProperties displayProperties) {
+            mDisplayProperties = displayProperties;
+            if (newState != currentConnectionState
+                    && mConnectionStateChangeListener != null) {
+                mConnectionStateChangeListener.onConnectionStateChanged(
+                    newState);
+            }
+            currentConnectionState = newState;
+        }
+
+        private void handleReportInputEvent(BrailleInputEvent event) {
+            OnInputEventListener localListener = mInputEventListener;
+            if (localListener != null) {
+                localListener.onInputEvent(event);
+            }
+        }
+
+        private void handleRebindService() {
+            if (mConnection != null) {
+                doUnbindService();
+            }
+            doBindService();
+        }
+    }
+}
diff --git a/display/IBrailleService.aidl b/display/IBrailleService.aidl
new file mode 100644
index 0000000..2b478bb
--- /dev/null
+++ b/display/IBrailleService.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ *
+ * 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.googlecode.eyesfree.braille.display;
+
+import com.googlecode.eyesfree.braille.display.IBrailleServiceCallback;
+
+/**
+ * Interface for clients to talk to the braille display service.
+ */
+interface IBrailleService {
+    /**
+     * Register a callback for the {@code callingApp} which will receive
+     * certain braille display related events.
+     */
+    boolean registerCallback(in IBrailleServiceCallback callback);
+
+    /**
+     * Unregister a previously registered callback for the {@code callingApp}.
+     */
+    oneway void unregisterCallback(in IBrailleServiceCallback callback);
+
+    /**
+     * Updates the main cells of the connected braille display
+     * with a given dot {@code pattern}.
+     *
+     * @return {@code true} on success and {@code false} otherwise.
+     */
+    void displayDots(in byte[] patterns);
+}
diff --git a/display/IBrailleServiceCallback.aidl b/display/IBrailleServiceCallback.aidl
new file mode 100644
index 0000000..545d1ad
--- /dev/null
+++ b/display/IBrailleServiceCallback.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ *
+ * 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.googlecode.eyesfree.braille.display;
+
+import com.googlecode.eyesfree.braille.display.BrailleDisplayProperties;
+import com.googlecode.eyesfree.braille.display.BrailleInputEvent;
+
+/**
+ * Callback interface that a braille display client can expose to
+ * get information about various braille display events.
+ */
+interface IBrailleServiceCallback {
+    void onDisplayConnected(in BrailleDisplayProperties displayProperties);
+    void onDisplayDisconnected();
+    void onInput(in BrailleInputEvent inputEvent);
+}
diff --git a/selfbraille/ISelfBrailleService.aidl b/selfbraille/ISelfBrailleService.aidl
new file mode 100644
index 0000000..770c283
--- /dev/null
+++ b/selfbraille/ISelfBrailleService.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ *
+ * 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.googlecode.eyesfree.braille.selfbraille;
+
+import com.googlecode.eyesfree.braille.selfbraille.WriteData;
+
+/**
+ * Interface for a client to control braille output for a part of the
+ * accessibility node tree.
+ */
+interface ISelfBrailleService {
+    void write(IBinder clientToken, in WriteData writeData);
+    oneway void disconnect(IBinder clientToken);
+}
diff --git a/selfbraille/SelfBrailleClient.java b/selfbraille/SelfBrailleClient.java
new file mode 100644
index 0000000..e4a363a
--- /dev/null
+++ b/selfbraille/SelfBrailleClient.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ *
+ * 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.googlecode.eyesfree.braille.selfbraille;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.Signature;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * Client-side interface to the self brailling interface.
+ *
+ * Threading: Instances of this object should be created and shut down
+ * in a thread with a {@link Looper} associated with it.  Other methods may
+ * be called on any thread.
+ */
+public class SelfBrailleClient {
+    private static final String LOG_TAG =
+            SelfBrailleClient.class.getSimpleName();
+    private static final String ACTION_SELF_BRAILLE_SERVICE =
+            "com.googlecode.eyesfree.braille.service.ACTION_SELF_BRAILLE_SERVICE";
+    private static final String BRAILLE_BACK_PACKAGE =
+            "com.googlecode.eyesfree.brailleback";
+    private static final Intent mServiceIntent =
+            new Intent(ACTION_SELF_BRAILLE_SERVICE)
+            .setPackage(BRAILLE_BACK_PACKAGE);
+    /**
+     * SHA-1 hash value of the Eyes-Free release key certificate, used to sign
+     * BrailleBack.  It was generated from the keystore with:
+     * $ keytool -exportcert -keystore <keystorefile> -alias android.keystore \
+     *   > cert
+     * $ keytool -printcert -file cert
+     */
+    // The typecasts are to silence a compiler warning about loss of precision
+    private static final byte[] EYES_FREE_CERT_SHA1 = new byte[] {
+        (byte) 0x9B, (byte) 0x42, (byte) 0x4C, (byte) 0x2D,
+        (byte) 0x27, (byte) 0xAD, (byte) 0x51, (byte) 0xA4,
+        (byte) 0x2A, (byte) 0x33, (byte) 0x7E, (byte) 0x0B,
+        (byte) 0xB6, (byte) 0x99, (byte) 0x1C, (byte) 0x76,
+        (byte) 0xEC, (byte) 0xA4, (byte) 0x44, (byte) 0x61
+    };
+    /**
+     * Delay before the first rebind attempt on bind error or service
+     * disconnect.
+     */
+    private static final int REBIND_DELAY_MILLIS = 500;
+    private static final int MAX_REBIND_ATTEMPTS = 5;
+
+    private final Binder mIdentity = new Binder();
+    private final Context mContext;
+    private final boolean mAllowDebugService;
+    private final SelfBrailleHandler mHandler = new SelfBrailleHandler();
+    private boolean mShutdown = false;
+
+    /**
+     * Written in handler thread, read in any thread calling methods on the
+     * object.
+     */
+    private volatile Connection mConnection;
+    /** Protected by synchronizing on mHandler. */
+    private int mNumFailedBinds = 0;
+
+    /**
+     * Constructs an instance of this class.  {@code context} is used to bind
+     * to the self braille service.  The current thread must have a Looper
+     * associated with it.  If {@code allowDebugService} is true, this instance
+     * will connect to a BrailleBack service without requiring it to be signed
+     * by the release key used to sign BrailleBack.
+     */
+    public SelfBrailleClient(Context context, boolean allowDebugService) {
+        mContext = context;
+        mAllowDebugService = allowDebugService;
+        doBindService();
+    }
+
+    /**
+     * Shuts this instance down, deallocating any global resources it is using.
+     * This method must be called on the same thread that created this object.
+     */
+    public void shutdown() {
+        mShutdown = true;
+        doUnbindService();
+    }
+
+    public void write(WriteData writeData) {
+        writeData.validate();
+        ISelfBrailleService localService = getSelfBrailleService();
+        if (localService != null) {
+            try {
+                localService.write(mIdentity, writeData);
+            } catch (RemoteException ex) {
+                Log.e(LOG_TAG, "Self braille write failed", ex);
+            }
+        }
+    }
+
+    private void doBindService() {
+        Connection localConnection = new Connection();
+        if (!mContext.bindService(mServiceIntent, localConnection,
+                Context.BIND_AUTO_CREATE)) {
+            Log.e(LOG_TAG, "Failed to bind to service");
+            mHandler.scheduleRebind();
+            return;
+        }
+        mConnection = localConnection;
+        Log.i(LOG_TAG, "Bound to self braille service");
+    }
+
+    private void doUnbindService() {
+        if (mConnection != null) {
+            ISelfBrailleService localService = getSelfBrailleService();
+            if (localService != null) {
+                try {
+                    localService.disconnect(mIdentity);
+                } catch (RemoteException ex) {
+                    // Nothing to do.
+                }
+            }
+            mContext.unbindService(mConnection);
+            mConnection = null;
+        }
+    }
+
+    private ISelfBrailleService getSelfBrailleService() {
+        Connection localConnection = mConnection;
+        if (localConnection != null) {
+            return localConnection.mService;
+        }
+        return null;
+    }
+
+    private boolean verifyPackage() {
+        PackageManager pm = mContext.getPackageManager();
+        PackageInfo pi;
+        try {
+            pi = pm.getPackageInfo(BRAILLE_BACK_PACKAGE,
+                    PackageManager.GET_SIGNATURES);
+        } catch (PackageManager.NameNotFoundException ex) {
+            Log.w(LOG_TAG, "Can't verify package " + BRAILLE_BACK_PACKAGE,
+                    ex);
+            return false;
+        }
+        MessageDigest digest;
+        try {
+            digest = MessageDigest.getInstance("SHA-1");
+        } catch (NoSuchAlgorithmException ex) {
+            Log.e(LOG_TAG, "SHA-1 not supported", ex);
+            return false;
+        }
+        // Check if any of the certificates match our hash.
+        for (Signature signature : pi.signatures) {
+            digest.update(signature.toByteArray());
+            if (MessageDigest.isEqual(EYES_FREE_CERT_SHA1, digest.digest())) {
+                return true;
+            }
+            digest.reset();
+        }
+        if (mAllowDebugService) {
+            Log.w(LOG_TAG, String.format(
+                "*** %s connected to BrailleBack with invalid (debug?) "
+                + "signature ***",
+                mContext.getPackageName()));
+            return true;
+        }
+        return false;
+    }
+    private class Connection implements ServiceConnection {
+        // Read in application threads, written in main thread.
+        private volatile ISelfBrailleService mService;
+
+        @Override
+        public void onServiceConnected(ComponentName className,
+                IBinder binder) {
+            if (!verifyPackage()) {
+                Log.w(LOG_TAG, String.format("Service certificate mismatch "
+                                + "for %s, dropping connection",
+                                BRAILLE_BACK_PACKAGE));
+                mHandler.unbindService();
+                return;
+            }
+            Log.i(LOG_TAG, "Connected to self braille service");
+            mService = ISelfBrailleService.Stub.asInterface(binder);
+            synchronized (mHandler) {
+                mNumFailedBinds = 0;
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName className) {
+            Log.e(LOG_TAG, "Disconnected from self braille service");
+            mService = null;
+            // Retry by rebinding.
+            mHandler.scheduleRebind();
+        }
+    }
+
+    private class SelfBrailleHandler extends Handler {
+        private static final int MSG_REBIND_SERVICE = 1;
+        private static final int MSG_UNBIND_SERVICE = 2;
+
+        public void scheduleRebind() {
+            synchronized (this) {
+                if (mNumFailedBinds < MAX_REBIND_ATTEMPTS) {
+                    int delay = REBIND_DELAY_MILLIS << mNumFailedBinds;
+                    sendEmptyMessageDelayed(MSG_REBIND_SERVICE, delay);
+                    ++mNumFailedBinds;
+                }
+            }
+        }
+
+        public void unbindService() {
+            sendEmptyMessage(MSG_UNBIND_SERVICE);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_REBIND_SERVICE:
+                    handleRebindService();
+                    break;
+                case MSG_UNBIND_SERVICE:
+                    handleUnbindService();
+                    break;
+            }
+        }
+
+        private void handleRebindService() {
+            if (mShutdown) {
+                return;
+            }
+            if (mConnection != null) {
+                doUnbindService();
+            }
+            doBindService();
+        }
+
+        private void handleUnbindService() {
+            doUnbindService();
+        }
+    }
+}
diff --git a/selfbraille/WriteData.aidl b/selfbraille/WriteData.aidl
new file mode 100644
index 0000000..b02ec85
--- /dev/null
+++ b/selfbraille/WriteData.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ *
+ * 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.googlecode.eyesfree.braille.selfbraille;
+
+parcelable WriteData;
diff --git a/selfbraille/WriteData.java b/selfbraille/WriteData.java
new file mode 100644
index 0000000..3c16502
--- /dev/null
+++ b/selfbraille/WriteData.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ *
+ * 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.googlecode.eyesfree.braille.selfbraille;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.View;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+/**
+ * Represents what should be shown on the braille display for a
+ * part of the accessibility node tree.
+ */
+public class WriteData implements Parcelable {
+
+    private static final String PROP_SELECTION_START = "selectionStart";
+    private static final String PROP_SELECTION_END = "selectionEnd";
+
+    private AccessibilityNodeInfo mAccessibilityNodeInfo;
+    private CharSequence mText;
+    private Bundle mProperties = Bundle.EMPTY;
+
+    /**
+     * Returns a new {@link WriteData} instance for the given {@code view}.
+     */
+    public static WriteData forView(View view) {
+        AccessibilityNodeInfo node = AccessibilityNodeInfo.obtain(view);
+        WriteData writeData = new WriteData();
+        writeData.mAccessibilityNodeInfo = node;
+        return writeData;
+    }
+
+    public AccessibilityNodeInfo getAccessibilityNodeInfo() {
+        return mAccessibilityNodeInfo;
+    }
+
+    /**
+     * Sets the text to be displayed when the accessibility node associated
+     * with this instance has focus.  If this method is not called (or
+     * {@code text} is {@code null}), this client relinquishes control over
+     * this node.
+     */
+    public WriteData setText(CharSequence text) {
+        mText = text;
+        return this;
+    }
+
+    public CharSequence getText() {
+        return mText;
+    }
+
+    /**
+     * Sets the start position in the text of a text selection or cursor that
+     * should be marked on the display.  A negative value (the default) means
+     * no selection will be added.
+     */
+    public WriteData setSelectionStart(int v) {
+        writableProperties().putInt(PROP_SELECTION_START, v);
+        return this;
+    }
+
+    /**
+     * @see {@link #setSelectionStart}.
+     */
+    public int getSelectionStart() {
+        return mProperties.getInt(PROP_SELECTION_START, -1);
+    }
+
+    /**
+     * Sets the end of the text selection to be marked on the display.  This
+     * value should only be non-negative if the selection start is
+     * non-negative.  If this value is <= the selection start, the selection
+     * is a cursor.  Otherwise, the selection covers the range from
+     * start(inclusive) to end (exclusive).
+     *
+     * @see {@link android.text.Selection}.
+     */
+    public WriteData setSelectionEnd(int v) {
+        writableProperties().putInt(PROP_SELECTION_END, v);
+        return this;
+    }
+
+    /**
+     * @see {@link #setSelectionEnd}.
+     */
+    public int getSelectionEnd() {
+        return mProperties.getInt(PROP_SELECTION_END, -1);
+    }
+
+    private Bundle writableProperties() {
+        if (mProperties == Bundle.EMPTY) {
+            mProperties = new Bundle();
+        }
+        return mProperties;
+    }
+
+    /**
+     * Checks constraints on the fields that must be satisfied before sending
+     * this instance to the self braille service.
+     * @throws IllegalStateException
+     */
+    public void validate() throws IllegalStateException {
+        if (mAccessibilityNodeInfo == null) {
+            throw new IllegalStateException(
+                "Accessibility node info can't be null");
+        }
+        int selectionStart = getSelectionStart();
+        int selectionEnd = getSelectionEnd();
+        if (mText == null) {
+            if (selectionStart > 0 || selectionEnd > 0) {
+                throw new IllegalStateException(
+                    "Selection can't be set without text");
+            }
+        } else {
+            if (selectionStart < 0 && selectionEnd >= 0) {
+                throw new IllegalStateException(
+                    "Selection end without start");
+            }
+            int textLength = mText.length();
+            if (selectionStart > textLength || selectionEnd > textLength) {
+                throw new IllegalStateException("Selection out of bounds");
+            }
+        }
+    }
+
+    // For Parcelable support.
+
+    public static final Parcelable.Creator<WriteData> CREATOR =
+        new Parcelable.Creator<WriteData>() {
+            @Override
+            public WriteData createFromParcel(Parcel in) {
+                return new WriteData(in);
+            }
+
+            @Override
+            public WriteData[] newArray(int size) {
+                return new WriteData[size];
+            }
+        };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     * <strong>Note:</strong> The {@link AccessibilityNodeInfo} will be
+     * recycled by this method, don't try to use this more than once.
+     */
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        mAccessibilityNodeInfo.writeToParcel(out, flags);
+        // The above call recycles the node, so make sure we don't use it
+        // anymore.
+        mAccessibilityNodeInfo = null;
+        out.writeString(mText.toString());
+        out.writeBundle(mProperties);
+    }
+
+    private WriteData() {
+    }
+
+    private WriteData(Parcel in) {
+        mAccessibilityNodeInfo =
+                AccessibilityNodeInfo.CREATOR.createFromParcel(in);
+        mText = in.readString();
+        mProperties = in.readBundle();
+    }
+}
diff --git a/translate/BrailleTranslator.java b/translate/BrailleTranslator.java
new file mode 100644
index 0000000..e7ee9cb
--- /dev/null
+++ b/translate/BrailleTranslator.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ *
+ * 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.googlecode.eyesfree.braille.translate;
+
+/**
+ * Translates from text to braille and the other way according to a
+ * particular translation table.
+ */
+public interface BrailleTranslator {
+    /**
+     * Translates a string into the corresponding dot patterns and returns the
+     * resulting byte array.  Returns {@code null} on error.
+     */
+    byte[] translate(String text);
+
+    /**
+     * Translates the braille {@code cells} into the corresponding text, which
+     * is returned.  Returns {@code null} on error.
+     */
+    String backTranslate(byte[] cells);
+}
diff --git a/translate/ITranslatorService.aidl b/translate/ITranslatorService.aidl
new file mode 100644
index 0000000..1ccab87
--- /dev/null
+++ b/translate/ITranslatorService.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ *
+ * 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.googlecode.eyesfree.braille.translate;
+
+import com.googlecode.eyesfree.braille.translate.ITranslatorServiceCallback;
+
+interface ITranslatorService {
+    /**
+     * Sets a callback to be called when the service is ready to translate.
+     * Using any of the other methods in this interface before the
+     * callback is called with a successful status will return
+     * failure.
+     */
+    void setCallback(ITranslatorServiceCallback callback);
+
+    /**
+     * Makes sure that the given table string is valid and that the
+     * table compiles.
+     */
+    boolean checkTable(String tableName);
+
+    /**
+     * Translates text into braille according to the give tableName.
+     * Returns null on fatal translation errors.
+     */
+    byte[] translate(String text, String tableName);
+
+    /**
+     * Translates braille cells into text according to the given table
+     * name.  Returns null on fatal translation errors.
+     */
+    String backTranslate(in byte[] cells, String tableName);
+}
diff --git a/translate/ITranslatorServiceCallback.aidl b/translate/ITranslatorServiceCallback.aidl
new file mode 100644
index 0000000..91c74cb
--- /dev/null
+++ b/translate/ITranslatorServiceCallback.aidl
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ *
+ * 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.googlecode.eyesfree.braille.translate;
+
+oneway interface ITranslatorServiceCallback {
+    void onInit(int status);
+}
diff --git a/translate/TranslatorManager.java b/translate/TranslatorManager.java
new file mode 100644
index 0000000..841a041
--- /dev/null
+++ b/translate/TranslatorManager.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ *
+ * 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.googlecode.eyesfree.braille.translate;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * Client-side interface to the central braille translator service.
+ *
+ * This class can be used to retrieve {@link BrailleTranslator} instances for
+ * performing translation between text and braille cells.
+ *
+ * Typically, an instance of this class is created at application
+ * initialization time and destroyed using the {@link destroy()} method when
+ * the application is about to be destroyed.  It is recommended that the
+ * instance is destroyed and recreated if braille translation is not going to
+ * be need for a long period of time.
+ *
+ * Threading:<br>
+ * The object must be destroyed on the same thread it was created.
+ * Other methods may be called from any thread.
+ */
+public class TranslatorManager {
+    private static final String LOG_TAG =
+            TranslatorManager.class.getSimpleName();
+    private static final String ACTION_TRANSLATOR_SERVICE =
+            "com.googlecode.eyesfree.braille.service.ACTION_TRANSLATOR_SERVICE";
+    private static final Intent mServiceIntent =
+            new Intent(ACTION_TRANSLATOR_SERVICE);
+    /**
+     * Delay before the first rebind attempt on bind error or service
+     * disconnect.
+     */
+    private static final int REBIND_DELAY_MILLIS = 500;
+    private static final int MAX_REBIND_ATTEMPTS = 5;
+    public static final int ERROR = -1;
+    public static final int SUCCESS = 0;
+
+    /**
+     * A callback interface to get notified when the translation
+     * manager is ready to be used, or an error occurred during
+     * initialization.
+     */
+    public interface OnInitListener {
+        /**
+         * Called exactly once when it has been determined that the
+         * translation service is either ready to be used ({@code SUCCESS})
+         * or the service is not available {@code ERROR}.
+         */
+        public void onInit(int status);
+    }
+
+    private final Context mContext;
+    private final TranslatorManagerHandler mHandler =
+            new TranslatorManagerHandler();
+    private final ServiceCallback mServiceCallback = new ServiceCallback();
+
+    private OnInitListener mOnInitListener;
+    private Connection mConnection;
+    private int mNumFailedBinds = 0;
+
+    /**
+     * Constructs an instance.  {@code context} is used to bind to the
+     * translator service.  The other methods of this class should not be
+     * called (they will fail) until {@code onInitListener.onInit()}
+     * is called.
+     */
+    public TranslatorManager(Context context, OnInitListener onInitListener) {
+        mContext = context;
+        mOnInitListener = onInitListener;
+        doBindService();
+    }
+
+    /**
+     * Destroys this instance, deallocating any global resources it is using.
+     * Any {@link BrailleTranslator} objects that were created using this
+     * object are invalid after this call.
+     */
+    public void destroy() {
+        doUnbindService();
+        mHandler.destroy();
+    }
+
+    /**
+     * Returns a new {@link BrailleTranslator} for the translation
+     * table specified by {@code tableName}.
+     */
+    // TODO: Document how to discover valid table names.
+    public BrailleTranslator getTranslator(String tableName) {
+        ITranslatorService localService = getTranslatorService();
+        if (localService != null) {
+            try {
+                if (localService.checkTable(tableName)) {
+                    return new BrailleTranslatorImpl(tableName);
+                }
+            } catch (RemoteException ex) {
+                Log.e(LOG_TAG, "Error in getTranslator", ex);
+            }
+        }
+        return null;
+    }
+
+    private void doBindService() {
+        Connection localConnection = new Connection();
+        if (!mContext.bindService(mServiceIntent, localConnection,
+                Context.BIND_AUTO_CREATE)) {
+            Log.e(LOG_TAG, "Failed to bind to service");
+            mHandler.scheduleRebind();
+            return;
+        }
+        mConnection = localConnection;
+        Log.i(LOG_TAG, "Bound to translator service");
+    }
+
+    private void doUnbindService() {
+        if (mConnection != null) {
+            mContext.unbindService(mConnection);
+            mConnection = null;
+        }
+    }
+
+    private ITranslatorService getTranslatorService() {
+        Connection localConnection = mConnection;
+        if (localConnection != null) {
+            return localConnection.mService;
+        }
+        return null;
+    }
+
+    private class Connection implements ServiceConnection {
+        // Read in application threads, written in main thread.
+        private volatile ITranslatorService mService;
+
+        @Override
+        public void onServiceConnected(ComponentName className,
+                IBinder binder) {
+            Log.i(LOG_TAG, "Connected to translation service");
+            ITranslatorService localService =
+                    ITranslatorService.Stub.asInterface(binder);
+            try {
+                localService.setCallback(mServiceCallback);
+                mService = localService;
+                synchronized (mHandler) {
+                    mNumFailedBinds = 0;
+                }
+            } catch (RemoteException ex) {
+                // Service went away, rely on disconnect handler to
+                // schedule a rebind.
+                Log.e(LOG_TAG, "Error when setting callback", ex);
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName className) {
+            Log.e(LOG_TAG, "Disconnected from translator service");
+            mService = null;
+            // Retry by rebinding, and finally call the onInit if aplicable.
+            mHandler.scheduleRebind();
+        }
+    }
+
+    private class BrailleTranslatorImpl implements BrailleTranslator {
+        private final String mTable;
+
+        public BrailleTranslatorImpl(String table) {
+            mTable = table;
+        }
+
+        @Override
+        public byte[] translate(String text) {
+            ITranslatorService localService = getTranslatorService();
+            if (localService != null) {
+                try {
+                    return localService.translate(text, mTable);
+                } catch (RemoteException ex) {
+                    Log.e(LOG_TAG, "Error in translate", ex);
+                }
+            }
+            return null;
+        }
+
+        @Override
+        public String backTranslate(byte[] cells) {
+            ITranslatorService localService = getTranslatorService();
+            if (localService != null) {
+                try {
+                    return localService.backTranslate(cells, mTable);
+                } catch (RemoteException ex) {
+                    Log.e(LOG_TAG, "Error in backTranslate", ex);
+                }
+            }
+            return null;
+        }
+    }
+
+    private class ServiceCallback extends ITranslatorServiceCallback.Stub {
+        @Override
+        public void onInit(int status) {
+            mHandler.onInit(status);
+        }
+    }
+
+    private class TranslatorManagerHandler extends Handler {
+        private static final int MSG_ON_INIT = 1;
+        private static final int MSG_REBIND_SERVICE = 2;
+
+        public void onInit(int status) {
+            obtainMessage(MSG_ON_INIT, status, 0).sendToTarget();
+        }
+
+        public void destroy() {
+            mOnInitListener = null;
+            // Cacnel outstanding messages, most importantly
+            // scheduled rebinds.
+            removeCallbacksAndMessages(null);
+        }
+
+        public void scheduleRebind() {
+            synchronized (this) {
+                if (mNumFailedBinds < MAX_REBIND_ATTEMPTS) {
+                    int delay = REBIND_DELAY_MILLIS << mNumFailedBinds;
+                    sendEmptyMessageDelayed(MSG_REBIND_SERVICE, delay);
+                    ++mNumFailedBinds;
+                } else {
+                    onInit(ERROR);
+                }
+            }
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_ON_INIT:
+                    handleOnInit(msg.arg1);
+                    break;
+                case MSG_REBIND_SERVICE:
+                    handleRebindService();
+                    break;
+            }
+        }
+
+        private void handleOnInit(int status) {
+            if (mOnInitListener != null) {
+                mOnInitListener.onInit(status);
+                mOnInitListener = null;
+            }
+        }
+
+        private void handleRebindService() {
+            if (mConnection != null) {
+                doUnbindService();
+            }
+            doBindService();
+        }
+    }
+}
