Bug 1303468 - Part 1: Move more things into GeckoView. r=jchen
authorNick Alexander <nalexander@mozilla.com>
Fri, 16 Sep 2016 15:53:39 -0700
changeset 357278 49a5ddfbe8a5273e2872d3072497bfa2df6a5ca6
parent 357252 de1a8aef2e8dea90c6ca09a7cb16edef83d0b27f
child 357279 d5f96835f8355a672c0fa75d2980af22af02ebb3
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-beta@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjchen
bugs1303468
milestone51.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1303468 - Part 1: Move more things into GeckoView. r=jchen MozReview-Commit-ID: CEjyq0TFn6j
mobile/android/base/java/org/mozilla/gecko/SysInfo.java
mobile/android/base/java/org/mozilla/gecko/annotation/JNITarget.java
mobile/android/base/java/org/mozilla/gecko/annotation/ReflectionTarget.java
mobile/android/base/java/org/mozilla/gecko/annotation/RobocopTarget.java
mobile/android/base/java/org/mozilla/gecko/annotation/WebRTCJNITarget.java
mobile/android/base/java/org/mozilla/gecko/annotation/WrapForJNI.java
mobile/android/base/moz.build
mobile/android/geckoview/src/main/java/org/mozilla/gecko/SysInfo.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/annotation/JNITarget.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/annotation/ReflectionTarget.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/annotation/RobocopTarget.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/annotation/WebRTCJNITarget.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/annotation/WrapForJNI.java
mobile/android/geckoview/src/thirdparty/java/com/googlecode/eyesfree/braille/selfbraille/ISelfBrailleService.java
mobile/android/geckoview/src/thirdparty/java/com/googlecode/eyesfree/braille/selfbraille/SelfBrailleClient.java
mobile/android/geckoview/src/thirdparty/java/com/googlecode/eyesfree/braille/selfbraille/WriteData.java
mobile/android/thirdparty/com/googlecode/eyesfree/braille/selfbraille/ISelfBrailleService.java
mobile/android/thirdparty/com/googlecode/eyesfree/braille/selfbraille/SelfBrailleClient.java
mobile/android/thirdparty/com/googlecode/eyesfree/braille/selfbraille/WriteData.java
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -6,31 +6,34 @@
 
 DIRS += ['locales']
 
 CONFIGURE_SUBST_FILES += ['adjust_sdk_app_token']
 
 include('android-services.mozbuild')
 
 geckoview_source_dir = TOPSRCDIR + '/mobile/android/geckoview/src/main/'
+geckoview_thirdparty_source_dir = TOPSRCDIR + '/mobile/android/geckoview/src/thirdparty/'
 thirdparty_source_dir = TOPSRCDIR + '/mobile/android/thirdparty/'
 
 constants_jar = add_java_jar('constants')
-constants_jar.sources = ['java/org/mozilla/gecko/' + x for x in [
-    'adjust/AdjustHelperInterface.java',
-    'adjust/AttributionHelperListener.java',
+constants_jar.sources += [geckoview_source_dir + 'java/org/mozilla/gecko/' + x for x in [
     'annotation/JNITarget.java',
     'annotation/ReflectionTarget.java',
     'annotation/RobocopTarget.java',
     'annotation/WebRTCJNITarget.java',
     'annotation/WrapForJNI.java',
+    'SysInfo.java',
+]]
+constants_jar.sources += ['java/org/mozilla/gecko/' + x for x in [
+    'adjust/AdjustHelperInterface.java',
+    'adjust/AttributionHelperListener.java',
     'db/BrowserContract.java',
     'LocaleManager.java',
     'Locales.java',
-    'SysInfo.java',
 ]]
 constants_jar.generated_sources = [
     'preprocessed/org/mozilla/gecko/AdjustConstants.java',
     'preprocessed/org/mozilla/gecko/AppConstants.java',
 ]
 constants_jar.extra_jars = [
     CONFIG['ANDROID_SUPPORT_ANNOTATIONS_JAR_LIB'],
     CONFIG['ANDROID_SUPPORT_V4_AAR_LIB'],
@@ -284,20 +287,20 @@ gvjar.sources += [geckoview_source_dir +
     'sqlite/ByteBufferInputStream.java',
     'sqlite/MatrixBlobCursor.java',
     'sqlite/SQLiteBridge.java',
     'sqlite/SQLiteBridgeException.java',
     'TouchEventInterceptor.java',
     'widget/SwipeDismissListViewTouchListener.java',
 ]]
 
-gvjar.sources += [thirdparty_source_dir + f for f in [
-    'com/googlecode/eyesfree/braille/selfbraille/ISelfBrailleService.java',
-    'com/googlecode/eyesfree/braille/selfbraille/SelfBrailleClient.java',
-    'com/googlecode/eyesfree/braille/selfbraille/WriteData.java',
+gvjar.sources += [geckoview_thirdparty_source_dir + f for f in [
+    'java/com/googlecode/eyesfree/braille/selfbraille/ISelfBrailleService.java',
+    'java/com/googlecode/eyesfree/braille/selfbraille/SelfBrailleClient.java',
+    'java/com/googlecode/eyesfree/braille/selfbraille/WriteData.java',
 ]]
 
 gvjar.extra_jars += [
     CONFIG['ANDROID_SUPPORT_ANNOTATIONS_JAR_LIB'],
     CONFIG['ANDROID_SUPPORT_V4_AAR_LIB'],
     CONFIG['ANDROID_SUPPORT_V4_AAR_INTERNAL_LIB'],
     'constants.jar',
     'gecko-R.jar',
rename from mobile/android/base/java/org/mozilla/gecko/SysInfo.java
rename to mobile/android/geckoview/src/main/java/org/mozilla/gecko/SysInfo.java
rename from mobile/android/base/java/org/mozilla/gecko/annotation/JNITarget.java
rename to mobile/android/geckoview/src/main/java/org/mozilla/gecko/annotation/JNITarget.java
rename from mobile/android/base/java/org/mozilla/gecko/annotation/ReflectionTarget.java
rename to mobile/android/geckoview/src/main/java/org/mozilla/gecko/annotation/ReflectionTarget.java
rename from mobile/android/base/java/org/mozilla/gecko/annotation/RobocopTarget.java
rename to mobile/android/geckoview/src/main/java/org/mozilla/gecko/annotation/RobocopTarget.java
rename from mobile/android/base/java/org/mozilla/gecko/annotation/WebRTCJNITarget.java
rename to mobile/android/geckoview/src/main/java/org/mozilla/gecko/annotation/WebRTCJNITarget.java
rename from mobile/android/base/java/org/mozilla/gecko/annotation/WrapForJNI.java
rename to mobile/android/geckoview/src/main/java/org/mozilla/gecko/annotation/WrapForJNI.java
new file mode 100644
--- /dev/null
+++ b/mobile/android/geckoview/src/thirdparty/java/com/googlecode/eyesfree/braille/selfbraille/ISelfBrailleService.java
@@ -0,0 +1,147 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package com.googlecode.eyesfree.braille.selfbraille;
+
+/**
+ * Interface for a client to control braille output for a part of the
+ * accessibility node tree.
+ */
+public interface ISelfBrailleService extends android.os.IInterface {
+    /** Local-side IPC implementation stub class. */
+    public static abstract class Stub extends android.os.Binder implements
+            com.googlecode.eyesfree.braille.selfbraille.ISelfBrailleService {
+        private static final java.lang.String DESCRIPTOR = "com.googlecode.eyesfree.braille.selfbraille.ISelfBrailleService";
+
+        /** Construct the stub at attach it to the interface. */
+        public Stub() {
+            this.attachInterface(this, DESCRIPTOR);
+        }
+
+        /**
+         * Cast an IBinder object into an
+         * com.googlecode.eyesfree.braille.selfbraille.ISelfBrailleService
+         * interface, generating a proxy if needed.
+         */
+        public static com.googlecode.eyesfree.braille.selfbraille.ISelfBrailleService asInterface(
+                android.os.IBinder obj) {
+            if ((obj == null)) {
+                return null;
+            }
+            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
+            if (((iin != null) && (iin instanceof com.googlecode.eyesfree.braille.selfbraille.ISelfBrailleService))) {
+                return ((com.googlecode.eyesfree.braille.selfbraille.ISelfBrailleService) iin);
+            }
+            return new com.googlecode.eyesfree.braille.selfbraille.ISelfBrailleService.Stub.Proxy(
+                    obj);
+        }
+
+        @Override
+        public android.os.IBinder asBinder() {
+            return this;
+        }
+
+        @Override
+        public boolean onTransact(int code, android.os.Parcel data,
+                android.os.Parcel reply, int flags)
+                throws android.os.RemoteException {
+            switch (code) {
+            case INTERFACE_TRANSACTION: {
+                reply.writeString(DESCRIPTOR);
+                return true;
+            }
+            case TRANSACTION_write: {
+                data.enforceInterface(DESCRIPTOR);
+                android.os.IBinder _arg0;
+                _arg0 = data.readStrongBinder();
+                com.googlecode.eyesfree.braille.selfbraille.WriteData _arg1;
+                if ((0 != data.readInt())) {
+                    _arg1 = com.googlecode.eyesfree.braille.selfbraille.WriteData.CREATOR
+                            .createFromParcel(data);
+                } else {
+                    _arg1 = null;
+                }
+                this.write(_arg0, _arg1);
+                reply.writeNoException();
+                return true;
+            }
+            case TRANSACTION_disconnect: {
+                data.enforceInterface(DESCRIPTOR);
+                android.os.IBinder _arg0;
+                _arg0 = data.readStrongBinder();
+                this.disconnect(_arg0);
+                return true;
+            }
+            }
+            return super.onTransact(code, data, reply, flags);
+        }
+
+        private static class Proxy implements
+                com.googlecode.eyesfree.braille.selfbraille.ISelfBrailleService {
+            private android.os.IBinder mRemote;
+
+            Proxy(android.os.IBinder remote) {
+                mRemote = remote;
+            }
+
+            @Override
+            public android.os.IBinder asBinder() {
+                return mRemote;
+            }
+
+            public java.lang.String getInterfaceDescriptor() {
+                return DESCRIPTOR;
+            }
+
+            @Override
+            public void write(
+                    android.os.IBinder clientToken,
+                    com.googlecode.eyesfree.braille.selfbraille.WriteData writeData)
+                    throws android.os.RemoteException {
+                android.os.Parcel _data = android.os.Parcel.obtain();
+                android.os.Parcel _reply = android.os.Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeStrongBinder(clientToken);
+                    if ((writeData != null)) {
+                        _data.writeInt(1);
+                        writeData.writeToParcel(_data, 0);
+                    } else {
+                        _data.writeInt(0);
+                    }
+                    mRemote.transact(Stub.TRANSACTION_write, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+
+            @Override
+            public void disconnect(android.os.IBinder clientToken)
+                    throws android.os.RemoteException {
+                android.os.Parcel _data = android.os.Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeStrongBinder(clientToken);
+                    mRemote.transact(Stub.TRANSACTION_disconnect, _data, null,
+                            android.os.IBinder.FLAG_ONEWAY);
+                } finally {
+                    _data.recycle();
+                }
+            }
+        }
+
+        static final int TRANSACTION_write = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
+        static final int TRANSACTION_disconnect = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
+    }
+
+    public void write(android.os.IBinder clientToken,
+            com.googlecode.eyesfree.braille.selfbraille.WriteData writeData)
+            throws android.os.RemoteException;
+
+    public void disconnect(android.os.IBinder clientToken)
+            throws android.os.RemoteException;
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/geckoview/src/thirdparty/java/com/googlecode/eyesfree/braille/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();
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/geckoview/src/thirdparty/java/com/googlecode/eyesfree/braille/selfbraille/WriteData.java
@@ -0,0 +1,192 @@
+/*
+ * 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 static WriteData forInfo(AccessibilityNodeInfo info){
+        WriteData writeData = new WriteData();
+        writeData.mAccessibilityNodeInfo = info;
+        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();
+    }
+}
deleted file mode 100644
--- a/mobile/android/thirdparty/com/googlecode/eyesfree/braille/selfbraille/ISelfBrailleService.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package com.googlecode.eyesfree.braille.selfbraille;
-
-/**
- * Interface for a client to control braille output for a part of the
- * accessibility node tree.
- */
-public interface ISelfBrailleService extends android.os.IInterface {
-    /** Local-side IPC implementation stub class. */
-    public static abstract class Stub extends android.os.Binder implements
-            com.googlecode.eyesfree.braille.selfbraille.ISelfBrailleService {
-        private static final java.lang.String DESCRIPTOR = "com.googlecode.eyesfree.braille.selfbraille.ISelfBrailleService";
-
-        /** Construct the stub at attach it to the interface. */
-        public Stub() {
-            this.attachInterface(this, DESCRIPTOR);
-        }
-
-        /**
-         * Cast an IBinder object into an
-         * com.googlecode.eyesfree.braille.selfbraille.ISelfBrailleService
-         * interface, generating a proxy if needed.
-         */
-        public static com.googlecode.eyesfree.braille.selfbraille.ISelfBrailleService asInterface(
-                android.os.IBinder obj) {
-            if ((obj == null)) {
-                return null;
-            }
-            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
-            if (((iin != null) && (iin instanceof com.googlecode.eyesfree.braille.selfbraille.ISelfBrailleService))) {
-                return ((com.googlecode.eyesfree.braille.selfbraille.ISelfBrailleService) iin);
-            }
-            return new com.googlecode.eyesfree.braille.selfbraille.ISelfBrailleService.Stub.Proxy(
-                    obj);
-        }
-
-        @Override
-        public android.os.IBinder asBinder() {
-            return this;
-        }
-
-        @Override
-        public boolean onTransact(int code, android.os.Parcel data,
-                android.os.Parcel reply, int flags)
-                throws android.os.RemoteException {
-            switch (code) {
-            case INTERFACE_TRANSACTION: {
-                reply.writeString(DESCRIPTOR);
-                return true;
-            }
-            case TRANSACTION_write: {
-                data.enforceInterface(DESCRIPTOR);
-                android.os.IBinder _arg0;
-                _arg0 = data.readStrongBinder();
-                com.googlecode.eyesfree.braille.selfbraille.WriteData _arg1;
-                if ((0 != data.readInt())) {
-                    _arg1 = com.googlecode.eyesfree.braille.selfbraille.WriteData.CREATOR
-                            .createFromParcel(data);
-                } else {
-                    _arg1 = null;
-                }
-                this.write(_arg0, _arg1);
-                reply.writeNoException();
-                return true;
-            }
-            case TRANSACTION_disconnect: {
-                data.enforceInterface(DESCRIPTOR);
-                android.os.IBinder _arg0;
-                _arg0 = data.readStrongBinder();
-                this.disconnect(_arg0);
-                return true;
-            }
-            }
-            return super.onTransact(code, data, reply, flags);
-        }
-
-        private static class Proxy implements
-                com.googlecode.eyesfree.braille.selfbraille.ISelfBrailleService {
-            private android.os.IBinder mRemote;
-
-            Proxy(android.os.IBinder remote) {
-                mRemote = remote;
-            }
-
-            @Override
-            public android.os.IBinder asBinder() {
-                return mRemote;
-            }
-
-            public java.lang.String getInterfaceDescriptor() {
-                return DESCRIPTOR;
-            }
-
-            @Override
-            public void write(
-                    android.os.IBinder clientToken,
-                    com.googlecode.eyesfree.braille.selfbraille.WriteData writeData)
-                    throws android.os.RemoteException {
-                android.os.Parcel _data = android.os.Parcel.obtain();
-                android.os.Parcel _reply = android.os.Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeStrongBinder(clientToken);
-                    if ((writeData != null)) {
-                        _data.writeInt(1);
-                        writeData.writeToParcel(_data, 0);
-                    } else {
-                        _data.writeInt(0);
-                    }
-                    mRemote.transact(Stub.TRANSACTION_write, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void disconnect(android.os.IBinder clientToken)
-                    throws android.os.RemoteException {
-                android.os.Parcel _data = android.os.Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeStrongBinder(clientToken);
-                    mRemote.transact(Stub.TRANSACTION_disconnect, _data, null,
-                            android.os.IBinder.FLAG_ONEWAY);
-                } finally {
-                    _data.recycle();
-                }
-            }
-        }
-
-        static final int TRANSACTION_write = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
-        static final int TRANSACTION_disconnect = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
-    }
-
-    public void write(android.os.IBinder clientToken,
-            com.googlecode.eyesfree.braille.selfbraille.WriteData writeData)
-            throws android.os.RemoteException;
-
-    public void disconnect(android.os.IBinder clientToken)
-            throws android.os.RemoteException;
-}
deleted file mode 100644
--- a/mobile/android/thirdparty/com/googlecode/eyesfree/braille/selfbraille/SelfBrailleClient.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * 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();
-        }
-    }
-}
deleted file mode 100644
--- a/mobile/android/thirdparty/com/googlecode/eyesfree/braille/selfbraille/WriteData.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * 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 static WriteData forInfo(AccessibilityNodeInfo info){
-        WriteData writeData = new WriteData();
-        writeData.mAccessibilityNodeInfo = info;
-        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();
-    }
-}